From 759d70e8a4ef5d35385b3dbc6aed471f3480ea0e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Fri, 7 Dec 2012 22:44:51 -0800 Subject: [PATCH] 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 --- qv4codegen.cpp | 15 +++++++++++++-- qv4codegen_p.h | 1 + 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/qv4codegen.cpp b/qv4codegen.cpp index 8159ede..9555523 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(); - 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(); - 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; } diff --git a/qv4codegen_p.h b/qv4codegen_p.h index 474e558..ba3b477 100644 --- a/qv4codegen_p.h +++ b/qv4codegen_p.h @@ -201,6 +201,7 @@ protected: IR::Expr *member(IR::Expr *base, const QString *name); IR::Expr *subscript(IR::Expr *base, IR::Expr *index); IR::Expr *argument(IR::Expr *expr); + IR::Expr *reference(IR::Expr *expr); IR::Expr *unop(IR::AluOp op, IR::Expr *expr); IR::Expr *binop(IR::AluOp op, IR::Expr *left, IR::Expr *right); IR::Expr *call(IR::Expr *base, IR::ExprList *args); -- 2.7.4