aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorJohn Högberg <[email protected]>2019-05-28 17:22:21 +0200
committerJohn Högberg <[email protected]>2019-06-11 15:47:38 +0200
commitd6287ba96fddcad782316061a1813bbd627ae6c9 (patch)
tree56bdf7d05ff908c6561f120a64a80fcdab03b0ff /lib
parent43a386436b817e8d93fea8f6ea719f9162192241 (diff)
downloadotp-d6287ba96fddcad782316061a1813bbd627ae6c9.tar.gz
otp-d6287ba96fddcad782316061a1813bbd627ae6c9.tar.bz2
otp-d6287ba96fddcad782316061a1813bbd627ae6c9.zip
beam_validator: Simplify the match context type
There's no need to have an id as part of the type, as the value reference (through which the type is reached) uniquely identifies the match context.
Diffstat (limited to 'lib')
-rw-r--r--lib/compiler/src/beam_validator.erl34
1 files changed, 14 insertions, 20 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index c5e3f6ac35..a89295ab72 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -154,8 +154,7 @@ validate_0(Module, [{function,Name,Ar,Entry,Code}|Fs], Ft) ->
%% Match context type.
-record(ms,
- {id=make_ref() :: reference(), %Unique ID.
- valid=0 :: non_neg_integer(), %Valid slots
+ {valid=0 :: non_neg_integer(), %Valid slots
slots=0 :: non_neg_integer() %Number of slots
}).
@@ -487,7 +486,9 @@ valfun_1(remove_message, Vst) ->
%% without restrictions.
remove_fragility(Vst);
valfun_1({'%', {type_info, Reg, match_context}}, Vst) ->
- update_type(fun meet/2, #ms{}, Reg, Vst);
+ %% This is a gross hack, but we'll be rid of it once we have proper union
+ %% types.
+ override_type(#ms{}, Reg, Vst);
valfun_1({'%', {type_info, Reg, Type}}, Vst) ->
%% Explicit type information inserted by optimization passes to indicate
%% that Reg has a certain type, so that we can accept cross-function type
@@ -1260,21 +1261,22 @@ verify_remote_args_1(X, Vst) ->
verify_local_args(-1, _Lbl, _CtxIds, _Vst) ->
ok;
-verify_local_args(X, Lbl, CtxIds, Vst) ->
+verify_local_args(X, Lbl, CtxRefs, Vst) ->
Reg = {x, X},
assert_not_fragile(Reg, Vst),
case get_movable_term_type(Reg, Vst) of
- #ms{id=Id}=Type ->
- case CtxIds of
- #{ Id := Other } ->
+ #ms{}=Type ->
+ VRef = get_reg_vref(Reg, Vst),
+ case CtxRefs of
+ #{ VRef := Other } ->
error({multiple_match_contexts, [Reg, Other]});
#{} ->
verify_arg_type(Lbl, Reg, Type, Vst),
- verify_local_args(X - 1, Lbl, CtxIds#{ Id => Reg }, Vst)
+ verify_local_args(X - 1, Lbl, CtxRefs#{ VRef => Reg }, Vst)
end;
Type ->
verify_arg_type(Lbl, Reg, Type, Vst),
- verify_local_args(X - 1, Lbl, CtxIds, Vst)
+ verify_local_args(X - 1, Lbl, CtxRefs, Vst)
end.
%% Verifies that the given argument narrows to what the function expects.
@@ -2039,13 +2041,9 @@ join({atom,A}, {atom,B}) when is_boolean(A), is_boolean(B) ->
bool;
join({atom,_}, {atom,_}) ->
{atom,[]};
-join(#ms{id=Id1,valid=B1,slots=Slots1},
- #ms{id=Id2,valid=B2,slots=Slots2}) ->
- Id = if
- Id1 =:= Id2 -> Id1;
- true -> make_ref()
- end,
- #ms{id=Id,valid=B1 band B2,slots=min(Slots1, Slots2)};
+join(#ms{valid=B1,slots=Slots1},
+ #ms{valid=B2,slots=Slots2}) ->
+ #ms{valid=B1 band B2,slots=min(Slots1, Slots2)};
join(T1, T2) when T1 =/= T2 ->
%% We've exhaused all other options, so the type must either be a list or
%% a 'term'.
@@ -2107,10 +2105,6 @@ meet(term, Other) ->
Other;
meet(Other, term) ->
Other;
-meet(#ms{}, binary) ->
- #ms{};
-meet(binary, #ms{}) ->
- #ms{};
meet({literal,_}, {literal,_}) ->
none;
meet(T1, {literal,_}=T2) ->