summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSFunction.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
committerSimon Hausmann <simon.hausmann@nokia.com>2012-05-07 11:21:11 +0200
commit2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47 (patch)
tree988e8c5b116dd0466244ae2fe5af8ee9be926d76 /Source/JavaScriptCore/runtime/JSFunction.cpp
parentdd91e772430dc294e3bf478c119ef8d43c0a3358 (diff)
downloadqtwebkit-2cf6c8816a73e0132bd8fa3b509d62d7c51b6e47.tar.gz
Imported WebKit commit 7e538425aa020340619e927792f3d895061fb54b (http://svn.webkit.org/repository/webkit/trunk@116286)
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSFunction.cpp')
-rw-r--r--Source/JavaScriptCore/runtime/JSFunction.cpp106
1 files changed, 59 insertions, 47 deletions
diff --git a/Source/JavaScriptCore/runtime/JSFunction.cpp b/Source/JavaScriptCore/runtime/JSFunction.cpp
index fa798f41a..243946ba9 100644
--- a/Source/JavaScriptCore/runtime/JSFunction.cpp
+++ b/Source/JavaScriptCore/runtime/JSFunction.cpp
@@ -59,22 +59,25 @@ bool JSFunction::isHostFunctionNonInline() const
return isHostFunction();
}
-JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeFunction nativeFunction, NativeFunction nativeConstructor)
+JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeFunction nativeFunction, Intrinsic intrinsic, NativeFunction nativeConstructor)
{
- NativeExecutable* executable = exec->globalData().getHostFunction(nativeFunction, nativeConstructor);
+ NativeExecutable* executable;
+#if !ENABLE(JIT)
+ UNUSED_PARAM(intrinsic);
+#else
+ if (intrinsic != NoIntrinsic && exec->globalData().canUseJIT()) {
+ ASSERT(nativeConstructor == callHostFunctionAsConstructor);
+ executable = exec->globalData().getHostFunction(nativeFunction, intrinsic);
+ } else
+#endif
+ executable = exec->globalData().getHostFunction(nativeFunction, nativeConstructor);
+
JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
// Can't do this during initialization because getHostFunction might do a GC allocation.
function->finishCreation(exec, executable, length, name);
return function;
}
-JSFunction* JSFunction::create(ExecState* exec, JSGlobalObject* globalObject, int length, const Identifier& name, NativeExecutable* nativeExecutable)
-{
- JSFunction* function = new (NotNull, allocateCell<JSFunction>(*exec->heap())) JSFunction(exec, globalObject, globalObject->functionStructure());
- function->finishCreation(exec, nativeExecutable, length, name);
- return function;
-}
-
JSFunction::JSFunction(ExecState* exec, JSGlobalObject* globalObject, Structure* structure)
: Base(exec->globalData(), structure)
, m_executable()
@@ -172,21 +175,21 @@ CallType JSFunction::getCallData(JSCell* cell, CallData& callData)
JSValue JSFunction::argumentsGetter(ExecState* exec, JSValue slotBase, const Identifier&)
{
- JSFunction* thisObj = asFunction(slotBase);
+ JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ASSERT(!thisObj->isHostFunction());
return exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObj);
}
JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identifier&)
{
- JSFunction* thisObj = asFunction(slotBase);
+ JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ASSERT(!thisObj->isHostFunction());
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);
+ JSFunction* function = jsCast<JSFunction*>(caller);
if (function->isHostFunction() || !function->jsExecutable()->isStrictMode())
return caller;
return throwTypeError(exec, "Function.caller used to retrieve strict caller");
@@ -194,7 +197,7 @@ JSValue JSFunction::callerGetter(ExecState* exec, JSValue slotBase, const Identi
JSValue JSFunction::lengthGetter(ExecState*, JSValue slotBase, const Identifier&)
{
- JSFunction* thisObj = asFunction(slotBase);
+ JSFunction* thisObj = jsCast<JSFunction*>(slotBase);
ASSERT(!thisObj->isHostFunction());
return jsNumber(thisObj->jsExecutable()->parameterCount());
}
@@ -369,46 +372,55 @@ bool JSFunction::defineOwnProperty(JSObject* object, ExecState* exec, const Iden
// 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;
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ }
+
+ bool valueCheck;
+ if (propertyName == exec->propertyNames().arguments) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
+ thisObject->putDirectAccessor(exec->globalData(), propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
}
- if (descriptor.writablePresent() && descriptor.writable()) {
- if (throwException)
- throwError(exec, createTypeError(exec, "Attempting to change writable attribute of unconfigurable property."));
- return false;
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveArgumentsFromVMCode(exec, thisObject));
+ } else if (propertyName == exec->propertyNames().caller) {
+ if (thisObject->jsExecutable()->isStrictMode()) {
+ if (!Base::getOwnPropertyDescriptor(thisObject, exec, propertyName, descriptor))
+ thisObject->putDirectAccessor(exec->globalData(), propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
}
- 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;
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), exec->interpreter()->retrieveCallerFromVMCode(exec, thisObject));
+ } else if (propertyName == exec->propertyNames().length)
+ valueCheck = !descriptor.value() || sameValue(exec, descriptor.value(), jsNumber(thisObject->jsExecutable()->parameterCount()));
+ else
+ return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+
+ 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 (!valueCheck) {
if (throwException)
throwError(exec, createTypeError(exec, "Attempting to change value of a readonly property."));
return false;
}
-
- return Base::defineOwnProperty(object, exec, propertyName, descriptor, throwException);
+ return true;
}
// ECMA 13.2.2 [[Construct]]