diff options
author | Erik Verbruggen <erik.verbruggen@digia.com> | 2015-10-27 12:21:00 +0100 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@theqtcompany.com> | 2015-10-27 13:17:33 +0000 |
commit | 9730574818c80b956946dc26458c839915855196 (patch) | |
tree | 2721a5a2b3e4fc19f85f25ff71c4bb7277f54da0 | |
parent | 3832b1e05b80a0f509be17dd3619a2f8bb70074f (diff) |
QML: Fix typeof context property.
This was missing from f21e8c641af6b2d10f0d7e7e0fc6a755dab3673c.
Task-number: QTBUG-48524
Change-Id: I5cc6a979d965a1ef6b7fbc916a7ca9df868b459a
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
-rw-r--r-- | src/qml/compiler/qv4instr_moth_p.h | 16 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth.cpp | 19 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_moth_p.h | 1 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.cpp | 13 | ||||
-rw-r--r-- | src/qml/compiler/qv4isel_p.h | 1 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm.cpp | 17 | ||||
-rw-r--r-- | src/qml/jit/qv4isel_masm_p.h | 1 | ||||
-rw-r--r-- | src/qml/jit/qv4regalloc.cpp | 1 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime.cpp | 22 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4runtime_p.h | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4vme_moth.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmlengine/tst_qqmlengine.cpp | 14 |
13 files changed, 119 insertions, 2 deletions
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h index 1eebcbbe7f..97aee80e91 100644 --- a/src/qml/compiler/qv4instr_moth_p.h +++ b/src/qml/compiler/qv4instr_moth_p.h @@ -102,6 +102,8 @@ QT_BEGIN_NAMESPACE F(CallBuiltinDeleteMember, callBuiltinDeleteMember) \ F(CallBuiltinDeleteSubscript, callBuiltinDeleteSubscript) \ F(CallBuiltinDeleteName, callBuiltinDeleteName) \ + F(CallBuiltinTypeofScopeObjectProperty, callBuiltinTypeofScopeObjectProperty) \ + F(CallBuiltinTypeofContextObjectProperty, callBuiltinTypeofContextObjectProperty) \ F(CallBuiltinTypeofMember, callBuiltinTypeofMember) \ F(CallBuiltinTypeofSubscript, callBuiltinTypeofSubscript) \ F(CallBuiltinTypeofName, callBuiltinTypeofName) \ @@ -511,6 +513,18 @@ union Instr int name; Param result; }; + struct instr_callBuiltinTypeofScopeObjectProperty { + MOTH_INSTR_HEADER + int index; + Param base; + Param result; + }; + struct instr_callBuiltinTypeofContextObjectProperty { + MOTH_INSTR_HEADER + int index; + Param base; + Param result; + }; struct instr_callBuiltinTypeofMember { MOTH_INSTR_HEADER int member; @@ -809,6 +823,8 @@ union Instr instr_callBuiltinDeleteMember callBuiltinDeleteMember; instr_callBuiltinDeleteSubscript callBuiltinDeleteSubscript; instr_callBuiltinDeleteName callBuiltinDeleteName; + instr_callBuiltinTypeofScopeObjectProperty callBuiltinTypeofScopeObjectProperty; + instr_callBuiltinTypeofContextObjectProperty callBuiltinTypeofContextObjectProperty; instr_callBuiltinTypeofMember callBuiltinTypeofMember; instr_callBuiltinTypeofSubscript callBuiltinTypeofSubscript; instr_callBuiltinTypeofName callBuiltinTypeofName; diff --git a/src/qml/compiler/qv4isel_moth.cpp b/src/qml/compiler/qv4isel_moth.cpp index 0dae4d7696..afb36c5f14 100644 --- a/src/qml/compiler/qv4isel_moth.cpp +++ b/src/qml/compiler/qv4isel_moth.cpp @@ -1177,6 +1177,25 @@ void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args addInstruction(call); } +void InstructionSelection::callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) +{ + if (kind == IR::Member::MemberOfQmlScopeObject) { + Instruction::CallBuiltinTypeofScopeObjectProperty call; + call.base = getParam(base); + call.index = propertyIndex; + call.result = getResultParam(result); + addInstruction(call); + } else if (kind == IR::Member::MemberOfQmlContextObject) { + Instruction::CallBuiltinTypeofContextObjectProperty call; + call.base = getParam(base); + call.index = propertyIndex; + call.result = getResultParam(result); + addInstruction(call); + } else { + Q_UNREACHABLE(); + } +} + void InstructionSelection::callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) { diff --git a/src/qml/compiler/qv4isel_moth_p.h b/src/qml/compiler/qv4isel_moth_p.h index 947461f98e..e2385aad6d 100644 --- a/src/qml/compiler/qv4isel_moth_p.h +++ b/src/qml/compiler/qv4isel_moth_p.h @@ -84,6 +84,7 @@ protected: virtual void visitRet(IR::Ret *); virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result); + virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result); virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result); virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result); virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result); diff --git a/src/qml/compiler/qv4isel_p.cpp b/src/qml/compiler/qv4isel_p.cpp index 9d172b1223..184cff43e6 100644 --- a/src/qml/compiler/qv4isel_p.cpp +++ b/src/qml/compiler/qv4isel_p.cpp @@ -282,8 +282,17 @@ void IRDecoder::callBuiltin(IR::Call *call, Expr *result) return; case IR::Name::builtin_typeof: { - if (IR::Member *m = call->args->expr->asMember()) { - callBuiltinTypeofMember(m->base, *m->name, result); + if (IR::Member *member = call->args->expr->asMember()) { +#ifndef V4_BOOTSTRAP + Q_ASSERT(member->kind != IR::Member::MemberOfIdObjectsArray); + if (member->kind == IR::Member::MemberOfQmlScopeObject || member->kind == IR::Member::MemberOfQmlContextObject) { + callBuiltinTypeofQmlContextProperty(member->base, + IR::Member::MemberKind(member->kind), + member->property->coreIndex, result); + return; + } +#endif + callBuiltinTypeofMember(member->base, *member->name, result); return; } else if (IR::Subscript *ss = call->args->expr->asSubscript()) { callBuiltinTypeofSubscript(ss->base, ss->index, result); diff --git a/src/qml/compiler/qv4isel_p.h b/src/qml/compiler/qv4isel_p.h index 50ee955378..b78d323e7d 100644 --- a/src/qml/compiler/qv4isel_p.h +++ b/src/qml/compiler/qv4isel_p.h @@ -118,6 +118,7 @@ public: // visitor methods for StmtVisitor: public: // to implement by subclasses: virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result) = 0; + virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result) = 0; virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) = 0; virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result) = 0; virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result) = 0; diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 9696f59e7c..dad18c8cf2 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -399,6 +399,23 @@ void InstructionSelection::callBuiltinInvalid(IR::Name *func, IR::ExprList *args } } +void InstructionSelection::callBuiltinTypeofQmlContextProperty(IR::Expr *base, + IR::Member::MemberKind kind, + int propertyIndex, IR::Expr *result) +{ + if (kind == IR::Member::MemberOfQmlScopeObject) { + generateFunctionCall(result, Runtime::typeofScopeObjectProperty, Assembler::EngineRegister, + Assembler::PointerToValue(base), + Assembler::TrustedImm32(propertyIndex)); + } else if (kind == IR::Member::MemberOfQmlContextObject) { + generateFunctionCall(result, Runtime::typeofContextObjectProperty, + Assembler::EngineRegister, Assembler::PointerToValue(base), + Assembler::TrustedImm32(propertyIndex)); + } else { + Q_UNREACHABLE(); + } +} + void InstructionSelection::callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result) { diff --git a/src/qml/jit/qv4isel_masm_p.h b/src/qml/jit/qv4isel_masm_p.h index 29749f7492..6e9b02b034 100644 --- a/src/qml/jit/qv4isel_masm_p.h +++ b/src/qml/jit/qv4isel_masm_p.h @@ -80,6 +80,7 @@ protected: virtual QQmlRefPointer<QV4::CompiledData::CompilationUnit> backendCompileStep(); virtual void callBuiltinInvalid(IR::Name *func, IR::ExprList *args, IR::Expr *result); + virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *base, IR::Member::MemberKind kind, int propertyIndex, IR::Expr *result); virtual void callBuiltinTypeofMember(IR::Expr *base, const QString &name, IR::Expr *result); virtual void callBuiltinTypeofSubscript(IR::Expr *base, IR::Expr *index, IR::Expr *result); virtual void callBuiltinTypeofName(const QString &name, IR::Expr *result); diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index e980f181c2..5e836f06f1 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -267,6 +267,7 @@ public: protected: // IRDecoder virtual void callBuiltinInvalid(IR::Name *, IR::ExprList *, IR::Expr *) {} + virtual void callBuiltinTypeofQmlContextProperty(IR::Expr *, IR::Member::MemberKind, int, IR::Expr *) {} virtual void callBuiltinTypeofMember(IR::Expr *, const QString &, IR::Expr *) {} virtual void callBuiltinTypeofSubscript(IR::Expr *, IR::Expr *, IR::Expr *) {} virtual void callBuiltinTypeofName(const QString &, IR::Expr *) {} diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index 0d7a1851b8..0e90a3d021 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -1146,6 +1146,28 @@ QV4::ReturnedValue Runtime::typeofName(ExecutionEngine *engine, int nameIndex) return Runtime::typeofValue(engine, prop); } +#ifndef V4_BOOTSTRAP +ReturnedValue Runtime::typeofScopeObjectProperty(ExecutionEngine *engine, const Value &context, + int propertyIndex) +{ + Scope scope(engine); + ScopedValue prop(scope, getQmlScopeObjectProperty(engine, context, propertyIndex)); + if (scope.engine->hasException) + return Encode::undefined(); + return Runtime::typeofValue(engine, prop); +} + +ReturnedValue Runtime::typeofContextObjectProperty(ExecutionEngine *engine, const Value &context, + int propertyIndex) +{ + Scope scope(engine); + ScopedValue prop(scope, getQmlContextObjectProperty(engine, context, propertyIndex)); + if (scope.engine->hasException) + return Encode::undefined(); + return Runtime::typeofValue(engine, prop); +} +#endif // V4_BOOTSTRAP + QV4::ReturnedValue Runtime::typeofMember(ExecutionEngine *engine, const Value &base, int nameIndex) { Scope scope(engine); diff --git a/src/qml/jsruntime/qv4runtime_p.h b/src/qml/jsruntime/qv4runtime_p.h index 571abac21e..0d81edca1e 100644 --- a/src/qml/jsruntime/qv4runtime_p.h +++ b/src/qml/jsruntime/qv4runtime_p.h @@ -127,6 +127,8 @@ struct Q_QML_PRIVATE_EXPORT Runtime { // typeof static ReturnedValue typeofValue(ExecutionEngine *engine, const Value &val); static ReturnedValue typeofName(ExecutionEngine *engine, int nameIndex); + static ReturnedValue typeofScopeObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex); + static ReturnedValue typeofContextObjectProperty(ExecutionEngine *engine, const Value &context, int propertyIndex); static ReturnedValue typeofMember(ExecutionEngine *engine, const Value &base, int nameIndex); static ReturnedValue typeofElement(ExecutionEngine *engine, const Value &base, const Value &index); diff --git a/src/qml/jsruntime/qv4vme_moth.cpp b/src/qml/jsruntime/qv4vme_moth.cpp index 68f996c4c7..024a72bde2 100644 --- a/src/qml/jsruntime/qv4vme_moth.cpp +++ b/src/qml/jsruntime/qv4vme_moth.cpp @@ -684,6 +684,14 @@ QV4::ReturnedValue VME::run(ExecutionEngine *engine, const uchar *code STOREVALUE(instr.result, Runtime::deleteName(engine, instr.name)); MOTH_END_INSTR(CallBuiltinDeleteName) + MOTH_BEGIN_INSTR(CallBuiltinTypeofScopeObjectProperty) + STOREVALUE(instr.result, Runtime::typeofScopeObjectProperty(engine, VALUE(instr.base), instr.index)); + MOTH_END_INSTR(CallBuiltinTypeofMember) + + MOTH_BEGIN_INSTR(CallBuiltinTypeofContextObjectProperty) + STOREVALUE(instr.result, Runtime::typeofContextObjectProperty(engine, VALUE(instr.base), instr.index)); + MOTH_END_INSTR(CallBuiltinTypeofMember) + MOTH_BEGIN_INSTR(CallBuiltinTypeofMember) STOREVALUE(instr.result, Runtime::typeofMember(engine, VALUE(instr.base), instr.member)); MOTH_END_INSTR(CallBuiltinTypeofMember) diff --git a/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml b/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml new file mode 100644 index 0000000000..2196543dc8 --- /dev/null +++ b/tests/auto/qml/qqmlengine/data/TypeofQmlProperty.qml @@ -0,0 +1,6 @@ +import QtQuick 2.5 + +Item { + property var someProp: 1 + Component.onCompleted: console.log("typeof someProp:", typeof(someProp)); +} diff --git a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp index cb911d0115..486a0b4e87 100644 --- a/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp +++ b/tests/auto/qml/qqmlengine/tst_qqmlengine.cpp @@ -75,6 +75,8 @@ private slots: void urlInterceptor_data(); void urlInterceptor(); + void qmlContextProperties(); + public slots: QObject *createAQObjectForOwnershipTest () { @@ -778,6 +780,18 @@ void tst_qqmlengine::urlInterceptor() QCOMPARE(o->property("absoluteUrl").toString(), expectedAbsoluteUrl); } +void tst_qqmlengine::qmlContextProperties() +{ + QQmlEngine e; + + QQmlComponent c(&e, testFileUrl("TypeofQmlProperty.qml")); + QObject *o = c.create(); + if (!o) { + qDebug() << c.errorString(); + } + QVERIFY(o); +} + QTEST_MAIN(tst_qqmlengine) #include "tst_qqmlengine.moc" |