diff options
author | Erlang/OTP <[email protected]> | 2016-07-14 11:22:30 +0200 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2016-07-14 11:22:30 +0200 |
commit | 23bb0ba4db2351c2b89e8fb80371fad74d58d544 (patch) | |
tree | 70342d22fd41575c3d950b242d61afb47e2c6832 /erts/emulator/beam/beam_emu.c | |
parent | 0076aef1e9c531389050b947fe09d6d7ebe6f2e4 (diff) | |
parent | 3585c1e6832083acbfc130c0aafc8f2db2f3f706 (diff) | |
download | otp-23bb0ba4db2351c2b89e8fb80371fad74d58d544.tar.gz otp-23bb0ba4db2351c2b89e8fb80371fad74d58d544.tar.bz2 otp-23bb0ba4db2351c2b89e8fb80371fad74d58d544.zip |
Merge branch 'sverker/bsl-gc-overflow/OTP-13732' into maint-19
* sverker/bsl-gc-overflow/OTP-13732:
erts: Fix GC overrun bug in 'bsl' op with small Op1
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 14 |
1 files changed, 7 insertions, 7 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index 4716460a6b..c6258287c4 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -3032,6 +3032,7 @@ do { \ if (i == 0) { StoreBifResult(4, Op1); } + ires = big_size(Op1); goto big_shift; } } else if (is_big(Op2)) { @@ -3047,7 +3048,6 @@ do { \ OpCase(i_bsl_jIssd): GetArg2(2, Op1, Op2); - do_bsl: if (is_small(Op2)) { i = signed_val(Op2); @@ -3073,16 +3073,12 @@ do { \ StoreBifResult(4, Op1); } } - Op1 = small_to_big(ires, tmp_big); -#ifdef TAG_LITERAL_PTR - Op1 |= TAG_LITERAL_PTR; -#endif + ires = 1; /* big_size(small_to_big(Op1)) */ big_shift: if (i > 0) { /* Left shift. */ - ires = big_size(Op1) + (i / D_EXP); + ires += (i / D_EXP); } else { /* Right shift. */ - ires = big_size(Op1); if (ires <= (-i / D_EXP)) ires = 3; /* ??? */ else @@ -3101,6 +3097,9 @@ do { \ goto lb_Cl_error; } TestHeapPreserve(ires+1, Arg(1), Op1); + if (is_small(Op1)) { + Op1 = small_to_big(signed_val(Op1), tmp_big); + } bigp = HTOP; Op1 = big_lshift(Op1, i, bigp); if (is_big(Op1)) { @@ -3123,6 +3122,7 @@ do { \ if (i == 0) { StoreBifResult(4, Op1); } + ires = big_size(Op1); goto big_shift; } } else if (is_big(Op2)) { |