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