From 9c104bb97098f690e4c8af6e17b7217891a8c690 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Mon, 10 Dec 2012 19:30:08 +0100 Subject: [PATCH] Properly set up the 'this' pointer Make sure the this pointer is setup correctly for function calls. Also make sure we set the strict mode flag correctly in all functions. Change-Id: Idaacc92bf6469145b7addfac2bbddea588e85c2d Reviewed-by: Erik Verbruggen --- qmljs_engine.cpp | 1 + qmljs_environment.cpp | 11 +++++++++-- qmljs_objects.cpp | 8 +------- qmljs_runtime.cpp | 4 +--- qv4codegen.cpp | 3 ++- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/qmljs_engine.cpp b/qmljs_engine.cpp index a694d3e..4da9564 100644 --- a/qmljs_engine.cpp +++ b/qmljs_engine.cpp @@ -177,6 +177,7 @@ ExecutionEngine::ExecutionEngine(MemoryManager *memoryManager, EvalISelFactory * VM::Object *glo = newObject(/*rootContext*/); globalObject = Value::fromObject(glo); rootContext->activation = glo; + rootContext->thisObject = Value::fromObject(glo); glo->__put__(rootContext, identifier(QStringLiteral("Object")), objectCtor); glo->__put__(rootContext, identifier(QStringLiteral("String")), stringCtor); diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp index 4f2f798..9f900f9 100644 --- a/qmljs_environment.cpp +++ b/qmljs_environment.cpp @@ -210,7 +210,7 @@ void ExecutionContext::init(ExecutionEngine *eng) { engine = eng; parent = 0; - thisObject = Value::nullValue(); + thisObject = eng->globalObject; function = 0; arguments = 0; @@ -385,11 +385,18 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha engine = parent->engine; this->parent = parent; - thisObject = that; function = f; strictMode = f->strictMode; + thisObject = that; + if (!strictMode && !thisObject.isObject()) { + if (thisObject.isUndefined() || thisObject.isNull()) + thisObject = engine->globalObject; + else + thisObject = thisObject.toObject(this); + } + arguments = args; argumentCount = argc; if (function->needsActivation || argc < function->formalParameterCount){ diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index d74a501..6e0af63 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -450,7 +450,7 @@ Value FunctionObject::construct(ExecutionContext *context, Value *args, int argc { ExecutionContext k; ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k; - ctx->initCallContext(context, Value::nullValue(), this, args, argc); + ctx->initCallContext(context, Value::undefinedValue(), this, args, argc); Value result = construct(ctx); ctx->wireUpPrototype(); ctx->leaveCallContext(); @@ -464,12 +464,6 @@ Value FunctionObject::call(ExecutionContext *context, Value thisObject, Value *a ExecutionContext k; ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k; - if (!strictMode && !thisObject.isObject()) { - if (thisObject.isUndefined() || thisObject.isNull()) - thisObject = context->engine->globalObject; - else - thisObject = __qmljs_to_object(thisObject, context); - } ctx->initCallContext(context, thisObject, this, args, argc); Value result = call(ctx); ctx->leaveCallContext(); diff --git a/qmljs_runtime.cpp b/qmljs_runtime.cpp index 53f313f..62e7be4 100644 --- a/qmljs_runtime.cpp +++ b/qmljs_runtime.cpp @@ -628,9 +628,7 @@ Value __qmljs_get_activation_property(ExecutionContext *ctx, String *name) Value __qmljs_get_thisObject(ExecutionContext *ctx) { - if (ctx->thisObject.isObject()) - return ctx->thisObject; - return ctx->engine->globalObject; + return ctx->thisObject; } uint __qmljs_equal(Value x, Value y, ExecutionContext *ctx) diff --git a/qv4codegen.cpp b/qv4codegen.cpp index eefd3a3..d9ac31d 100644 --- a/qv4codegen.cpp +++ b/qv4codegen.cpp @@ -207,7 +207,8 @@ protected: inline void enterEnvironment(Node *node) { Environment *e = _cg->newEnvironment(node, _env); - e->isStrict = _cg->_context->strictMode; + if (!e->isStrict) + e->isStrict = _cg->_context->strictMode; _envStack.append(e); _env = e; } -- 2.7.4