Move the generic construct() implementation into ScriptFunction
authorLars Knoll <lars.knoll@digia.com>
Thu, 14 Feb 2013 10:00:39 +0000 (11:00 +0100)
committerSimon Hausmann <simon.hausmann@digia.com>
Thu, 14 Feb 2013 11:03:37 +0000 (12:03 +0100)
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 <simon.hausmann@digia.com>
src/v4/qv4arrayobject.cpp
src/v4/qv4arrayobject.h
src/v4/qv4functionobject.cpp
src/v4/qv4functionobject.h

index 3f70029..2999ce0 100644 (file)
@@ -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));
index eb8bd05..48250dd 100644 (file)
@@ -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
index 69302dd..9fdd56a 100644 (file)
@@ -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<ExecutionContext *>(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<ExecutionContext *>(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);
index dff95d2..c1e9b28 100644 (file)
@@ -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; }