summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/API
diff options
context:
space:
mode:
authorLeon Clarke <leonclarke@google.com>2010-06-03 14:33:32 +0100
committerLeon Clarke <leonclarke@google.com>2010-06-08 12:24:51 +0100
commit5af96e2c7b73ebc627c6894727826a7576d31758 (patch)
treef9d5e6f6175ccd7e3d14de9b290f08937a0d17ba /JavaScriptCore/API
parent8cc4fcf4f6adcbc0e0aebfc24fbad9a4cddf2cfb (diff)
downloadexternal_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.zip
external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.gz
external_webkit-5af96e2c7b73ebc627c6894727826a7576d31758.tar.bz2
Merge webkit.org at r60469 : Initial merge by git.
Change-Id: I66a0047aa2af802f66bb0c7f2a8b02247a596234
Diffstat (limited to 'JavaScriptCore/API')
-rw-r--r--JavaScriptCore/API/JSCallbackFunction.cpp12
-rw-r--r--JavaScriptCore/API/JSCallbackFunction.h2
-rw-r--r--JavaScriptCore/API/JSCallbackObject.h2
-rw-r--r--JavaScriptCore/API/JSCallbackObjectFunctions.h13
-rw-r--r--JavaScriptCore/API/JSObjectRef.cpp2
-rw-r--r--JavaScriptCore/API/tests/testapi.c60
6 files changed, 76 insertions, 15 deletions
diff --git a/JavaScriptCore/API/JSCallbackFunction.cpp b/JavaScriptCore/API/JSCallbackFunction.cpp
index 4953010..9db9983 100644
--- a/JavaScriptCore/API/JSCallbackFunction.cpp
+++ b/JavaScriptCore/API/JSCallbackFunction.cpp
@@ -47,22 +47,22 @@ JSCallbackFunction::JSCallbackFunction(ExecState* exec, JSGlobalObject* globalOb
{
}
-JSValue JSCallbackFunction::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
+JSValue JSCallbackFunction::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
- JSObjectRef functionRef = toRef(functionObject);
- JSObjectRef thisObjRef = toRef(thisValue.toThisObject(exec));
+ JSObjectRef functionRef = toRef(exec->callee());
+ JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
- int argumentCount = static_cast<int>(args.size());
+ int argumentCount = static_cast<int>(exec->argumentCount());
Vector<JSValueRef, 16> arguments(argumentCount);
for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, args.at(i));
+ arguments[i] = toRef(exec, exec->argument(i));
JSValueRef exception = 0;
JSValueRef result;
{
APICallbackShim callbackShim(exec);
- result = static_cast<JSCallbackFunction*>(functionObject)->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
+ result = static_cast<JSCallbackFunction*>(toJS(functionRef))->m_callback(execRef, functionRef, thisObjRef, argumentCount, arguments.data(), &exception);
}
if (exception)
exec->setException(toJS(exec, exception));
diff --git a/JavaScriptCore/API/JSCallbackFunction.h b/JavaScriptCore/API/JSCallbackFunction.h
index b0dc425..3940e7d 100644
--- a/JavaScriptCore/API/JSCallbackFunction.h
+++ b/JavaScriptCore/API/JSCallbackFunction.h
@@ -48,7 +48,7 @@ private:
virtual CallType getCallData(CallData&);
virtual const ClassInfo* classInfo() const { return &info; }
- static JSValue JSC_HOST_CALL call(ExecState*, JSObject*, JSValue, const ArgList&);
+ static JSValue JSC_HOST_CALL call(ExecState*);
JSObjectCallAsFunctionCallback m_callback;
};
diff --git a/JavaScriptCore/API/JSCallbackObject.h b/JavaScriptCore/API/JSCallbackObject.h
index 0660b45..7216ac5 100644
--- a/JavaScriptCore/API/JSCallbackObject.h
+++ b/JavaScriptCore/API/JSCallbackObject.h
@@ -182,7 +182,7 @@ private:
static JSCallbackObject* asCallbackObject(JSValue);
- static JSValue JSC_HOST_CALL call(ExecState*, JSObject* functionObject, JSValue thisValue, const ArgList&);
+ static JSValue JSC_HOST_CALL call(ExecState*);
static JSObject* construct(ExecState*, JSObject* constructor, const ArgList&);
static JSValue staticValueGetter(ExecState*, JSValue, const Identifier&);
diff --git a/JavaScriptCore/API/JSCallbackObjectFunctions.h b/JavaScriptCore/API/JSCallbackObjectFunctions.h
index 6573ed9..ef1efd2 100644
--- a/JavaScriptCore/API/JSCallbackObjectFunctions.h
+++ b/JavaScriptCore/API/JSCallbackObjectFunctions.h
@@ -29,6 +29,7 @@
#include "Error.h"
#include "JSCallbackFunction.h"
#include "JSClassRef.h"
+#include "JSFunction.h"
#include "JSGlobalObject.h"
#include "JSLock.h"
#include "JSObjectRef.h"
@@ -370,18 +371,18 @@ CallType JSCallbackObject<Base>::getCallData(CallData& callData)
}
template <class Base>
-JSValue JSCallbackObject<Base>::call(ExecState* exec, JSObject* functionObject, JSValue thisValue, const ArgList& args)
+JSValue JSCallbackObject<Base>::call(ExecState* exec)
{
JSContextRef execRef = toRef(exec);
- JSObjectRef functionRef = toRef(functionObject);
- JSObjectRef thisObjRef = toRef(thisValue.toThisObject(exec));
+ JSObjectRef functionRef = toRef(exec->callee());
+ JSObjectRef thisObjRef = toRef(exec->hostThisValue().toThisObject(exec));
- for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(functionObject)->classRef(); jsClass; jsClass = jsClass->parentClass) {
+ for (JSClassRef jsClass = static_cast<JSCallbackObject<Base>*>(toJS(functionRef))->classRef(); jsClass; jsClass = jsClass->parentClass) {
if (JSObjectCallAsFunctionCallback callAsFunction = jsClass->callAsFunction) {
- int argumentCount = static_cast<int>(args.size());
+ int argumentCount = static_cast<int>(exec->argumentCount());
Vector<JSValueRef, 16> arguments(argumentCount);
for (int i = 0; i < argumentCount; i++)
- arguments[i] = toRef(exec, args.at(i));
+ arguments[i] = toRef(exec, exec->argument(i));
JSValueRef exception = 0;
JSValue result;
{
diff --git a/JavaScriptCore/API/JSObjectRef.cpp b/JavaScriptCore/API/JSObjectRef.cpp
index 73bba67..70c4e14 100644
--- a/JavaScriptCore/API/JSObjectRef.cpp
+++ b/JavaScriptCore/API/JSObjectRef.cpp
@@ -236,7 +236,7 @@ void JSObjectSetPrototype(JSContextRef ctx, JSObjectRef object, JSValueRef value
JSObject* jsObject = toJS(object);
JSValue jsValue = toJS(exec, value);
- jsObject->setPrototype(jsValue.isObject() ? jsValue : jsNull());
+ jsObject->setPrototypeWithCycleCheck(jsValue.isObject() ? jsValue : jsNull());
}
bool JSObjectHasProperty(JSContextRef ctx, JSObjectRef object, JSStringRef propertyName)
diff --git a/JavaScriptCore/API/tests/testapi.c b/JavaScriptCore/API/tests/testapi.c
index 28b4ec8..780e996 100644
--- a/JavaScriptCore/API/tests/testapi.c
+++ b/JavaScriptCore/API/tests/testapi.c
@@ -764,6 +764,59 @@ static void makeGlobalNumberValue(JSContextRef context) {
v = NULL;
}
+static bool assertTrue(bool value, const char* message)
+{
+ if (!value) {
+ if (message)
+ fprintf(stderr, "assertTrue failed: '%s'\n", message);
+ else
+ fprintf(stderr, "assertTrue failed.\n");
+ failed = 1;
+ }
+ return value;
+}
+
+static bool checkForCycleInPrototypeChain()
+{
+ bool result = true;
+ JSGlobalContextRef context = JSGlobalContextCreate(0);
+ JSObjectRef object1 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+ JSObjectRef object2 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+ JSObjectRef object3 = JSObjectMake(context, /* jsClass */ 0, /* data */ 0);
+
+ JSObjectSetPrototype(context, object1, JSValueMakeNull(context));
+ ASSERT(JSValueIsNull(context, JSObjectGetPrototype(context, object1)));
+
+ // object1 -> object1
+ JSObjectSetPrototype(context, object1, object1);
+ result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to assign self as a prototype");
+
+ // object1 -> object2 -> object1
+ JSObjectSetPrototype(context, object2, object1);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object1));
+ JSObjectSetPrototype(context, object1, object2);
+ result &= assertTrue(JSValueIsNull(context, JSObjectGetPrototype(context, object1)), "It is possible to close a prototype chain cycle");
+
+ // object1 -> object2 -> object3 -> object1
+ JSObjectSetPrototype(context, object2, object3);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object2), object3));
+ JSObjectSetPrototype(context, object1, object2);
+ ASSERT(JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object1), object2));
+ JSObjectSetPrototype(context, object3, object1);
+ result &= assertTrue(!JSValueIsStrictEqual(context, JSObjectGetPrototype(context, object3), object1), "It is possible to close a prototype chain cycle");
+
+ JSValueRef exception;
+ JSStringRef code = JSStringCreateWithUTF8CString("o = { }; p = { }; o.__proto__ = p; p.__proto__ = o");
+ JSStringRef file = JSStringCreateWithUTF8CString("");
+ result &= assertTrue(!JSEvaluateScript(context, code, /* thisObject*/ 0, file, 1, &exception)
+ , "An exception should be thrown");
+
+ JSStringRelease(code);
+ JSStringRelease(file);
+ JSGlobalContextRelease(context);
+ return result;
+}
+
int main(int argc, char* argv[])
{
const char *scriptPath = "testapi.js";
@@ -1346,6 +1399,13 @@ int main(int argc, char* argv[])
printf("PASS: Infinite prototype chain does not occur.\n");
+ if (checkForCycleInPrototypeChain())
+ printf("PASS: A cycle in a prototype chain can't be created.\n");
+ else {
+ printf("FAIL: A cycle in a prototype chain can be created.\n");
+ failed = true;
+ }
+
if (failed) {
printf("FAIL: Some tests failed.\n");
return 1;