return expr;
case IR::OpCompl:
return _block->CONST(IR::NumberType, ~VM::Value::toInt32(c->value));
+ case IR::OpIncrement:
+ return _block->CONST(IR::NumberType, c->value + 1);
+ case IR::OpDecrement:
+ return _block->CONST(IR::NumberType, c->value - 1);
default:
break;
}
case IR::OpUMinus:
case IR::OpUPlus:
case IR::OpCompl:
+ case IR::OpIncrement:
+ case IR::OpDecrement:
case IR::OpInvalid:
break;
}
bool Codegen::visit(PostDecrementExpression *ast)
{
+ // ###
+ // Throw a SyntaxError exception if the following conditions are all true:
+ // Type(lhs) is Reference is true
+ // IsStrictReference(lhs) is true
+ // Type(GetBase(lhs)) is Environment Record
+ // GetReferencedName(lhs) is either "eval" or "arguments"
+
+
Result expr = expression(ast->base);
if (_expr.accept(nx)) {
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpSub);
+ move(*expr, unop(IR::OpDecrement, *expr));
} else {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), *expr);
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpSub);
+ move(*expr, unop(IR::OpDecrement, _block->TEMP(t)));
_expr.code = _block->TEMP(t);
}
return false;
bool Codegen::visit(PostIncrementExpression *ast)
{
+ // ###
+ // Throw a SyntaxError exception if the following conditions are all true:
+ // Type(lhs) is Reference is true
+ // IsStrictReference(lhs) is true
+ // Type(GetBase(lhs)) is Environment Record
+ // GetReferencedName(lhs) is either "eval" or "arguments"
+
Result expr = expression(ast->base);
if (_expr.accept(nx)) {
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpAdd);
+ move(*expr, unop(IR::OpIncrement, *expr));
} else {
const unsigned t = _block->newTemp();
move(_block->TEMP(t), *expr);
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpAdd);
+ move(*expr, unop(IR::OpIncrement, _block->TEMP(t)));
_expr.code = _block->TEMP(t);
}
return false;
bool Codegen::visit(PreDecrementExpression *ast)
{
+ // ###
+ // Throw a SyntaxError exception if the following conditions are all true:
+ // Type(lhs) is Reference is true
+ // IsStrictReference(lhs) is true
+ // Type(GetBase(lhs)) is Environment Record
+ // GetReferencedName(lhs) is either "eval" or "arguments"
+
Result expr = expression(ast->expression);
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpSub);
+ move(*expr, unop(IR::OpDecrement, *expr));
if (_expr.accept(nx)) {
// nothing to do
} else {
bool Codegen::visit(PreIncrementExpression *ast)
{
- Result expr = expression(ast->expression);
- move(*expr, _block->CONST(IR::NumberType, 1), IR::OpAdd);
+ // ###
+ // Throw a SyntaxError exception if the following conditions are all true:
+ // Type(lhs) is Reference is true
+ // IsStrictReference(lhs) is true
+ // Type(GetBase(lhs)) is Environment Record
+ // GetReferencedName(lhs) is either "eval" or "arguments"
+ Result expr = expression(ast->expression);
+ move(*expr, unop(IR::OpIncrement, *expr));
if (_expr.accept(nx)) {
// nothing to do
} else {
NULL_OP, // OpUMinus
NULL_OP, // OpUPlus
NULL_OP, // OpCompl
+ NULL_OP, // OpIncrement
+ NULL_OP, // OpDecrement
INLINE_OP(__qmljs_bit_and, &Assembler::inline_and32, &Assembler::inline_and32), // OpBitAnd
INLINE_OP(__qmljs_bit_or, &Assembler::inline_or32, &Assembler::inline_or32), // OpBitOr
case IR::OpUMinus: setOp(op, opName, __qmljs_uminus); break;
case IR::OpUPlus: setOp(op, opName, __qmljs_uplus); break;
case IR::OpCompl: setOp(op, opName, __qmljs_compl); break;
+ case IR::OpIncrement: setOp(op, opName, __qmljs_increment); break;
+ case IR::OpDecrement: setOp(op, opName, __qmljs_decrement); break;
default: assert(!"unreachable"); break;
} // switch