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