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()) {
{
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;
}
{
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;
}
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);