From 4e643637dd7997b36b58edad079c2d4c71dc7222 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 1 Dec 2012 14:25:54 +0100 Subject: [PATCH] Further clean up the ExecutionContext remove the distinction between initCallContext and initConstructorContext. Since the context now has a pointer to the current function, we can also simplify the wireupPrototype method. Change-Id: I06cbaced2438b01b3033182e136e1504c087c8c0 Reviewed-by: Simon Hausmann --- qmljs_environment.cpp | 68 ++++++++++++++++++++------------------------------- qmljs_environment.h | 5 +--- qmljs_objects.cpp | 5 ++-- qv4ecmaobjects.cpp | 2 +- 4 files changed, 31 insertions(+), 49 deletions(-) diff --git a/qmljs_environment.cpp b/qmljs_environment.cpp index ebbe7d3..ce1bf9d 100644 --- a/qmljs_environment.cpp +++ b/qmljs_environment.cpp @@ -73,33 +73,6 @@ String *DiagnosticMessage::buildFullMessage(ExecutionContext *ctx) const return ctx->engine->newString(msg); } -void ExecutionContext::init(FunctionObject *f, Value *args, uint argc) -{ - function = f; - engine = f->scope->engine; - strictMode = f->strictMode; - - arguments = args; - argumentCount = argc; - if (function->needsActivation || argc < function->formalParameterCount){ - arguments = new Value[qMax(argc, function->formalParameterCount)]; - if (argc) - std::copy(args, args + argc, arguments); - if (argc < function->formalParameterCount) - std::fill(arguments + argc, arguments + function->formalParameterCount, Value::undefinedValue()); - } - locals = function->varCount ? new Value[function->varCount] : 0; - if (function->varCount) - std::fill(locals, locals + function->varCount, Value::undefinedValue()); - - if (function->needsActivation) - activation = engine->newActivationObject(this); - else - activation = 0; - - withObject = 0; -} - bool ExecutionContext::hasBinding(String *name) const { if (!function) @@ -328,10 +301,31 @@ void ExecutionContext::initCallContext(ExecutionContext *parent, const Value tha { engine = parent->engine; this->parent = parent; + thisObject = that; + + function = f; + strictMode = f->strictMode; - init(f, args, argc); + arguments = args; + argumentCount = argc; + if (function->needsActivation || argc < function->formalParameterCount){ + arguments = new Value[qMax(argc, function->formalParameterCount)]; + if (argc) + std::copy(args, args + argc, arguments); + if (argc < function->formalParameterCount) + std::fill(arguments + argc, arguments + function->formalParameterCount, Value::undefinedValue()); + } + locals = function->varCount ? new Value[function->varCount] : 0; + if (function->varCount) + std::fill(locals, locals + function->varCount, Value::undefinedValue()); + + if (function->needsActivation) + activation = engine->newActivationObject(this); + else + activation = 0; + + withObject = 0; - thisObject = that; if (engine->debugger) engine->debugger->aboutToCall(f, this); @@ -344,27 +338,17 @@ void ExecutionContext::leaveCallContext() delete[] locals; locals = 0; } + parent = 0; if (engine->debugger) engine->debugger->justLeft(this); } -void ExecutionContext::initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc) -{ - initCallContext(parent, that, f, args, argc); -} - -void ExecutionContext::leaveConstructorContext(FunctionObject *f) -{ - wireUpPrototype(f); - leaveCallContext(); -} - -void ExecutionContext::wireUpPrototype(FunctionObject *f) +void ExecutionContext::wireUpPrototype() { assert(thisObject.isObject()); - Value proto = f->__get__(this, engine->id_prototype); + Value proto = function->__get__(this, engine->id_prototype); if (proto.isObject()) thisObject.objectValue()->prototype = proto.objectValue(); else diff --git a/qmljs_environment.h b/qmljs_environment.h index a34774e..3457771 100644 --- a/qmljs_environment.h +++ b/qmljs_environment.h @@ -97,7 +97,6 @@ struct ExecutionContext void init(ExecutionEngine *e); - void init(FunctionObject *f, Value *args, uint argc); bool hasBinding(String *name) const; void createMutableBinding(ExecutionContext *ctx, String *name, bool deletable); @@ -111,9 +110,7 @@ struct ExecutionContext void initCallContext(ExecutionContext *parent, const Value that, FunctionObject *f, Value *args, unsigned argc); void leaveCallContext(); - void initConstructorContext(ExecutionContext *parent, Value that, FunctionObject *f, Value *args, unsigned argc); - void leaveConstructorContext(FunctionObject *f); - void wireUpPrototype(FunctionObject *f); + void wireUpPrototype(); void throwError(Value value); void throwError(const QString &message); diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index 75fab4b..5ed251e 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -392,9 +392,10 @@ Value FunctionObject::construct(ExecutionContext *context, Value *args, int argc { ExecutionContext k; ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k; - ctx->initConstructorContext(context, Value::nullValue(), this, args, argc); + ctx->initCallContext(context, Value::nullValue(), this, args, argc); Value result = construct(ctx); - ctx->leaveConstructorContext(this); + ctx->wireUpPrototype(); + ctx->leaveCallContext(); if (ctx != &k) delete ctx; return result; diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp index 642eaa8..8edd43c 100644 --- a/qv4ecmaobjects.cpp +++ b/qv4ecmaobjects.cpp @@ -2723,7 +2723,7 @@ Value ErrorCtor::call(ExecutionContext *ctx) { Value that = ctx->thisObject; construct(ctx); - ctx->wireUpPrototype(this); + ctx->wireUpPrototype(); Value res = ctx->thisObject; ctx->thisObject = that; -- 2.7.4