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

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

JavaScriptCore:

2009-02-16 Sam Weinig <[email protected]>

Reviewed by Geoffrey Garen.

Fix for <rdar://problem/6468156>
REGRESSION (r36779): Adding link, images, flash in TinyMCE blocks entire page (21382)

No performance regression.

  • runtime/Arguments.cpp: (JSC::Arguments::fillArgList): Add codepath for when the "length" property has been overridden.

LayoutTests:

2009-02-16 Sam Weinig <[email protected]>

Reviewed by Geoffrey Garen.

Add tests for <rdar://problem/6468156>
REGRESSION (r36779): Adding link, images, flash in TinyMCE blocks entire page (21382)

  • fast/js/function-apply-expected.txt:
  • fast/js/resources/function-apply.js: Add cases covering setting arugments.length and Array.length explicitly or implicitly using Array.prototype.unshift.
  • Property svn:eol-style set to native
File size: 7.7 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 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::mark()
47{
48 JSObject::mark();
49
50 if (d->registerArray) {
51 for (unsigned i = 0; i < d->numParameters; ++i) {
52 if (!d->registerArray[i].marked())
53 d->registerArray[i].mark();
54 }
55 }
56
57 if (d->extraArguments) {
58 unsigned numExtraArguments = d->numArguments - d->numParameters;
59 for (unsigned i = 0; i < numExtraArguments; ++i) {
60 if (!d->extraArguments[i].marked())
61 d->extraArguments[i].mark();
62 }
63 }
64
65 if (!d->callee->marked())
66 d->callee->mark();
67
68 if (d->activation && !d->activation->marked())
69 d->activation->mark();
70}
71
72void Arguments::fillArgList(ExecState* exec, ArgList& args)
73{
74 if (UNLIKELY(d->overrodeLength)) {
75 unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
76 for (unsigned i = 0; i < length; i++)
77 args.append(get(exec, i));
78 return;
79 }
80
81 if (LIKELY(!d->deletedArguments)) {
82 if (LIKELY(!d->numParameters)) {
83 args.initialize(d->extraArguments, d->numArguments);
84 return;
85 }
86
87 if (d->numParameters == d->numArguments) {
88 args.initialize(&d->registers[d->firstParameterIndex], d->numArguments);
89 return;
90 }
91
92 unsigned parametersLength = min(d->numParameters, d->numArguments);
93 unsigned i = 0;
94 for (; i < parametersLength; ++i)
95 args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
96 for (; i < d->numArguments; ++i)
97 args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
98 return;
99 }
100
101 unsigned parametersLength = min(d->numParameters, d->numArguments);
102 unsigned i = 0;
103 for (; i < parametersLength; ++i) {
104 if (!d->deletedArguments[i])
105 args.append(d->registers[d->firstParameterIndex + i].jsValue(exec));
106 else
107 args.append(get(exec, i));
108 }
109 for (; i < d->numArguments; ++i) {
110 if (!d->deletedArguments[i])
111 args.append(d->extraArguments[i - d->numParameters].jsValue(exec));
112 else
113 args.append(get(exec, i));
114 }
115}
116
117bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& slot)
118{
119 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
120 if (i < d->numParameters) {
121 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
122 } else
123 slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
124 return true;
125 }
126
127 return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot);
128}
129
130bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot)
131{
132 bool isArrayIndex;
133 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
134 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
135 if (i < d->numParameters) {
136 slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]);
137 } else
138 slot.setValue(d->extraArguments[i - d->numParameters].jsValue(exec));
139 return true;
140 }
141
142 if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) {
143 slot.setValue(jsNumber(exec, d->numArguments));
144 return true;
145 }
146
147 if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) {
148 slot.setValue(d->callee);
149 return true;
150 }
151
152 return JSObject::getOwnPropertySlot(exec, propertyName, slot);
153}
154
155void Arguments::put(ExecState* exec, unsigned i, JSValuePtr value, PutPropertySlot& slot)
156{
157 if (i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
158 if (i < d->numParameters)
159 d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
160 else
161 d->extraArguments[i - d->numParameters] = JSValuePtr(value);
162 return;
163 }
164
165 JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot);
166}
167
168void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValuePtr value, PutPropertySlot& slot)
169{
170 bool isArrayIndex;
171 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
172 if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) {
173 if (i < d->numParameters)
174 d->registers[d->firstParameterIndex + i] = JSValuePtr(value);
175 else
176 d->extraArguments[i - d->numParameters] = JSValuePtr(value);
177 return;
178 }
179
180 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
181 d->overrodeLength = true;
182 putDirect(propertyName, value, DontEnum);
183 return;
184 }
185
186 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
187 d->overrodeCallee = true;
188 putDirect(propertyName, value, DontEnum);
189 return;
190 }
191
192 JSObject::put(exec, propertyName, value, slot);
193}
194
195bool Arguments::deleteProperty(ExecState* exec, unsigned i)
196{
197 if (i < d->numArguments) {
198 if (!d->deletedArguments) {
199 d->deletedArguments.set(new bool[d->numArguments]);
200 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
201 }
202 if (!d->deletedArguments[i]) {
203 d->deletedArguments[i] = true;
204 return true;
205 }
206 }
207
208 return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i)));
209}
210
211bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName)
212{
213 bool isArrayIndex;
214 unsigned i = propertyName.toArrayIndex(&isArrayIndex);
215 if (isArrayIndex && i < d->numArguments) {
216 if (!d->deletedArguments) {
217 d->deletedArguments.set(new bool[d->numArguments]);
218 memset(d->deletedArguments.get(), 0, sizeof(bool) * d->numArguments);
219 }
220 if (!d->deletedArguments[i]) {
221 d->deletedArguments[i] = true;
222 return true;
223 }
224 }
225
226 if (propertyName == exec->propertyNames().length && !d->overrodeLength) {
227 d->overrodeLength = true;
228 return true;
229 }
230
231 if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) {
232 d->overrodeCallee = true;
233 return true;
234 }
235
236 return JSObject::deleteProperty(exec, propertyName);
237}
238
239} // namespace JSC
Note: See TracBrowser for help on using the repository browser.