diff options
Diffstat (limited to 'lib/compiler/src/v3_codegen.erl')
-rw-r--r-- | lib/compiler/src/v3_codegen.erl | 30 |
1 files changed, 18 insertions, 12 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), |