From c6251acc4b6595fd84ce6ad1aea4c9d39c07d952 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sun, 16 Dec 2012 23:08:07 +0100 Subject: [PATCH] Cleanup constructor handling Simplify the code and unify the generic part of object construction in FunctionObject::construct. Change-Id: Ie430458bedaa211efba37c8283e26a9b84e6764a Reviewed-by: Erik Verbruggen --- qmljs_objects.cpp | 39 +++++++++-------------------- qmljs_objects.h | 2 -- qv4ecmaobjects.cpp | 73 ++++++++++++++---------------------------------------- qv4ecmaobjects_p.h | 1 - 4 files changed, 31 insertions(+), 84 deletions(-) diff --git a/qmljs_objects.cpp b/qmljs_objects.cpp index a7ab96f..a7703d8 100644 --- a/qmljs_objects.cpp +++ b/qmljs_objects.cpp @@ -497,15 +497,21 @@ bool FunctionObject::hasInstance(ExecutionContext *ctx, const Value &value) Value FunctionObject::construct(ExecutionContext *context, Value *args, int argc) { + Object *obj = context->engine->newObject(); + Value proto = __get__(context, context->engine->id_prototype); + if (proto.isObject()) + obj->prototype = proto.objectValue(); + ExecutionContext k; ExecutionContext *ctx = needsActivation ? context->engine->newContext() : &k; - ctx->initCallContext(context, Value::undefinedValue(), this, args, argc); + + ctx->initCallContext(context, Value::fromObject(obj), this, args, argc); Value result = construct(ctx); - ctx->wireUpPrototype(); ctx->leaveCallContext(); - if (ctx != &k) - delete ctx; - return result; + + if (result.isObject()) + return result; + return Value::fromObject(obj); } Value FunctionObject::call(ExecutionContext *context, Value thisObject, Value *args, int argc) @@ -527,15 +533,7 @@ Value FunctionObject::call(ExecutionContext *ctx) Value FunctionObject::construct(ExecutionContext *ctx) { - Object *obj = ctx->engine->newObject(); - Value proto = __get__(ctx, ctx->engine->id_prototype); - if (proto.isObject()) - obj->prototype = proto.objectValue(); - ctx->thisObject = Value::fromObject(obj); - Value result = call(ctx); - if (result.isObject()) - return result; - return ctx->thisObject; + return call(ctx); } ScriptFunction::ScriptFunction(ExecutionContext *scope, VM::Function *function) @@ -790,19 +788,6 @@ SyntaxErrorObject::SyntaxErrorObject(ExecutionContext *ctx, DiagnosticMessage *m } -Value ScriptFunction::construct(VM::ExecutionContext *ctx) -{ - Object *obj = ctx->engine->newObject(); - Value proto = __get__(ctx, ctx->engine->id_prototype); - if (proto.isObject()) - obj->prototype = proto.objectValue(); - ctx->thisObject = Value::fromObject(obj); - Value result = function->code(ctx, function->codeData); - if (result.isObject()) - return result; - return ctx->thisObject; -} - ArgumentsObject::ArgumentsObject(ExecutionContext *context) : context(context) , currentIndex(-1) diff --git a/qmljs_objects.h b/qmljs_objects.h index eacbc00..eae6eeb 100644 --- a/qmljs_objects.h +++ b/qmljs_objects.h @@ -598,7 +598,6 @@ struct NativeFunction: FunctionObject { NativeFunction(ExecutionContext *scope, String *name, Value (*code)(ExecutionContext *)); virtual Value call(ExecutionContext *ctx) { return code(ctx); } - virtual Value construct(ExecutionContext *ctx) { ctx->thisObject = code(ctx); return ctx->thisObject; } }; struct ScriptFunction: FunctionObject { @@ -608,7 +607,6 @@ struct ScriptFunction: FunctionObject { virtual ~ScriptFunction(); virtual Value call(ExecutionContext *ctx); - virtual Value construct(ExecutionContext *ctx); virtual ScriptFunction *asScriptFunction() { return this; } }; diff --git a/qv4ecmaobjects.cpp b/qv4ecmaobjects.cpp index 4774c78..12ef269 100644 --- a/qv4ecmaobjects.cpp +++ b/qv4ecmaobjects.cpp @@ -532,10 +532,8 @@ ObjectCtor::ObjectCtor(ExecutionContext *scope) Value ObjectCtor::construct(ExecutionContext *ctx) { if (!ctx->argumentCount || ctx->argument(0).isUndefined() || ctx->argument(0).isNull()) - ctx->thisObject = Value::fromObject(ctx->engine->newObject()); - else - ctx->thisObject = __qmljs_to_object(ctx->argument(0), ctx); - return ctx->thisObject; + return ctx->thisObject; + return __qmljs_to_object(ctx->argument(0), ctx); } Value ObjectCtor::call(ExecutionContext *ctx) @@ -1004,8 +1002,7 @@ Value StringCtor::construct(ExecutionContext *ctx) value = Value::fromString(ctx->argument(0).toString(ctx)); else value = Value::fromString(ctx, QString()); - ctx->thisObject = Value::fromObject(ctx->engine->newStringObject(value)); - return ctx->thisObject; + return Value::fromObject(ctx->engine->newStringObject(value)); } Value StringCtor::call(ExecutionContext *ctx) @@ -1318,8 +1315,7 @@ NumberCtor::NumberCtor(ExecutionContext *scope) Value NumberCtor::construct(ExecutionContext *ctx) { double d = ctx->argumentCount ? ctx->argument(0).toNumber(ctx) : 0; - ctx->thisObject = Value::fromObject(ctx->engine->newNumberObject(Value::fromDouble(d))); - return ctx->thisObject; + return Value::fromObject(ctx->engine->newNumberObject(Value::fromDouble(d))); } Value NumberCtor::call(ExecutionContext *ctx) @@ -1497,8 +1493,7 @@ BooleanCtor::BooleanCtor(ExecutionContext *scope) Value BooleanCtor::construct(ExecutionContext *ctx) { const double n = ctx->argument(0).toBoolean(ctx); - ctx->thisObject = Value::fromObject(ctx->engine->newBooleanObject(Value::fromBoolean(n))); - return ctx->thisObject; + return Value::fromObject(ctx->engine->newBooleanObject(Value::fromBoolean(n))); } Value BooleanCtor::call(ExecutionContext *ctx) @@ -1541,13 +1536,6 @@ ArrayCtor::ArrayCtor(ExecutionContext *scope) { } -Value ArrayCtor::construct(ExecutionContext *ctx) -{ - Value result = call(ctx); - ctx->thisObject = result; - return result; -} - Value ArrayCtor::call(ExecutionContext *ctx) { Array value; @@ -2066,17 +2054,13 @@ Value FunctionCtor::construct(ExecutionContext *ctx) QScopedPointer isel(ctx->engine->iselFactory->create(ctx->engine, &module)); VM::Function *vmf = isel->vmFunction(irf); - ctx->thisObject = Value::fromObject(ctx->engine->newScriptFunction(ctx->engine->rootContext, vmf)); - return ctx->thisObject; + return Value::fromObject(ctx->engine->newScriptFunction(ctx->engine->rootContext, vmf)); } // 15.3.1: This is equivalent to new Function(...) Value FunctionCtor::call(ExecutionContext *ctx) { - Value v = ctx->thisObject; - Value result = construct(ctx); - ctx->thisObject = v; - return result; + return construct(ctx); } void FunctionPrototype::init(ExecutionContext *ctx, const Value &ctor) @@ -2185,8 +2169,7 @@ Value DateCtor::construct(ExecutionContext *ctx) } Object *d = ctx->engine->newDateObject(Value::fromDouble(t)); - ctx->thisObject = Value::fromObject(d); - return ctx->thisObject; + return Value::fromObject(d); } Value DateCtor::call(ExecutionContext *ctx) @@ -2756,8 +2739,7 @@ Value RegExpCtor::construct(ExecutionContext *ctx) ctx->throwTypeError(); RegExpObject *o = ctx->engine->newRegExpObject(re->value, re->global); - ctx->thisObject = Value::fromObject(o); - return ctx->thisObject; + return Value::fromObject(o); } if (r.isUndefined()) @@ -2788,8 +2770,7 @@ Value RegExpCtor::construct(ExecutionContext *ctx) ctx->throwTypeError(); RegExpObject *o = ctx->engine->newRegExpObject(re, global); - ctx->thisObject = Value::fromObject(o); - return ctx->thisObject; + return Value::fromObject(o); } Value RegExpCtor::call(ExecutionContext *ctx) @@ -2799,10 +2780,7 @@ Value RegExpCtor::call(ExecutionContext *ctx) return ctx->argument(0); } - Value that = ctx->thisObject; - Value result = construct(ctx); - ctx->thisObject = that; - return result; + return construct(ctx); } void RegExpPrototype::init(ExecutionContext *ctx, const Value &ctor) @@ -2880,55 +2858,42 @@ ErrorCtor::ErrorCtor(ExecutionContext *scope) Value ErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(ctx->engine->newErrorObject(ctx->argument(0))); - return ctx->thisObject; + return Value::fromObject(ctx->engine->newErrorObject(ctx->argument(0))); } Value ErrorCtor::call(ExecutionContext *ctx) { - Value that = ctx->thisObject; - construct(ctx); - ctx->wireUpPrototype(); - Value res = ctx->thisObject; - - ctx->thisObject = that; - return res; + return construct(ctx); } Value EvalErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) EvalErrorObject(ctx)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) EvalErrorObject(ctx)); } Value RangeErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) RangeErrorObject(ctx)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) RangeErrorObject(ctx)); } Value ReferenceErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) ReferenceErrorObject(ctx)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) ReferenceErrorObject(ctx)); } Value SyntaxErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) SyntaxErrorObject(ctx, 0)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) SyntaxErrorObject(ctx, 0)); } Value TypeErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) TypeErrorObject(ctx)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) TypeErrorObject(ctx)); } Value URIErrorCtor::construct(ExecutionContext *ctx) { - ctx->thisObject = Value::fromObject(new (ctx->engine->memoryManager) URIErrorObject(ctx)); - return ctx->thisObject; + return Value::fromObject(new (ctx->engine->memoryManager) URIErrorObject(ctx)); } void ErrorPrototype::init(ExecutionContext *ctx, const Value &ctor, Object *obj) diff --git a/qv4ecmaobjects_p.h b/qv4ecmaobjects_p.h index be4b938..8b16b95 100644 --- a/qv4ecmaobjects_p.h +++ b/qv4ecmaobjects_p.h @@ -167,7 +167,6 @@ struct ArrayCtor: FunctionObject { ArrayCtor(ExecutionContext *scope); - virtual Value construct(ExecutionContext *ctx); virtual Value call(ExecutionContext *ctx); }; -- 2.7.4