summaryrefslogtreecommitdiff
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2018-08-30 22:30:50 +0200
committerLars Knoll <lars.knoll@qt.io>2018-08-31 06:08:51 +0000
commit1102cefcd75b250d4b42673b8a606d167cb15048 (patch)
tree34887646d0cb29ba87eac5d563776676bc8f249f /src/qml/compiler/qv4codegen.cpp
parentac3a9fd8f352b1d717334d16111d22d6c155e4e2 (diff)
downloadqtdeclarative-1102cefcd75b250d4b42673b8a606d167cb15048.tar.gz
Fix thisObject when calling super properties
Change-Id: Ia520d43ea2c29c16cfc8ffc86a32187a78848502 Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp32
1 files changed, 29 insertions, 3 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index b09deb1eaf..62dbcdaa7d 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1826,6 +1826,8 @@ bool Codegen::visit(CallExpression *ast)
case Reference::Super:
handleConstruct(base, ast->arguments);
return false;
+ case Reference::SuperProperty:
+ break;
default:
base = base.storeOnStack();
break;
@@ -1861,11 +1863,11 @@ bool Codegen::visit(CallExpression *ast)
}
- handleCall(base, calldata);
+ handleCall(base, calldata, functionObject, thisObject);
return false;
}
-void Codegen::handleCall(Reference &base, Arguments calldata)
+void Codegen::handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject)
{
//### Do we really need all these call instructions? can's we load the callee in a temp?
if (base.type == Reference::QmlScopeObject) {
@@ -1924,6 +1926,22 @@ void Codegen::handleCall(Reference &base, Arguments calldata)
call.argv = calldata.argv;
bytecodeGenerator->addInstruction(call);
}
+ } else if (base.type == Reference::SuperProperty) {
+ Reference receiver = base.baseObject();
+ if (!base.isStackSlot()) {
+ base.storeOnStack(slotForFunction);
+ base = Reference::fromStackSlot(this, slotForFunction);
+ }
+ if (!receiver.isStackSlot()) {
+ receiver.storeOnStack(slotForThisObject);
+ receiver = Reference::fromStackSlot(this, slotForThisObject);
+ }
+ Instruction::CallWithReceiver call;
+ call.name = base.stackSlot();
+ call.thisObject = receiver.stackSlot();
+ call.argc = calldata.argc;
+ call.argv = calldata.argv;
+ bytecodeGenerator->addInstruction(call);
} else {
Q_ASSERT(base.isStackSlot());
Instruction::CallValue call;
@@ -2157,6 +2175,8 @@ bool Codegen::visit(TaggedTemplate *ast)
RegisterScope scope(this);
+ int functionObject = -1, thisObject = -1;
+
Reference base = expression(ast->base);
if (hasError)
return false;
@@ -2167,6 +2187,10 @@ bool Codegen::visit(TaggedTemplate *ast)
break;
case Reference::Name:
break;
+ case Reference::SuperProperty:
+ thisObject = bytecodeGenerator->newRegister();
+ functionObject = bytecodeGenerator->newRegister();
+ break;
default:
base = base.storeOnStack();
break;
@@ -2181,7 +2205,7 @@ bool Codegen::visit(TaggedTemplate *ast)
Q_ASSERT(calldata.argv == arrayTemp + 1);
--calldata.argv;
- handleCall(base, calldata);
+ handleCall(base, calldata, functionObject, thisObject);
return false;
}
@@ -3978,6 +4002,8 @@ Codegen::Reference Codegen::Reference::baseObject() const
Q_UNREACHABLE();
} else if (type == Reference::Subscript) {
return Reference::fromStackSlot(codegen, elementBase.stackSlot());
+ } else if (type == Reference::SuperProperty) {
+ return Reference::fromStackSlot(codegen, CallData::This);
} else {
return Reference::fromConst(codegen, Encode::undefined());
}