From 03026421af42a44cf5edca48847abcee8841df4d Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 14 Feb 2013 11:00:39 +0100 Subject: [PATCH] Move the generic construct() implementation into ScriptFunction This is the only place we really need it, as the generic construct method defined by the spec mainly applies to functions defined in script. Change-Id: I4fe4219715a4a9393900db6a2532e42fafaea2db Reviewed-by: Simon Hausmann --- src/v4/qv4arrayobject.cpp | 21 ++++++++++++--------- src/v4/qv4arrayobject.h | 3 ++- src/v4/qv4functionobject.cpp | 43 +++++++++++++++++++++++++++---------------- src/v4/qv4functionobject.h | 1 + 4 files changed, 42 insertions(+), 26 deletions(-) diff --git a/src/v4/qv4arrayobject.cpp b/src/v4/qv4arrayobject.cpp index 3f70029..2999ce0 100644 --- a/src/v4/qv4arrayobject.cpp +++ b/src/v4/qv4arrayobject.cpp @@ -49,26 +49,24 @@ ArrayCtor::ArrayCtor(ExecutionContext *scope) { } -Value ArrayCtor::call(ExecutionContext *ctx) +Value ArrayCtor::construct(ExecutionContext *ctx, Value *argv, int argc) { ArrayObject *a = ctx->engine->newArrayObject(ctx); uint len; - if (ctx->argumentCount == 1 && ctx->argument(0).isNumber()) { + if (argc == 1 && argv[0].isNumber()) { bool ok; - len = ctx->argument(0).asArrayLength(ctx, &ok); + len = argv[0].asArrayLength(ctx, &ok); - if (!ok) { - ctx->throwRangeError(ctx->argument(0)); - return Value::undefinedValue(); - } + if (!ok) + ctx->throwRangeError(argv[0]); if (len < 0x1000) a->arrayReserve(len); } else { - len = ctx->argumentCount; + len = argc; a->arrayReserve(len); for (unsigned int i = 0; i < len; ++i) - fillDescriptor(a->arrayData + i, ctx->argument(i)); + fillDescriptor(a->arrayData + i, argv[i]); a->arrayDataLen = len; } a->setArrayLengthUnchecked(len); @@ -76,6 +74,11 @@ Value ArrayCtor::call(ExecutionContext *ctx) return Value::fromObject(a); } +Value ArrayCtor::call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc) +{ + return construct(ctx, argv, argc); +} + void ArrayPrototype::init(ExecutionContext *ctx, const Value &ctor) { ctor.objectValue()->defineReadonlyProperty(ctx->engine->id_length, Value::fromInt32(1)); diff --git a/src/v4/qv4arrayobject.h b/src/v4/qv4arrayobject.h index eb8bd05..48250dd 100644 --- a/src/v4/qv4arrayobject.h +++ b/src/v4/qv4arrayobject.h @@ -55,7 +55,8 @@ struct ArrayCtor: FunctionObject { ArrayCtor(ExecutionContext *scope); - virtual Value call(ExecutionContext *ctx); + virtual Value construct(ExecutionContext *ctx, Value *argv, int argc); + virtual Value call(ExecutionContext *ctx, Value thisObject, Value *argv, int argc); }; struct ArrayPrototype: ArrayObject diff --git a/src/v4/qv4functionobject.cpp b/src/v4/qv4functionobject.cpp index 69302dd..9fdd56a 100644 --- a/src/v4/qv4functionobject.cpp +++ b/src/v4/qv4functionobject.cpp @@ -127,27 +127,12 @@ bool FunctionObject::hasInstance(Managed *that, ExecutionContext *ctx, const Val return false; } -Value FunctionObject::construct(ExecutionContext *context, Value *args, int argc) +Value FunctionObject::construct(ExecutionContext *context, Value *, int) { Object *obj = context->engine->newObject(); Value proto = __get__(context, context->engine->id_prototype); if (proto.isObject()) obj->prototype = proto.objectValue(); - - uint size = requiredMemoryForExecutionContect(this, argc); - ExecutionContext *ctx = static_cast(needsActivation ? malloc(size) : alloca(size)); - - ctx->thisObject = Value::fromObject(obj); - ctx->function = this; - ctx->arguments = args; - ctx->argumentCount = argc; - - ctx->initCallContext(context); - Value result = call(ctx); - ctx->leaveCallContext(); - - if (result.isObject()) - return result; return Value::fromObject(obj); } @@ -400,6 +385,32 @@ ScriptFunction::~ScriptFunction() { } +Value ScriptFunction::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(); + + uint size = requiredMemoryForExecutionContect(this, argc); + ExecutionContext *ctx = static_cast(needsActivation ? malloc(size) : alloca(size)); + + ctx->thisObject = Value::fromObject(obj); + ctx->function = this; + ctx->arguments = args; + ctx->argumentCount = argc; + + ctx->initCallContext(context); + Value result = call(ctx); + ctx->leaveCallContext(); + + if (result.isObject()) + return result; + return Value::fromObject(obj); +} + + + Value ScriptFunction::call(ExecutionContext *ctx) { assert(function->code); diff --git a/src/v4/qv4functionobject.h b/src/v4/qv4functionobject.h index dff95d2..c1e9b28 100644 --- a/src/v4/qv4functionobject.h +++ b/src/v4/qv4functionobject.h @@ -210,6 +210,7 @@ struct ScriptFunction: FunctionObject { ScriptFunction(ExecutionContext *scope, VM::Function *function); virtual ~ScriptFunction(); + virtual Value construct(ExecutionContext *context, Value *args, int argc); virtual Value call(ExecutionContext *ctx); virtual ScriptFunction *asScriptFunction() { return this; } -- 2.7.4