anchor.diff:      {TailType, _, _} = beam_call_types:types(erlang, tl, [SrcType]),
   
       extract_term(TailType, get_tl, [Src], Dst, Vst);
  -valfun_1({get_tuple_element,Src,N,Dst}, Vst) ->
  +vi_safe({get_tuple_element,Src,N,Dst}, Vst) ->
       Index = N+1,
       assert_not_literal(Src),
       assert_type(#t_tuple{size=Index}, Src, Vst),
       #t_tuple{elements=Es} = normalize(get_term_type(Src, Vst)),
       Type = beam_types:get_tuple_element(Index, Es),
       extract_term(Type, {bif,element}, [{integer,Index}, Src], Dst, Vst);
  -valfun_1({jump,{f,Lbl}}, Vst) ->
  +vi_safe({jump,{f,Lbl}}, Vst) ->
       branch(Lbl, Vst,
              fun(SuccVst) ->
                      %% The next instruction is never executed.
                      kill_state(SuccVst)
              end);
  -valfun_1(I, Vst0) ->
  +
  +vi_safe(return, Vst) ->
  +    assert_durable_term({x,0}, Vst),
  +    verify_return(Vst),
  +    kill_state(Vst);
  +
  +%%
  +%% Matching and test instructions.
  +%%
  +
  +vi_safe({select_val,Src,{f,Fail},{list,Choices}}, Vst) ->
  +    assert_term(Src, Vst),
  +    assert_choices(Choices),
  +    validate_select_val(Fail, Choices, Src, Vst);
  +vi_safe({select_tuple_arity,Tuple,{f,Fail},{list,Choices}}, Vst) ->
  +    assert_type(#t_tuple{}, Tuple, Vst),
  +    assert_arities(Choices),
  +    validate_select_tuple_arity(Fail, Choices, Tuple, Vst);
  +vi_safe({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) ->
  +    verify_has_map_fields(Lbl, Src, List, Vst);
  +vi_safe({test,is_atom,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_atom{}, Src, Vst);
  +vi_safe({test,is_binary,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_bitstring{size_unit=8}, Src, Vst);
  +vi_safe({test,is_bitstr,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_bitstring{}, Src, Vst);
  +vi_safe({test,is_boolean,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, beam_types:make_boolean(), Src, Vst);
  +vi_safe({test,is_float,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_float{}, Src, Vst);
  +vi_safe({test,is_tuple,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_tuple{}, Src, Vst);
  +vi_safe({test,is_integer,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_integer{}, Src, Vst);
  +vi_safe({test,is_nonempty_list,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_cons{}, Src, Vst);
  +vi_safe({test,is_number,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, number, Src, Vst);
  +vi_safe({test,is_list,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_list{}, Src, Vst);
  +vi_safe({test,is_map,{f,Lbl},[Src]}, Vst) ->
  +    type_test(Lbl, #t_map{}, Src, Vst);
  +vi_safe({test,is_nil,{f,Lbl},[Src]}, Vst) ->
  +    %% is_nil is an exact check against the 'nil' value, and should not be
  +    %% treated as a simple type test.
  +    assert_term(Src, Vst),
  +    branch(Lbl, Vst,
  +           fun(FailVst) ->
  +                   update_ne_types(Src, nil, FailVst)
  +           end,
  +           fun(SuccVst) ->
  +                   update_eq_types(Src, nil, SuccVst)
  +           end);
  +vi_safe({test,test_arity,{f,Lbl},[Tuple,Sz]}, Vst) when is_integer(Sz) ->
  +    assert_type(#t_tuple{}, Tuple, Vst),
  +    Type =  #t_tuple{exact=true,size=Sz},
  +    type_test(Lbl, Type, Tuple, Vst);
  +vi_safe({test,is_tagged_tuple,{f,Lbl},[Src,Sz,Atom]}, Vst) ->
  +    assert_term(Src, Vst),
  +    Es = #{ 1 => get_literal_type(Atom) },
  +    Type = #t_tuple{exact=true,size=Sz,elements=Es},
  +    type_test(Lbl, Type, Src, Vst);
  +vi_safe({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst) ->
  +    validate_src(Ss, Vst),
  +    branch(Lbl, Vst,
  +           fun(FailVst) ->
  +                   update_ne_types(Src, Val, FailVst)
  +           end,
  +           fun(SuccVst) ->
  +                   update_eq_types(Src, Val, SuccVst)
  +           end);
  +vi_safe({test,is_ne_exact,{f,Lbl},[Src,Val]=Ss}, Vst) ->
  +    validate_src(Ss, Vst),
  +    branch(Lbl, Vst,
  +           fun(FailVst) ->
  +                   update_eq_types(Src, Val, FailVst)
  +           end,
  +           fun(SuccVst) ->
  +                   update_ne_types(Src, Val, SuccVst)
  +           end);
  +%%
  +%% New bit syntax matching instructions.
  +%%
  +vi_safe({bs_start_match4,Fail,Live,Src,Dst}, Vst) ->
  +    validate_bs_start_match(Fail, Live, 0, Src, Dst, Vst);
  +vi_safe({test,bs_start_match3,{f,_}=Fail,Live,[Src],Dst}, Vst) ->
  +    validate_bs_start_match(Fail, Live, 0, Src, Dst, Vst);
  +vi_safe({test,bs_start_match2,{f,_}=Fail,Live,[Src,Slots],Dst}, Vst) ->
  +    validate_bs_start_match(Fail, Live, Slots, Src, Dst, Vst);
  +%%
  +%% Bit syntax positioning
  +%%
  +vi_safe({bs_save2,Ctx,SavePoint}, Vst) ->
  +    bsm_save(Ctx, SavePoint, Vst);
  +vi_safe({bs_restore2,Ctx,SavePoint}, Vst) ->
  +    bsm_restore(Ctx, SavePoint, Vst);
  +vi_safe({bs_get_position, Ctx, Dst, Live}, Vst0) ->
  +    assert_type(#t_bs_context{}, Ctx, Vst0),
  +    verify_live(Live, Vst0),
  +    verify_y_init(Vst0),
  +    Vst = prune_x_regs(Live, Vst0),
  +    create_term(#t_abstract{kind=ms_position}, bs_get_position, [Ctx],
  +                Dst, Vst, Vst0);
  +vi_safe({bs_set_position, Ctx, Pos}, Vst) ->
  +    assert_type(#t_bs_context{}, Ctx, Vst),
  +    assert_type(#t_abstract{kind=ms_position}, Pos, Vst),
  +    Vst;
  +%%
  +%% Bit syntax matching
  +%%
  +vi_safe({test,bs_match_string,{f,Fail},[Ctx,Rem,{string,String}]}, Vst) ->
  +    true = is_bitstring(String),                %Assertion.
  +    Stride = bit_size(String) + Rem,
  +    validate_bs_skip(Fail, Ctx, Stride, Vst);
  +vi_safe({test,bs_skip_bits2,{f,Fail},[Ctx,Size,Unit,_Flags]}, Vst) ->
  +    assert_term(Size, Vst),
  +
  +    Stride = case get_raw_type(Size, Vst) of
  +                 #t_integer{elements={Same,Same}} -> Same * Unit;
  +                 _ -> Unit
  +             end,
  +
  +    validate_bs_skip(Fail, Ctx, Stride, Vst);
  +vi_safe({test,bs_test_tail2,{f,Fail},[Ctx,_Size]}, Vst) ->
  +    assert_type(#t_bs_context{}, Ctx, Vst),
  +    branch(Fail, Vst, fun(V) -> V end);
  +vi_safe({test,bs_test_unit,{f,Fail},[Ctx,Unit]}, Vst) ->
  +    assert_type(#t_bs_context{}, Ctx, Vst),
  +    type_test(Fail, #t_bs_context{tail_unit=Unit}, Ctx, Vst);
  +vi_safe({test,bs_skip_utf8,{f,Fail},[Ctx,Live,_]}, Vst) ->
  +    validate_bs_skip(Fail, Ctx, 8, Live, Vst);
  +vi_safe({test,bs_skip_utf16,{f,Fail},[Ctx,Live,_]}, Vst) ->
  +    validate_bs_skip(Fail, Ctx, 16, Live, Vst);
  +vi_safe({test,bs_skip_utf32,{f,Fail},[Ctx,Live,_]}, Vst) ->
  +    validate_bs_skip(Fail, Ctx, 32, Live, Vst);
  +vi_safe({test,bs_get_integer2=Op,{f,Fail},Live,
  +          [Ctx,{integer,Size},Unit,{field_flags,Flags}],Dst},Vst) ->
  +    NumBits = Size * Unit,
  +    Type = case member(unsigned, Flags) of
  +               true when NumBits =< 64 ->
  +                   beam_types:make_integer(0, (1 bsl NumBits)-1);
  +               _ ->
  +                   %% Signed integer or way too large, don't bother.
  +                   #t_integer{}
  +           end,
  +    validate_bs_get(Op, Fail, Ctx, Live, NumBits, Type, Dst, Vst);
  +vi_safe({test,bs_get_integer2=Op,{f,Fail},Live,
  +          [Ctx,_Size,Unit,_Flags],Dst},Vst) ->
  +    validate_bs_get(Op, Fail, Ctx, Live, Unit, #t_integer{}, Dst, Vst);
  +vi_safe({test,bs_get_float2=Op,{f,Fail},Live,[Ctx,_,_,_],Dst}, Vst) ->
  +    validate_bs_get(Op, Fail, Ctx, Live, 1, #t_float{}, Dst, Vst);
  +vi_safe({test,bs_get_binary2=Op,{f,Fail},Live,[Ctx,_,Unit,_],Dst}, Vst) ->
  +    Type = #t_bitstring{size_unit=Unit},
  +    validate_bs_get(Op, Fail, Ctx, Live, Unit, Type, Dst, Vst);
  +vi_safe({test,bs_get_utf8=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
  +    Type = beam_types:make_integer(0, ?UNICODE_MAX),
  +    validate_bs_get(Op, Fail, Ctx, Live, 8, Type, Dst, Vst);
  +vi_safe({test,bs_get_utf16=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
  +    Type = beam_types:make_integer(0, ?UNICODE_MAX),
  +    validate_bs_get(Op, Fail, Ctx, Live, 16, Type, Dst, Vst);
  +vi_safe({test,bs_get_utf32=Op,{f,Fail},Live,[Ctx,_],Dst}, Vst) ->
  +    Type = beam_types:make_integer(0, ?UNICODE_MAX),
  +    validate_bs_get(Op, Fail, Ctx, Live, 32, Type, Dst, Vst);
  +
  +vi_safe({test,_Op,{f,Lbl},Src}, Vst) ->
  +    %% is_pid, is_reference, et cetera.
  +    validate_src(Src, Vst),
  +    branch(Lbl, Vst, fun(V) -> V end);
  +vi_safe({put_map_assoc=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) ->
  +    verify_put_map(Op, Fail, Src, Dst, Live, List, Vst);
  +vi_safe({put_map_exact=Op,{f,Fail},Src,Dst,Live,{list,List}}, Vst) ->
  +    verify_put_map(Op, Fail, Src, Dst, Live, List, Vst);
  +vi_safe({get_map_elements,{f,Fail},Src,{list,List}}, Vst) ->
  +    verify_get_map(Fail, Src, List, Vst);
  +vi_safe(I, Vst0) ->
       Vst = branch_exception(Vst0),
  -    valfun_2(I, Vst).
  +    vi_float(I, Vst).
   
   validate_var_info([{fun_type, Type} | Info], Reg, Vst0) ->
       %% Explicit type information inserted after make_fun2 instructions to mark
  
positive.code:         Type ->
              error({wrong_tag_type,Type})
      end;
  valfun_1({try_end,Reg}, #vst{current=#st{ct=[Tag|_]}}=Vst) ->
      case get_tag_type(Reg, Vst) of
          {trytag,_Fail}=Tag ->
              %% Kill the catch tag. Note that x registers and the receive marker
  
negative.code:     {HeadType, _, _} = beam_call_types:types(erlang, hd, [SrcType]),
  
      extract_term(HeadType, get_hd, [Src], Dst, Vst);
  vi_safe({get_tl,Src,Dst}, Vst) ->
      assert_not_literal(Src),
      assert_type(#t_cons{}, Src, Vst),
  
  