diff options
Diffstat (limited to 'JavaScriptCore/runtime/Arguments.cpp')
| -rw-r--r-- | JavaScriptCore/runtime/Arguments.cpp | 86 |
1 files changed, 67 insertions, 19 deletions
diff --git a/JavaScriptCore/runtime/Arguments.cpp b/JavaScriptCore/runtime/Arguments.cpp index bb30e3b..39886a8 100644 --- a/JavaScriptCore/runtime/Arguments.cpp +++ b/JavaScriptCore/runtime/Arguments.cpp @@ -151,13 +151,37 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, unsigned i, PropertySlot& sl return true; } - return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::from(i)), slot); + return JSObject::getOwnPropertySlot(exec, Identifier(exec, UString::number(i)), slot); +} + +void Arguments::createStrictModeCallerIfNecessary(ExecState* exec) +{ + if (d->overrodeCaller) + return; + + d->overrodeCaller = true; + PropertyDescriptor descriptor; + JSValue thrower = createTypeErrorFunction(exec, "Unable to access caller of strict mode function"); + descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); + defineOwnProperty(exec, exec->propertyNames().caller, descriptor, false); +} + +void Arguments::createStrictModeCalleeIfNecessary(ExecState* exec) +{ + if (d->overrodeCallee) + return; + + d->overrodeCallee = true; + PropertyDescriptor descriptor; + JSValue thrower = createTypeErrorFunction(exec, "Unable to access callee of strict mode function"); + descriptor.setAccessorDescriptor(thrower, thrower, DontEnum | DontDelete | Getter | Setter); + defineOwnProperty(exec, exec->propertyNames().callee, descriptor, false); } bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyName, PropertySlot& slot) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) { slot.setRegisterSlot(&d->registers[d->firstParameterIndex + i]); @@ -167,22 +191,28 @@ bool Arguments::getOwnPropertySlot(ExecState* exec, const Identifier& propertyNa } if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { - slot.setValue(jsNumber(exec, d->numArguments)); + slot.setValue(jsNumber(d->numArguments)); return true; } if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { - slot.setValue(d->callee); - return true; + if (!d->isStrictMode) { + slot.setValue(d->callee); + return true; + } + createStrictModeCalleeIfNecessary(exec); } + if (propertyName == exec->propertyNames().caller && d->isStrictMode) + createStrictModeCallerIfNecessary(exec); + return JSObject::getOwnPropertySlot(exec, propertyName, slot); } bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) { descriptor.setDescriptor(d->registers[d->firstParameterIndex + i].jsValue(), DontEnum); @@ -192,14 +222,20 @@ bool Arguments::getOwnPropertyDescriptor(ExecState* exec, const Identifier& prop } if (propertyName == exec->propertyNames().length && LIKELY(!d->overrodeLength)) { - descriptor.setDescriptor(jsNumber(exec, d->numArguments), DontEnum); + descriptor.setDescriptor(jsNumber(d->numArguments), DontEnum); return true; } if (propertyName == exec->propertyNames().callee && LIKELY(!d->overrodeCallee)) { - descriptor.setDescriptor(d->callee, DontEnum); - return true; + if (!d->isStrictMode) { + descriptor.setDescriptor(d->callee, DontEnum); + return true; + } + createStrictModeCalleeIfNecessary(exec); } + + if (propertyName == exec->propertyNames().caller && d->isStrictMode) + createStrictModeCallerIfNecessary(exec); return JSObject::getOwnPropertyDescriptor(exec, propertyName, descriptor); } @@ -209,7 +245,7 @@ void Arguments::getOwnPropertyNames(ExecState* exec, PropertyNameArray& property if (mode == IncludeDontEnumProperties) { for (unsigned i = 0; i < d->numArguments; ++i) { if (!d->deletedArguments || !d->deletedArguments[i]) - propertyNames.add(Identifier(exec, UString::from(i))); + propertyNames.add(Identifier(exec, UString::number(i))); } propertyNames.add(exec->propertyNames().callee); propertyNames.add(exec->propertyNames().length); @@ -227,13 +263,13 @@ void Arguments::put(ExecState* exec, unsigned i, JSValue value, PutPropertySlot& return; } - JSObject::put(exec, Identifier(exec, UString::from(i)), value, slot); + JSObject::put(exec, Identifier(exec, UString::number(i)), value, slot); } void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue value, PutPropertySlot& slot) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments && (!d->deletedArguments || !d->deletedArguments[i])) { if (i < d->numParameters) d->registers[d->firstParameterIndex + i] = JSValue(value); @@ -249,11 +285,17 @@ void Arguments::put(ExecState* exec, const Identifier& propertyName, JSValue val } if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { - d->overrodeCallee = true; - putDirect(propertyName, value, DontEnum); - return; + if (!d->isStrictMode) { + d->overrodeCallee = true; + putDirect(propertyName, value, DontEnum); + return; + } + createStrictModeCalleeIfNecessary(exec); } + if (propertyName == exec->propertyNames().caller && d->isStrictMode) + createStrictModeCallerIfNecessary(exec); + JSObject::put(exec, propertyName, value, slot); } @@ -270,13 +312,13 @@ bool Arguments::deleteProperty(ExecState* exec, unsigned i) } } - return JSObject::deleteProperty(exec, Identifier(exec, UString::from(i))); + return JSObject::deleteProperty(exec, Identifier(exec, UString::number(i))); } bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) { bool isArrayIndex; - unsigned i = propertyName.toArrayIndex(&isArrayIndex); + unsigned i = propertyName.toArrayIndex(isArrayIndex); if (isArrayIndex && i < d->numArguments) { if (!d->deletedArguments) { d->deletedArguments.set(new bool[d->numArguments]); @@ -294,9 +336,15 @@ bool Arguments::deleteProperty(ExecState* exec, const Identifier& propertyName) } if (propertyName == exec->propertyNames().callee && !d->overrodeCallee) { - d->overrodeCallee = true; - return true; + if (!d->isStrictMode) { + d->overrodeCallee = true; + return true; + } + createStrictModeCalleeIfNecessary(exec); } + + if (propertyName == exec->propertyNames().caller && !d->isStrictMode) + createStrictModeCallerIfNecessary(exec); return JSObject::deleteProperty(exec, propertyName); } |
