aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
authorErlang/OTP <otp@erlang.org>2016-07-14 11:22:30 +0200
committerErlang/OTP <otp@erlang.org>2016-07-14 11:22:30 +0200
commit23bb0ba4db2351c2b89e8fb80371fad74d58d544 (patch)
tree70342d22fd41575c3d950b242d61afb47e2c6832 /erts/emulator/beam
parent0076aef1e9c531389050b947fe09d6d7ebe6f2e4 (diff)
parent3585c1e6832083acbfc130c0aafc8f2db2f3f706 (diff)
downloadotp-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')
-rw-r--r--erts/emulator/beam/beam_emu.c14
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)) {