anchor.diff:  
   verify_call_args(_, 0, #vst{}) ->
       ok;
  -verify_call_args({f,Lbl}, Live, #vst{ft=Ft}=Vst) when is_integer(Live) ->
  +verify_call_args({f,Lbl}, Live, #vst{ft=Ft}=Vst) ->
       case Ft of
           #{ Lbl := FuncInfo } ->
               #{ arity := Live,
  
positive.code:     end;
  validate_instrs([I|Is], MFA, Offset, Vst0) ->
      validate_instrs(Is, MFA, Offset+1,
  	   try
  	       Vst = validate_mutation(I, Vst0),
  	       vi_safe(I, Vst)
  	   catch Error ->
  		   error({MFA,{I,Offset,Error}})
  	   end).
  
  %%%
  %%% vi_safe/2 handles instructions that will never throw an exception, and can
  %%% thus be used when the state is undecided in some way.
  %%%
  vi_safe({label,Lbl}, #vst{current=St0,
                            ref_ctr=Counter0,
                            branched=Branched0,
                            labels=Labels0}=Vst) ->
  
negative.code:     VrefB = get_reg_vref(RegB, Vst2),
      Vst = set_reg_vref(VrefB, RegA, Vst2),
      set_reg_vref(VrefA, RegB, Vst);
  vi({fmove,Src,{fr,_}=Dst}, Vst) ->
      assert_type(#t_float{}, Src, Vst),
      set_freg(Dst, Vst);
  vi({fmove,{fr,_}=Src,Dst}, Vst0) ->
      assert_freg_set(Src, Vst0),
      assert_fls(checked, Vst0),
      Vst = eat_heap_float(Vst0),
      create_term(#t_float{}, fmove, [], Dst, Vst);
  vi({kill,Reg}, Vst) ->
      create_tag(initialized, kill, [], Reg, Vst);
  vi({init,Reg}, Vst) ->
      create_tag(initialized, init, [], Reg, Vst);
  
  %%
  %% Matching and test instructions.
  %%
  
  vi({jump,{f,Lbl}}, Vst) ->
      assert_no_exception(Lbl),
  
      %% The next instruction is never executed.
      branch(Lbl, Vst, fun kill_state/1);
  vi({select_val,Src,{f,Fail},{list,Choices}}, Vst) ->
      assert_term(Src, Vst),
      assert_choices(Choices),
      validate_select_val(Fail, Choices, Src, Vst);
  vi({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({test,has_map_fields,{f,Lbl},Src,{list,List}}, Vst) ->
      verify_has_map_fields(Lbl, Src, List, Vst);
  vi({test,is_atom,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_atom{}, Src, Vst);
  vi({test,is_binary,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_bitstring{size_unit=8}, Src, Vst);
  vi({test,is_bitstr,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_bitstring{}, Src, Vst);
  vi({test,is_boolean,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, beam_types:make_boolean(), Src, Vst);
  vi({test,is_float,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_float{}, Src, Vst);
  vi({test,is_tuple,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_tuple{}, Src, Vst);
  vi({test,is_integer,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_integer{}, Src, Vst);
  vi({test,is_nonempty_list,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_cons{}, Src, Vst);
  vi({test,is_number,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, number, Src, Vst);
  vi({test,is_list,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_list{}, Src, Vst);
  vi({test,is_map,{f,Lbl},[Src]}, Vst) ->
      type_test(Lbl, #t_map{}, Src, Vst);
  vi({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({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({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({test,is_eq_exact,{f,Lbl},[Src,Val]=Ss}, Vst) ->
      assert_no_exception(Lbl),
      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({test,is_ne_exact,{f,Lbl},[Src,Val]=Ss}, Vst) ->
      assert_no_exception(Lbl),
      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);
  
  
  %%
  %% Simple getters that can't fail.
  %%
  
  vi({get_list,Src,D1,D2}, Vst0) ->
      assert_not_literal(Src),
      assert_type(#t_cons{}, Src, Vst0),
  
      SrcType = get_term_type(Src, Vst0),
      {HeadType, _, _} = beam_call_types:types(erlang, hd, [SrcType]),
      {TailType, _, _} = beam_call_types:types(erlang, tl, [SrcType]),
  
      Vst = extract_term(HeadType, get_hd, [Src], D1, Vst0),
      extract_term(TailType, get_tl, [Src], D2, Vst, Vst0);
  vi({get_hd,Src,Dst}, Vst) ->
      assert_not_literal(Src),
      assert_type(#t_cons{}, Src, Vst),
  
      SrcType = get_term_type(Src, Vst),
      {HeadType, _, _} = beam_call_types:types(erlang, hd, [SrcType]),
  
      extract_term(HeadType, get_hd, [Src], Dst, Vst);
  vi({get_tl,Src,Dst}, Vst) ->
      assert_not_literal(Src),
      assert_type(#t_cons{}, Src, Vst),
  
      SrcType = get_term_type(Src, Vst),
      {TailType, _, _} = beam_call_types:types(erlang, tl, [SrcType]),
  
      extract_term(TailType, get_tl, [Src], Dst, Vst);
  vi({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);
  
  %%
  %% Allocate, deallocate, et.al.
  %%
  
  vi({test_heap,Heap,Live}, Vst) ->
      test_heap(Heap, Live, Vst);
  vi({allocate,Stk,Live}, Vst) ->
      allocate(uninitialized, Stk, 0, Live, Vst);
  vi({allocate_heap,Stk,Heap,Live}, Vst) ->
      allocate(uninitialized, Stk, Heap, Live, Vst);
  vi({allocate_zero,Stk,Live}, Vst) ->
      allocate(initialized, Stk, 0, Live, Vst);
  vi({allocate_heap_zero,Stk,Heap,Live}, Vst) ->
      allocate(initialized, Stk, Heap, Live, Vst);
  vi({deallocate,StkSize}, #vst{current=#st{numy=StkSize}}=Vst) ->
      verify_no_ct(Vst),
      deallocate(Vst);
  vi({deallocate,_}, #vst{current=#st{numy=NumY}}) ->
      error({allocated,NumY});
  vi({trim,N,Remaining}, #vst{current=St0}=Vst) ->
      #st{numy=NumY} = St0,
      if
          N =< NumY, N+Remaining =:= NumY ->
              Vst#vst{current=trim_stack(N, 0, NumY, St0)};
          N > NumY; N+Remaining =/= NumY ->
              error({trim,N,Remaining,allocated,NumY})
      end;
  
  %%
  %% Term-building instructions
  %%
  
  vi({put_list,A,B,Dst}, Vst0) ->
      Vst = eat_heap(2, Vst0),
  
      Head = get_term_type(A, Vst),
      Tail = get_term_type(B, Vst),
  
      create_term(beam_types:make_cons(Head, Tail), put_list, [A, B], Dst, Vst);
  vi({put_tuple2,Dst,{list,Elements}}, Vst0) ->
      _ = [assert_term(El, Vst0) || El <- Elements],
      Size = length(Elements),
      Vst = eat_heap(Size+1, Vst0),
  