diff options
author | Lars Knoll <lars.knoll@digia.com> | 2012-12-07 22:44:51 -0800 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-12-08 17:22:23 +0100 |
commit | 759d70e8a4ef5d35385b3dbc6aed471f3480ea0e (patch) | |
tree | b15f82ffb5b199bbb68a6e599fe299af9172cae2 /qv4codegen.cpp | |
parent | 6287991abb09441e6990b1e0b05f393ce2e3d08c (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.cpp | 15 |
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; } |