aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-11-07 05:12:54 +0100
committerBjörn Gustavsson <[email protected]>2017-11-07 09:22:55 +0100
commit1f8177e950715b3444dadfb1624875afe228195b (patch)
treee4590caa48d7dd33633741d86bc4442437457a88
parent6d810d71f4f2e2ee0be749a53e328c3719db00f9 (diff)
downloadotp-1f8177e950715b3444dadfb1624875afe228195b.tar.gz
otp-1f8177e950715b3444dadfb1624875afe228195b.tar.bz2
otp-1f8177e950715b3444dadfb1624875afe228195b.zip
Strengthen tests of definition of specific instructions
Don't allow defining an specific operation more than once with the exact same operands. Don't allow a specific operation to be defined with different arities.
-rw-r--r--erts/emulator/beam/ops.tab2
-rwxr-xr-xerts/emulator/utils/beam_makeops20
2 files changed, 20 insertions, 2 deletions
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 7a2c39b3a8..a560bde920 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -511,8 +511,6 @@ put_list y x x
put_list y y x
put_list x y x
-put_list y x x
-
# put_list SrcReg Constant Dst
put_list x c x
diff --git a/erts/emulator/utils/beam_makeops b/erts/emulator/utils/beam_makeops
index d5cb127246..da994fae3e 100755
--- a/erts/emulator/utils/beam_makeops
+++ b/erts/emulator/utils/beam_makeops
@@ -78,6 +78,10 @@ my %num_specific;
my %gen_to_spec;
my %specific_op;
+# The following hashes are used for error checking.
+my %print_name;
+my %specific_op_arity;
+
# Information about each specific operator. Key is the print name (e.g. get_list_xxy).
# Value is a hash.
my %spec_op_info;
@@ -1055,6 +1059,22 @@ sub parse_specific_op {
my $key = "$name/$arity";
foreach my $args_ref (@res) {
@args = @$args_ref;
+ my $arity = @args;
+ my $loc = "$ARGV($.)";
+ if (defined $specific_op_arity{$name}) {
+ my($prev_arity,$loc) = @{$specific_op_arity{$name}};
+ if ($arity != $prev_arity) {
+ error("$name defined with arity $arity, " .
+ "but previously defined with arity $prev_arity at $loc");
+ }
+ }
+ $specific_op_arity{$name} = [$arity,$loc];
+ my $print_name = print_name($name, @args);
+ if (defined $print_name{$print_name}) {
+ error("$name @args: already defined at " .
+ $print_name{$print_name});
+ }
+ $print_name{$print_name} = $loc;
push @{$specific_op{$key}}, [$name,$hotness,@args];
}