blob: 25793765bb01479e6885add6eae65bebd583c4ae [file] [log] [blame]
weinig@apple.com7dab4652008-07-05 23:19:36 +00001/*
2 * Copyright (C) 1999-2002 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
oliver@apple.com5fca29f2009-08-11 04:35:02 +00004 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
weinig@apple.com7dab4652008-07-05 23:19:36 +00005 * Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
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
weinig@apple.com3a54d0f2008-07-05 23:32:45 +000028#include "JSActivation.h"
mrowe@apple.come8d2f732008-09-22 00:12:14 +000029#include "JSFunction.h"
weinig@apple.com7dab4652008-07-05 23:19:36 +000030#include "JSGlobalObject.h"
weinig@apple.com7dab4652008-07-05 23:19:36 +000031
pewtermoose@webkit.org98891fd2008-09-22 21:59:45 +000032using namespace std;
33
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +000034namespace JSC {
weinig@apple.com7dab4652008-07-05 23:19:36 +000035
ggaren@apple.comfea43532008-08-17 20:23:49 +000036ASSERT_CLASS_FITS_IN_CELL(Arguments);
37
mhahnenberg@apple.com3e084662011-09-26 07:05:28 +000038const ClassInfo Arguments::s_info = { "Arguments", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
weinig@apple.com7dab4652008-07-05 23:19:36 +000039
mhahnenberg@apple.com982c9ea2011-09-23 19:40:09 +000040void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
41{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +000042 Arguments* thisObject = jsCast<Arguments*>(cell);
mhahnenberg@apple.com982c9ea2011-09-23 19:40:09 +000043 ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info);
oliver@apple.com41037162011-05-14 22:10:01 +000044 COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag);
mhahnenberg@apple.com982c9ea2011-09-23 19:40:09 +000045 ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
46 JSObject::visitChildren(thisObject, visitor);
cwzwarich@webkit.org4e9a20c2008-09-21 08:37:01 +000047
mhahnenberg@apple.com982c9ea2011-09-23 19:40:09 +000048 if (thisObject->d->registerArray)
ggaren@apple.com0af14682011-12-12 00:35:51 +000049 visitor.appendValues(thisObject->d->registerArray.get(), thisObject->d->numArguments);
mhahnenberg@apple.com982c9ea2011-09-23 19:40:09 +000050 visitor.append(&thisObject->d->callee);
ggaren@apple.comacb40df2012-08-27 03:57:02 +000051 visitor.append(&thisObject->d->activation);
weinig@apple.com7dab4652008-07-05 23:19:36 +000052}
53
mrowe@apple.com5a525ae2012-01-05 07:39:36 +000054void Arguments::destroy(JSCell* cell)
55{
ggaren@apple.com72da8112012-05-26 22:40:46 +000056 static_cast<Arguments*>(cell)->Arguments::~Arguments();
mrowe@apple.com5a525ae2012-01-05 07:39:36 +000057}
58
ggaren@apple.com0af14682011-12-12 00:35:51 +000059void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length)
oliver@apple.com65e286e2009-04-08 23:08:28 +000060{
oliver@apple.comef1f9712011-12-13 23:17:43 +000061 if (UNLIKELY(d->overrodeLength)) {
62 length = min(get(exec, exec->propertyNames().length).toUInt32(exec), length);
63 for (unsigned i = 0; i < length; i++)
64 callFrame->setArgument(i, get(exec, i));
65 return;
66 }
ggaren@apple.com0af14682011-12-12 00:35:51 +000067 ASSERT(length == this->length(exec));
68 for (size_t i = 0; i < length; ++i) {
69 if (!d->deletedArguments || !d->deletedArguments[i])
70 callFrame->setArgument(i, argument(i).get());
oliver@apple.com65e286e2009-04-08 23:08:28 +000071 else
ggaren@apple.com0af14682011-12-12 00:35:51 +000072 callFrame->setArgument(i, get(exec, i));
oliver@apple.com65e286e2009-04-08 23:08:28 +000073 }
74}
75
oliver@apple.comf32186e2009-04-30 01:21:52 +000076void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args)
weinig@apple.comcbf3ca92008-09-22 21:20:52 +000077{
oliver@apple.comef1f9712011-12-13 23:17:43 +000078 if (UNLIKELY(d->overrodeLength)) {
79 unsigned length = get(exec, exec->propertyNames().length).toUInt32(exec);
80 for (unsigned i = 0; i < length; i++)
81 args.append(get(exec, i));
82 return;
83 }
ggaren@apple.com0af14682011-12-12 00:35:51 +000084 uint32_t length = this->length(exec);
85 for (size_t i = 0; i < length; ++i) {
86 if (!d->deletedArguments || !d->deletedArguments[i])
87 args.append(argument(i).get());
weinig@apple.comcbf3ca92008-09-22 21:20:52 +000088 else
89 args.append(get(exec, i));
90 }
91}
92
mhahnenberg@apple.com6f0c32e2011-10-24 18:37:37 +000093bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i, PropertySlot& slot)
mhahnenberg@apple.com19869642011-10-08 21:31:32 +000094{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +000095 Arguments* thisObject = jsCast<Arguments*>(cell);
mhahnenberg@apple.com19869642011-10-08 21:31:32 +000096 if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
ggaren@apple.com0af14682011-12-12 00:35:51 +000097 slot.setValue(thisObject->argument(i).get());
darin@apple.com2d1b3582008-09-21 21:35:23 +000098 return true;
99 }
100
mhahnenberg@apple.com19869642011-10-08 21:31:32 +0000101 return JSObject::getOwnPropertySlot(thisObject, exec, Identifier(exec, UString::number(i)), slot);
weinig@apple.com7dab4652008-07-05 23:19:36 +0000102}
oliver@apple.com59301852010-10-11 19:12:29 +0000103
104void Arguments::createStrictModeCallerIfNecessary(ExecState* exec)
105{
106 if (d->overrodeCaller)
107 return;
108
109 d->overrodeCaller = true;
110 PropertyDescriptor descriptor;
barraclough@apple.combebfe4d2012-01-12 03:53:22 +0000111 descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
mhahnenberg@apple.com8c9572d2011-11-09 10:18:04 +0000112 methodTable()->defineOwnProperty(this, exec, exec->propertyNames().caller, descriptor, false);
oliver@apple.com59301852010-10-11 19:12:29 +0000113}
114
115void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec)
116{
117 if (d->overrodeCallee)
118 return;
119
120 d->overrodeCallee = true;
121 PropertyDescriptor descriptor;
barraclough@apple.combebfe4d2012-01-12 03:53:22 +0000122 descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor);
mhahnenberg@apple.com8c9572d2011-11-09 10:18:04 +0000123 methodTable()->defineOwnProperty(this, exec, exec->propertyNames().callee, descriptor, false);
oliver@apple.com59301852010-10-11 19:12:29 +0000124}
weinig@apple.com7dab4652008-07-05 23:19:36 +0000125
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000126bool Arguments::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000127{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000128 Arguments* thisObject = jsCast<Arguments*>(cell);
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000129 unsigned i = propertyName.asIndex();
130 if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
131 ASSERT(i < PropertyName::NotAnIndex);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000132 slot.setValue(thisObject->argument(i).get());
weinig@apple.com0e2d66e2008-07-06 05:26:58 +0000133 return true;
134 }
weinig@apple.com7dab4652008-07-05 23:19:36 +0000135
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000136 if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
137 slot.setValue(jsNumber(thisObject->d->numArguments));
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000138 return true;
139 }
140
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000141 if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
142 if (!thisObject->d->isStrictMode) {
143 slot.setValue(thisObject->d->callee.get());
oliver@apple.com59301852010-10-11 19:12:29 +0000144 return true;
145 }
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000146 thisObject->createStrictModeCalleeIfNecessary(exec);
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000147 }
148
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000149 if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
150 thisObject->createStrictModeCallerIfNecessary(exec);
oliver@apple.com59301852010-10-11 19:12:29 +0000151
mhahnenberg@apple.comf0418c852011-10-15 02:00:23 +0000152 return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot);
weinig@apple.com7dab4652008-07-05 23:19:36 +0000153}
154
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000155bool Arguments::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor)
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000156{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000157 Arguments* thisObject = jsCast<Arguments*>(object);
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000158 unsigned i = propertyName.asIndex();
159 if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
160 ASSERT(i < PropertyName::NotAnIndex);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000161 descriptor.setDescriptor(thisObject->argument(i).get(), None);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000162 return true;
163 }
164
mhahnenberg@apple.com7f2f7e52011-11-09 21:09:37 +0000165 if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) {
166 descriptor.setDescriptor(jsNumber(thisObject->d->numArguments), DontEnum);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000167 return true;
168 }
169
mhahnenberg@apple.com7f2f7e52011-11-09 21:09:37 +0000170 if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) {
171 if (!thisObject->d->isStrictMode) {
172 descriptor.setDescriptor(thisObject->d->callee.get(), DontEnum);
oliver@apple.com59301852010-10-11 19:12:29 +0000173 return true;
174 }
mhahnenberg@apple.com7f2f7e52011-11-09 21:09:37 +0000175 thisObject->createStrictModeCalleeIfNecessary(exec);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000176 }
oliver@apple.com59301852010-10-11 19:12:29 +0000177
mhahnenberg@apple.com7f2f7e52011-11-09 21:09:37 +0000178 if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
179 thisObject->createStrictModeCallerIfNecessary(exec);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000180
mhahnenberg@apple.com7f2f7e52011-11-09 21:09:37 +0000181 return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor);
oliver@apple.com4b4f7852009-08-26 16:52:15 +0000182}
183
mhahnenberg@apple.com57262382011-11-03 00:25:45 +0000184void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode)
eric@webkit.orgc293f4c2010-01-13 00:58:21 +0000185{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000186 Arguments* thisObject = jsCast<Arguments*>(object);
mhahnenberg@apple.com57262382011-11-03 00:25:45 +0000187 for (unsigned i = 0; i < thisObject->d->numArguments; ++i) {
188 if (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])
barraclough@apple.comc0aaee42011-10-18 17:03:55 +0000189 propertyNames.add(Identifier(exec, UString::number(i)));
190 }
eric@webkit.orgc293f4c2010-01-13 00:58:21 +0000191 if (mode == IncludeDontEnumProperties) {
eric@webkit.orgc293f4c2010-01-13 00:58:21 +0000192 propertyNames.add(exec->propertyNames().callee);
193 propertyNames.add(exec->propertyNames().length);
194 }
mhahnenberg@apple.com57262382011-11-03 00:25:45 +0000195 JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode);
eric@webkit.orgc293f4c2010-01-13 00:58:21 +0000196}
197
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000198void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow)
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000199{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000200 Arguments* thisObject = jsCast<Arguments*>(cell);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000201 if (i < static_cast<unsigned>(thisObject->d->numArguments) && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
202 thisObject->argument(i).set(exec->globalData(), thisObject, value);
darin@apple.com2d1b3582008-09-21 21:35:23 +0000203 return;
204 }
205
barraclough@apple.comb1db28d82012-03-06 07:23:21 +0000206 PutPropertySlot slot(shouldThrow);
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000207 JSObject::put(thisObject, exec, Identifier(exec, UString::number(i)), value, slot);
darin@apple.com2d1b3582008-09-21 21:35:23 +0000208}
209
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000210void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot)
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000211{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000212 Arguments* thisObject = jsCast<Arguments*>(cell);
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000213 unsigned i = propertyName.asIndex();
214 if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) {
215 ASSERT(i < PropertyName::NotAnIndex);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000216 thisObject->argument(i).set(exec->globalData(), thisObject, value);
cwzwarich@webkit.org4e9a20c2008-09-21 08:37:01 +0000217 return;
218 }
219
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000220 if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
221 thisObject->d->overrodeLength = true;
222 thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000223 return;
224 }
225
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000226 if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
227 if (!thisObject->d->isStrictMode) {
228 thisObject->d->overrodeCallee = true;
229 thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum);
oliver@apple.com59301852010-10-11 19:12:29 +0000230 return;
231 }
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000232 thisObject->createStrictModeCalleeIfNecessary(exec);
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000233 }
234
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000235 if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
236 thisObject->createStrictModeCallerIfNecessary(exec);
oliver@apple.com59301852010-10-11 19:12:29 +0000237
mhahnenberg@apple.com5e2b7122011-10-08 00:06:07 +0000238 JSObject::put(thisObject, exec, propertyName, value, slot);
darin@apple.com2d1b3582008-09-21 21:35:23 +0000239}
240
mhahnenberg@apple.com8a10db92011-10-20 18:14:50 +0000241bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000242{
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000243 Arguments* thisObject = jsCast<Arguments*>(cell);
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000244 if (i < thisObject->d->numArguments) {
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000245 if (!Base::deletePropertyByIndex(cell, exec, i))
246 return false;
247
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000248 if (!thisObject->d->deletedArguments) {
249 thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
250 memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
darin@apple.com2d1b3582008-09-21 21:35:23 +0000251 }
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000252 if (!thisObject->d->deletedArguments[i]) {
253 thisObject->d->deletedArguments[i] = true;
darin@apple.com2d1b3582008-09-21 21:35:23 +0000254 return true;
255 }
256 }
257
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000258 return JSObject::deleteProperty(thisObject, exec, Identifier(exec, UString::number(i)));
weinig@apple.com7dab4652008-07-05 23:19:36 +0000259}
260
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000261bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName)
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000262{
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000263 if (exec->globalData().isInDefineOwnProperty())
264 return Base::deleteProperty(cell, exec, propertyName);
265
mhahnenberg@apple.com135f0512011-11-11 20:40:10 +0000266 Arguments* thisObject = jsCast<Arguments*>(cell);
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000267 unsigned i = propertyName.asIndex();
268 if (i < thisObject->d->numArguments) {
269 ASSERT(i < PropertyName::NotAnIndex);
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000270 if (!Base::deleteProperty(cell, exec, propertyName))
271 return false;
272
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000273 if (!thisObject->d->deletedArguments) {
274 thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
275 memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
cwzwarich@webkit.org4e9a20c2008-09-21 08:37:01 +0000276 }
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000277 if (!thisObject->d->deletedArguments[i]) {
278 thisObject->d->deletedArguments[i] = true;
darin@apple.com2d1b3582008-09-21 21:35:23 +0000279 return true;
cwzwarich@webkit.org4e9a20c2008-09-21 08:37:01 +0000280 }
281 }
282
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000283 if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
284 thisObject->d->overrodeLength = true;
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000285 return true;
286 }
287
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000288 if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
289 if (!thisObject->d->isStrictMode) {
290 thisObject->d->overrodeCallee = true;
oliver@apple.com59301852010-10-11 19:12:29 +0000291 return true;
292 }
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000293 thisObject->createStrictModeCalleeIfNecessary(exec);
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000294 }
oliver@apple.com59301852010-10-11 19:12:29 +0000295
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000296 if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000297 thisObject->createStrictModeCallerIfNecessary(exec);
cwzwarich@webkit.org2d883f72008-09-23 10:59:42 +0000298
mhahnenberg@apple.com914c3ee2011-10-08 06:37:45 +0000299 return JSObject::deleteProperty(thisObject, exec, propertyName);
weinig@apple.com7dab4652008-07-05 23:19:36 +0000300}
301
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000302bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool shouldThrow)
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000303{
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000304 Arguments* thisObject = jsCast<Arguments*>(object);
barraclough@apple.com38d3c752012-05-12 00:39:43 +0000305 unsigned i = propertyName.asIndex();
306 if (i < thisObject->d->numArguments) {
307 ASSERT(i < PropertyName::NotAnIndex);
barraclough@apple.com7ca5cdc2012-04-30 22:29:10 +0000308 // If the property is not yet present on the object, and is not yet marked as deleted, then add it now.
309 PropertySlot slot;
310 if ((!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i]) && !JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot))
311 object->putDirect(exec->globalData(), propertyName, thisObject->argument(i).get(), 0);
barraclough@apple.com4e348942012-02-23 19:43:07 +0000312 if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
313 return false;
314
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000315 if (!thisObject->d->deletedArguments) {
316 thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
317 memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
318 }
319 // From ES 5.1, 10.6 Arguments Object
320 // 5. If the value of isMapped is not undefined, then
321 if (!thisObject->d->deletedArguments[i]) {
322 // a. If IsAccessorDescriptor(Desc) is true, then
323 if (descriptor.isAccessorDescriptor()) {
324 // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
325 thisObject->d->deletedArguments[i] = true;
barraclough@apple.comeb88e082012-03-06 20:20:04 +0000326 } else { // b. Else
327 // i. If Desc.[[Value]] is present, then
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000328 // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
barraclough@apple.comeb88e082012-03-06 20:20:04 +0000329 if (descriptor.value())
330 thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value());
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000331 // ii. If Desc.[[Writable]] is present and its value is false, then
barraclough@apple.comeb88e082012-03-06 20:20:04 +0000332 // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000333 if (descriptor.writablePresent() && !descriptor.writable())
barraclough@apple.comeb88e082012-03-06 20:20:04 +0000334 thisObject->d->deletedArguments[i] = true;
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000335 }
336 }
barraclough@apple.com4e348942012-02-23 19:43:07 +0000337 return true;
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000338 }
barraclough@apple.com4e348942012-02-23 19:43:07 +0000339
340 if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
barraclough@apple.com7ef41522012-03-19 21:34:25 +0000341 thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->d->numArguments), DontEnum);
barraclough@apple.com4e348942012-02-23 19:43:07 +0000342 thisObject->d->overrodeLength = true;
barraclough@apple.com7ef41522012-03-19 21:34:25 +0000343 } else if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
344 thisObject->putDirect(exec->globalData(), propertyName, thisObject->d->callee.get(), DontEnum);
barraclough@apple.com4e348942012-02-23 19:43:07 +0000345 thisObject->d->overrodeCallee = true;
barraclough@apple.com7ef41522012-03-19 21:34:25 +0000346 } else if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
barraclough@apple.com4e348942012-02-23 19:43:07 +0000347 thisObject->createStrictModeCallerIfNecessary(exec);
348
349 return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
barraclough@apple.coma9b45392012-02-23 01:25:37 +0000350}
351
ggaren@apple.com0af14682011-12-12 00:35:51 +0000352void Arguments::tearOff(CallFrame* callFrame)
353{
354 if (isTornOff())
355 return;
356
357 if (!d->numArguments)
358 return;
359
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000360 // Must be called for the same call frame from which it was created.
361 ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == d->registers);
362
ggaren@apple.com0af14682011-12-12 00:35:51 +0000363 d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
364 d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
365
366 if (!callFrame->isInlineCallFrame()) {
367 for (size_t i = 0; i < d->numArguments; ++i)
368 argument(i).set(callFrame->globalData(), this, callFrame->argument(i));
369 return;
370 }
371
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000372 tearOffForInlineCallFrame(
373 callFrame->globalData(), callFrame->registers(), callFrame->inlineCallFrame());
374}
375
376void Arguments::tearOff(CallFrame* callFrame, InlineCallFrame* inlineCallFrame)
377{
378 if (isTornOff())
379 return;
380
381 if (!d->numArguments)
382 return;
383
384 d->registerArray = adoptArrayPtr(new WriteBarrier<Unknown>[d->numArguments]);
385 d->registers = d->registerArray.get() + CallFrame::offsetFor(d->numArguments + 1);
386
387 tearOffForInlineCallFrame(
388 callFrame->globalData(), callFrame->registers() + inlineCallFrame->stackOffset,
389 inlineCallFrame);
390}
391
392void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* registers, InlineCallFrame* inlineCallFrame)
393{
ggaren@apple.com0af14682011-12-12 00:35:51 +0000394 for (size_t i = 0; i < d->numArguments; ++i) {
395 ValueRecovery& recovery = inlineCallFrame->arguments[i + 1];
396 // In the future we'll support displaced recoveries (indicating that the
397 // argument was flushed to a different location), but for now we don't do
398 // that so this code will fail if that were to happen. On the other hand,
399 // it's much less likely that we'll support in-register recoveries since
400 // this code does not (easily) have access to registers.
401 JSValue value;
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000402 Register* location = &registers[CallFrame::argumentOffset(i)];
ggaren@apple.com0af14682011-12-12 00:35:51 +0000403 switch (recovery.technique()) {
404 case AlreadyInRegisterFile:
405 value = location->jsValue();
406 break;
407 case AlreadyInRegisterFileAsUnboxedInt32:
408 value = jsNumber(location->unboxedInt32());
409 break;
410 case AlreadyInRegisterFileAsUnboxedCell:
411 value = location->unboxedCell();
412 break;
413 case AlreadyInRegisterFileAsUnboxedBoolean:
414 value = jsBoolean(location->unboxedBoolean());
415 break;
fpizlo@apple.com10f22fc2011-12-14 07:16:36 +0000416 case AlreadyInRegisterFileAsUnboxedDouble:
417#if USE(JSVALUE64)
418 value = jsNumber(*bitwise_cast<double*>(location));
419#else
420 value = location->jsValue();
421#endif
422 break;
ggaren@apple.com0af14682011-12-12 00:35:51 +0000423 case Constant:
424 value = recovery.constant();
425 break;
426 default:
427 ASSERT_NOT_REACHED();
428 break;
429 }
fpizlo@apple.comc6446112012-05-23 20:52:42 +0000430 argument(i).set(globalData, this, value);
ggaren@apple.com0af14682011-12-12 00:35:51 +0000431 }
432}
433
cwzwarich@webkit.org3f782f62008-09-08 01:28:33 +0000434} // namespace JSC