From: Lars Knoll Date: Mon, 10 Dec 2012 18:30:08 +0000 (+0100) Subject: Properly set up the 'this' pointer X-Git-Tag: upstream/5.2.1~669^2~659^2~726 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9c104bb97098f690e4c8af6e17b7217891a8c690;p=platform%2Fupstream%2Fqtdeclarative.git 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 --- 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; }