diff options
| author | Erik Verbruggen <erik.verbruggen@qt.io> | 2017-06-13 15:47:58 +0200 |
|---|---|---|
| committer | Lars Knoll <lars.knoll@qt.io> | 2017-06-20 09:45:14 +0000 |
| commit | a8fb08b239de6bf52371b62633e8f8b9b59797bb (patch) | |
| tree | 8d267a6cb8adf42e1fa0a2466a1c6cea7e449c11 /src/qml/compiler/qv4codegen.cpp | |
| parent | 87a7fe6a1d7be05b3b3b25a418b9e3852e424e59 (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.cpp | 52 |
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()); } |
