* extract calculation of unit init/fini entries into separate method get_init_final_list() so that it can be used by the AVR code as well

git-svn-id: trunk@36257 -
This commit is contained in:
svenbarth 2017-05-19 16:12:22 +00:00
parent 720ac63a28
commit d311881b34

View File

@ -28,11 +28,21 @@ interface
uses uses
cclasses,globtype, cclasses,globtype,
fmodule,
aasmdata, aasmdata,
node,nbas,symtype,symsym,symconst,symdef; node,nbas,symtype,symsym,symconst,symdef;
type type
tinitfinalentry = record
initfunc : TSymStr;
finifunc : TSymStr;
initpd : tprocdef;
finipd : tprocdef;
module : tmodule;
end;
pinitfinalentry = ^tinitfinalentry;
tnodeutils = class tnodeutils = class
class function call_fail_node:tnode; virtual; class function call_fail_node:tnode; virtual;
class function initialize_data_node(p:tnode; force: boolean):tnode; virtual; class function initialize_data_node(p:tnode; force: boolean):tnode; virtual;
@ -103,6 +113,9 @@ interface
protected protected
class procedure InsertRuntimeInits(const prefix:string;list:TLinkedList;unitflag:cardinal); virtual; class procedure InsertRuntimeInits(const prefix:string;list:TLinkedList;unitflag:cardinal); virtual;
class procedure InsertRuntimeInitsTablesTable(const prefix,tablename:string;unitflag:cardinal); virtual; class procedure InsertRuntimeInitsTablesTable(const prefix,tablename:string;unitflag:cardinal); virtual;
class function get_init_final_list: tfplist;
class procedure release_init_final_list(list:tfplist);
public public
class procedure InsertThreadvarTablesTable; virtual; class procedure InsertThreadvarTablesTable; virtual;
class procedure InsertThreadvars; virtual; class procedure InsertThreadvars; virtual;
@ -133,7 +146,7 @@ implementation
uses uses
verbose,version,globals,cutils,constexp,compinnr, verbose,version,globals,cutils,constexp,compinnr,
systems,procinfo,fmodule,pparautl, systems,procinfo,pparautl,
aasmbase,aasmtai,aasmcnst, aasmbase,aasmtai,aasmcnst,
symbase,symtable,defutil, symbase,symtable,defutil,
nadd,ncal,ncnv,ncon,nflw,ninl,nld,nmem,nutils, nadd,ncal,ncnv,ncon,nflw,ninl,nld,nmem,nutils,
@ -890,51 +903,128 @@ implementation
end; end;
class procedure tnodeutils.InsertInitFinalTable; class function tnodeutils.get_init_final_list:tfplist;
var
hp : tused_unit;
unitinits : ttai_typedconstbuilder;
count : aint;
tablecountplaceholder: ttypedconstplaceholder;
nameinit,namefini : TSymStr;
tabledef: tdef;
procedure write_struct_inits(u: tmodule); procedure append_struct_inits(u:tmodule);
var var
i: integer; i : integer;
structlist: TFPList; structlist : tfplist;
pd: tprocdef; pd : tprocdef;
entry : pinitfinalentry;
begin begin
structlist := TFPList.Create; structlist:=tfplist.Create;
if assigned(u.globalsymtable) then if assigned(u.globalsymtable) then
u.globalsymtable.DefList.ForEachCall(@AddToStructInits,structlist); u.globalsymtable.DefList.ForEachCall(@AddToStructInits,structlist);
u.localsymtable.DefList.ForEachCall(@AddToStructInits,structlist); u.localsymtable.DefList.ForEachCall(@AddToStructInits,structlist);
{ write structures } { write structures }
for i:=0 to structlist.Count-1 do for i:=0 to structlist.Count-1 do
begin begin
new(entry);
entry^.module:=u;
pd:=tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_constructor); pd:=tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_constructor);
if assigned(pd) then if assigned(pd) then
begin begin
unitinits.emit_procdef_const(pd); entry^.initfunc:=pd.mangledname;
if u<>current_module then entry^.initpd:=pd;
current_module.addimportedsym(pd.procsym);
end end
else else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype); begin
entry^.initfunc:='';
entry^.initpd:=nil;
end;
pd := tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_destructor); pd := tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_destructor);
if assigned(pd) then if assigned(pd) then
begin begin
unitinits.emit_procdef_const(pd); entry^.finifunc:=pd.mangledname;
if u<>current_module then entry^.finipd:=pd;
current_module.addimportedsym(pd.procsym);
end end
else else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype); begin
inc(count); entry^.finifunc:='';
entry^.finipd:=nil;
end;
if assigned(entry^.finipd) or assigned(entry^.initpd) then
result.add(entry)
else
{ AddToStructInits only adds structs that have either a class constructor or destructor or both }
internalerror(2017051902);
end; end;
structlist.free; structlist.free;
end; end;
var
hp : tused_unit;
entry : pinitfinalentry;
begin
result:=tfplist.create;
hp:=tused_unit(usedunits.first);
while assigned(hp) do
begin
{ insert class constructors/destructors of the unit }
if (hp.u.flags and uf_classinits) <> 0 then
append_struct_inits(hp.u);
if (hp.u.flags and (uf_init or uf_finalize))<>0 then
begin
new(entry);
entry^.module:=hp.u;
entry^.initpd:=nil;
entry^.finipd:=nil;
if (hp.u.flags and uf_init)<>0 then
entry^.initfunc:=make_mangledname('INIT$',hp.u.globalsymtable,'')
else
entry^.initfunc:='';
if (hp.u.flags and uf_finalize)<>0 then
entry^.finifunc:=make_mangledname('FINALIZE$',hp.u.globalsymtable,'')
else
entry^.finifunc:='';
result.add(entry);
end;
hp:=tused_unit(hp.next);
end;
if (current_module.flags and uf_classinits) <> 0 then
append_struct_inits(current_module);
{ Insert initialization/finalization of the program }
if (current_module.flags and (uf_init or uf_finalize))<>0 then
begin
new(entry);
entry^.module:=current_module;
entry^.initpd:=nil;
entry^.finipd:=nil;
if (current_module.flags and uf_init)<>0 then
entry^.initfunc:=make_mangledname('INIT$',current_module.localsymtable,'')
else
entry^.initfunc:='';
if (current_module.flags and uf_finalize)<>0 then
entry^.finifunc:=make_mangledname('FINALIZE$',current_module.localsymtable,'')
else
entry^.finifunc:='';
result.add(entry);
end;
end;
class procedure tnodeutils.release_init_final_list(list:tfplist);
var
i : longint;
begin
if not assigned(list) then
internalerror(2017051901);
for i:=0 to list.count-1 do
dispose(pinitfinalentry(list[i]));
list.free;
end;
class procedure tnodeutils.InsertInitFinalTable;
var
i : longint;
unitinits : ttai_typedconstbuilder;
nameinit,namefini : TSymStr;
tabledef: tdef;
entries : tfplist;
entry : pinitfinalentry;
procedure add_initfinal_import(symtable:tsymtable); procedure add_initfinal_import(symtable:tsymtable);
var var
i,j : longint; i,j : longint;
@ -979,72 +1069,65 @@ implementation
unitinits.begin_anonymous_record('',default_settings.packrecords,sizeof(pint), unitinits.begin_anonymous_record('',default_settings.packrecords,sizeof(pint),
targetinfos[target_info.system]^.alignment.recordalignmin, targetinfos[target_info.system]^.alignment.recordalignmin,
targetinfos[target_info.system]^.alignment.maxCrecordalign); targetinfos[target_info.system]^.alignment.maxCrecordalign);
{ placeholder for tablecount }
tablecountplaceholder:=unitinits.emit_placeholder(aluuinttype); entries:=get_init_final_list;
{ tablecount }
unitinits.emit_ord_const(entries.count,aluuinttype);
{ initcount (initialised at run time } { initcount (initialised at run time }
unitinits.emit_ord_const(0,aluuinttype); unitinits.emit_ord_const(0,aluuinttype);
count:=0;
hp:=tused_unit(usedunits.first); for i:=0 to entries.count-1 do
while assigned(hp) do
begin begin
{ insert class constructors/destructors of the unit } entry:=pinitfinalentry(entries[i]);
if (hp.u.flags and uf_classinits) <> 0 then if assigned(entry^.initpd) or assigned(entry^.finipd) then
write_struct_inits(hp.u); begin
{ call the unit init code and make it external } if assigned(entry^.initpd) then
if (hp.u.flags and (uf_init or uf_finalize))<>0 then begin
unitinits.emit_procdef_const(entry^.initpd);
if entry^.module<>current_module then
current_module.addimportedsym(entry^.initpd.procsym);
end
else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
if assigned(entry^.finipd) then
begin
unitinits.emit_procdef_const(entry^.finipd);
if entry^.module<>current_module then
current_module.addimportedsym(entry^.finipd.procsym);
end
else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
end
else
begin begin
if count=high(aint) then
Message1(cg_f_max_units_reached,tostr(count));
nameinit:=''; nameinit:='';
namefini:=''; namefini:='';
if (hp.u.flags and uf_init)<>0 then if entry^.initfunc<>'' then
begin begin
nameinit:=make_mangledname('INIT$',hp.u.globalsymtable,''); nameinit:=entry^.initfunc;
unitinits.emit_tai( unitinits.emit_tai(
Tai_const.Createname(nameinit,AT_FUNCTION,0), Tai_const.Createname(nameinit,AT_FUNCTION,0),
voidcodepointertype); voidcodepointertype);
end end
else else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype); unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
if (hp.u.flags and uf_finalize)<>0 then if entry^.finifunc<>'' then
begin begin
namefini:=make_mangledname('FINALIZE$',hp.u.globalsymtable,''); namefini:=entry^.finifunc;
unitinits.emit_tai( unitinits.emit_tai(
Tai_const.Createname(namefini,AT_FUNCTION,0), Tai_const.Createname(namefini,AT_FUNCTION,0),
voidcodepointertype) voidcodepointertype);
end end
else else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype); unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
add_initfinal_import(hp.u.localsymtable); if entry^.module<>current_module then
inc(count); add_initfinal_import(entry^.module.localsymtable);
end; end;
hp:=tused_unit(hp.next);
end; end;
{ insert class constructors/destructor of the program }
if (current_module.flags and uf_classinits) <> 0 then
write_struct_inits(current_module);
{ Insert initialization/finalization of the program }
if (current_module.flags and (uf_init or uf_finalize))<>0 then
begin
if (current_module.flags and uf_init)<>0 then
unitinits.emit_tai(
Tai_const.Createname(make_mangledname('INIT$',current_module.localsymtable,''),AT_FUNCTION,0),
voidcodepointertype)
else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
if (current_module.flags and uf_finalize)<>0 then
unitinits.emit_tai(
Tai_const.Createname(make_mangledname('FINALIZE$',current_module.localsymtable,''),AT_FUNCTION,0),
voidcodepointertype)
else
unitinits.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype);
inc(count);
end;
{ fill in tablecount }
tablecountplaceholder.replace(tai_const.Create_aint(count),aluuinttype);
tablecountplaceholder.free;
{ Add to data segment }
release_init_final_list(entries);
{ Add to data segment }
tabledef:=unitinits.end_anonymous_record; tabledef:=unitinits.end_anonymous_record;
current_asmdata.asmlists[al_globals].concatlist( current_asmdata.asmlists[al_globals].concatlist(
unitinits.get_final_asmlist( unitinits.get_final_asmlist(