]> git.saurik.com Git - apple/javascriptcore.git/blob - runtime/RegExpConstructor.h
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / runtime / RegExpConstructor.h
1 /*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2003, 2007, 2008 Apple Inc. All Rights Reserved.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 *
19 */
20
21 #ifndef RegExpConstructor_h
22 #define RegExpConstructor_h
23
24 #include "InternalFunction.h"
25 #include "RegExp.h"
26 #include "RegExpCachedResult.h"
27 #include "RegExpObject.h"
28
29 namespace JSC {
30
31 class RegExpPrototype;
32
33 class RegExpConstructor : public InternalFunction {
34 public:
35 typedef InternalFunction Base;
36 static const unsigned StructureFlags = Base::StructureFlags | OverridesGetOwnPropertySlot;
37
38 static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
39 {
40 RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
41 constructor->finishCreation(vm, regExpPrototype);
42 return constructor;
43 }
44
45 static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue prototype)
46 {
47 return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
48 }
49
50 static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
51
52 DECLARE_INFO;
53
54 MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
55 MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
56
57 void setMultiline(bool multiline) { m_multiline = multiline; }
58 bool multiline() const { return m_multiline; }
59
60 JSValue getBackref(ExecState*, unsigned);
61 JSValue getLastParen(ExecState*);
62 JSValue getLeftContext(ExecState*);
63 JSValue getRightContext(ExecState*);
64
65 void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
66 JSString* input() { return m_cachedResult.input(); }
67
68 static void visitChildren(JSCell*, SlotVisitor&);
69
70 protected:
71 void finishCreation(VM&, RegExpPrototype*);
72
73 private:
74 RegExpConstructor(VM&, Structure*, RegExpPrototype*);
75 static void destroy(JSCell*);
76 static ConstructType getConstructData(JSCell*, ConstructData&);
77 static CallType getCallData(JSCell*, CallData&);
78
79 RegExpCachedResult m_cachedResult;
80 bool m_multiline;
81 Vector<int, 32> m_ovector;
82 };
83
84 RegExpConstructor* asRegExpConstructor(JSValue);
85
86 JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, bool callAsConstructor = false);
87
88 inline RegExpConstructor* asRegExpConstructor(JSValue value)
89 {
90 ASSERT(asObject(value)->inherits(RegExpConstructor::info()));
91 return static_cast<RegExpConstructor*>(asObject(value));
92 }
93
94 /*
95 To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
96 expression matching through the performMatch function. We use cached results to calculate,
97 e.g., RegExp.lastMatch and RegExp.leftParen.
98 */
99 ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
100 {
101 int position = regExp->match(vm, input, startOffset, m_ovector);
102
103 if (ovector)
104 *ovector = m_ovector.data();
105
106 if (position == -1)
107 return MatchResult::failed();
108
109 ASSERT(!m_ovector.isEmpty());
110 ASSERT(m_ovector[0] == position);
111 ASSERT(m_ovector[1] >= position);
112 size_t end = m_ovector[1];
113
114 m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
115
116 return MatchResult(position, end);
117 }
118 ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
119 {
120 MatchResult result = regExp->match(vm, input, startOffset);
121 if (result)
122 m_cachedResult.record(vm, this, regExp, string, result);
123 return result;
124 }
125
126 } // namespace JSC
127
128 #endif // RegExpConstructor_h