diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 10 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_masm.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 10 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 16 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 13 |
6 files changed, 58 insertions, 7 deletions
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 9baf7f89ca..a2b8c870a5 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -98,6 +98,7 @@ QT_BEGIN_NAMESPACE F(CallBuiltinConvertThisToObject, callBuiltinConvertThisToObject) \ F(CreateValue, createValue) \ F(CreateProperty, createProperty) \ + F(ConstructPropertyLookup, constructPropertyLookup) \ F(CreateActivationProperty, createActivationProperty) \ F(ConstructGlobalLookup, constructGlobalLookup) \ F(Jump, jump) \ @@ -491,6 +492,14 @@ union Instr Param base; Param result; }; + struct instr_constructPropertyLookup { + MOTH_INSTR_HEADER + int index; + quint32 argc; + quint32 callData; + Param base; + Param result; + }; struct instr_createActivationProperty { MOTH_INSTR_HEADER int name; @@ -712,6 +721,7 @@ union Instr instr_callBuiltinConvertThisToObject callBuiltinConvertThisToObject; instr_createValue createValue; instr_createProperty createProperty; + instr_constructPropertyLookup constructPropertyLookup; instr_createActivationProperty createActivationProperty; instr_constructGlobalLookup constructGlobalLookup; instr_jump jump; diff --git a/src/qml/compiler/qv4isel_masm.cpp b/src/qml/compiler/qv4isel_masm.cpp index 9d470c417d..91cc5a9b4e 100644 --- a/src/qml/compiler/qv4isel_masm.cpp +++ b/src/qml/compiler/qv4isel_masm.cpp @@ -1777,9 +1777,18 @@ void InstructionSelection::constructActivationProperty(V4IR::Name *func, V4IR::E void InstructionSelection::constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) { - prepareCallData(args, 0); + prepareCallData(args, base); + if (useFastLookups) { + uint index = registerGetterLookup(name); + generateFunctionCall(result, __qmljs_construct_property_lookup, + Assembler::ContextRegister, + Assembler::TrustedImm32(index), + baseAddressForCallData()); + return; + } + generateFunctionCall(result, __qmljs_construct_property, Assembler::ContextRegister, - Assembler::Reference(base), Assembler::PointerToString(name), + Assembler::PointerToString(name), baseAddressForCallData()); } diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 6db8f11a9e..40ccc358f7 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -351,6 +351,16 @@ void InstructionSelection::constructActivationProperty(V4IR::Name *func, void InstructionSelection::constructProperty(V4IR::Temp *base, const QString &name, V4IR::ExprList *args, V4IR::Temp *result) { + if (useFastLookups) { + Instruction::ConstructPropertyLookup call; + call.base = getParam(base); + call.index = registerGetterLookup(name); + prepareCallArgs(args, call.argc); + call.callData = callDataStart(); + call.result = getResultParam(result); + addInstruction(call); + return; + } Instruction::CreateProperty create; create.base = getParam(base); create.name = registerString(name); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index a8cabcb374..4c0573ceaf 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -966,10 +966,10 @@ ReturnedValue __qmljs_construct_value(ExecutionContext *context, const ValueRef return f->construct(callData); } -ReturnedValue __qmljs_construct_property(ExecutionContext *context, const ValueRef base, const StringRef name, CallDataRef callData) +ReturnedValue __qmljs_construct_property(ExecutionContext *context, const StringRef name, CallDataRef callData) { Scope scope(context); - ScopedObject thisObject(scope, base->toObject(context)); + ScopedObject thisObject(scope, callData->thisObject.toObject(context)); if (scope.engine->hasException) return Encode::undefined(); @@ -980,6 +980,18 @@ ReturnedValue __qmljs_construct_property(ExecutionContext *context, const ValueR return f->construct(callData); } +ReturnedValue __qmljs_construct_property_lookup(ExecutionContext *context, uint index, CallDataRef callData) +{ + Lookup *l = context->lookups + index; + SafeValue v; + v = l->getter(l, callData->thisObject); + if (!v.isManaged()) + return context->throwTypeError(); + + return v.managed()->construct(callData); +} + + void __qmljs_throw(ExecutionContext *context, const ValueRef value) { if (!value->isEmpty()) diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index b5567693e5..194523727f 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -125,7 +125,8 @@ QV4::ReturnedValue __qmljs_call_element(ExecutionContext *context, const ValueRe QV4::ReturnedValue __qmljs_call_value(QV4::ExecutionContext *context, const QV4::ValueRef func, CallDataRef callData); QV4::ReturnedValue __qmljs_construct_activation_property(QV4::ExecutionContext *, const QV4::StringRef name, CallDataRef callData); -QV4::ReturnedValue __qmljs_construct_property(QV4::ExecutionContext *context, const QV4::ValueRef base, const QV4::StringRef name, CallDataRef callData); +QV4::ReturnedValue __qmljs_construct_property(QV4::ExecutionContext *context, const QV4::StringRef name, CallDataRef callData); +QV4::ReturnedValue __qmljs_construct_property_lookup(ExecutionContext *context, uint index, CallDataRef callData); QV4::ReturnedValue __qmljs_construct_value(QV4::ExecutionContext *context, const QV4::ValueRef func, CallDataRef callData); QV4::ReturnedValue __qmljs_builtin_typeof(QV4::ExecutionContext *ctx, const QV4::ValueRef val); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 72db469ee6..98b446ef2e 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -503,10 +503,19 @@ QV4::ReturnedValue VME::run(QV4::ExecutionContext *context, const uchar *code, QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); callData->tag = QV4::Value::Integer_Type; callData->argc = instr.argc; - callData->thisObject = QV4::Primitive::undefinedValue(); - STOREVALUE(instr.result, __qmljs_construct_property(context, VALUEPTR(instr.base), runtimeStrings[instr.name], callData)); + callData->thisObject = VALUE(instr.base); + STOREVALUE(instr.result, __qmljs_construct_property(context, runtimeStrings[instr.name], callData)); MOTH_END_INSTR(CreateProperty) + MOTH_BEGIN_INSTR(ConstructPropertyLookup) + Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize); + QV4::CallData *callData = reinterpret_cast<QV4::CallData *>(stack + instr.callData); + callData->tag = QV4::Value::Integer_Type; + callData->argc = instr.argc; + callData->thisObject = VALUE(instr.base); + STOREVALUE(instr.result, __qmljs_construct_property_lookup(context, instr.index, callData)); + MOTH_END_INSTR(ConstructPropertyLookup) + MOTH_BEGIN_INSTR(CreateActivationProperty) TRACE(inline, "property name = %s, args = %d, argc = %d", runtimeStrings[instr.name]->toQString().toUtf8().constData(), instr.args, instr.argc); Q_ASSERT(instr.callData + instr.argc + qOffsetOf(QV4::CallData, args)/sizeof(QV4::SafeValue) <= stackSize); |