summaryrefslogtreecommitdiffstats
path: root/src/script/bridge/qscriptfunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/bridge/qscriptfunction.cpp')
-rw-r--r--src/script/bridge/qscriptfunction.cpp61
1 files changed, 43 insertions, 18 deletions
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));
}