diff options
author | Lars Knoll <lars.knoll@qt.io> | 2018-08-30 22:30:50 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2018-08-31 06:08:51 +0000 |
commit | 1102cefcd75b250d4b42673b8a606d167cb15048 (patch) | |
tree | 34887646d0cb29ba87eac5d563776676bc8f249f /src/qml/compiler/qv4codegen.cpp | |
parent | ac3a9fd8f352b1d717334d16111d22d6c155e4e2 (diff) | |
download | qtdeclarative-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.cpp | 32 |
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()); } |