weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 1999-2002 Harri Porten (porten@kde.org) |
| 3 | * Copyright (C) 2001 Peter Kelly (pmk@post.com) |
oliver@apple.com | 5fca29f | 2009-08-11 04:35:02 +0000 | [diff] [blame] | 4 | * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 5 | * 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.com | 3a54d0f | 2008-07-05 23:32:45 +0000 | [diff] [blame] | 28 | #include "JSActivation.h" |
mrowe@apple.com | e8d2f73 | 2008-09-22 00:12:14 +0000 | [diff] [blame] | 29 | #include "JSFunction.h" |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 30 | #include "JSGlobalObject.h" |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 31 | |
pewtermoose@webkit.org | 98891fd | 2008-09-22 21:59:45 +0000 | [diff] [blame] | 32 | using namespace std; |
| 33 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 34 | namespace JSC { |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 35 | |
ggaren@apple.com | fea4353 | 2008-08-17 20:23:49 +0000 | [diff] [blame] | 36 | ASSERT_CLASS_FITS_IN_CELL(Arguments); |
| 37 | |
mhahnenberg@apple.com | 3e08466 | 2011-09-26 07:05:28 +0000 | [diff] [blame] | 38 | const ClassInfo Arguments::s_info = { "Arguments", &JSNonFinalObject::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) }; |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 39 | |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 40 | void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor) |
| 41 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 42 | Arguments* thisObject = jsCast<Arguments*>(cell); |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 43 | ASSERT_GC_OBJECT_INHERITS(thisObject, &s_info); |
oliver@apple.com | 4103716 | 2011-05-14 22:10:01 +0000 | [diff] [blame] | 44 | COMPILE_ASSERT(StructureFlags & OverridesVisitChildren, OverridesVisitChildrenWithoutSettingFlag); |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 45 | ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren()); |
| 46 | JSObject::visitChildren(thisObject, visitor); |
cwzwarich@webkit.org | 4e9a20c | 2008-09-21 08:37:01 +0000 | [diff] [blame] | 47 | |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 48 | if (thisObject->d->registerArray) |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 49 | visitor.appendValues(thisObject->d->registerArray.get(), thisObject->d->numArguments); |
mhahnenberg@apple.com | 982c9ea | 2011-09-23 19:40:09 +0000 | [diff] [blame] | 50 | visitor.append(&thisObject->d->callee); |
ggaren@apple.com | acb40df | 2012-08-27 03:57:02 +0000 | [diff] [blame] | 51 | visitor.append(&thisObject->d->activation); |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 52 | } |
| 53 | |
mrowe@apple.com | 5a525ae | 2012-01-05 07:39:36 +0000 | [diff] [blame] | 54 | void Arguments::destroy(JSCell* cell) |
| 55 | { |
ggaren@apple.com | 72da811 | 2012-05-26 22:40:46 +0000 | [diff] [blame] | 56 | static_cast<Arguments*>(cell)->Arguments::~Arguments(); |
mrowe@apple.com | 5a525ae | 2012-01-05 07:39:36 +0000 | [diff] [blame] | 57 | } |
| 58 | |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 59 | void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t length) |
oliver@apple.com | 65e286e | 2009-04-08 23:08:28 +0000 | [diff] [blame] | 60 | { |
oliver@apple.com | ef1f971 | 2011-12-13 23:17:43 +0000 | [diff] [blame] | 61 | 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.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 67 | 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.com | 65e286e | 2009-04-08 23:08:28 +0000 | [diff] [blame] | 71 | else |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 72 | callFrame->setArgument(i, get(exec, i)); |
oliver@apple.com | 65e286e | 2009-04-08 23:08:28 +0000 | [diff] [blame] | 73 | } |
| 74 | } |
| 75 | |
oliver@apple.com | f32186e | 2009-04-30 01:21:52 +0000 | [diff] [blame] | 76 | void Arguments::fillArgList(ExecState* exec, MarkedArgumentBuffer& args) |
weinig@apple.com | cbf3ca9 | 2008-09-22 21:20:52 +0000 | [diff] [blame] | 77 | { |
oliver@apple.com | ef1f971 | 2011-12-13 23:17:43 +0000 | [diff] [blame] | 78 | 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.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 84 | 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.com | cbf3ca9 | 2008-09-22 21:20:52 +0000 | [diff] [blame] | 88 | else |
| 89 | args.append(get(exec, i)); |
| 90 | } |
| 91 | } |
| 92 | |
mhahnenberg@apple.com | 6f0c32e | 2011-10-24 18:37:37 +0000 | [diff] [blame] | 93 | bool Arguments::getOwnPropertySlotByIndex(JSCell* cell, ExecState* exec, unsigned i, PropertySlot& slot) |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 94 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 95 | Arguments* thisObject = jsCast<Arguments*>(cell); |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 96 | if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) { |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 97 | slot.setValue(thisObject->argument(i).get()); |
darin@apple.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 98 | return true; |
| 99 | } |
| 100 | |
mhahnenberg@apple.com | 1986964 | 2011-10-08 21:31:32 +0000 | [diff] [blame] | 101 | return JSObject::getOwnPropertySlot(thisObject, exec, Identifier(exec, UString::number(i)), slot); |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 102 | } |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 103 | |
| 104 | void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) |
| 105 | { |
| 106 | if (d->overrodeCaller) |
| 107 | return; |
| 108 | |
| 109 | d->overrodeCaller = true; |
| 110 | PropertyDescriptor descriptor; |
barraclough@apple.com | bebfe4d | 2012-01-12 03:53:22 +0000 | [diff] [blame] | 111 | descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor); |
mhahnenberg@apple.com | 8c9572d | 2011-11-09 10:18:04 +0000 | [diff] [blame] | 112 | methodTable()->defineOwnProperty(this, exec, exec->propertyNames().caller, descriptor, false); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 113 | } |
| 114 | |
| 115 | void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) |
| 116 | { |
| 117 | if (d->overrodeCallee) |
| 118 | return; |
| 119 | |
| 120 | d->overrodeCallee = true; |
| 121 | PropertyDescriptor descriptor; |
barraclough@apple.com | bebfe4d | 2012-01-12 03:53:22 +0000 | [diff] [blame] | 122 | descriptor.setAccessorDescriptor(globalObject()->throwTypeErrorGetterSetter(exec), DontEnum | DontDelete | Accessor); |
mhahnenberg@apple.com | 8c9572d | 2011-11-09 10:18:04 +0000 | [diff] [blame] | 123 | methodTable()->defineOwnProperty(this, exec, exec->propertyNames().callee, descriptor, false); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 124 | } |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 125 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 126 | bool Arguments::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot) |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 127 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 128 | Arguments* thisObject = jsCast<Arguments*>(cell); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 129 | unsigned i = propertyName.asIndex(); |
| 130 | if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) { |
| 131 | ASSERT(i < PropertyName::NotAnIndex); |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 132 | slot.setValue(thisObject->argument(i).get()); |
weinig@apple.com | 0e2d66e | 2008-07-06 05:26:58 +0000 | [diff] [blame] | 133 | return true; |
| 134 | } |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 135 | |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 136 | if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) { |
| 137 | slot.setValue(jsNumber(thisObject->d->numArguments)); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 138 | return true; |
| 139 | } |
| 140 | |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 141 | if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) { |
| 142 | if (!thisObject->d->isStrictMode) { |
| 143 | slot.setValue(thisObject->d->callee.get()); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 144 | return true; |
| 145 | } |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 146 | thisObject->createStrictModeCalleeIfNecessary(exec); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 147 | } |
| 148 | |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 149 | if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode) |
| 150 | thisObject->createStrictModeCallerIfNecessary(exec); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 151 | |
mhahnenberg@apple.com | f0418c85 | 2011-10-15 02:00:23 +0000 | [diff] [blame] | 152 | return JSObject::getOwnPropertySlot(thisObject, exec, propertyName, slot); |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 153 | } |
| 154 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 155 | bool Arguments::getOwnPropertyDescriptor(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor) |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 156 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 157 | Arguments* thisObject = jsCast<Arguments*>(object); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 158 | unsigned i = propertyName.asIndex(); |
| 159 | if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) { |
| 160 | ASSERT(i < PropertyName::NotAnIndex); |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 161 | descriptor.setDescriptor(thisObject->argument(i).get(), None); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 162 | return true; |
| 163 | } |
| 164 | |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 165 | if (propertyName == exec->propertyNames().length && LIKELY(!thisObject->d->overrodeLength)) { |
| 166 | descriptor.setDescriptor(jsNumber(thisObject->d->numArguments), DontEnum); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 167 | return true; |
| 168 | } |
| 169 | |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 170 | if (propertyName == exec->propertyNames().callee && LIKELY(!thisObject->d->overrodeCallee)) { |
| 171 | if (!thisObject->d->isStrictMode) { |
| 172 | descriptor.setDescriptor(thisObject->d->callee.get(), DontEnum); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 173 | return true; |
| 174 | } |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 175 | thisObject->createStrictModeCalleeIfNecessary(exec); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 176 | } |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 177 | |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 178 | if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode) |
| 179 | thisObject->createStrictModeCallerIfNecessary(exec); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 180 | |
mhahnenberg@apple.com | 7f2f7e5 | 2011-11-09 21:09:37 +0000 | [diff] [blame] | 181 | return JSObject::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor); |
oliver@apple.com | 4b4f785 | 2009-08-26 16:52:15 +0000 | [diff] [blame] | 182 | } |
| 183 | |
mhahnenberg@apple.com | 5726238 | 2011-11-03 00:25:45 +0000 | [diff] [blame] | 184 | void Arguments::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 185 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 186 | Arguments* thisObject = jsCast<Arguments*>(object); |
mhahnenberg@apple.com | 5726238 | 2011-11-03 00:25:45 +0000 | [diff] [blame] | 187 | for (unsigned i = 0; i < thisObject->d->numArguments; ++i) { |
| 188 | if (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i]) |
barraclough@apple.com | c0aaee4 | 2011-10-18 17:03:55 +0000 | [diff] [blame] | 189 | propertyNames.add(Identifier(exec, UString::number(i))); |
| 190 | } |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 191 | if (mode == IncludeDontEnumProperties) { |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 192 | propertyNames.add(exec->propertyNames().callee); |
| 193 | propertyNames.add(exec->propertyNames().length); |
| 194 | } |
mhahnenberg@apple.com | 5726238 | 2011-11-03 00:25:45 +0000 | [diff] [blame] | 195 | JSObject::getOwnPropertyNames(thisObject, exec, propertyNames, mode); |
eric@webkit.org | c293f4c | 2010-01-13 00:58:21 +0000 | [diff] [blame] | 196 | } |
| 197 | |
barraclough@apple.com | b1db28d8 | 2012-03-06 07:23:21 +0000 | [diff] [blame] | 198 | void Arguments::putByIndex(JSCell* cell, ExecState* exec, unsigned i, JSValue value, bool shouldThrow) |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 199 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 200 | Arguments* thisObject = jsCast<Arguments*>(cell); |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 201 | 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.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 203 | return; |
| 204 | } |
| 205 | |
barraclough@apple.com | b1db28d8 | 2012-03-06 07:23:21 +0000 | [diff] [blame] | 206 | PutPropertySlot slot(shouldThrow); |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 207 | JSObject::put(thisObject, exec, Identifier(exec, UString::number(i)), value, slot); |
darin@apple.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 208 | } |
| 209 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 210 | void Arguments::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 211 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 212 | Arguments* thisObject = jsCast<Arguments*>(cell); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 213 | unsigned i = propertyName.asIndex(); |
| 214 | if (i < thisObject->d->numArguments && (!thisObject->d->deletedArguments || !thisObject->d->deletedArguments[i])) { |
| 215 | ASSERT(i < PropertyName::NotAnIndex); |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 216 | thisObject->argument(i).set(exec->globalData(), thisObject, value); |
cwzwarich@webkit.org | 4e9a20c | 2008-09-21 08:37:01 +0000 | [diff] [blame] | 217 | return; |
| 218 | } |
| 219 | |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 220 | if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) { |
| 221 | thisObject->d->overrodeLength = true; |
| 222 | thisObject->putDirect(exec->globalData(), propertyName, value, DontEnum); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 223 | return; |
| 224 | } |
| 225 | |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 226 | 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.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 230 | return; |
| 231 | } |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 232 | thisObject->createStrictModeCalleeIfNecessary(exec); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 233 | } |
| 234 | |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 235 | if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode) |
| 236 | thisObject->createStrictModeCallerIfNecessary(exec); |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 237 | |
mhahnenberg@apple.com | 5e2b712 | 2011-10-08 00:06:07 +0000 | [diff] [blame] | 238 | JSObject::put(thisObject, exec, propertyName, value, slot); |
darin@apple.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 239 | } |
| 240 | |
mhahnenberg@apple.com | 8a10db9 | 2011-10-20 18:14:50 +0000 | [diff] [blame] | 241 | bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i) |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 242 | { |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 243 | Arguments* thisObject = jsCast<Arguments*>(cell); |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 244 | if (i < thisObject->d->numArguments) { |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 245 | if (!Base::deletePropertyByIndex(cell, exec, i)) |
| 246 | return false; |
| 247 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 248 | 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.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 251 | } |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 252 | if (!thisObject->d->deletedArguments[i]) { |
| 253 | thisObject->d->deletedArguments[i] = true; |
darin@apple.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 254 | return true; |
| 255 | } |
| 256 | } |
| 257 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 258 | return JSObject::deleteProperty(thisObject, exec, Identifier(exec, UString::number(i))); |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 259 | } |
| 260 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 261 | bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 262 | { |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 263 | if (exec->globalData().isInDefineOwnProperty()) |
| 264 | return Base::deleteProperty(cell, exec, propertyName); |
| 265 | |
mhahnenberg@apple.com | 135f051 | 2011-11-11 20:40:10 +0000 | [diff] [blame] | 266 | Arguments* thisObject = jsCast<Arguments*>(cell); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 267 | unsigned i = propertyName.asIndex(); |
| 268 | if (i < thisObject->d->numArguments) { |
| 269 | ASSERT(i < PropertyName::NotAnIndex); |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 270 | if (!Base::deleteProperty(cell, exec, propertyName)) |
| 271 | return false; |
| 272 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 273 | 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.org | 4e9a20c | 2008-09-21 08:37:01 +0000 | [diff] [blame] | 276 | } |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 277 | if (!thisObject->d->deletedArguments[i]) { |
| 278 | thisObject->d->deletedArguments[i] = true; |
darin@apple.com | 2d1b358 | 2008-09-21 21:35:23 +0000 | [diff] [blame] | 279 | return true; |
cwzwarich@webkit.org | 4e9a20c | 2008-09-21 08:37:01 +0000 | [diff] [blame] | 280 | } |
| 281 | } |
| 282 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 283 | if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) { |
| 284 | thisObject->d->overrodeLength = true; |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 285 | return true; |
| 286 | } |
| 287 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 288 | if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) { |
| 289 | if (!thisObject->d->isStrictMode) { |
| 290 | thisObject->d->overrodeCallee = true; |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 291 | return true; |
| 292 | } |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 293 | thisObject->createStrictModeCalleeIfNecessary(exec); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 294 | } |
oliver@apple.com | 5930185 | 2010-10-11 19:12:29 +0000 | [diff] [blame] | 295 | |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 296 | if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode) |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 297 | thisObject->createStrictModeCallerIfNecessary(exec); |
cwzwarich@webkit.org | 2d883f7 | 2008-09-23 10:59:42 +0000 | [diff] [blame] | 298 | |
mhahnenberg@apple.com | 914c3ee | 2011-10-08 06:37:45 +0000 | [diff] [blame] | 299 | return JSObject::deleteProperty(thisObject, exec, propertyName); |
weinig@apple.com | 7dab465 | 2008-07-05 23:19:36 +0000 | [diff] [blame] | 300 | } |
| 301 | |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 302 | bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, PropertyDescriptor& descriptor, bool shouldThrow) |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 303 | { |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 304 | Arguments* thisObject = jsCast<Arguments*>(object); |
barraclough@apple.com | 38d3c75 | 2012-05-12 00:39:43 +0000 | [diff] [blame] | 305 | unsigned i = propertyName.asIndex(); |
| 306 | if (i < thisObject->d->numArguments) { |
| 307 | ASSERT(i < PropertyName::NotAnIndex); |
barraclough@apple.com | 7ca5cdc | 2012-04-30 22:29:10 +0000 | [diff] [blame] | 308 | // 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.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 312 | if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow)) |
| 313 | return false; |
| 314 | |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 315 | 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.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 326 | } else { // b. Else |
| 327 | // i. If Desc.[[Value]] is present, then |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 328 | // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments. |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 329 | if (descriptor.value()) |
| 330 | thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value()); |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 331 | // ii. If Desc.[[Writable]] is present and its value is false, then |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 332 | // 1. Call the [[Delete]] internal method of map passing P and false as arguments. |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 333 | if (descriptor.writablePresent() && !descriptor.writable()) |
barraclough@apple.com | eb88e08 | 2012-03-06 20:20:04 +0000 | [diff] [blame] | 334 | thisObject->d->deletedArguments[i] = true; |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 335 | } |
| 336 | } |
barraclough@apple.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 337 | return true; |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 338 | } |
barraclough@apple.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 339 | |
| 340 | if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) { |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 341 | thisObject->putDirect(exec->globalData(), propertyName, jsNumber(thisObject->d->numArguments), DontEnum); |
barraclough@apple.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 342 | thisObject->d->overrodeLength = true; |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 343 | } else if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) { |
| 344 | thisObject->putDirect(exec->globalData(), propertyName, thisObject->d->callee.get(), DontEnum); |
barraclough@apple.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 345 | thisObject->d->overrodeCallee = true; |
barraclough@apple.com | 7ef4152 | 2012-03-19 21:34:25 +0000 | [diff] [blame] | 346 | } else if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode) |
barraclough@apple.com | 4e34894 | 2012-02-23 19:43:07 +0000 | [diff] [blame] | 347 | thisObject->createStrictModeCallerIfNecessary(exec); |
| 348 | |
| 349 | return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow); |
barraclough@apple.com | a9b4539 | 2012-02-23 01:25:37 +0000 | [diff] [blame] | 350 | } |
| 351 | |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 352 | void Arguments::tearOff(CallFrame* callFrame) |
| 353 | { |
| 354 | if (isTornOff()) |
| 355 | return; |
| 356 | |
| 357 | if (!d->numArguments) |
| 358 | return; |
| 359 | |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 360 | // 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.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 363 | 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.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 372 | tearOffForInlineCallFrame( |
| 373 | callFrame->globalData(), callFrame->registers(), callFrame->inlineCallFrame()); |
| 374 | } |
| 375 | |
| 376 | void 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 | |
| 392 | void Arguments::tearOffForInlineCallFrame(JSGlobalData& globalData, Register* registers, InlineCallFrame* inlineCallFrame) |
| 393 | { |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 394 | 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.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 402 | Register* location = ®isters[CallFrame::argumentOffset(i)]; |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 403 | 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.com | 10f22fc | 2011-12-14 07:16:36 +0000 | [diff] [blame] | 416 | 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.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 423 | case Constant: |
| 424 | value = recovery.constant(); |
| 425 | break; |
| 426 | default: |
| 427 | ASSERT_NOT_REACHED(); |
| 428 | break; |
| 429 | } |
fpizlo@apple.com | c644611 | 2012-05-23 20:52:42 +0000 | [diff] [blame] | 430 | argument(i).set(globalData, this, value); |
ggaren@apple.com | 0af1468 | 2011-12-12 00:35:51 +0000 | [diff] [blame] | 431 | } |
| 432 | } |
| 433 | |
cwzwarich@webkit.org | 3f782f6 | 2008-09-08 01:28:33 +0000 | [diff] [blame] | 434 | } // namespace JSC |