aboutsummaryrefslogtreecommitdiffstats
path: root/qv4codegen.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2012-12-07 22:44:51 -0800
committerSimon Hausmann <simon.hausmann@digia.com>2012-12-08 17:22:23 +0100
commit759d70e8a4ef5d35385b3dbc6aed471f3480ea0e (patch)
treeb15f82ffb5b199bbb68a6e599fe299af9172cae2 /qv4codegen.cpp
parent6287991abb09441e6990b1e0b05f393ce2e3d08c (diff)
Keep references while moving other expressions into a temp
delete and typeof need to get correct references as arguments. But we still need to evaluate other expressions correctly. The best way to do that is to store them in a temp. Change-Id: I7bcd152742bf752df47fd63a837952c57ea70bf5 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'qv4codegen.cpp')
-rw-r--r--qv4codegen.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/qv4codegen.cpp b/qv4codegen.cpp
index 8159ede389..95555238da 100644
--- a/qv4codegen.cpp
+++ b/qv4codegen.cpp
@@ -490,6 +490,17 @@ IR::Expr *Codegen::argument(IR::Expr *expr)
return expr;
}
+// keeps references alive, converts other expressions to temps
+IR::Expr *Codegen::reference(IR::Expr *expr)
+{
+ if (expr && !expr->asTemp() && !expr->asName() && !expr->asMember() && !expr->asSubscript()) {
+ const unsigned t = _block->newTemp();
+ move(_block->TEMP(t), expr);
+ expr = _block->TEMP(t);
+ }
+ return expr;
+}
+
IR::Expr *Codegen::unop(IR::AluOp op, IR::Expr *expr)
{
if (IR::Const *c = expr->asConst()) {
@@ -1159,7 +1170,7 @@ bool Codegen::visit(DeleteExpression *ast)
{
Result expr = expression(ast->expression);
IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(*expr);
+ args->init(reference(*expr));
_expr.code = call(_block->NAME(IR::Name::builtin_delete, ast->deleteToken.startLine, ast->deleteToken.startColumn), args);
return false;
}
@@ -1384,7 +1395,7 @@ bool Codegen::visit(TypeOfExpression *ast)
{
Result expr = expression(ast->expression);
IR::ExprList *args = _function->New<IR::ExprList>();
- args->init(*expr);
+ args->init(reference(*expr));
_expr.code = call(_block->NAME(IR::Name::builtin_typeof, ast->typeofToken.startLine, ast->typeofToken.startColumn), args);
return false;
}