Skip to content

Commit

Permalink
khepri_fun: Add guard for unwrapping type-tagged registers
Browse files Browse the repository at this point in the history
The latest `beam_disasm` (OTP26+) unwraps the type-tag. Registers
passed into this function after that change are mistakenly unwrapped,
so types like

    #tr{reg = {x, 0}, t = #t_map{super_key = any, super_value = any}}

Are mistakenly unwrapped as

    #tr{reg = {x, 0}, t = t_map}

Which causes an internal failure in `beam_validator` when passed into
`compile:forms/2`.

This change prevents this future breakage by guarding on the type
being a tuple. This match should never succeed on OTP26+ since all
types in `beam_types.hrl` are specified as records, so the first
element will always be an atom.
  • Loading branch information
the-mikedavis committed Nov 7, 2022
1 parent eb31817 commit 0c8cd86
Showing 1 changed file with 11 additions and 8 deletions.
19 changes: 11 additions & 8 deletions src/khepri_fun.erl
Original file line number Diff line number Diff line change
Expand Up @@ -2073,14 +2073,17 @@ fix_integer(Other) -> Other.
%% registers" (`tr') to allow the JIT to do some optimizations. See:
%% https://www.erlang.org/blog/type-based-optimizations-in-the-jit/
%%
%% `beam_disasm' decodes the typed registers but leaves them in their encoded
%% form inside the beam file. We need to recover the proper typed register
%% form.

fix_type_tagged_beam_register({tr, Reg, {TypeUnion, _Min, _Max}}) ->
%% TODO: We could use `Min' and `Max' to improve the decoded typed
%% register, but 1), they are badly decoded by `beam_disasm' (unsigned
%% instead of signed) and 2)is there any benefit at this point?
%% OTP25's `beam_disasm' decoded the typed registers but left them in their
%% encoded form inside the beam file. We need to recover the proper typed
%% register form.
%%
%% This function mirrors `beam_disasm:resolve_arg/1'.
%% We could attempt to use the Min/Max to narrow down the type but there
%% doesn't seem to be any advantage to doing so.
%% See: https://github.com/erlang/otp/blob/be2a9c06aee359b77568ad1f9fb4313500f2f9ed/lib/compiler/src/beam_disasm.erl#L1293

fix_type_tagged_beam_register({tr, Reg, {TypeUnion, _Min, _Max}})
when is_tuple(TypeUnion) ->
{tr, Reg, TypeUnion};
fix_type_tagged_beam_register(Other) ->
Other.
Expand Down

0 comments on commit 0c8cd86

Please sign in to comment.