diff options
Diffstat (limited to 'lib/compiler/src')
| -rw-r--r-- | lib/compiler/src/v3_codegen.erl | 30 | ||||
| -rw-r--r-- | lib/compiler/src/v3_kernel.erl | 8 | ||||
| -rw-r--r-- | lib/compiler/src/v3_life.erl | 26 | 
3 files changed, 25 insertions, 39 deletions
| diff --git a/lib/compiler/src/v3_codegen.erl b/lib/compiler/src/v3_codegen.erl index 4df1aadd0a..c2e0c2bd1a 100644 --- a/lib/compiler/src/v3_codegen.erl +++ b/lib/compiler/src/v3_codegen.erl @@ -151,6 +151,8 @@ cg({bif,Bif,As,Rs}, Le, Vdb, Bef, St) ->      bif_cg(Bif, As, Rs, Le, Vdb, Bef, St);  cg({gc_bif,Bif,As,Rs}, Le, Vdb, Bef, St) ->      gc_bif_cg(Bif, As, Rs, Le, Vdb, Bef, St); +cg({internal,Bif,As,Rs}, Le, Vdb, Bef, St) -> +    internal_cg(Bif, As, Rs, Le, Vdb, Bef, St);  cg({receive_loop,Te,Rvar,Rm,Tes,Rs}, Le, Vdb, Bef, St) ->      recv_loop_cg(Te, Rvar, Rm, Tes, Rs, Le, Vdb, Bef, St);  cg(receive_next, Le, Vdb, Bef, St) -> @@ -208,15 +210,10 @@ need_heap_1(#l{ke={set,_,Val}}, H) ->  		{tuple,Es} -> 1 + length(Es);  		_Other -> 0  	    end}; -need_heap_1(#l{ke={bif,dsetelement,_As,_Rs},i=I}, H) -> -    {need_heap_need(I, H),0}; -need_heap_1(#l{ke={bif,{make_fun,_,_,_,_},_As,_Rs},i=I}, H) -> -    {need_heap_need(I, H),0}; -need_heap_1(#l{ke={bif,bs_init_writable,_As,_Rs},i=I}, H) -> -    {need_heap_need(I, H),0};  need_heap_1(#l{ke={bif,_Bif,_As,_Rs}}, H) ->      {[],H};  need_heap_1(#l{i=I}, H) -> +    %% Call or call-like instruction such as set_tuple_element/3.      {need_heap_need(I, H),0}.  need_heap_need(_I, 0) -> []; @@ -1301,10 +1298,10 @@ trap_bif(erlang, group_leader, 2) -> true;  trap_bif(erlang, exit, 2) -> true;  trap_bif(_, _, _) -> false. -%% bif_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) -> +%% internal_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) ->  %%      {[Ainstr],StackReg,State}. -bif_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) -> +internal_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) ->      [Src] = cg_reg_args([Src0], Bef),      case is_register(Src) of  	false -> @@ -1312,25 +1309,34 @@ bif_cg(bs_context_to_binary=Instr, [Src0], [], Le, Vdb, Bef, St0) ->  	true ->  	    {[{Instr,Src}],clear_dead(Bef, Le#l.i, Vdb), St0}      end; -bif_cg(dsetelement, [Index0,Tuple0,New0], _Rs, Le, Vdb, Bef, St0) -> +internal_cg(dsetelement, [Index0,Tuple0,New0], _Rs, Le, Vdb, Bef, St0) ->      [New,Tuple,{integer,Index1}] = cg_reg_args([New0,Tuple0,Index0], Bef),      Index = Index1-1,      {[{set_tuple_element,New,Tuple,Index}],       clear_dead(Bef, Le#l.i, Vdb), St0}; -bif_cg({make_fun,Func,Arity,Index,Uniq}, As, Rs, Le, Vdb, Bef, St0) -> +internal_cg(make_fun, [Func0,Arity0|As], Rs, Le, Vdb, Bef, St0) ->      %% This behaves more like a function call. +    {atom,Func} = Func0, +    {integer,Arity} = Arity0,      {Sis,Int} = cg_setup_call(As, Bef, Le#l.i, Vdb),      Reg = load_vars(Rs, clear_regs(Int#sr.reg)),      {FuncLbl,St1} = local_func_label(Func, Arity, St0), -    MakeFun = {make_fun2,{f,FuncLbl},Index,Uniq,length(As)}, +    MakeFun = {make_fun2,{f,FuncLbl},0,0,length(As)},      {Sis ++ [MakeFun],       clear_dead(Int#sr{reg=Reg}, Le#l.i, Vdb),       St1}; -bif_cg(bs_init_writable=I, As, Rs, Le, Vdb, Bef, St) -> +internal_cg(bs_init_writable=I, As, Rs, Le, Vdb, Bef, St) ->      %% This behaves like a function call.      {Sis,Int} = cg_setup_call(As, Bef, Le#l.i, Vdb),      Reg = load_vars(Rs, clear_regs(Int#sr.reg)),      {Sis++[I],clear_dead(Int#sr{reg=Reg}, Le#l.i, Vdb),St}; +internal_cg(raise, As, Rs, Le, Vdb, Bef, St) -> +    %% raise can be treated like a guard BIF. +    bif_cg(raise, As, Rs, Le, Vdb, Bef, St). + +%% bif_cg(Bif, [Arg], [Ret], Le, Vdb, StackReg, State) -> +%%      {[Ainstr],StackReg,State}. +  bif_cg(Bif, As, [{var,V}], Le, Vdb, Bef, St0) ->      Ars = cg_reg_args(As, Bef), diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl index e3103e040e..859f110a53 100644 --- a/lib/compiler/src/v3_kernel.erl +++ b/lib/compiler/src/v3_kernel.erl @@ -1791,13 +1791,9 @@ uexpr(#ifun{anno=A,vars=Vs,body=B0}, {break,Rs}, St0) ->  	end,      Fun = #k_fdef{anno=#k{us=[],ns=[],a=A},func=Fname,arity=Arity,  		  vars=Vs ++ Fvs,body=B1}, -    %% Set dummy values for Index and Uniq -- the real values will -    %% be assigned by beam_asm. -    Index = Uniq = 0,      {#k_bif{anno=#k{us=Free,ns=lit_list_vars(Rs),a=A}, - 	    op=#k_internal{name=make_fun,arity=length(Free)+3}, - 	    args=[#k_atom{val=Fname},#k_int{val=Arity}, - 		  #k_int{val=Index},#k_int{val=Uniq}|Fvs], +	    op=#k_internal{name=make_fun,arity=length(Free)+2}, +	    args=[#k_atom{val=Fname},#k_int{val=Arity}|Fvs],   	    ret=Rs},       Free,add_local_function(Fun, St)};  uexpr(Lit, {break,Rs0}, St0) -> diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl index 65c2735a4c..4337ec732c 100644 --- a/lib/compiler/src/v3_life.erl +++ b/lib/compiler/src/v3_life.erl @@ -211,7 +211,6 @@ body_try(#k_try{anno=A,arg=Ka,vars=Vs,body=Kb,evars=Evs,handler=Kh,ret=Rs},         i=I,vdb=Tdb1,a=A#k.a}.  %% call_op(Op) -> Op. -%% bif_op(Op) -> Op.  %% test_op(Op) -> Op.  %%  Do any necessary name translations here to munge into beam format. @@ -219,28 +218,14 @@ call_op(#k_local{name=N}) -> N;  call_op(#k_remote{mod=M,name=N}) -> {remote,atomic(M),atomic(N)};  call_op(Other) -> variable(Other). -bif_op(#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=N}}) -> N; -bif_op(#k_internal{name=N}) -> N. -  test_op(#k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=N}}) -> N.  %% k_bif(Anno, Op, [Arg], [Ret], Vdb) -> Expr. -%%  Build bifs, do special handling of internal some calls. - -k_bif(_A, #k_internal{name=dsetelement,arity=3}, As, []) -> -    {bif,dsetelement,atomic_list(As),[]}; -k_bif(_A, #k_internal{name=bs_context_to_binary=Op,arity=1}, As, []) -> -    {bif,Op,atomic_list(As),[]}; -k_bif(_A, #k_internal{name=bs_init_writable=Op,arity=1}, As, Rs) -> -    {bif,Op,atomic_list(As),var_list(Rs)}; -k_bif(_A, #k_internal{name=make_fun}, -      [#k_atom{val=Fun},#k_int{val=Arity}, -       #k_int{val=Index},#k_int{val=Uniq}|Free], -      Rs) -> -    {bif,{make_fun,Fun,Arity,Index,Uniq},var_list(Free),var_list(Rs)}; -k_bif(_A, Op, As, Rs) -> -    %% The general case. -    Name = bif_op(Op), +%%  Build bifs. + +k_bif(_A, #k_internal{name=Name}, As, Rs) -> +    {internal,Name,atomic_list(As),var_list(Rs)}; +k_bif(_A, #k_remote{mod=#k_atom{val=erlang},name=#k_atom{val=Name}}, As, Rs) ->      Ar = length(As),      case is_gc_bif(Name, Ar) of  	false -> @@ -390,7 +375,6 @@ is_gc_bif(node, 0) -> false;  is_gc_bif(node, 1) -> false;  is_gc_bif(element, 2) -> false;  is_gc_bif(get, 1) -> false; -is_gc_bif(raise, 2) -> false;  is_gc_bif(tuple_size, 1) -> false;  is_gc_bif(Bif, Arity) ->      not (erl_internal:bool_op(Bif, Arity) orelse | 
