summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSFunction.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-03-12 14:11:15 +0100
commitdd91e772430dc294e3bf478c119ef8d43c0a3358 (patch)
tree6f33ce4d5872a5691e0291eb45bf6ab373a5f567 /Source/JavaScriptCore/runtime/JSFunction.cpp
parentad0d549d4cc13433f77c1ac8f0ab379c83d93f28 (diff)
downloadqtwebkit-dd91e772430dc294e3bf478c119ef8d43c0a3358.tar.gz
Imported WebKit commit 3db4eb1820ac8fb03065d7ea73a4d9db1e8fea1a (http://svn.webkit.org/repository/webkit/trunk@110422)
This includes build fixes for the latest qtbase/qtdeclarative as well as the final QML2 API.
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSFunction.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp77
1 files changed, 72 insertions, 5 deletions
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index 253128279..fa798f41a 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -181,7 +181,15 @@ JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identi
{
JSFunction* thisObj = asFunction(slotBase);
ASSERT(!thisObj->isHostFunction());
- return exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj);
+ JSValue caller = exec->interpreter()->retrieveCallerFromVMCode(exec, thisObj);
+
+ // See ES5.1 15.3.5.4 - Function.caller may not be used to retrieve a strict caller.
+ if (!caller.isObject() || !asObject(caller)->inherits(&JSFunction::s_info))
+ return caller;
+ JSFunction* function = asFunction(caller);
+ if (function->isHostFunction() || !function->jsExecutable()->isStrictMode())
+ return caller;
+ return throwTypeError(exec, "Function.caller used to retrieve strict caller");
}
JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, const Identifier&)
@@ -329,21 +337,80 @@ void JSFunction::put(JSCell* cell, ExecState* exec, const Identifier& propertyNa
Base::put(thisObject, exec, propertyName, value, slot);
return;
}
- if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().caller) {
+ if (slot.isStrictMode())
+ throwTypeError(exec, StrictModeReadonlyPropertyWriteError);
return;
+ }
Base::put(thisObject, exec, propertyName, value, slot);
}
bool JSFunction::deleteProperty(JSCell* cell, ExecState* exec, const Identifier& propertyName)
{
JSFunction* thisObject = jsCast<JSFunction*>(cell);
- if (thisObject->isHostFunction())
- return Base::deleteProperty(thisObject, exec, propertyName);
- if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length)
+ // For non-host functions, don't let these properties by deleted - except by DefineOwnProperty.
+ if (!thisObject->isHostFunction() && !exec->globalData().isInDefineOwnProperty()
+ && (propertyName == exec->propertyNames().arguments
+ || propertyName == exec->propertyNames().length
+ || propertyName == exec->propertyNames().prototype
+ || propertyName == exec->propertyNames().caller))
return false;
return Base::deleteProperty(thisObject, exec, propertyName);
}
+bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, const Identifier& propertyName, PropertyDescriptor& descriptor, bool throwException)
+{
+ JSFunction* thisObject = jsCast<JSFunction*>(object);
+ if (thisObject->isHostFunction())
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+
+ if (propertyName == exec->propertyNames().prototype) {
+ // Make sure prototype has been reified, such that it can only be overwritten
+ // following the rules set out in ECMA-262 8.12.9.
+ PropertySlot slot;
+ thisObject->methodTable()->getOwnPropertySlot(thisObject, exec, propertyName, slot);
+ } else if (propertyName == exec->propertyNames().arguments || propertyName == exec->propertyNames().length || propertyName == exec->propertyNames().caller) {
+ if (!object->isExtensible()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to define property on object that is not extensible."));
+ return false;
+ }
+ if (descriptor.configurablePresent() && descriptor.configurable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to configurable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.enumerablePresent() && descriptor.enumerable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change enumerable attribute of unconfigurable property."));
+ return false;
+ }
+ if (descriptor.isAccessorDescriptor()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change access mechanism for an unconfigurable property."));
+ return false;
+ }
+ if (descriptor.writablePresent() && descriptor.writable()) {
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
+ return false;
+ }
+ if (!descriptor.value())
+ return true;
+ if (propertyName == exec->propertyNames().arguments && sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject)))
+ return true;
+ if (propertyName == exec->propertyNames().length && sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount())))
+ return true;
+ if (propertyName == exec->propertyNames().caller && sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject)))
+ return true;
+ if (throwException)
+ throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
+ return false;
+ }
+
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+}
+
// ECMA 13.2.2 [[Construct]]
ConstructType JSFunction::getConstructData(JSCell* cell, ConstructData& constructData)
{