diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-07-08 16:15:49 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-07-08 16:17:37 (GMT) |
commit | a4e0ae8af7b550117d1e9d9dbb90564d50985fe3 (patch) | |
tree | f74e6ab0ec829bca0ecea607d06a5d90aa445ecc /src/script/bridge | |
parent | 9fa78177eb5f31e6941b165949957f2b92b8dd0a (diff) | |
download | Qt-a4e0ae8af7b550117d1e9d9dbb90564d50985fe3.zip Qt-a4e0ae8af7b550117d1e9d9dbb90564d50985fe3.tar.gz Qt-a4e0ae8af7b550117d1e9d9dbb90564d50985fe3.tar.bz2 |
rewrite most of QScriptContext handling
Do it The right way(TM), by lazily wrapping JSC::ExecState objects.
Diffstat (limited to 'src/script/bridge')
-rw-r--r-- | src/script/bridge/qscriptfunction.cpp | 60 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject.cpp | 58 | ||||
-rw-r--r-- | src/script/bridge/qscriptqobject_p.h | 3 |
3 files changed, 56 insertions, 65 deletions
diff --git a/src/script/bridge/qscriptfunction.cpp b/src/script/bridge/qscriptfunction.cpp index e9d94a1..c93e025 100644 --- a/src/script/bridge/qscriptfunction.cpp +++ b/src/script/bridge/qscriptfunction.cpp @@ -50,42 +50,36 @@ JSC::ConstructType FunctionWrapper::getConstructData(JSC::ConstructData& consDat return JSC::ConstructTypeHost; } -JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *, JSC::JSObject *callee, +JSC::JSValue FunctionWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee, JSC::JSValue thisObject, const JSC::ArgList &args) { FunctionWrapper *self = static_cast<FunctionWrapper*>(callee); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, thisObject, args, - /*calledAsConstructor=*/false, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; + QScriptContext *ctx = eng_p->contextForFrame(exec); QScriptValue result = self->data->function(ctx, self->data->engine); if (!result.isValid()) result = QScriptValue(QScriptValue::UndefinedValue); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; + eng_p->releaseContextForFrame(exec); return eng_p->scriptValueToJSCValue(result); } -JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *, JSC::JSObject *callee, +JSC::JSObject* FunctionWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee, const JSC::ArgList &args) { FunctionWrapper *self = static_cast<FunctionWrapper*>(callee); QScriptValue object = self->data->engine->newObject(); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, eng_p->scriptValueToJSCValue(object), - args, /*calledAsConstructor=*/true, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + JSC::ExecState *previousFrame = eng_p->currentFrame; + QScriptContext *ctx = eng_p->contextForFrame(exec); + eng_p->currentFrame = exec; QScriptValue result = self->data->function(ctx, self->data->engine); if (!result.isValid()) result = QScriptValue(QScriptValue::UndefinedValue); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; + eng_p->releaseContextForFrame(exec); if (result.isObject()) return JSC::asObject(eng_p->scriptValueToJSCValue(result)); return JSC::asObject(eng_p->scriptValueToJSCValue(object)); @@ -112,38 +106,32 @@ JSC::ConstructType FunctionWithArgWrapper::getConstructData(JSC::ConstructData& return JSC::ConstructTypeHost; } -JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *, JSC::JSObject *callee, +JSC::JSValue FunctionWithArgWrapper::proxyCall(JSC::ExecState *exec, JSC::JSObject *callee, JSC::JSValue thisObject, const JSC::ArgList &args) { FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, thisObject, args, - /*calledAsConstructor=*/false, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + JSC::ExecState *previousFrame = eng_p->currentFrame; + QScriptContext *ctx = eng_p->contextForFrame(exec); + eng_p->currentFrame = exec; QScriptValue result = self->data->function(ctx, self->data->engine, self->data->arg); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; + eng_p->releaseContextForFrame(exec); return eng_p->scriptValueToJSCValue(result); } -JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *, JSC::JSObject *callee, +JSC::JSObject* FunctionWithArgWrapper::proxyConstruct(JSC::ExecState *exec, JSC::JSObject *callee, const JSC::ArgList &args) { FunctionWithArgWrapper *self = static_cast<FunctionWithArgWrapper*>(callee); QScriptValue object = self->data->engine->newObject(); QScriptEnginePrivate *eng_p = QScriptEnginePrivate::get(self->data->engine); - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, eng_p->scriptValueToJSCValue(object), - args, /*calledAsConstructor=*/true, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + JSC::ExecState *previousFrame = eng_p->currentFrame; + QScriptContext *ctx = eng_p->contextForFrame(exec); + eng_p->currentFrame = exec; QScriptValue result = self->data->function(ctx, self->data->engine, self->data->arg); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; + eng_p->releaseContextForFrame(exec); if (result.isObject()) return JSC::asObject(eng_p->scriptValueToJSCValue(result)); return JSC::asObject(eng_p->scriptValueToJSCValue(object)); diff --git a/src/script/bridge/qscriptqobject.cpp b/src/script/bridge/qscriptqobject.cpp index 5565b48..9a804f0 100644 --- a/src/script/bridge/qscriptqobject.cpp +++ b/src/script/bridge/qscriptqobject.cpp @@ -464,7 +464,7 @@ JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, { Q_ASSERT(data->object.isObject(&QObjectWrapperObject::info)); QObjectWrapperObject *wrapper = static_cast<QObjectWrapperObject*>(JSC::asObject(data->object)); - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; + QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; QObject *qobj = wrapper->value(); Q_ASSERT_X(qobj != 0, "QtFunction::call", "handle the case when QObject has been deleted"); @@ -946,7 +946,7 @@ JSC::JSValue QtFunction::execute(JSC::ExecState *exec, JSC::JSValue thisValue, return result; } -const JSC::ClassInfo QtFunction::info = { "QtFunction", 0, 0, 0 }; +const JSC::ClassInfo QtFunction::info = { "QtFunction", &InternalFunction::info, 0, 0 }; JSC::JSValue JSC_HOST_CALL QtFunction::call(JSC::ExecState *exec, JSC::JSObject *callee, JSC::JSValue thisValue, const JSC::ArgList &args) @@ -954,20 +954,15 @@ JSC::JSValue JSC_HOST_CALL QtFunction::call(JSC::ExecState *exec, JSC::JSObject if (!callee->isObject(&QtFunction::info)) return throwError(exec, JSC::TypeError, "callee is not a QtFunction object"); QtFunction *qfun = static_cast<QtFunction*>(callee); - QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, thisValue, args, - /*calledAsConstructor=*/false, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; JSC::JSValue result = qfun->execute(exec, thisValue, args); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; return result; } -const JSC::ClassInfo QtPropertyFunction::info = { "QtPropertyFunction", 0, 0, 0 }; +const JSC::ClassInfo QtPropertyFunction::info = { "QtPropertyFunction", &InternalFunction::info, 0, 0 }; QtPropertyFunction::QtPropertyFunction(const QMetaObject *meta, int index, JSC::JSGlobalData *data, @@ -996,16 +991,11 @@ JSC::JSValue JSC_HOST_CALL QtPropertyFunction::call( if (!callee->isObject(&QtPropertyFunction::info)) return throwError(exec, JSC::TypeError, "callee is not a QtPropertyFunction object"); QtPropertyFunction *qfun = static_cast<QtPropertyFunction*>(callee); - QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; - QScriptContext *previousContext = eng_p->currentContext; - QScriptContextPrivate ctx_p(callee, thisValue, args, - /*calledAsConstructor=*/false, - previousContext, eng_p); - QScriptContext *ctx = QScriptContextPrivate::create(ctx_p); - eng_p->currentContext = ctx; + QScriptEnginePrivate *eng_p = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; + JSC::ExecState *previousFrame = eng_p->currentFrame; + eng_p->currentFrame = exec; JSC::JSValue result = qfun->execute(exec, thisValue, args); - eng_p->currentContext = previousContext; - delete ctx; + eng_p->currentFrame = previousFrame; return result; } @@ -1016,7 +1006,7 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, JSC::JSValue result = JSC::jsUndefined(); // ### don't go via QScriptValue - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; + QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; QScriptValue object = engine->scriptValueFromJSCValue(thisValue); QObject *qobject = object.toQObject(); while ((!qobject || (qobject->metaObject() != data->meta)) @@ -1078,6 +1068,16 @@ JSC::JSValue QtPropertyFunction::execute(JSC::ExecState *exec, return result; } +const QMetaObject *QtPropertyFunction::metaObject() const +{ + return data->meta; +} + +int QtPropertyFunction::propertyIndex() const +{ + return data->index; +} + const JSC::ClassInfo QObjectWrapperObject::info = { "QObject", 0, 0, 0 }; QObjectWrapperObject::QObjectWrapperObject( @@ -1130,7 +1130,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec, const QScriptEngine::QObjectWrapOptions &opt = data->options; const QMetaObject *meta = qobject->metaObject(); - QScriptEnginePrivate *eng = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; + QScriptEnginePrivate *eng = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; int index = -1; if (name.contains('(')) { QByteArray normalized = QMetaObject::normalizedSignature(name); @@ -1141,7 +1141,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec, || (index >= meta->methodOffset())) { QtFunction *fun = new (exec)QtFunction( this, index, /*maybeOverloaded=*/false, - &exec->globalData(), exec->dynamicGlobalObject()->functionStructure(), + &exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), propertyName); slot.setValue(fun); data->cachedMembers.insert(name, fun); @@ -1160,7 +1160,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec, if (GeneratePropertyFunctions) { QtPropertyFunction *fun = new (exec)QtPropertyFunction( meta, index, &exec->globalData(), - exec->dynamicGlobalObject()->functionStructure(), + exec->lexicalGlobalObject()->functionStructure(), propertyName); data->cachedMembers.insert(name, fun); slot.setGetterSlot(fun); @@ -1192,7 +1192,7 @@ bool QObjectWrapperObject::getOwnPropertySlot(JSC::ExecState *exec, && (methodName(method) == name)) { QtFunction *fun = new (exec)QtFunction( this, index, /*maybeOverloaded=*/true, - &exec->globalData(), exec->dynamicGlobalObject()->functionStructure(), + &exec->globalData(), exec->lexicalGlobalObject()->functionStructure(), propertyName); slot.setValue(fun); data->cachedMembers.insert(name, fun); @@ -1230,7 +1230,7 @@ void QObjectWrapperObject::put(JSC::ExecState* exec, const JSC::Identifier& prop const QScriptEngine::QObjectWrapOptions &opt = data->options; const QMetaObject *meta = qobject->metaObject(); - QScriptEnginePrivate *eng = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; + QScriptEnginePrivate *eng = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; int index = -1; if (name.contains('(')) { QByteArray normalized = QMetaObject::normalizedSignature(name); @@ -1486,7 +1486,7 @@ static JSC::JSValue JSC_HOST_CALL qobjectProtoFuncFindChild(JSC::ExecState *exec name = QScript::qtStringFromJSCUString(args.at(0).toString(exec)); QObject *child = qFindChild<QObject*>(obj, name); QScriptEngine::QObjectWrapOptions opt = QScriptEngine::PreferExistingWrapperObject; - QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->dynamicGlobalObject())->engine; + QScriptEnginePrivate *engine = static_cast<QScript::GlobalObject*>(exec->lexicalGlobalObject())->engine; return engine->newQObject(child, QScriptEngine::QtOwnership, opt); } @@ -1783,7 +1783,7 @@ void QObjectConnectionManager::execute(int slotIndex, void **argv) if (receiver && receiver.isObject()) thisObject = receiver; else - thisObject = exec->dynamicGlobalObject(); + thisObject = exec->lexicalGlobalObject(); JSC::CallData callData; JSC::CallType callType = slot.getCallData(callData); diff --git a/src/script/bridge/qscriptqobject_p.h b/src/script/bridge/qscriptqobject_p.h index 31f6446..e5b65b6 100644 --- a/src/script/bridge/qscriptqobject_p.h +++ b/src/script/bridge/qscriptqobject_p.h @@ -210,6 +210,9 @@ public: JSC::JSValue execute(JSC::ExecState *exec, JSC::JSValue thisValue, const JSC::ArgList &args); + const QMetaObject *metaObject() const; + int propertyIndex() const; + private: Data *data; }; |