source: webkit/trunk/JavaScriptCore/runtime/RegExpObject.cpp@ 48331

Last change on this file since 48331 was 47780, checked in by [email protected], 16 years ago

[ES5] Implement getOwnPropertyDescriptor
https://bugs.webkit.org/show_bug.cgi?id=28724

Reviewed by Gavin Barraclough.

JavaScriptCore:
Implement the core runtime support for getOwnPropertyDescriptor.
This adds a virtual getOwnPropertyDescriptor method to every class
that implements getOwnPropertySlot that shadows the behaviour of
getOwnPropertySlot. The alternative would be to make getOwnPropertySlot
(or PropertySlots in general) provide property attribute information,
but quick testing showed this to be a regression.

WebCore:
Implement the WebCore side of getOwnPropertyDescriptor. This
requires a custom implementation of getOwnPropertyDescriptor
for every class with a custom implementation of getOwnPropertySlot.

The bindings generator has been updated to generate appropriate
versions of getOwnPropertyDescriptor for the general case where
a custom getOwnPropertyDescriptor is not needed. ES5 is vague
about how getOwnPropertyDescriptor should work in the context of
"host" functions with polymorphic GetOwnProperty, so it seems
okay that occasionally we "guess" what attributes -- eg. determining
whether a property is writable.

Test: fast/js/getOwnPropertyDescriptor.html

  • Property svn:eol-style set to native
File size: 5.7 KB
Line 
1/*
2 * Copyright (C) 1999-2000 Harri Porten ([email protected])
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
31namespace JSC {
32
33static JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot&);
34static JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot&);
35static JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot&);
36static JSValue regExpObjectSource(ExecState*, const Identifier&, const PropertySlot&);
37static JSValue regExpObjectLastIndex(ExecState*, const Identifier&, const PropertySlot&);
38static void setRegExpObjectLastIndex(ExecState*, JSObject*, JSValue);
39
40} // namespace JSC
41
42#include "RegExpObject.lut.h"
43
44namespace JSC {
45
46ASSERT_CLASS_FITS_IN_CELL(RegExpObject);
47
48const 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
60RegExpObject::RegExpObject(PassRefPtr<Structure> structure, PassRefPtr<RegExp> regExp)
61 : JSObject(structure)
62 , d(new RegExpObjectData(regExp, 0))
63{
64}
65
66RegExpObject::~RegExpObject()
67{
68}
69
70bool RegExpObject::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
71{
72 return getStaticValueSlot<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, slot);
73}
74
75bool RegExpObject::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
76{
77 return getStaticValueDescriptor<RegExpObject, JSObject>(exec, ExecState::regExpTable(exec), this, propertyName, descriptor);
78}
79
80JSValue regExpObjectGlobal(ExecState*, const Identifier&, const PropertySlot& slot)
81{
82 return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->global());
83}
84
85JSValue regExpObjectIgnoreCase(ExecState*, const Identifier&, const PropertySlot& slot)
86{
87 return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->ignoreCase());
88}
89
90JSValue regExpObjectMultiline(ExecState*, const Identifier&, const PropertySlot& slot)
91{
92 return jsBoolean(asRegExpObject(slot.slotBase())->regExp()->multiline());
93}
94
95JSValue regExpObjectSource(ExecState* exec, const Identifier&, const PropertySlot& slot)
96{
97 return jsString(exec, asRegExpObject(slot.slotBase())->regExp()->pattern());
98}
99
100JSValue regExpObjectLastIndex(ExecState* exec, const Identifier&, const PropertySlot& slot)
101{
102 return jsNumber(exec, asRegExpObject(slot.slotBase())->lastIndex());
103}
104
105void 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
110void setRegExpObjectLastIndex(ExecState* exec, JSObject* baseObject, JSValue value)
111{
112 asRegExpObject(baseObject)->setLastIndex(value.toInteger(exec));
113}
114
115JSValue RegExpObject::test(ExecState* exec, const ArgList& args)
116{
117 return jsBoolean(match(exec, args));
118}
119
120JSValue 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
127static JSValue JSC_HOST_CALL callRegExpObject(ExecState* exec, JSObject* function, JSValue, const ArgList& args)
128{
129 return asRegExpObject(function)->exec(exec, args);
130}
131
132CallType RegExpObject::getCallData(CallData& callData)
133{
134 callData.native.function = callRegExpObject;
135 return CallTypeHost;
136}
137
138// Shared implementation used by test and exec.
139bool 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;
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
Note: See TracBrowser for help on using the repository browser.