summaryrefslogtreecommitdiffstats
path: root/src/script/bridge
diff options
context:
space:
mode:
authorOlivier Goffart <ogoffart@trolltech.com>2009-08-11 11:53:04 (GMT)
committerOlivier Goffart <ogoffart@trolltech.com>2009-08-12 13:15:23 (GMT)
commit45e2a19b4b75fe94a78161f26862bf3c6f727d74 (patch)
treea6e698eee514ad28815519f3b2ba5ac592941de3 /src/script/bridge
parente806a4e887b6584f1115ced3cb489bb0e9a2de36 (diff)
downloadQt-45e2a19b4b75fe94a78161f26862bf3c6f727d74.zip
Qt-45e2a19b4b75fe94a78161f26862bf3c6f727d74.tar.gz
Qt-45e2a19b4b75fe94a78161f26862bf3c6f727d74.tar.bz2
Refactor the way the JS stack are created for native function
The original JavaScriptCore doesn't create stack frame or scope for native function. JSC has been patched to support that. This commit revert our patches to JSC, and implement create the stack frame from QScript Reviewed-by: Kent Hansen
Diffstat (limited to 'src/script/bridge')
-rw-r--r--src/script/bridge/qscriptclassobject.cpp24
-rw-r--r--src/script/bridge/qscriptfunction.cpp61
-rw-r--r--src/script/bridge/qscriptqobject.cpp11
3 files changed, 66 insertions, 30 deletions
diff --git a/src/script/bridge/qscriptclassobject.cpp b/src/script/bridge/qscriptclassobject.cpp
index 50547e81..3a41dae 100644
--- a/src/script/bridge/qscriptclassobject.cpp
+++ b/src/script/bridge/qscriptclassobject.cpp
@@ -214,14 +214,16 @@ JSC::JSValue JSC_HOST_CALL ClassObjectDelegate::call(JSC::ExecState *exec, JSC::
if (!delegate || (delegate->type() != QScriptObjectDelegate::ClassObject))
return JSC::throwError(exec, JSC::TypeError, "callee is not a ClassObject object");
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec, true);
-
QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
- QScriptContext *ctx = eng_p->contextForFrame(exec);
+
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisValue, args, callee);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
QScriptValue scriptObject = eng_p->scriptValueFromJSCValue(obj);
QVariant result = scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx));
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
return eng_p->jscValueFromVariant(result);
}
@@ -241,11 +243,19 @@ JSC::JSObject* ClassObjectDelegate::construct(JSC::ExecState *exec, JSC::JSObjec
QScriptObjectDelegate *delegate = obj->delegate();
QScriptClass *scriptClass = static_cast<ClassObjectDelegate*>(delegate)->scriptClass();
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec, true);
+ JSC::Structure* structure;
+ JSC::JSValue prototype = JSC::asObject(callee)->get(exec, exec->propertyNames().prototype);
+ if (prototype.isObject())
+ structure = JSC::asObject(prototype)->inheritorID();
+ else
+ structure = exec->lexicalGlobalObject()->emptyObjectStructure();
+ JSC::JSObject* thisObject = new (exec) QScriptObject(structure);
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
- QScriptContext *ctx = eng_p->contextForFrame(exec);
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisObject, args, callee, true);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
+
QScriptValue defaultObject = ctx->thisObject();
QScriptValue result = qvariant_cast<QScriptValue>(scriptClass->extension(QScriptClass::Callable, qVariantFromValue(ctx)));
if (!result.isObject())
diff --git a/src/script/bridge/qscriptfunction.cpp b/src/script/bridge/qscriptfunction.cpp
index 2124128..f3880b4 100644
--- a/src/script/bridge/qscriptfunction.cpp
+++ b/src/script/bridge/qscriptfunction.cpp
@@ -46,12 +46,12 @@
#include "private/qscriptcontext_p.h"
#include "private/qscriptvalue_p.h"
#include "qscriptactivationobject_p.h"
+#include "qscriptobject_p.h"
#include "JSGlobalObject.h"
#include "DebuggerCallFrame.h"
#include "Debugger.h"
-
namespace JSC
{
ASSERT_CLASS_FITS_IN_CELL(QScript::FunctionWrapper);
@@ -91,29 +91,38 @@ JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *cal
{
FunctionWrapper *self = static_cast<FunctionWrapper*>(callee);
QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);
- QScriptContext *ctx = eng_p->contextForFrame(exec);
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec);
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisObject, args, callee);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p));
if (!result.isValid())
result = QScriptValue(QScriptValue::UndefinedValue);
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
+
return eng_p->scriptValueToJSCValue(result);
}
JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee,
const JSC::ArgList &args)
{
+ JSC::Structure* structure;
+ JSC::JSValue prototype = JSC::asObject(callee)->get(exec, exec->propertyNames().prototype);
+ if (prototype.isObject())
+ structure = JSC::asObject(prototype)->inheritorID();
+ else
+ structure = exec->lexicalGlobalObject()->emptyObjectStructure();
+ JSC::JSObject* thisObject = new (exec) QScriptObject(structure);
+
FunctionWrapper *self = static_cast<FunctionWrapper*>(callee);
QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);
- QScriptContext *ctx = eng_p->contextForFrame(exec);
-
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec, true);
- QScriptValue defaultObject = ctx->thisObject();
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisObject, args, callee, true);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p));
#ifdef QT_BUILD_SCRIPT_LIB
@@ -121,7 +130,10 @@ JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObje
debugger->functionExit(QScriptValuePrivate::get(result)->jscValue, -1);
#endif
if (!result.isObject())
- result = defaultObject;
+ result = ctx->thisObject();
+
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}
@@ -152,10 +164,14 @@ JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObje
FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee);
QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec);
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisObject, args, callee);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
+
+ QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p), self->data->arg);
- QScriptValue result = self->data->function(eng_p->contextForFrame(exec), QScriptEnginePrivate::get(eng_p), self->data->arg);
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
return eng_p->scriptValueToJSCValue(result);
}
@@ -163,18 +179,27 @@ JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObje
JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee,
const JSC::ArgList &args)
{
+ JSC::Structure* structure;
+ JSC::JSValue prototype = JSC::asObject(callee)->get(exec, exec->propertyNames().prototype);
+ if (prototype.isObject())
+ structure = JSC::asObject(prototype)->inheritorID();
+ else
+ structure = exec->lexicalGlobalObject()->emptyObjectStructure();
+ JSC::JSObject* thisObject = new (exec) QScriptObject(structure);
+
FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee);
QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);
- QScriptContext *ctx = eng_p->contextForFrame(exec);
- //We might have nested eval inside our function so we should create another scope
- QScriptPushScopeHelper scope(exec, true);
+ JSC::ExecState *oldFrame = eng_p->currentFrame;
+ eng_p->pushContext(exec, thisObject, args, callee, true);
+ QScriptContext *ctx = eng_p->contextForFrame(eng_p->currentFrame);
- QScriptValue defaultObject = ctx->thisObject();
QScriptValue result = self->data->function(ctx, QScriptEnginePrivate::get(eng_p) , self->data->arg);
if (!result.isObject())
- result = defaultObject;
+ result = ctx->thisObject();
+ eng_p->popContext();
+ eng_p->currentFrame = oldFrame;
return JSC::asObject(eng_p->scriptValueToJSCValue(result));
}
diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp
index 69ae205..a15e632 100644
--- a/src/script/bridge/qscriptqobject.cpp
+++ b/src/script/bridge/qscriptqobject.cpp
@@ -1837,8 +1837,9 @@ JSC::JSValue JSC_HOST_CALL QMetaObjectWrapperObject::call(
return throwError(exec, JSC::TypeError, "callee is not a QMetaObject");
QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee);
JSC::ExecState *previousFrame = eng_p->currentFrame;
- eng_p->currentFrame = exec;
- JSC::JSValue result = self->execute(exec, args, /*calledAsConstructor=*/false);
+ eng_p->pushContext(exec, thisValue, args, callee);
+ JSC::JSValue result = self->execute(eng_p->currentFrame, args, /*calledAsConstructor=*/false);
+ eng_p->popContext();
eng_p->currentFrame = previousFrame;
return result;
}
@@ -1848,8 +1849,9 @@ JSC::JSObject* QMetaObjectWrapperObject::construct(JSC::ExecState *exec, JSC::JS
QMetaObjectWrapperObject *self = static_cast<QMetaObjectWrapperObject*>(callee);
QScriptEnginePrivate *eng_p = scriptEngineFromExec(exec);
JSC::ExecState *previousFrame = eng_p->currentFrame;
- eng_p->currentFrame = exec;
- JSC::JSValue result = self->execute(exec, args, /*calledAsConstructor=*/true);
+ eng_p->pushContext(exec, JSC::JSValue(), args, callee, true);
+ JSC::JSValue result = self->execute(eng_p->currentFrame, args, /*calledAsConstructor=*/true);
+ eng_p->popContext();
eng_p->currentFrame = previousFrame;
if (!result || !result.isObject())
return 0;
@@ -1863,7 +1865,6 @@ JSC::JSValue QMetaObjectWrapperObject::execute(JSC::ExecState *exec,
if (data->ctor) {
QScriptEnginePrivate *eng_p = QScript::scriptEngineFromExec(exec);
QScriptContext *ctx = eng_p->contextForFrame(exec);
- QScriptPushScopeHelper scope(exec, calledAsConstructor);
JSC::CallData callData;
JSC::CallType callType = data->ctor.getCallData(callData);
Q_ASSERT_X(callType == JSC::CallTypeHost, Q_FUNC_INFO, "script constructors not supported");