]>
Commit | Line | Data |
---|---|---|
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 | #include "config.h" | |
22 | #include "RegExpObject.h" | |
23 | ||
24 | #include "Error.h" | |
25 | #include "JSArray.h" | |
26 | #include "JSGlobalObject.h" | |
27 | #include "JSString.h" | |
28 | #include "Lookup.h" | |
29 | #include "RegExpConstructor.h" | |
30 | #include "RegExpPrototype.h" | |
31 | ||
32 | namespace JSC { | |
33 | ||
34 | static JSValue regExpObjectGlobal(ExecState*, JSValue, const Identifier&); | |
35 | static JSValue regExpObjectIgnoreCase(ExecState*, JSValue, const Identifier&); | |
36 | static JSValue regExpObjectMultiline(ExecState*, JSValue, const Identifier&); | |
37 | static JSValue regExpObjectSource(ExecState*, JSValue, const Identifier&); | |
38 | static JSValue regExpObjectLastIndex(ExecState*, JSValue, const Identifier&); | |
39 | static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue); | |
40 | ||
41 | } // namespace JSC | |
42 | ||
43 | #include "RegExpObject.lut.h" | |
44 | ||
45 | namespace JSC { | |
46 | ||
47 | ASSERT_CLASS_FITS_IN_CELL(RegExpObject); | |
48 | ||
49 | const ClassInfo RegExpObject::info = { "RegExp", 0, 0, ExecState::regExpTable }; | |
50 | ||
51 | /* Source for RegExpObject.lut.h | |
52 | @begin regExpTable | |
53 | global regExpObjectGlobal DontDelete|ReadOnly|DontEnum | |
54 | ignoreCase regExpObjectIgnoreCase DontDelete|ReadOnly|DontEnum | |
55 | multiline regExpObjectMultiline DontDelete|ReadOnly|DontEnum | |
56 | source regExpObjectSource DontDelete|ReadOnly|DontEnum | |
57 | lastIndex regExpObjectLastIndex DontDelete|DontEnum | |
58 | @end | |
59 | */ | |
60 | ||
61 | RegExpObject::RegExpObject(NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp) | |
62 | : JSObject(structure) | |
63 | , d(new RegExpObjectData(regExp, 0)) | |
64 | { | |
65 | } | |
66 | ||
67 | RegExpObject::~RegExpObject() | |
68 | { | |
69 | } | |
70 | ||
71 | bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) | |
72 | { | |
73 | return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot); | |
74 | } | |
75 | ||
76 | bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) | |
77 | { | |
78 | return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor); | |
79 | } | |
80 | ||
81 | JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&) | |
82 | { | |
83 | return jsBoolean(asRegExpObject(slotBase)->regExp()->global()); | |
84 | } | |
85 | ||
86 | JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&) | |
87 | { | |
88 | return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()); | |
89 | } | |
90 | ||
91 | JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&) | |
92 | { | |
93 | return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()); | |
94 | } | |
95 | ||
96 | JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&) | |
97 | { | |
98 | return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern()); | |
99 | } | |
100 | ||
101 | JSValue regExpObjectLastIndex(ExecState* exec, JSValue slotBase, const Identifier&) | |
102 | { | |
103 | return jsNumber(exec, asRegExpObject(slotBase)->lastIndex()); | |
104 | } | |
105 | ||
106 | void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) | |
107 | { | |
108 | lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); | |
109 | } | |
110 | ||
111 | void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value) | |
112 | { | |
113 | asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec)); | |
114 | } | |
115 | ||
116 | JSValue RegExpObject::test(ExecState* exec, const ArgList& args) | |
117 | { | |
118 | return jsBoolean(match(exec, args)); | |
119 | } | |
120 | ||
121 | JSValue RegExpObject::exec(ExecState* exec, const ArgList& args) | |
122 | { | |
123 | if (match(exec, args)) | |
124 | return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec); | |
125 | return jsNull(); | |
126 | } | |
127 | ||
128 | static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args) | |
129 | { | |
130 | return asRegExpObject(function)->exec(exec, args); | |
131 | } | |
132 | ||
133 | CallType RegExpObject::getCallData(CallData& callData) | |
134 | { | |
135 | callData.native.function = callRegExpObject; | |
136 | return CallTypeHost; | |
137 | } | |
138 | ||
139 | // Shared implementation used by test and exec. | |
140 | bool RegExpObject::match(ExecState* exec, const ArgList& args) | |
141 | { | |
142 | RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor(); | |
143 | ||
144 | UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec); | |
145 | if (input.isNull()) { | |
146 | throwError(exec, GeneralError, makeString("No input to ", toString(exec), ".")); | |
147 | return false; | |
148 | } | |
149 | ||
150 | if (!regExp()->global()) { | |
151 | int position; | |
152 | int length; | |
153 | regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length); | |
154 | return position >= 0; | |
155 | } | |
156 | ||
157 | if (d->lastIndex < 0 || d->lastIndex > input.size()) { | |
158 | d->lastIndex = 0; | |
159 | return false; | |
160 | } | |
161 | ||
162 | int position; | |
163 | int length = 0; | |
164 | regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length); | |
165 | if (position < 0) { | |
166 | d->lastIndex = 0; | |
167 | return false; | |
168 | } | |
169 | ||
170 | d->lastIndex = position + length; | |
171 | return true; | |
172 | } | |
173 | ||
174 | } // namespace JSC |