summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/Arguments.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/JavaScriptCore/runtime/Arguments.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/Arguments.cpp73
1 files changed, 72 insertions, 1 deletions
diff --git a/Source/JavaScriptCore/runtime/Arguments.cpp b/Source/JavaScriptCore/runtime/Arguments.cpp
index 6a675ab84..a099adb75 100644
--- a/Source/JavaScriptCore/runtime/Arguments.cpp
+++ b/Source/JavaScriptCore/runtime/Arguments.cpp
@@ -243,6 +243,9 @@ bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
{
Arguments* thisObject = jsCast<Arguments*>(cell);
if (i < thisObject->d->numArguments) {
+ if (!Base::deletePropertyByIndex(cell, exec, i))
+ return false;
+
if (!thisObject->d->deletedArguments) {
thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
@@ -258,10 +261,16 @@ bool Arguments::deletePropertyByIndex(JSCell* cell, ExecState* exec, unsigned i)
bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
+ if (exec->globalData().isInDefineOwnProperty())
+ return Base::deleteProperty(cell, exec, propertyName);
+
Arguments* thisObject = jsCast<Arguments*>(cell);
bool isArrayIndex;
unsigned i = propertyName.toArrayIndex(isArrayIndex);
if (isArrayIndex && i < thisObject->d->numArguments) {
+ if (!Base::deleteProperty(cell, exec, propertyName))
+ return false;
+
if (!thisObject->d->deletedArguments) {
thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
@@ -285,12 +294,74 @@ bool Arguments::deleteProperty(JSCell* cell, ExecState* exec, const Identifier&
thisObject->createStrictModeCalleeIfNecessary(exec);
}
- if (propertyName == exec->propertyNames().caller && !thisObject->d->isStrictMode)
+ if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
thisObject->createStrictModeCallerIfNecessary(exec);
return JSObject::deleteProperty(thisObject, exec, propertyName);
}
+bool Arguments::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool shouldThrow)
+{
+ Arguments* thisObject = jsCast<Arguments*>(object);
+ bool isArrayIndex;
+ unsigned i = propertyName.toArrayIndex(isArrayIndex);
+ if (isArrayIndex && i < thisObject->d->numArguments) {
+ if (!Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow))
+ return false;
+
+ if (!thisObject->d->deletedArguments) {
+ thisObject->d->deletedArguments = adoptArrayPtr(new bool[thisObject->d->numArguments]);
+ memset(thisObject->d->deletedArguments.get(), 0, sizeof(bool) * thisObject->d->numArguments);
+ }
+ // From ES 5.1, 10.6 Arguments Object
+ // 5. If the value of isMapped is not undefined, then
+ if (!thisObject->d->deletedArguments[i]) {
+ // a. If IsAccessorDescriptor(Desc) is true, then
+ if (descriptor.isAccessorDescriptor()) {
+ // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
+ thisObject->d->deletedArguments[i] = true;
+ } else if (descriptor.value()) { // b. Else i. If Desc.[[Value]] is present, then
+ // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
+ // ii. If Desc.[[Writable]] is present and its value is false, then
+ thisObject->argument(i).set(exec->globalData(), thisObject, descriptor.value());
+ if (descriptor.writablePresent() && !descriptor.writable())
+ thisObject->d->deletedArguments[i] = true; // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
+ }
+ }
+
+ return true;
+ }
+
+ if (propertyName == exec->propertyNames().length && !thisObject->d->overrodeLength) {
+ thisObject->d->overrodeLength = true;
+ if (!descriptor.isAccessorDescriptor()) {
+ if (!descriptor.value())
+ descriptor.setValue(jsNumber(thisObject->d->numArguments));
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+
+ if (propertyName == exec->propertyNames().callee && !thisObject->d->overrodeCallee) {
+ thisObject->d->overrodeCallee = true;
+ if (!descriptor.isAccessorDescriptor()) {
+ if (!descriptor.value())
+ descriptor.setValue(thisObject->d->callee.get());
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+ if (!descriptor.configurablePresent())
+ descriptor.setConfigurable(true);
+ }
+
+ if (propertyName == exec->propertyNames().caller && thisObject->d->isStrictMode)
+ thisObject->createStrictModeCallerIfNecessary(exec);
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
+}
+
void Arguments::tearOff(CallFrame* callFrame)
{
if (isTornOff())