0
|
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 "RegExpConstructor.h"
|
|
29 |
#include "RegExpPrototype.h"
|
|
30 |
|
|
31 |
namespace JSC {
|
|
32 |
|
|
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);
|
|
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(NonNullPassRefPtr<Structure> structure, NonNullPassRefPtr<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 |
|
|
75 |
bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
|
|
76 |
{
|
|
77 |
return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor);
|
|
78 |
}
|
|
79 |
|
|
80 |
JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
|
|
81 |
{
|
|
82 |
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
|
|
83 |
}
|
|
84 |
|
|
85 |
JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
|
|
86 |
{
|
|
87 |
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
|
|
88 |
}
|
|
89 |
|
|
90 |
JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
|
|
91 |
{
|
|
92 |
return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
|
|
93 |
}
|
|
94 |
|
|
95 |
JSValue regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
|
|
96 |
{
|
|
97 |
return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
|
|
98 |
}
|
|
99 |
|
|
100 |
JSValue regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
|
|
101 |
{
|
|
102 |
return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
|
|
103 |
}
|
|
104 |
|
|
105 |
void RegExpObject::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
|
|
106 |
{
|
|
107 |
lookupPut<RegExpObject, JSObject>(exec, propertyName, value, ExecState::regExpTable(exec), this, slot);
|
|
108 |
}
|
|
109 |
|
|
110 |
void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
|
|
111 |
{
|
|
112 |
asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
|
|
113 |
}
|
|
114 |
|
|
115 |
JSValue RegExpObject::test(ExecState* exec, const ArgList& args)
|
|
116 |
{
|
|
117 |
return jsBoolean(match(exec, args));
|
|
118 |
}
|
|
119 |
|
|
120 |
JSValue RegExpObject::exec(ExecState* exec, const ArgList& args)
|
|
121 |
{
|
|
122 |
if (match(exec, args))
|
|
123 |
return exec->lexicalGlobalObject()->regExpConstructor()->arrayOfMatches(exec);
|
|
124 |
return jsNull();
|
|
125 |
}
|
|
126 |
|
|
127 |
static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args)
|
|
128 |
{
|
|
129 |
return asRegExpObject(function)->exec(exec, args);
|
|
130 |
}
|
|
131 |
|
|
132 |
CallType RegExpObject::getCallData(CallData& callData)
|
|
133 |
{
|
|
134 |
callData.native.function = callRegExpObject;
|
|
135 |
return CallTypeHost;
|
|
136 |
}
|
|
137 |
|
|
138 |
// Shared implementation used by test and exec.
|
|
139 |
bool RegExpObject::match(ExecState* exec, const ArgList& args)
|
|
140 |
{
|
|
141 |
RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
|
|
142 |
|
|
143 |
UString input = args.isEmpty() ? regExpConstructor->input() : args.at(0).toString(exec);
|
|
144 |
if (input.isNull()) {
|
|
145 |
throwError(exec, GeneralError, "No input to " + toString(exec) + ".");
|
|
146 |
return false;
|
|
147 |
}
|
|
148 |
|
|
149 |
if (!regExp()->global()) {
|
|
150 |
int position;
|
|
151 |
int length;
|
|
152 |
regExpConstructor->performMatch(d->regExp.get(), input, 0, position, length);
|
|
153 |
return position >= 0;
|
|
154 |
}
|
|
155 |
|
|
156 |
if (d->lastIndex < 0 || d->lastIndex > input.size()) {
|
|
157 |
d->lastIndex = 0;
|
|
158 |
return false;
|
|
159 |
}
|
|
160 |
|
|
161 |
int position;
|
|
162 |
int length = 0;
|
|
163 |
regExpConstructor->performMatch(d->regExp.get(), input, static_cast<int>(d->lastIndex), position, length);
|
|
164 |
if (position < 0) {
|
|
165 |
d->lastIndex = 0;
|
|
166 |
return false;
|
|
167 |
}
|
|
168 |
|
|
169 |
d->lastIndex = position + length;
|
|
170 |
return true;
|
|
171 |
}
|
|
172 |
|
|
173 |
} // namespace JSC
|