mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-31 17:10:14 +02:00
* 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:
parent
720ac63a28
commit
d311881b34
@ -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(
|
||||||
|
Loading…
Reference in New Issue
Block a user