aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qv4codegen.cpp
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2017-06-13 15:47:58 +0200
committerLars Knoll <lars.knoll@qt.io>2017-06-20 09:45:14 +0000
commita8fb08b239de6bf52371b62633e8f8b9b59797bb (patch)
tree8d267a6cb8adf42e1fa0a2466a1c6cea7e449c11 /src/qml/compiler/qv4codegen.cpp
parent87a7fe6a1d7be05b3b3b25a418b9e3852e424e59 (diff)
Support CallExpressions
Change-Id: I7d44c177e795f2392f6c9e582e4a28d593837a62 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/qml/compiler/qv4codegen.cpp')
-rw-r--r--src/qml/compiler/qv4codegen.cpp52
1 files changed, 35 insertions, 17 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp
index 3ece031a63..9504a01489 100644
--- a/src/qml/compiler/qv4codegen.cpp
+++ b/src/qml/compiler/qv4codegen.cpp
@@ -1566,23 +1566,39 @@ bool Codegen::visit(CallExpression *ast)
if (hasError)
return false;
- Result base = expression(ast->base);
- IR::ExprList *args = 0, **args_it = &args;
- for (ArgumentList *it = ast->arguments; it; it = it->next) {
- Result arg = expression(it->expression);
- if (hasError)
- return false;
- IR::Expr *actual = argument(*arg);
- *args_it = _function->New<IR::ExprList>();
- (*args_it)->init(actual);
- args_it = &(*args_it)->next;
- }
+ Reference base = expression(ast->base);
if (hasError)
return false;
- _expr.code = call(*base, args);
+
+ Q_ASSERT(base.type == Reference::Name); //### TODO: support more calls
+
+ auto argc = pushArgs(ast->arguments);
+ if (hasError)
+ return false;
+
+ QV4::Moth::Instruction::CallActivationProperty call;
+ call.name = base.nameIndex;
+ call.argc = argc;
+ call.callData = 0;
+ call.result = Moth::Param::createTemp(0); bytecodeGenerator->addInstruction(call);
+ _expr.result = Reference::fromTemp(this, 0);
return false;
}
+int Codegen::pushArgs(ArgumentList *args)
+{
+ int minNrOfStackEntries = offsetof(QV4::CallData, args)/sizeof(QV4::Value);
+ int argc = 0;
+ for (ArgumentList *it = args; it; it = it->next) {
+ Reference arg = expression(it->expression);
+ if (hasError)
+ return -1;
+ Reference::fromTemp(this, minNrOfStackEntries + argc).store(arg);
+ argc += 1;
+ }
+ return argc;
+}
+
bool Codegen::visit(ConditionalExpression *ast)
{
if (hasError)
@@ -2352,6 +2368,13 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
}
}
+ { // reserve space for outgoing call arguments
+ Q_ASSERT(function->tempCount == 0);
+ int minNrOfStackEntries = offsetof(QV4::CallData, args)/sizeof(QV4::Value);
+ function->tempCount = minNrOfStackEntries + _variableEnvironment->maxNumberOfArguments;
+ function->currentTemp = function->tempCount;
+ }
+
unsigned returnAddress = entryBlock->newTemp();
//### setLocation(exitBlock->RET(exitBlock->TEMP(returnAddress)), ast->lastSourceLocation());
@@ -2367,11 +2390,6 @@ int Codegen::defineFunction(const QString &name, AST::Node *ast,
retTemp.store(Reference::fromConst(this, Encode::undefined()));
}
- { // reserve space for outgoing call arguments
- _function->tempCount += _variableEnvironment->maxNumberOfArguments;
- _function->currentTemp = _function->tempCount;
- }
-
for (FormalParameterList *it = formals; it; it = it->next) {
_function->RECEIVE(it->name.toString());
}