aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h10
-rw-r--r--src/qml/compiler/qv4isel_masm.cpp13
-rw-r--r--src/qml/compiler/qv4isel_moth.cpp10
-rw-r--r--src/qml/jsruntime/qv4runtime.cpp16
-rw-r--r--src/qml/jsruntime/qv4runtime_p.h3
-rw-r--r--src/qml/jsruntime/qv4vme_moth.cpp13
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);