Converted calling runtime functions to new calling convention
authorSimon Hausmann <simon.hausmann@digia.com>
Thu, 14 Feb 2013 12:28:49 +0000 (13:28 +0100)
committerLars Knoll <lars.knoll@digia.com>
Thu, 14 Feb 2013 13:06:28 +0000 (14:06 +0100)
Change-Id: I03837e9b392957bd64a6710c1b85b4429556ba06
Reviewed-by: Lars Knoll <lars.knoll@digia.com>
src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h
src/v4/llvm_runtime.cpp
src/v4/moth/qv4vme_moth.cpp
src/v4/qmljs_runtime.cpp
src/v4/qmljs_runtime.h
src/v4/qv4isel_masm.cpp
src/v4/qv4isel_masm_p.h
src/v4/qv4sparsearray.cpp

index c2af240..89cffb1 100644 (file)
@@ -134,6 +134,13 @@ public:
         ASSERT_VALID_CODE_POINTER(m_value);
     }
 
+    template<typename returnType, typename argType1, typename argType2, typename argType3, typename argType4, typename argType5, typename argType6>
+    FunctionPtr(returnType(*value)(argType1, argType2, argType3, argType4, argType5, argType6))
+        : m_value((void*)value)
+    {
+        ASSERT_VALID_CODE_POINTER(m_value);
+    }
+
 // MSVC doesn't seem to treat functions with different calling conventions as
 // different types; these methods already defined for fastcall, below.
 #if CALLING_CONVENTION_IS_STDCALL && !OS(WINDOWS)
index 2f6e9f1..9be3b6d 100644 (file)
@@ -405,8 +405,7 @@ void __qmljs_llvm_call_activation_property(ExecutionContext *context, Value *res
 
 void __qmljs_llvm_call_value(ExecutionContext *context, Value *result, const Value *thisObject, const Value *func, Value *args, int argc)
 {
-    Value that = thisObject ? *thisObject : Value::undefinedValue();
-    *result = __qmljs_call_value(context, that, *func, args, argc);
+    __qmljs_call_value(context, result, thisObject, *func, args, argc);
 }
 
 void __qmljs_llvm_construct_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
@@ -436,7 +435,7 @@ void __qmljs_llvm_get_property(ExecutionContext *ctx, Value *result, Value *obje
 
 void __qmljs_llvm_call_property(ExecutionContext *context, Value *result, const Value *base, String *name, Value *args, int argc)
 {
-    *result = __qmljs_call_property(context, *base, name, args, argc);
+    __qmljs_call_property(context, result, *base, name, args, argc);
 }
 
 void __qmljs_llvm_construct_property(ExecutionContext *context, Value *result, const Value *base, String *name, Value *args, int argc)
index e366ec3..f711fd0 100644 (file)
@@ -221,20 +221,20 @@ VM::Value VME::operator()(QQmlJS::VM::ExecutionContext *context, const uchar *co
 #endif // DO_TRACE_INSTR
         Q_ASSERT(instr.args + instr.argc < stackSize);
         VM::Value *args = stack + instr.args;
-        VALUE(instr.result) = __qmljs_call_value(context, VM::Value::undefinedValue(), VALUE(instr.dest), args, instr.argc);
+        __qmljs_call_value(context, VALUEPTR(instr.result), /*thisObject*/0, VALUE(instr.dest), args, instr.argc);
     MOTH_END_INSTR(CallValue)
 
     MOTH_BEGIN_INSTR(CallProperty)
         TRACE(property name, "%s, args=%u, argc=%u", qPrintable(instr.name->toQString()), instr.args, instr.argc);
         Q_ASSERT(instr.args + instr.argc < stackSize);
         VM::Value *args = stack + instr.args;
-        VALUE(instr.result) = __qmljs_call_property(context, VALUE(instr.base), instr.name, args, instr.argc);
+        __qmljs_call_property(context, VALUEPTR(instr.result), VALUE(instr.base), instr.name, args, instr.argc);
     MOTH_END_INSTR(CallProperty)
 
     MOTH_BEGIN_INSTR(CallElement)
         Q_ASSERT(instr.args + instr.argc < stackSize);
         VM::Value *args = stack + instr.args;
-        VALUE(instr.result) = __qmljs_call_element(context, VALUE(instr.base), VALUE(instr.index), args, instr.argc);
+        __qmljs_call_element(context, VALUEPTR(instr.result), VALUE(instr.base), VALUE(instr.index), args, instr.argc);
     MOTH_END_INSTR(CallProperty)
 
     MOTH_BEGIN_INSTR(CallActivationProperty)
index 58ff36a..1976bd2 100644 (file)
@@ -821,8 +821,9 @@ void __qmljs_call_activation_property(ExecutionContext *context, Value *result,
         *result = res;
 }
 
-Value __qmljs_call_property(ExecutionContext *context, Value thisObject, String *name, Value *args, int argc)
+void __qmljs_call_property(ExecutionContext *context, Value *result, const Value &thatObject, String *name, Value *args, int argc)
 {
+    Value thisObject = thatObject;
     Object *baseObject;
     if (thisObject.isString()) {
         baseObject = context->engine->stringPrototype;
@@ -839,11 +840,14 @@ Value __qmljs_call_property(ExecutionContext *context, Value thisObject, String
     if (!o)
         context->throwTypeError();
 
-    return o->call(context, thisObject, args, argc);
+    Value res = o->call(context, thisObject, args, argc);
+    if (result)
+        *result = res;
 }
 
-Value __qmljs_call_property_lookup(ExecutionContext *context, Value thisObject, uint index, Value *args, int argc)
+void __qmljs_call_property_lookup(ExecutionContext *context, Value *result, const Value &thatObject, uint index, Value *args, int argc)
 {
+    Value thisObject = thatObject;
     Lookup *l = context->lookups + index;
 
     Object *baseObject;
@@ -894,10 +898,12 @@ Value __qmljs_call_property_lookup(ExecutionContext *context, Value thisObject,
     if (!o)
         context->throwTypeError();
 
-    return o->call(context, thisObject, args, argc);
+    Value res = o->call(context, thisObject, args, argc);
+    if (result)
+        *result = res;
 }
 
-Value __qmljs_call_element(ExecutionContext *context, Value that, Value index, Value *args, int argc)
+void __qmljs_call_element(ExecutionContext *context, Value *result, const Value &that, const Value &index, Value *args, int argc)
 {
     Value thisObject = that;
     if (!thisObject.isObject())
@@ -911,15 +917,19 @@ Value __qmljs_call_element(ExecutionContext *context, Value that, Value index, V
     if (!o)
         context->throwTypeError();
 
-    return o->call(context, thisObject, args, argc);
+    Value res = o->call(context, thisObject, args, argc);
+    if (result)
+        *result = res;
 }
 
-Value __qmljs_call_value(ExecutionContext *context, Value thisObject, Value func, Value *args, int argc)
+void __qmljs_call_value(ExecutionContext *context, Value *result, const Value *thisObject, const Value &func, Value *args, int argc)
 {
     FunctionObject *o = func.asFunctionObject();
     if (!o)
         context->throwTypeError();
-    return o->call(context, thisObject, args, argc);
+    Value res = o->call(context, thisObject ? *thisObject : Value::undefinedValue(), args, argc);
+    if (result)
+        *result = res;
 }
 
 void __qmljs_construct_activation_property(ExecutionContext *context, Value *result, String *name, Value *args, int argc)
index 0a08b71..c0f2643 100644 (file)
@@ -92,10 +92,10 @@ extern "C" {
 
 // context
 void __qmljs_call_activation_property(ExecutionContext *, Value *result, String *name, Value *args, int argc);
-Value __qmljs_call_property(ExecutionContext *context, Value that, String *name, Value *args, int argc);
-Value __qmljs_call_property_lookup(ExecutionContext *context, Value thisObject, uint index, Value *args, int argc);
-Value __qmljs_call_element(ExecutionContext *context, Value that, Value index, Value *args, int argc);
-Value __qmljs_call_value(ExecutionContext *context, Value thisObject, Value func, Value *args, int argc);
+void __qmljs_call_property(ExecutionContext *context, Value *result, const Value &that, String *name, Value *args, int argc);
+void __qmljs_call_property_lookup(ExecutionContext *context, Value *result, const Value &thisObject, uint index, Value *args, int argc);
+void __qmljs_call_element(ExecutionContext *context, Value *result, const Value &that, const Value &index, Value *args, int argc);
+void __qmljs_call_value(ExecutionContext *context, Value *result, const Value *thisObject, const Value &func, Value *args, int argc);
 
 void __qmljs_construct_activation_property(ExecutionContext *, Value *result, String *name, Value *args, int argc);
 Value __qmljs_construct_property(ExecutionContext *context, Value base, String *name, Value *args, int argc);
index 1c14384..4337c72 100644 (file)
@@ -647,7 +647,7 @@ void InstructionSelection::callValue(IR::Temp *value, IR::ExprList *args, IR::Te
 {
     int argc = prepareVariableArguments(args);
     IR::Temp* thisObject = 0;
-    generateFunctionCall(result, __qmljs_call_value, Assembler::ContextRegister, thisObject, value, baseAddressForCallArguments(), Assembler::TrustedImm32(argc));
+    generateFunctionCall(Assembler::Void, __qmljs_call_value, Assembler::ContextRegister, Assembler::PointerToValue(result), Assembler::PointerToValue(thisObject), Assembler::PointerToValue(value), baseAddressForCallArguments(), Assembler::TrustedImm32(argc));
 }
 
 void InstructionSelection::loadThisObject(IR::Temp *temp)
@@ -854,13 +854,15 @@ void InstructionSelection::callProperty(IR::Temp *base, const QString &name,
 
     if (useFastLookups) {
         uint index = addLookup(s);
-        generateFunctionCall(result, __qmljs_call_property_lookup,
-                             Assembler::ContextRegister, base, Assembler::TrustedImm32(index),
+        generateFunctionCall(Assembler::Void, __qmljs_call_property_lookup,
+                             Assembler::ContextRegister, Assembler::PointerToValue(result),
+                             Assembler::PointerToValue(base), Assembler::TrustedImm32(index),
                              baseAddressForCallArguments(),
                              Assembler::TrustedImm32(argc));
     } else {
-        generateFunctionCall(result, __qmljs_call_property,
-                             Assembler::ContextRegister, base, s,
+        generateFunctionCall(Assembler::Void, __qmljs_call_property,
+                             Assembler::ContextRegister, Assembler::PointerToValue(result),
+                             Assembler::PointerToValue(base), s,
                              baseAddressForCallArguments(),
                              Assembler::TrustedImm32(argc));
     }
@@ -871,8 +873,9 @@ void InstructionSelection::callSubscript(IR::Temp *base, IR::Temp *index, IR::Ex
     assert(base != 0);
 
     int argc = prepareVariableArguments(args);
-    generateFunctionCall(result, __qmljs_call_element,
-                         Assembler::ContextRegister, base, index,
+    generateFunctionCall(Assembler::Void, __qmljs_call_element,
+                         Assembler::ContextRegister, Assembler::PointerToValue(result),
+                         Assembler::PointerToValue(base), Assembler::PointerToValue(index),
                          baseAddressForCallArguments(),
                          Assembler::TrustedImm32(argc));
 }
index 75b5deb..77d1ce9 100644 (file)
@@ -461,10 +461,10 @@ public:
         int currentRegisterIndex;
     };
 
-    template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
-    void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
+    template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename Arg6>
+    void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5, Arg6 arg6)
     {
-        int totalNumberOfArgs = 5;
+        int totalNumberOfArgs = 6;
 
         // If necessary reserve space for the return value on the stack and
         // pass the pointer to it as the first hidden parameter.
@@ -477,6 +477,7 @@ public:
         }
 
         ArgumentLoader l(this, totalNumberOfArgs);
+        l.load(arg6);
         l.load(arg5);
         l.load(arg4);
         l.load(arg3);
@@ -502,6 +503,12 @@ public:
             add32(TrustedImm32(stackSizeToCorrect), StackPointerRegister);
     }
 
+    template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+    void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5)
+    {
+        generateFunctionCallImp(r, functionName, function, arg1, arg2, arg3, arg4, arg5, VoidType());
+    }
+
     template <typename ArgRet, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
     void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4)
     {
index 703669b..a94e652 100644 (file)
@@ -68,7 +68,8 @@ bool ArrayElementLessThan::operator()(const PropertyDescriptor &p1, const Proper
         return true;
     if (!m_comparefn.isUndefined()) {
         Value args[] = { v1, v2 };
-        Value result = __qmljs_call_value(m_context, Value::undefinedValue(), m_comparefn, args, 2);
+        Value result = Value::undefinedValue();
+        __qmljs_call_value(m_context, &result, /*thisObject*/0, m_comparefn, args, 2);
         return result.toNumber(m_context) <= 0;
     }
     return v1.toString(m_context)->toQString() < v2.toString(m_context)->toQString();