source: webkit/trunk/JavaScriptCore/runtime/Arguments.cpp@ 58224

Last change on this file since 58224 was 53170, checked in by [email protected], 15 years ago

2010-01-12 Kent Hansen <[email protected]>

Reviewed by Geoffrey Garen.

[ES5] Implement Object.getOwnPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=32242

Add an extra argument to getPropertyNames() and getOwnPropertyNames()
(and all reimplementations thereof) that indicates whether non-enumerable
properties should be added.

  • API/JSCallbackObject.h:
  • API/JSCallbackObjectFunctions.h: (JSC::::getOwnPropertyNames):
  • JavaScriptCore.exp:
  • JavaScriptCore.vcproj/JavaScriptCore/JavaScriptCore.def:
  • debugger/DebuggerActivation.cpp: (JSC::DebuggerActivation::getOwnPropertyNames):
  • debugger/DebuggerActivation.h:
  • runtime/Arguments.cpp: (JSC::Arguments::getOwnPropertyNames):
  • runtime/Arguments.h:
  • runtime/CommonIdentifiers.h:
  • runtime/JSArray.cpp: (JSC::JSArray::getOwnPropertyNames):
  • runtime/JSArray.h:
  • runtime/JSByteArray.cpp: (JSC::JSByteArray::getOwnPropertyNames):
  • runtime/JSByteArray.h:
  • runtime/JSFunction.cpp: (JSC::JSFunction::getOwnPropertyNames):
  • runtime/JSFunction.h:
  • runtime/JSNotAnObject.cpp: (JSC::JSNotAnObject::getOwnPropertyNames):
  • runtime/JSNotAnObject.h:
  • runtime/JSObject.cpp: (JSC::getClassPropertyNames): (JSC::JSObject::getPropertyNames): (JSC::JSObject::getOwnPropertyNames):
  • runtime/JSObject.h:
  • runtime/JSVariableObject.cpp: (JSC::JSVariableObject::getOwnPropertyNames):
  • runtime/JSVariableObject.h:
  • runtime/ObjectConstructor.cpp: (JSC::ObjectConstructor::ObjectConstructor): (JSC::objectConstructorGetOwnPropertyNames):
  • runtime/RegExpMatchesArray.h: (JSC::RegExpMatchesArray::getOwnPropertyNames):
  • runtime/StringObject.cpp: (JSC::StringObject::getOwnPropertyNames):
  • runtime/StringObject.h:
  • runtime/Structure.cpp: Rename getEnumerablePropertyNames() to getPropertyNames(), which takes an extra argument. (JSC::Structure::getPropertyNames):
  • runtime/Structure.h: (JSC::):

2010-01-12 Kent Hansen <[email protected]>

Reviewed by Geoffrey Garen.

[ES5] Implement Object.getOwnPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=32242

Add new argument to the reimplementation of getOwnPropertyNames().

  • UserObjectImp.cpp: (UserObjectImp::getOwnPropertyNames):
  • UserObjectImp.h:

2010-01-12 Kent Hansen <[email protected]>

Reviewed by Geoffrey Garen.

[ES5] Implement Object.getOwnPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=32242

Add tests for Object.getOwnPropertyNames(o), both standard usage and cross origin.

  • fast/js/Object-getOwnPropertyNames-expected.txt: Added.
  • fast/js/Object-getOwnPropertyNames.html: Added.
  • fast/js/script-tests/Object-getOwnPropertyNames.js: Added.
  • http/tests/security/cross-frame-access-enumeration-expected.txt:
  • http/tests/security/cross-frame-access-enumeration.html:

2010-01-12 Kent Hansen <[email protected]>

Reviewed by Geoffrey Garen.

[ES5] Implement Object.getOwnPropertyNames
https://bugs.webkit.org/show_bug.cgi?id=32242

Add new argument to reimplementations of getPropertyNames()
and getOwnPropertyNames(), and update the JS bindings generator.

Test: fast/js/Object-getOwnPropertyNames.html

  • bindings/js/JSDOMWindowCustom.cpp: (WebCore::JSDOMWindow::getPropertyNames): (WebCore::JSDOMWindow::getOwnPropertyNames):
  • bindings/js/JSDOMWindowShell.cpp: (WebCore::JSDOMWindowShell::getPropertyNames): (WebCore::JSDOMWindowShell::getOwnPropertyNames):
  • bindings/js/JSDOMWindowShell.h:
  • bindings/js/JSHistoryCustom.cpp: (WebCore::JSHistory::getOwnPropertyNames):
  • bindings/js/JSLocationCustom.cpp: (WebCore::JSLocation::getOwnPropertyNames):
  • bindings/js/JSQuarantinedObjectWrapper.cpp: (WebCore::JSQuarantinedObjectWrapper::getPropertyNames): (WebCore::JSQuarantinedObjectWrapper::getOwnPropertyNames):
  • bindings/js/JSQuarantinedObjectWrapper.h:
  • bindings/js/JSStorageCustom.cpp: (WebCore::JSStorage::getOwnPropertyNames):
  • bindings/scripts/CodeGeneratorJS.pm:
  • bridge/runtime_array.cpp: (JSC::RuntimeArray::getOwnPropertyNames):
  • bridge/runtime_array.h:
  • bridge/runtime_object.cpp: (JSC::RuntimeObjectImp::getPropertyNames): (JSC::RuntimeObjectImp::getOwnPropertyNames):
  • bridge/runtime_object.h:
  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 * Copyright (C) 1999-2002 Harri Porten ([email protected])
3 * Copyright (C) 2001 Peter Kelly ([email protected])
4 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
5 * Copyright (C) 2007 Cameron Zwarich ([email protected])
6 * Copyright (C) 2007 Maks Orlovich
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#include "config.h"
26#include "Arguments.h"
27
28#include "JSActivation.h"
29#include "JSFunction.h"
30#include "JSGlobalObject.h"
31
32using namespace std;
33
34namespace JSC {
35
36ASSERT_CLASS_FITS_IN_CELL(Arguments);
37
38const ClassInfo Arguments::info = { "Arguments", 0, 0, 0 };
39
40Arguments::~Arguments()
41{
42 if (d->extraArguments != d->extraArgumentsFixedBuffer)
43 delete [] d->extraArguments;
44}
45
46void Arguments::markChildren(MarkStack& markStack)
47{
48 JSObject::markChildren(markStack);
49
50 if (d->registerArray)
51 markStack.appendValues(reinterpret_cast<JSValue*>(d->registerArray.get()), d->numParameters);
52
53 if (d->extraArguments) {
54 unsigned numExtraArguments = d->numArguments - d->numParameters;
55 markStack.appendValues(reinterpret_cast<JSValue*>(d->extraArguments), numExtraArguments);
56 }
57
58 markStack.append(d->callee);
59
60 if (d->activation)
61 markStack.append(d->activation);
62}
63
64void Arguments::copyToRegisters(ExecState* exec, Register* buffer, uint32_t maxSize)
65{
66 if (UNLIKELY(d->overrodeLength)) {
67 unsigned length = min(get(exec, exec->propertyNames().length).toUInt32(exec), maxSize);
68 for (unsigned i = 0; i < length; i++)
69 buffer[i] = get(exec, i);
70 return;
71 }
72
73 if (LIKELY(!d->deletedArguments)) {
74 unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
75 unsigned i = 0;
76 for (; i < parametersLength; ++i)
77 buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
78 for (; i < d->numArguments; ++i)
79 buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
80 return;
81 }
82
83 unsigned parametersLength = min(min(d->numParameters, d->numArguments), maxSize);
84 unsigned i = 0;
85 for (; i < parametersLength; ++i) {
86 if (!d->deletedArguments[i])
87 buffer[i] = d->registers[d->firstParameterIndex + i].jsValue();
88 else
89 buffer[i] = get(exec, i);
90 }
91 for (; i < d->numArguments; ++i) {
92 if (!d->deletedArguments[i])
93 buffer[i] = d->extraArguments[i - d->numParameters].jsValue();
94 else
95 buffer[i] = get(exec, i);
96 }
97}
98
99void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
100{
101 if (UNLIKELY(d->overrodeLength)) {
102 unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
103 for (unsigned i = 0; i < length; i++)
104 args.append(get(exec, i));
105 return;
106 }
107
108 if (LIKELY(!d->deletedArguments)) {
109 if (LIKELY(!d->numParameters)) {
110 args.initialize(d->extraArguments, d->numArguments);
111 return;
112 }
113
114 if (d->numParameters == d->numArguments) {
115 args.initialize(&d->registers[d->firstParameterIndex], d->numArguments);
116 return;
117 }
118
119 unsigned parametersLength = min(d->numParameters, d->numArguments);
120 unsigned i = 0;
121 for (; i < parametersLength; ++i)
122 args.append(d->registers[d->firstParameterIndex + i].jsValue());
123 for (; i < d->numArguments; ++i)
124 args.append(d->extraArguments[i - d->numParameters].jsValue());
125 return;
126 }
127
128 unsigned parametersLength = min(d->numParameters, d->numArguments);
129 unsigned i = 0;
130 for (; i < parametersLength; ++i) {
131 if (!d->deletedArguments[i])
132 args.append(d->registers[d->firstParameterIndex + i].jsValue());
133 else
134 args.append(get(exec, i));
135 }
136 for (; i < d->numArguments; ++i) {
137 if (!d->deletedArguments[i])
138 args.append(d->extraArguments[i - d->numParameters].jsValue());
139 else
140 args.append(get(exec, i));
141 }
142}
143
144bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
145{
146 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
147 if (i < d->numParameters) {
148 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
149 } else
150 slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
151 return true;
152 }
153
154 return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot);
155}
156
157bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
158{
159 bool isArrayIndex;
160 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
161 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
162 if (i < d->numParameters) {
163 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
164 } else
165 slot.setValue(d->extraArguments[i - d->numParameters].jsValue());
166 return true;
167 }
168
169 if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) {
170 slot.setValue(jsNumber(exec, d->numArguments));
171 return true;
172 }
173
174 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
175 slot.setValue(d->callee);
176 return true;
177 }
178
179 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
180}
181
182bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor)
183{
184 bool isArrayIndex;
185 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
186 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
187 if (i < d->numParameters) {
188 descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum);
189 } else
190 descriptor.setDescriptor(d->extraArguments[i - d->numParameters].jsValue(), DontEnum);
191 return true;
192 }
193
194 if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) {
195 descriptor.setDescriptor(jsNumber(exec, d->numArguments), DontEnum);
196 return true;
197 }
198
199 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
200 descriptor.setDescriptor(d->callee, DontEnum);
201 return true;
202 }
203
204 return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor);
205}
206
207void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
208{
209 if (mode == IncludeDontEnumProperties) {
210 for (unsigned i = 0; i < d->numArguments; ++i) {
211 if (!d->deletedArguments || !d->deletedArguments[i])
212 propertyNames.add(Identifier(exec, UString::from(i)));
213 }
214 propertyNames.add(exec->propertyNames().callee);
215 propertyNames.add(exec->propertyNames().length);
216 }
217 JSObject::getOwnPropertyNames(exec, propertyNames, mode);
218}
219
220void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& slot)
221{
222 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
223 if (i < d->numParameters)
224 d->registers[d->firstParameterIndex + i] = JSValue(value);
225 else
226 d->extraArguments[i - d->numParameters] = JSValue(value);
227 return;
228 }
229
230 JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
231}
232
233void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot)
234{
235 bool isArrayIndex;
236 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
237 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
238 if (i < d->numParameters)
239 d->registers[d->firstParameterIndex + i] = JSValue(value);
240 else
241 d->extraArguments[i - d->numParameters] = JSValue(value);
242 return;
243 }
244
245 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
246 d->overrodeLength = true;
247 putDirect(propertyName, value, DontEnum);
248 return;
249 }
250
251 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
252 d->overrodeCallee = true;
253 putDirect(propertyName, value, DontEnum);
254 return;
255 }
256
257 JSObject::put(exec, propertyName, value, slot);
258}
259
260bool Arguments::deleteProperty(ExecState* exec, unsigned i)
261{
262 if (i < d->numArguments) {
263 if (!d->deletedArguments) {
264 d->deletedArguments.set(new bool[d->numArguments]);
265 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
266 }
267 if (!d->deletedArguments[i]) {
268 d->deletedArguments[i] = true;
269 return true;
270 }
271 }
272
273 return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)));
274}
275
276bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
277{
278 bool isArrayIndex;
279 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
280 if (isArrayIndex && i < d->numArguments) {
281 if (!d->deletedArguments) {
282 d->deletedArguments.set(new bool[d->numArguments]);
283 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
284 }
285 if (!d->deletedArguments[i]) {
286 d->deletedArguments[i] = true;
287 return true;
288 }
289 }
290
291 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
292 d->overrodeLength = true;
293 return true;
294 }
295
296 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
297 d->overrodeCallee = true;
298 return true;
299 }
300
301 return JSObject::deleteProperty(exec, propertyName);
302}
303
304} // namespace JSC
Note: See TracBrowser for help on using the repository browser.