diff options
Diffstat (limited to 'lib/compiler/src')
-rw-r--r-- | lib/compiler/src/beam_validator.erl | 26 | ||||
-rw-r--r-- | lib/compiler/src/sys_core_fold.erl | 7 | ||||
-rw-r--r-- | lib/compiler/src/v3_core.erl | 36 |
3 files changed, 38 insertions, 31 deletions
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl index a1b71251b7..a0eef826ce 100644 --- a/lib/compiler/src/beam_validator.erl +++ b/lib/compiler/src/beam_validator.erl @@ -451,6 +451,19 @@ valfun_1({try_case,Reg}, #vst{current=#st{ct=[Fail|Fails]}}=Vst0) -> Type -> error({bad_type,Type}) end; +valfun_1({get_list,Src,D1,D2}, Vst0) -> + assert_type(cons, Src, Vst0), + Vst = set_type_reg(term, Src, D1, Vst0), + set_type_reg(term, Src, D2, Vst); +valfun_1({get_hd,Src,Dst}, Vst) -> + assert_type(cons, Src, Vst), + set_type_reg(term, Src, Dst, Vst); +valfun_1({get_tl,Src,Dst}, Vst) -> + assert_type(cons, Src, Vst), + set_type_reg(term, Src, Dst, Vst); +valfun_1({get_tuple_element,Src,I,Dst}, Vst) -> + assert_type({tuple_element,I+1}, Src, Vst), + set_type_reg(term, Src, Dst, Vst); valfun_1(I, Vst) -> valfun_2(I, Vst). @@ -609,19 +622,6 @@ valfun_4({select_val,Src,{f,Fail},{list,Choices}}, Vst) -> valfun_4({select_tuple_arity,Tuple,{f,Fail},{list,Choices}}, Vst) -> assert_type(tuple, Tuple, Vst), kill_state(branch_arities(Choices, Tuple, branch_state(Fail, Vst))); -valfun_4({get_list,Src,D1,D2}, Vst0) -> - assert_type(cons, Src, Vst0), - Vst = set_type_reg(term, Src, D1, Vst0), - set_type_reg(term, Src, D2, Vst); -valfun_4({get_hd,Src,Dst}, Vst) -> - assert_type(cons, Src, Vst), - set_type_reg(term, Src, Dst, Vst); -valfun_4({get_tl,Src,Dst}, Vst) -> - assert_type(cons, Src, Vst), - set_type_reg(term, Src, Dst, Vst); -valfun_4({get_tuple_element,Src,I,Dst}, Vst) -> - assert_type({tuple_element,I+1}, Src, Vst), - set_type_reg(term, Src, Dst, Vst); %% New bit syntax matching instructions. valfun_4({test,bs_start_match2,{f,Fail},Live,[Ctx,NeedSlots],Ctx}, Vst0) -> diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl index 0e4f2d5cb8..3a65b40fa5 100644 --- a/lib/compiler/src/sys_core_fold.erl +++ b/lib/compiler/src/sys_core_fold.erl @@ -115,13 +115,6 @@ module(#c_module{defs=Ds0}=Mod, Opts) -> {ok,Mod#c_module{defs=Ds1},get_warnings()}. function_1({#c_var{name={F,Arity}}=Name,B0}) -> - %% Find a suitable starting value for the variable counter. Note - %% that this pass assumes that new_var_name/1 returns a variable - %% name distinct from any variable used in the entire body of - %% the function. We use integers as variable names to avoid - %% filling up the atom table when compiling huge functions. - Count = cerl_trees:next_free_variable_name(B0), - put(new_var_num, Count), try %% Find a suitable starting value for the variable %% counter. Note that this pass assumes that new_var_name/1 diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl index 0196e7fdfd..3b746ab5bf 100644 --- a/lib/compiler/src/v3_core.erl +++ b/lib/compiler/src/v3_core.erl @@ -1501,7 +1501,7 @@ bc_initial_size(E0, Q, St0) -> end. bc_elem_size({bin,_,El}, St0) -> - case bc_elem_size_1(El, 0, []) of + case bc_elem_size_1(El, ordsets:new(), 0, []) of {Bits,[]} -> {#c_literal{val=Bits},[],[],St0}; {Bits,Vars0} -> @@ -1515,19 +1515,33 @@ bc_elem_size(_, _) -> throw(impossible). bc_elem_size_1([{bin_element,_,{string,_,String},{integer,_,N},_}=El|Es], - Bits, Vars) -> + DefVars, Bits, SizeVars) -> U = get_unit(El), - bc_elem_size_1(Es, Bits+U*N*length(String), Vars); -bc_elem_size_1([{bin_element,_,_,{integer,_,N},_}=El|Es], Bits, Vars) -> + bc_elem_size_1(Es, DefVars, Bits+U*N*length(String), SizeVars); +bc_elem_size_1([{bin_element,_,Expr,{integer,_,N},_}=El|Es], + DefVars0, Bits, SizeVars) -> U = get_unit(El), - bc_elem_size_1(Es, Bits+U*N, Vars); -bc_elem_size_1([{bin_element,_,_,{var,_,Var},_}=El|Es], Bits, Vars) -> - U = get_unit(El), - bc_elem_size_1(Es, Bits, [{U,#c_var{name=Var}}|Vars]); -bc_elem_size_1([_|_], _, _) -> + DefVars = bc_elem_size_def_var(Expr, DefVars0), + bc_elem_size_1(Es, DefVars, Bits+U*N, SizeVars); +bc_elem_size_1([{bin_element,_,Expr,{var,_,Src},_}=El|Es], + DefVars0, Bits, SizeVars) -> + case ordsets:is_element(Src, DefVars0) of + false -> + U = get_unit(El), + DefVars = bc_elem_size_def_var(Expr, DefVars0), + bc_elem_size_1(Es, DefVars, Bits, [{U,#c_var{name=Src}}|SizeVars]); + true -> + throw(impossible) + end; +bc_elem_size_1([_|_], _, _, _) -> throw(impossible); -bc_elem_size_1([], Bits, Vars) -> - {Bits,Vars}. +bc_elem_size_1([], _DefVars, Bits, SizeVars) -> + {Bits,SizeVars}. + +bc_elem_size_def_var({var,_,Var}, DefVars) -> + ordsets:add_element(Var, DefVars); +bc_elem_size_def_var(_Expr, DefVars) -> + DefVars. bc_elem_size_combine([{U,V}|T], U, UVars, Acc) -> bc_elem_size_combine(T, U, [V|UVars], Acc); |