From 4377d44fb7399751ed4f284bb4be7ece494aff6d Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Thu, 14 Feb 2013 13:28:49 +0100 Subject: [PATCH] Converted calling runtime functions to new calling convention Change-Id: I03837e9b392957bd64a6710c1b85b4429556ba06 Reviewed-by: Lars Knoll --- .../masm/assembler/MacroAssemblerCodeRef.h | 7 ++++++ src/v4/llvm_runtime.cpp | 5 ++--- src/v4/moth/qv4vme_moth.cpp | 6 ++--- src/v4/qmljs_runtime.cpp | 26 +++++++++++++++------- src/v4/qmljs_runtime.h | 8 +++---- src/v4/qv4isel_masm.cpp | 17 ++++++++------ src/v4/qv4isel_masm_p.h | 13 ++++++++--- src/v4/qv4sparsearray.cpp | 3 ++- 8 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h index c2af240..89cffb1 100644 --- a/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h +++ b/src/3rdparty/masm/assembler/MacroAssemblerCodeRef.h @@ -134,6 +134,13 @@ public: ASSERT_VALID_CODE_POINTER(m_value); } + template + 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) diff --git a/src/v4/llvm_runtime.cpp b/src/v4/llvm_runtime.cpp index 2f6e9f1..9be3b6d 100644 --- a/src/v4/llvm_runtime.cpp +++ b/src/v4/llvm_runtime.cpp @@ -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) diff --git a/src/v4/moth/qv4vme_moth.cpp b/src/v4/moth/qv4vme_moth.cpp index e366ec3..f711fd0 100644 --- a/src/v4/moth/qv4vme_moth.cpp +++ b/src/v4/moth/qv4vme_moth.cpp @@ -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) diff --git a/src/v4/qmljs_runtime.cpp b/src/v4/qmljs_runtime.cpp index 58ff36a..1976bd2 100644 --- a/src/v4/qmljs_runtime.cpp +++ b/src/v4/qmljs_runtime.cpp @@ -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) diff --git a/src/v4/qmljs_runtime.h b/src/v4/qmljs_runtime.h index 0a08b71..c0f2643 100644 --- a/src/v4/qmljs_runtime.h +++ b/src/v4/qmljs_runtime.h @@ -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); diff --git a/src/v4/qv4isel_masm.cpp b/src/v4/qv4isel_masm.cpp index 1c14384..4337c72 100644 --- a/src/v4/qv4isel_masm.cpp +++ b/src/v4/qv4isel_masm.cpp @@ -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)); } diff --git a/src/v4/qv4isel_masm_p.h b/src/v4/qv4isel_masm_p.h index 75b5deb..77d1ce9 100644 --- a/src/v4/qv4isel_masm_p.h +++ b/src/v4/qv4isel_masm_p.h @@ -461,10 +461,10 @@ public: int currentRegisterIndex; }; - template - void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) + template + 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 + 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 void generateFunctionCallImp(ArgRet r, const char* functionName, FunctionPtr function, Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) { diff --git a/src/v4/qv4sparsearray.cpp b/src/v4/qv4sparsearray.cpp index 703669b..a94e652 100644 --- a/src/v4/qv4sparsearray.cpp +++ b/src/v4/qv4sparsearray.cpp @@ -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(); -- 2.7.4