]>
Commit | Line | Data |
---|---|---|
9dae56ea A |
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 | ||
ba379fdc | 24 | #include "Error.h" |
9dae56ea A |
25 | #include "JSArray.h" |
26 | #include "JSGlobalObject.h" | |
27 | #include "JSString.h" | |
4e4e5a6f | 28 | #include "Lookup.h" |
9dae56ea A |
29 | #include "RegExpConstructor.h" |
30 | #include "RegExpPrototype.h" | |
31 | ||
32 | namespace JSC { | |
33 | ||
4e4e5a6f A |
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&); | |
ba379fdc | 39 | static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue); |
9dae56ea A |
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 | ||
f9bf01c6 | 61 | RegExpObject::RegExpObject(NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<RegExp> regExp) |
9dae56ea A |
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 | ||
f9bf01c6 A |
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 | ||
4e4e5a6f | 81 | JSValue regExpObjectGlobal(ExecState*, JSValue slotBase, const Identifier&) |
9dae56ea | 82 | { |
4e4e5a6f | 83 | return jsBoolean(asRegExpObject(slotBase)->regExp()->global()); |
9dae56ea A |
84 | } |
85 | ||
4e4e5a6f | 86 | JSValue regExpObjectIgnoreCase(ExecState*, JSValue slotBase, const Identifier&) |
9dae56ea | 87 | { |
4e4e5a6f | 88 | return jsBoolean(asRegExpObject(slotBase)->regExp()->ignoreCase()); |
9dae56ea A |
89 | } |
90 | ||
4e4e5a6f | 91 | JSValue regExpObjectMultiline(ExecState*, JSValue slotBase, const Identifier&) |
9dae56ea | 92 | { |
4e4e5a6f | 93 | return jsBoolean(asRegExpObject(slotBase)->regExp()->multiline()); |
9dae56ea A |
94 | } |
95 | ||
4e4e5a6f | 96 | JSValue regExpObjectSource(ExecState* exec, JSValue slotBase, const Identifier&) |
9dae56ea | 97 | { |
4e4e5a6f | 98 | return jsString(exec, asRegExpObject(slotBase)->regExp()->pattern()); |
9dae56ea A |
99 | } |
100 | ||
4e4e5a6f | 101 | JSValue regExpObjectLastIndex(ExecState* exec, JSValue slotBase, const Identifier&) |
9dae56ea | 102 | { |
4e4e5a6f | 103 | return jsNumber(exec, asRegExpObject(slotBase)->lastIndex()); |
9dae56ea A |
104 | } |
105 | ||
ba379fdc | 106 | void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) |
9dae56ea A |
107 | { |
108 | lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot); | |
109 | } | |
110 | ||
ba379fdc | 111 | void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value) |
9dae56ea A |
112 | { |
113 | asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec)); | |
114 | } | |
115 | ||
ba379fdc | 116 | JSValue RegExpObject::test(ExecState* exec, const ArgList& args) |
9dae56ea A |
117 | { |
118 | return jsBoolean(match(exec, args)); | |
119 | } | |
120 | ||
ba379fdc | 121 | JSValue RegExpObject::exec(ExecState* exec, const ArgList& args) |
9dae56ea A |
122 | { |
123 | if (match(exec, args)) | |
124 | return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec); | |
125 | return jsNull(); | |
126 | } | |
127 | ||
ba379fdc | 128 | static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args) |
9dae56ea A |
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 | ||
ba379fdc | 144 | UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec); |
9dae56ea | 145 | if (input.isNull()) { |
f9bf01c6 | 146 | throwError(exec, GeneralError, makeString("No input to ", toString(exec), ".")); |
9dae56ea A |
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; | |
f9bf01c6 | 163 | int length = 0; |
9dae56ea A |
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 |