1/*
2 * Copyright (C) 2019 Apple Inc. All Rights Reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#pragma once
27
28#include "RegExpGlobalData.h"
29
30namespace JSC {
31
32inline void RegExpGlobalData::setInput(JSGlobalObject* globalObject, JSString* string)
33{
34 m_cachedResult.setInput(globalObject, globalObject, string);
35}
36
37/*
38 To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
39 expression matching through the performMatch function. We use cached results to calculate,
40 e.g., RegExp.lastMatch and RegExp.leftParen.
41*/
42ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
43{
44 int position = regExp->match(vm, input, startOffset, m_ovector);
45
46 if (ovector)
47 *ovector = m_ovector.data();
48
49 if (position == -1)
50 return MatchResult::failed();
51
52 ASSERT(!m_ovector.isEmpty());
53 ASSERT(m_ovector[0] == position);
54 ASSERT(m_ovector[1] >= position);
55 size_t end = m_ovector[1];
56
57 m_cachedResult.record(vm, owner, regExp, string, MatchResult(position, end));
58
59 return MatchResult(position, end);
60}
61
62ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset)
63{
64 MatchResult result = regExp->match(vm, input, startOffset);
65 if (result)
66 m_cachedResult.record(vm, owner, regExp, string, result);
67 return result;
68}
69
70ALWAYS_INLINE void RegExpGlobalData::recordMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const MatchResult& result)
71{
72 ASSERT(result);
73 m_cachedResult.record(vm, owner, regExp, string, result);
74}
75
76}
77