Fix moth isel for typeof.
authorErik Verbruggen <erik.verbruggen@digia.com>
Tue, 18 Dec 2012 09:59:26 +0000 (10:59 +0100)
committerLars Knoll <lars.knoll@digia.com>
Tue, 18 Dec 2012 10:41:36 +0000 (11:41 +0100)
Change-Id: If5b5a91a69d6b6bf0fd3eaf4c21a42c575839be2
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
moth/qv4instr_moth_p.h
moth/qv4isel_moth.cpp
moth/qv4vme_moth.cpp

index 1699598..d1b2de6 100644 (file)
     F(CallBuiltinDeleteSubscript, callBuiltinDeleteSubscript) \
     F(CallBuiltinDeleteName, callBuiltinDeleteName) \
     F(CallBuiltinDeleteValue, callBuiltinDeleteValue) \
+    F(CallBuiltinTypeofMember, callBuiltinTypeofMember) \
+    F(CallBuiltinTypeofSubscript, callBuiltinTypeofSubscript) \
+    F(CallBuiltinTypeofName, callBuiltinTypeofName) \
+    F(CallBuiltinTypeofValue, callBuiltinTypeofValue) \
     F(CallBuiltinDeclareVar, callBuiltinDeclareVar) \
     F(CreateValue, createValue) \
     F(CreateProperty, createProperty) \
@@ -148,7 +152,6 @@ union Instr
     struct instr_callBuiltin {
         MOTH_INSTR_HEADER
         enum {
-            builtin_typeof,
             builtin_throw,
             builtin_rethrow,
             builtin_create_exception_handler,
@@ -185,6 +188,28 @@ union Instr
         int tempIndex;
         int targetTempIndex;
     };
+    struct instr_callBuiltinTypeofMember {
+        MOTH_INSTR_HEADER
+        int base;
+        VM::String *member;
+        int targetTempIndex;
+    };
+    struct instr_callBuiltinTypeofSubscript {
+        MOTH_INSTR_HEADER
+        int base;
+        int index;
+        int targetTempIndex;
+    };
+    struct instr_callBuiltinTypeofName {
+        MOTH_INSTR_HEADER
+        VM::String *name;
+        int targetTempIndex;
+    };
+    struct instr_callBuiltinTypeofValue {
+        MOTH_INSTR_HEADER
+        int tempIndex;
+        int targetTempIndex;
+    };
     struct instr_callBuiltinDeclareVar {
         MOTH_INSTR_HEADER
         bool isDeletable;
@@ -283,6 +308,10 @@ union Instr
     instr_callBuiltinDeleteSubscript callBuiltinDeleteSubscript;
     instr_callBuiltinDeleteName callBuiltinDeleteName;
     instr_callBuiltinDeleteValue callBuiltinDeleteValue;
+    instr_callBuiltinTypeofMember callBuiltinTypeofMember;
+    instr_callBuiltinTypeofSubscript callBuiltinTypeofSubscript;
+    instr_callBuiltinTypeofName callBuiltinTypeofName;
+    instr_callBuiltinTypeofValue callBuiltinTypeofValue;
     instr_callBuiltinDeclareVar callBuiltinDeclareVar;
     instr_createValue createValue;
     instr_createProperty createProperty;
index ebd3099..a3d03d4 100644 (file)
@@ -279,14 +279,32 @@ void InstructionSelection::callActivationProperty(IR::Call *c, int targetTempInd
     } break;
 
     case IR::Name::builtin_typeof: {
-        IR::Temp *arg = c->args->expr->asTemp();
-        assert(arg != 0);
-
-        Instruction::CallBuiltin call;
-        call.builtin = Instruction::CallBuiltin::builtin_typeof;
-        prepareCallArgs(c->args, call.argc, call.args);
-        call.targetTempIndex = targetTempIndex;
-        addInstruction(call);
+        if (IR::Member *m = c->args->expr->asMember()) {
+            Instruction::CallBuiltinTypeofMember call;
+            call.base = m->base->asTemp()->index;
+            call.member = engine()->identifier(*m->name);
+            call.targetTempIndex = targetTempIndex;
+            addInstruction(call);
+        } else if (IR::Subscript *ss = c->args->expr->asSubscript()) {
+            Instruction::CallBuiltinTypeofSubscript call;
+            call.base = ss->base->asTemp()->index;
+            call.index = ss->index->asTemp()->index;
+            call.targetTempIndex = targetTempIndex;
+            addInstruction(call);
+        } else if (IR::Name *n = c->args->expr->asName()) {
+            Instruction::CallBuiltinTypeofName call;
+            call.name = engine()->identifier(*n->id);
+            call.targetTempIndex = targetTempIndex;
+            addInstruction(call);
+        } else if (IR::Temp *arg = c->args->expr->asTemp()){
+            assert(arg != 0);
+            Instruction::CallBuiltinTypeofValue call;
+            call.tempIndex = arg->index;
+            call.targetTempIndex = targetTempIndex;
+            addInstruction(call);
+        } else {
+            assert(false);
+        }
     } break;
 
     case IR::Name::builtin_delete: {
index 86b396f..b8404bc 100644 (file)
@@ -234,10 +234,6 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
         VM::Value *args = stack + argStart;
         void *buf;
         switch (instr.builtin) {
-        case Instr::instr_callBuiltin::builtin_typeof:
-            Q_ASSERT(instr.argc == 1);
-            TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(args[0], context);
-            break;
         case Instr::instr_callBuiltin::builtin_throw:
             TRACE(builtin_throw, "Throwing now...%s", "");
             Q_ASSERT(instr.argc == 1);
@@ -305,6 +301,22 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
         TEMP(instr.targetTempIndex) = VM::Value::fromBoolean(false);
     MOTH_END_INSTR(CallBuiltinDeleteValue)
 
+    MOTH_BEGIN_INSTR(CallBuiltinTypeofMember)
+        TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_member(TEMP(instr.base), instr.member, context);
+    MOTH_END_INSTR(CallBuiltinTypeofMember)
+
+    MOTH_BEGIN_INSTR(CallBuiltinTypeofSubscript)
+        TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_element(TEMP(instr.base), TEMP(instr.index), context);
+    MOTH_END_INSTR(CallBuiltinTypeofSubscript)
+
+    MOTH_BEGIN_INSTR(CallBuiltinTypeofName)
+        TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof_name(instr.name, context);
+    MOTH_END_INSTR(CallBuiltinTypeofName)
+
+    MOTH_BEGIN_INSTR(CallBuiltinTypeofValue)
+        TEMP(instr.targetTempIndex) = __qmljs_builtin_typeof(TEMP(instr.tempIndex), context);
+    MOTH_END_INSTR(CallBuiltinTypeofValue)
+
     MOTH_BEGIN_INSTR(CallBuiltinDeclareVar)
         __qmljs_builtin_declare_var(context, instr.isDeletable, instr.varName);
     MOTH_END_INSTR(CallBuiltinDeleteValue)