Fix prototypes and implemented isel for constructValue.
authorRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 08:09:41 +0000 (10:09 +0200)
committerRoberto Raggi <roberto.raggi@nokia.com>
Mon, 21 May 2012 08:09:41 +0000 (10:09 +0200)
qmljs_objects.cpp
qv4isel.cpp
qv4isel_p.h

index eb4eb44..eace571 100644 (file)
@@ -263,7 +263,10 @@ FunctionObject *ExecutionEngine::newScriptFunction(Context *scope, IR::Function
 
 Object *ExecutionEngine::newObject()
 {
-    return new Object();
+    Object *object = new Object();
+    if (objectPrototype.isObject())
+        object->prototype = objectPrototype.objectValue;
+    return object;
 }
 
 FunctionObject *ExecutionEngine::newObjectCtor(Context *ctx)
@@ -283,7 +286,10 @@ String *ExecutionEngine::newString(const QString &s)
 
 Object *ExecutionEngine::newStringObject(const Value &value)
 {
-    return new StringObject(value);
+    StringObject *object = new StringObject(value);
+    if (stringPrototype.isObject())
+        object->prototype = stringPrototype.objectValue;
+    return object;
 }
 
 FunctionObject *ExecutionEngine::newStringCtor(Context *ctx)
@@ -300,7 +306,10 @@ Object *ExecutionEngine::newStringPrototype(Context *ctx, FunctionObject *proto)
 
 Object *ExecutionEngine::newNumberObject(const Value &value)
 {
-    return new NumberObject(value);
+    NumberObject *object = new NumberObject(value);
+    if (numberPrototype.isObject())
+        object->prototype = numberPrototype.objectValue;
+    return object;
 }
 
 FunctionObject *ExecutionEngine::newNumberCtor(Context *ctx)
@@ -317,7 +326,10 @@ Object *ExecutionEngine::newNumberPrototype(Context *ctx, FunctionObject *proto)
 
 Object *ExecutionEngine::newBooleanObject(const Value &value)
 {
-    return new BooleanObject(value);
+    Object *object = new BooleanObject(value);
+    if (booleanPrototype.isObject())
+        object->prototype = booleanPrototype.objectValue;
+    return object;
 }
 
 FunctionObject *ExecutionEngine::newBooleanCtor(Context *ctx)
@@ -335,14 +347,16 @@ Object *ExecutionEngine::newBooleanPrototype(Context *ctx, FunctionObject *proto
 Object *ExecutionEngine::newArrayObject()
 {
     ArrayObject *object = new ArrayObject();
-    object->prototype = arrayPrototype.objectValue;
+    if (arrayPrototype.isObject())
+        object->prototype = arrayPrototype.objectValue;
     return object;
 }
 
 Object *ExecutionEngine::newArrayObject(const Array &value)
 {
     ArrayObject *object = new ArrayObject(value);
-    object->prototype = arrayPrototype.objectValue;
+    if (arrayPrototype.isObject())
+        object->prototype = arrayPrototype.objectValue;
     return object;
 }
 
@@ -360,7 +374,10 @@ Object *ExecutionEngine::newArrayPrototype(Context *ctx, FunctionObject *proto)
 
 Object *ExecutionEngine::newDateObject(const Value &value)
 {
-    return new DateObject(value);
+    Object *object = new DateObject(value);
+    if (datePrototype.isObject())
+        object->prototype = datePrototype.objectValue;
+    return object;
 }
 
 FunctionObject *ExecutionEngine::newDateCtor(Context *ctx)
index 505f765..47b9a77 100644 (file)
@@ -345,6 +345,39 @@ void InstructionSelection::constructProperty(IR::New *call, IR::Temp *result)
     amd64_call_code(_codePtr, __qmljs_construct_property);
 }
 
+void InstructionSelection::constructValue(IR::New *call, IR::Temp *result)
+{
+    IR::Temp *baseTemp = call->base->asTemp();
+    assert(baseTemp != 0);
+
+    int argc = 0;
+    for (IR::ExprList *it = call->args; it; it = it->next) {
+        ++argc;
+    }
+
+    int i = 0;
+    for (IR::ExprList *it = call->args; it; it = it->next, ++i) {
+        IR::Temp *arg = it->expr->asTemp();
+        assert(arg != 0);
+        amd64_lea_membase(_codePtr, AMD64_RDI, AMD64_RSP, sizeof(Value) * i);
+        loadTempAddress(AMD64_RSI, arg);
+        amd64_call_code(_codePtr, __qmljs_copy);
+    }
+
+    amd64_mov_reg_reg(_codePtr, AMD64_RDI, AMD64_R14, 8); // load the context
+
+    if (result)
+        loadTempAddress(AMD64_RSI, result);
+    else
+        amd64_alu_reg_reg(_codePtr, X86_XOR, AMD64_RSI, AMD64_RSI);
+
+    amd64_alu_reg_reg(_codePtr, X86_XOR, AMD64_RDX, AMD64_RDX);
+    loadTempAddress(AMD64_RCX, baseTemp);
+    amd64_lea_membase(_codePtr, AMD64_R8, AMD64_RSP, 0);
+    amd64_mov_reg_imm(_codePtr, AMD64_R9, argc);
+    amd64_call_code(_codePtr, __qmljs_construct_value);
+}
+
 void InstructionSelection::visitExp(IR::Exp *s)
 {
     if (IR::Call *c = s->expr->asCall()) {
@@ -495,6 +528,9 @@ void InstructionSelection::visitMove(IR::Move *s)
                 } else if (ctor->base->asMember()) {
                     constructProperty(ctor, t);
                     return;
+                } else if (ctor->base->asTemp()) {
+                    constructValue(ctor, t);
+                    return;
                 }
             } else if (IR::Member *m = s->source->asMember()) {
                 //__qmljs_get_property(ctx, result, object, name);
index ac6092d..c6da581 100644 (file)
@@ -25,6 +25,7 @@ protected:
     void constructActivationProperty(IR::New *call, IR::Temp *result);
     void constructProperty(IR::New *ctor, IR::Temp *result);
     void callValue(IR::Call *call, IR::Temp *result);
+    void constructValue(IR::New *call, IR::Temp *result);
 
     virtual void visitExp(IR::Exp *);
     virtual void visitEnter(IR::Enter *);