diff options
-rw-r--r-- | erts/emulator/beam/generators.tab | 24 | ||||
-rw-r--r-- | erts/emulator/beam/instrs.tab | 6 | ||||
-rw-r--r-- | erts/emulator/beam/ops.tab | 14 |
3 files changed, 25 insertions, 19 deletions
diff --git a/erts/emulator/beam/generators.tab b/erts/emulator/beam/generators.tab index c3e30d6840..49afb3a6b1 100644 --- a/erts/emulator/beam/generators.tab +++ b/erts/emulator/beam/generators.tab @@ -270,8 +270,12 @@ gen.put_binary(Fail, Size, Unit, Flags, Src) { op->a[2] = Src; } else { error: - $BeamOpNameArity(op, badarg, 1); - op->a[0] = Fail; + /* + * Invalid size. This instruction can't possibly be + * reached, because bs_add or bs_init* would already + * have raised a system_limit exception. + */ + $BeamOpNameArity(op, delete_me, 0); } } else if (Size.type == TAG_q) { #ifdef ARCH_64 @@ -316,8 +320,12 @@ gen.put_integer(Fail, Size, Unit, Flags, Src) { Uint size; if (!beam_load_safe_mul(Size.val, Unit.val, &size)) { error: - $BeamOpNameArity(op, badarg, 1); - op->a[0] = Fail; + /* + * Invalid size. This instruction can't possibly be + * reached, because bs_add or bs_init* would already + * have raised a system_limit exception. + */ + $BeamOpNameArity(op, delete_me, 0); return op; } $BeamOpNameArity(op, i_new_bs_put_integer_imm, 4); @@ -364,8 +372,12 @@ gen.put_float(Fail, Size, Unit, Flags, Src) { op->a[0] = Fail; op->a[1].type = TAG_u; if (!beam_load_safe_mul(Size.val, Unit.val, &op->a[1].val)) { - $BeamOpNameArity(op, badarg, 1); - op->a[0] = Fail; + /* + * Size overflow. This instruction can't possibly be reached, because + * bs_add or bs_init* would already have raised a system_limit + * exception. + */ + $BeamOpNameArity(op, delete_me, 0); } else { op->a[2] = Flags; op->a[3] = Src; diff --git a/erts/emulator/beam/instrs.tab b/erts/emulator/beam/instrs.tab index 697c777825..a9e1dd1bfe 100644 --- a/erts/emulator/beam/instrs.tab +++ b/erts/emulator/beam/instrs.tab @@ -1035,12 +1035,6 @@ is_ge_literal(Fail, X, Y) { CMP_GE_LITERAL_ACTION($X, $Y, $FAIL($Fail)); } -badarg_body() { - c_p->freason = BADARG; - $FAIL_BODY(); - //| -no_next; -} - badmatch(Src) { c_p->fvalue = $Src; c_p->freason = BADMATCH; diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab index 49bd7a128c..e676cd0e67 100644 --- a/erts/emulator/beam/ops.tab +++ b/erts/emulator/beam/ops.tab @@ -261,12 +261,9 @@ raise Trace Value => move Trace x | move Value x=1 | move x x=2 | i_raise i_raise -# Internal now, but could be useful to make known to the compiler. -badarg/1 -badarg p => badarg_body -badarg Fail=f => jump Fail - -badarg_body +# Workaround the limitation that generators must always return at least one instruction. +delete_me/0 +delete_me => system_limit/1 system_limit p => system_limit_body @@ -1392,7 +1389,10 @@ i_bs_validate_unicode Fail Src=c => move Src x | i_bs_validate_unicode Fail x # # Storing floats into binaries. # -bs_put_float Fail Sz=q Unit Flags Val => badarg Fail + +# Will fail. No need to keep the instruction, because bs_add or +# bs_init* would already have raised an exception. +bs_put_float Fail Sz=q Unit Flags Val => bs_put_float Fail=j Sz=s Unit=u Flags=u Src=s => \ put_float(Fail, Sz, Unit, Flags, Src) |