aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler')
-rw-r--r--src/qml/compiler/qv4bytecodehandler.cpp3
-rw-r--r--src/qml/compiler/qv4codegen.cpp56
-rw-r--r--src/qml/compiler/qv4codegen_p.h2
-rw-r--r--src/qml/compiler/qv4instr_moth.cpp4
-rw-r--r--src/qml/compiler/qv4instr_moth_p.h2
5 files changed, 57 insertions, 10 deletions
diff --git a/src/qml/compiler/qv4bytecodehandler.cpp b/src/qml/compiler/qv4bytecodehandler.cpp
index 181594010d..3a3f4a6adb 100644
--- a/src/qml/compiler/qv4bytecodehandler.cpp
+++ b/src/qml/compiler/qv4bytecodehandler.cpp
@@ -246,6 +246,9 @@ std::vector<int> ByteCodeHandler::collectLabelsInBytecode(const char *code, uint
COLLECTOR_BEGIN_INSTR(CallValue)
COLLECTOR_END_INSTR(CallValue)
+ COLLECTOR_BEGIN_INSTR(CallWithReceiver)
+ COLLECTOR_END_INSTR(CallWithReceiver)
+
COLLECTOR_BEGIN_INSTR(CallProperty)
COLLECTOR_END_INSTR(CallProperty)
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 412d787d11..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;
}
@@ -2450,7 +2474,7 @@ bool Codegen::visit(ObjectPattern *ast)
for (; it; it = it->next) {
PatternProperty *p = it->property;
AST::ComputedPropertyName *cname = AST::cast<AST::ComputedPropertyName *>(p->name);
- if (cname || p->type == PatternProperty::Getter || p->type == PatternProperty::Setter)
+ if (cname || p->type != PatternProperty::Literal)
break;
QString name = p->name->asString();
uint arrayIndex = QV4::String::toArrayIndex(name);
@@ -2477,7 +2501,9 @@ bool Codegen::visit(ObjectPattern *ast)
PatternProperty *p = it->property;
AST::ComputedPropertyName *cname = AST::cast<AST::ComputedPropertyName *>(p->name);
ObjectLiteralArgument argType = ObjectLiteralArgument::Value;
- if (p->type == PatternProperty::Getter)
+ if (p->type == PatternProperty::Method)
+ argType = ObjectLiteralArgument::Method;
+ else if (p->type == PatternProperty::Getter)
argType = ObjectLiteralArgument::Getter;
else if (p->type == PatternProperty::Setter)
argType = ObjectLiteralArgument::Setter;
@@ -2508,10 +2534,20 @@ bool Codegen::visit(ObjectPattern *ast)
push(Reference::fromAccumulator(this));
{
RegisterScope innerScope(this);
- Reference value = expression(p->initializer);
- if (hasError)
- return false;
- value.loadInAccumulator();
+ if (p->type != PatternProperty::Literal) {
+ // need to get the closure id for the method
+ FunctionExpression *f = p->initializer->asFunctionDefinition();
+ Q_ASSERT(f);
+ int function = defineFunction(f->name.toString(), f, f->formals, f->body);
+ if (hasError)
+ return false;
+ Reference::fromConst(this, Encode(function)).loadInAccumulator();
+ } else {
+ Reference value = expression(p->initializer);
+ if (hasError)
+ return false;
+ value.loadInAccumulator();
+ }
}
push(Reference::fromAccumulator(this));
}
@@ -3966,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());
}
diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h
index adea8b3009..ae3e074e07 100644
--- a/src/qml/compiler/qv4codegen_p.h
+++ b/src/qml/compiler/qv4codegen_p.h
@@ -683,7 +683,7 @@ public:
Reference jumpBinop(QSOperator::Op oper, Reference &left, Reference &right);
struct Arguments { int argc; int argv; bool hasSpread; };
Arguments pushArgs(AST::ArgumentList *args);
- void handleCall(Reference &base, Arguments calldata);
+ void handleCall(Reference &base, Arguments calldata, int slotForFunction, int slotForThisObject);
Arguments pushTemplateArgs(AST::TemplateLiteral *args);
int createTemplateArray(AST::TemplateLiteral *t);
diff --git a/src/qml/compiler/qv4instr_moth.cpp b/src/qml/compiler/qv4instr_moth.cpp
index 4653b7217d..e70b246181 100644
--- a/src/qml/compiler/qv4instr_moth.cpp
+++ b/src/qml/compiler/qv4instr_moth.cpp
@@ -357,6 +357,10 @@ void dumpBytecode(const char *code, int len, int nLocals, int nFormals, int /*st
d << dumpRegister(name, nFormals) << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallValue)
+ MOTH_BEGIN_INSTR(CallWithReceiver)
+ d << dumpRegister(name, nFormals) << dumpRegister(thisObject, nFormals) << dumpArguments(argc, argv, nFormals);
+ MOTH_END_INSTR(CallWithReceiver)
+
MOTH_BEGIN_INSTR(CallProperty)
d << dumpRegister(base, nFormals) << "." << name << dumpArguments(argc, argv, nFormals);
MOTH_END_INSTR(CallProperty)
diff --git a/src/qml/compiler/qv4instr_moth_p.h b/src/qml/compiler/qv4instr_moth_p.h
index 7c2cbf717e..2690151a23 100644
--- a/src/qml/compiler/qv4instr_moth_p.h
+++ b/src/qml/compiler/qv4instr_moth_p.h
@@ -104,6 +104,7 @@ QT_BEGIN_NAMESPACE
#define INSTR_LoadElement(op) INSTRUCTION(op, LoadElement, 1, base)
#define INSTR_StoreElement(op) INSTRUCTION(op, StoreElement, 2, base, index)
#define INSTR_CallValue(op) INSTRUCTION(op, CallValue, 3, name, argc, argv)
+#define INSTR_CallWithReceiver(op) INSTRUCTION(op, CallWithReceiver, 4, name, thisObject, argc, argv)
#define INSTR_CallProperty(op) INSTRUCTION(op, CallProperty, 4, name, base, argc, argv)
#define INSTR_CallPropertyLookup(op) INSTRUCTION(op, CallPropertyLookup, 4, lookupIndex, base, argc, argv)
#define INSTR_CallElement(op) INSTRUCTION(op, CallElement, 4, base, index, argc, argv)
@@ -283,6 +284,7 @@ QT_BEGIN_NAMESPACE
F(Mod) \
F(Sub) \
F(CallValue) \
+ F(CallWithReceiver) \
F(CallProperty) \
F(CallPropertyLookup) \
F(CallElement) \