summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Gustavsson <bjorn@erlang.org>2020-06-17 10:22:58 +0200
committerBjörn Gustavsson <bjorn@erlang.org>2020-06-18 08:44:37 +0200
commit5ffbf569c3817cb09ca4780802eddc7c7319f354 (patch)
tree76d56e3dd9e4caaeb03b34988d9074bc78e207f7
parente79ff7cab1776b1d71b079064f039adb7aa101e7 (diff)
downloaderlang-5ffbf569c3817cb09ca4780802eddc7c7319f354.tar.gz
Remove unreachable bs_put* instructions
bs_put* instructions with invalid sizes used to be converted to badarg instructions. This is unnecessary, since bs_add or bs_init* will raise an exception if the size is invalid. Therefore, if the size for a bs_put* instruction is invalid, simply remove the instruction.
-rw-r--r--erts/emulator/beam/generators.tab24
-rw-r--r--erts/emulator/beam/instrs.tab6
-rw-r--r--erts/emulator/beam/ops.tab14
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)