| Index: runtime/vm/intermediate_language_arm64.cc
|
| ===================================================================
|
| --- runtime/vm/intermediate_language_arm64.cc (revision 36227)
|
| +++ runtime/vm/intermediate_language_arm64.cc (working copy)
|
| @@ -2448,6 +2448,20 @@
|
| }
|
|
|
|
|
| +static void EmitJavascriptOverflowCheck(FlowGraphCompiler* compiler,
|
| + Range* range,
|
| + Label* overflow,
|
| + Register result) {
|
| + if (!range->IsWithin(-0x20000000000000LL, 0x20000000000000LL)) {
|
| + ASSERT(overflow != NULL);
|
| + __ CompareImmediate(result, -0x20000000000000LL, PP);
|
| + __ b(overflow, LT);
|
| + __ CompareImmediate(result, 0x20000000000000LL, PP);
|
| + __ b(overflow, GT);
|
| + }
|
| +}
|
| +
|
| +
|
| static void EmitSmiShiftLeft(FlowGraphCompiler* compiler,
|
| BinarySmiOpInstr* shift_left) {
|
| const bool is_truncating = shift_left->is_truncating();
|
| @@ -2484,6 +2498,9 @@
|
| // Shift for result now we know there is no overflow.
|
| __ Lsl(result, left, value);
|
| }
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
|
| + }
|
| return;
|
| }
|
|
|
| @@ -2514,6 +2531,9 @@
|
| __ Asr(TMP, right, kSmiTagSize); // SmiUntag right into TMP.
|
| __ lslv(result, left, TMP);
|
| }
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
|
| + }
|
| return;
|
| }
|
|
|
| @@ -2559,6 +2579,9 @@
|
| // Shift for result now we know there is no overflow.
|
| __ lslv(result, left, TMP);
|
| }
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, shift_left->range(), deopt, result);
|
| + }
|
| }
|
|
|
|
|
| @@ -2733,6 +2756,9 @@
|
| UNREACHABLE();
|
| break;
|
| }
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
|
| + }
|
| return;
|
| }
|
|
|
| @@ -2875,6 +2901,9 @@
|
| UNREACHABLE();
|
| break;
|
| }
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
|
| + }
|
| }
|
|
|
|
|
| @@ -3562,6 +3591,9 @@
|
| Label* deopt = compiler->AddDeoptStub(deopt_id(), ICData::kDeoptUnaryOp);
|
| __ subs(result, ZR, Operand(value));
|
| __ b(deopt, VS);
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, range(), deopt, value);
|
| + }
|
| break;
|
| }
|
| case Token::kBIT_NOT:
|
| @@ -3643,6 +3675,9 @@
|
| __ CompareImmediate(result, 0xC000000000000000, PP);
|
| __ b(&do_call, MI);
|
| __ SmiTag(result);
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, range(), &do_call, result);
|
| + }
|
| __ b(&done);
|
| __ Bind(&do_call);
|
| __ Push(value_obj);
|
| @@ -3688,6 +3723,9 @@
|
| __ CompareImmediate(result, 0xC000000000000000, PP);
|
| __ b(deopt, MI);
|
| __ SmiTag(result);
|
| + if (FLAG_throw_on_javascript_int_overflow) {
|
| + EmitJavascriptOverflowCheck(compiler, range(), deopt, result);
|
| + }
|
| }
|
|
|
|
|
| @@ -3994,7 +4032,9 @@
|
| __ add(TMP, result_mod, Operand(right));
|
| __ csel(result_mod, TMP, TMP2, GE);
|
| __ Bind(&done);
|
| -
|
| + // FLAG_throw_on_javascript_int_overflow: not needed.
|
| + // Note that the result of an integer division/modulo of two
|
| + // in-range arguments, cannot create out-of-range result.
|
| return;
|
| }
|
| if (kind() == MergedMathInstr::kSinCos) {
|
|
|