mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-10-01 10:40:59 +02:00
* migrated gen_initialize_code and gen_finalize_code from ncgutil to
hlcgobj so it can be overridden with target-specific code (e.g., the JVM target has to add initialisation code to allocate regular arrays and records in constructors and unit/program initialisation) git-svn-id: branches/jvmbackend@18452 -
This commit is contained in:
parent
53e6853667
commit
f57e9778d4
@ -400,6 +400,9 @@ unit hlcg2ll;
|
||||
|
||||
procedure gen_load_loc_cgpara(list: TAsmList; vardef: tdef; const l: tlocation; const cgpara: tcgpara); override;
|
||||
procedure gen_load_cgpara_loc(list: TAsmList; vardef: tdef; const para: TCGPara; var destloc: tlocation; reusepara: boolean); override;
|
||||
|
||||
protected
|
||||
procedure initialize_regvars(p: TObject; arg: pointer); override;
|
||||
end;
|
||||
|
||||
|
||||
@ -1207,4 +1210,20 @@ procedure thlcg2ll.a_loadaddr_ref_reg(list: TAsmList; fromsize, tosize: tdef; co
|
||||
ncgutil.gen_load_cgpara_loc(list, vardef, para, destloc, reusepara);
|
||||
end;
|
||||
|
||||
procedure thlcg2ll.initialize_regvars(p: TObject; arg: pointer);
|
||||
begin
|
||||
if (tsym(p).typ=staticvarsym) and
|
||||
{ not yet handled via tlhcgobj... }
|
||||
(tstaticvarsym(p).initialloc.loc=LOC_CMMREGISTER) then
|
||||
begin
|
||||
{ clear the whole register }
|
||||
cg.a_opmm_reg_reg(TAsmList(arg),OP_XOR,reg_cgsize(tstaticvarsym(p).initialloc.register),
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
nil);
|
||||
end
|
||||
else
|
||||
inherited initialize_regvars(p, arg);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -447,6 +447,24 @@ unit hlcgobj;
|
||||
procedure gen_proc_symbol(list:TAsmList);virtual;
|
||||
procedure gen_proc_symbol_end(list:TAsmList);virtual;
|
||||
|
||||
procedure gen_initialize_code(list:TAsmList);virtual;
|
||||
procedure gen_finalize_code(list:TAsmList);virtual;
|
||||
protected
|
||||
{ helpers called by gen_initialize_code/gen_finalize_code }
|
||||
procedure inittempvariables(list:TAsmList);virtual;
|
||||
procedure initialize_data(p:TObject;arg:pointer);virtual;
|
||||
procedure finalizetempvariables(list:TAsmList);virtual;
|
||||
procedure initialize_regvars(p:TObject;arg:pointer);virtual;
|
||||
procedure finalize_sym(asmlist:TAsmList;sym:tsym);virtual;
|
||||
{ generates the code for finalisation of local variables }
|
||||
procedure finalize_local_vars(p:TObject;arg:pointer);virtual;
|
||||
{ generates the code for finalization of static symtable and
|
||||
all local (static) typed consts }
|
||||
procedure finalize_static_data(p:TObject;arg:pointer);virtual;
|
||||
{ generates the code for decrementing the reference count of parameters }
|
||||
procedure final_paras(p:TObject;arg:pointer);
|
||||
public
|
||||
|
||||
procedure gen_load_para_value(list:TAsmList);virtual;
|
||||
protected
|
||||
{ helpers called by gen_load_para_value }
|
||||
@ -487,10 +505,11 @@ implementation
|
||||
uses
|
||||
globals,options,systems,
|
||||
fmodule,export,
|
||||
verbose,defutil,paramgr,symsym,
|
||||
ncon,
|
||||
verbose,defutil,paramgr,
|
||||
symbase,symsym,
|
||||
ncon,nld,pass_1,pass_2,
|
||||
cpuinfo,cgobj,tgobj,cutils,procinfo,
|
||||
ncgutil;
|
||||
ncgutil,ngenutil;
|
||||
|
||||
|
||||
procedure destroy_hlcodegen;
|
||||
@ -1926,6 +1945,298 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.gen_initialize_code(list: TAsmList);
|
||||
begin
|
||||
{ initialize local data like ansistrings }
|
||||
case current_procinfo.procdef.proctypeoption of
|
||||
potype_unitinit:
|
||||
begin
|
||||
{ this is also used for initialization of variables in a
|
||||
program which does not have a globalsymtable }
|
||||
if assigned(current_module.globalsymtable) then
|
||||
TSymtable(current_module.globalsymtable).SymList.ForEachCall(@initialize_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_regvars,list);
|
||||
end;
|
||||
{ units have seperate code for initilization and finalization }
|
||||
potype_unitfinalize: ;
|
||||
{ program init/final is generated in separate procedure }
|
||||
potype_proginit:
|
||||
begin
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_regvars,list);
|
||||
end;
|
||||
else
|
||||
current_procinfo.procdef.localst.SymList.ForEachCall(@initialize_data,list);
|
||||
end;
|
||||
|
||||
{ initialisizes temp. ansi/wide string data }
|
||||
inittempvariables(list);
|
||||
|
||||
{$ifdef OLDREGVARS}
|
||||
load_regvars(list,nil);
|
||||
{$endif OLDREGVARS}
|
||||
end;
|
||||
|
||||
procedure thlcgobj.gen_finalize_code(list: TAsmList);
|
||||
begin
|
||||
{$ifdef OLDREGVARS}
|
||||
cleanup_regvars(list);
|
||||
{$endif OLDREGVARS}
|
||||
|
||||
{ finalize temporary data }
|
||||
finalizetempvariables(list);
|
||||
|
||||
{ finalize local data like ansistrings}
|
||||
case current_procinfo.procdef.proctypeoption of
|
||||
potype_unitfinalize:
|
||||
begin
|
||||
{ this is also used for initialization of variables in a
|
||||
program which does not have a globalsymtable }
|
||||
if assigned(current_module.globalsymtable) then
|
||||
TSymtable(current_module.globalsymtable).SymList.ForEachCall(@finalize_static_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@finalize_static_data,list);
|
||||
end;
|
||||
{ units/progs have separate code for initialization and finalization }
|
||||
potype_unitinit: ;
|
||||
{ program init/final is generated in separate procedure }
|
||||
potype_proginit: ;
|
||||
else
|
||||
current_procinfo.procdef.localst.SymList.ForEachCall(@finalize_local_vars,list);
|
||||
end;
|
||||
|
||||
{ finalize paras data }
|
||||
if assigned(current_procinfo.procdef.parast) and
|
||||
not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||
current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
|
||||
end;
|
||||
|
||||
procedure thlcgobj.inittempvariables(list: TAsmList);
|
||||
var
|
||||
hp : ptemprecord;
|
||||
href : treference;
|
||||
begin
|
||||
hp:=tg.templist;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if assigned(hp^.def) and
|
||||
is_managed_type(hp^.def) then
|
||||
begin
|
||||
reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint));
|
||||
g_initialize(list,hp^.def,href);
|
||||
end;
|
||||
hp:=hp^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.initialize_data(p: TObject; arg: pointer);
|
||||
var
|
||||
OldAsmList : TAsmList;
|
||||
hp : tnode;
|
||||
begin
|
||||
if (tsym(p).typ = localvarsym) and
|
||||
{ local (procedure or unit) variables only need initialization if
|
||||
they are used }
|
||||
((tabstractvarsym(p).refs>0) or
|
||||
{ managed return symbols must be inited }
|
||||
((tsym(p).typ=localvarsym) and (vo_is_funcret in tlocalvarsym(p).varoptions))
|
||||
) and
|
||||
not(vo_is_typed_const in tabstractvarsym(p).varoptions) and
|
||||
not(vo_is_external in tabstractvarsym(p).varoptions) and
|
||||
(is_managed_type(tabstractvarsym(p).vardef) or
|
||||
((m_iso in current_settings.modeswitches) and (tabstractvarsym(p).vardef.typ=filedef))
|
||||
) then
|
||||
begin
|
||||
OldAsmList:=current_asmdata.CurrAsmList;
|
||||
current_asmdata.CurrAsmList:=TAsmList(arg);
|
||||
hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner));
|
||||
firstpass(hp);
|
||||
secondpass(hp);
|
||||
hp.free;
|
||||
current_asmdata.CurrAsmList:=OldAsmList;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.finalizetempvariables(list: TAsmList);
|
||||
var
|
||||
hp : ptemprecord;
|
||||
href : treference;
|
||||
begin
|
||||
hp:=tg.templist;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if assigned(hp^.def) and
|
||||
is_managed_type(hp^.def) then
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint));
|
||||
g_finalize(list,hp^.def,href);
|
||||
end;
|
||||
hp:=hp^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.initialize_regvars(p: TObject; arg: pointer);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
if (tsym(p).typ=staticvarsym) then
|
||||
begin
|
||||
{ Static variables can have the initialloc only set to LOC_CxREGISTER
|
||||
or LOC_INVALID, for explaination see gen_alloc_symtable (PFV) }
|
||||
case tstaticvarsym(p).initialloc.loc of
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
if (tstaticvarsym(p).initialloc.size in [OS_64,OS_S64]) then
|
||||
cg64.a_load64_const_reg(TAsmList(arg),0,tstaticvarsym(p).initialloc.register64)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
a_load_const_reg(TAsmList(arg),tstaticvarsym(p).vardef,0,
|
||||
tstaticvarsym(p).initialloc.register);
|
||||
end;
|
||||
(*
|
||||
LOC_CMMREGISTER :
|
||||
{ clear the whole register }
|
||||
cg.a_opmm_reg_reg(TAsmList(arg),OP_XOR,reg_cgsize(tstaticvarsym(p).initialloc.register),
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
nil);
|
||||
*)
|
||||
LOC_CFPUREGISTER :
|
||||
begin
|
||||
{ initialize fpu regvar by loading from memory }
|
||||
reference_reset_symbol(href,
|
||||
current_asmdata.RefAsmSymbol(tstaticvarsym(p).mangledname), 0,
|
||||
var_align(tstaticvarsym(p).vardef.alignment));
|
||||
a_loadfpu_ref_reg(TAsmList(arg), tstaticvarsym(p).vardef,
|
||||
tstaticvarsym(p).vardef, href, tstaticvarsym(p).initialloc.register);
|
||||
end;
|
||||
LOC_INVALID :
|
||||
;
|
||||
else
|
||||
internalerror(200410124);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.finalize_sym(asmlist: TAsmList; sym: tsym);
|
||||
var
|
||||
hp : tnode;
|
||||
OldAsmList : TAsmList;
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
OldAsmList:=current_asmdata.CurrAsmList;
|
||||
current_asmdata.CurrAsmList:=asmlist;
|
||||
hp:=cloadnode.create(sym,sym.owner);
|
||||
if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
|
||||
include(hp.flags,nf_isinternal_ignoreconst);
|
||||
hp:=cnodeutils.finalize_data_node(hp);
|
||||
firstpass(hp);
|
||||
secondpass(hp);
|
||||
hp.free;
|
||||
current_asmdata.CurrAsmList:=OldAsmList;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.finalize_local_vars(p: TObject; arg: pointer);
|
||||
begin
|
||||
if (tsym(p).typ=localvarsym) and
|
||||
(tlocalvarsym(p).refs>0) and
|
||||
not(vo_is_external in tlocalvarsym(p).varoptions) and
|
||||
not(vo_is_funcret in tlocalvarsym(p).varoptions) and
|
||||
is_managed_type(tlocalvarsym(p).vardef) then
|
||||
finalize_sym(TAsmList(arg),tsym(p));
|
||||
end;
|
||||
|
||||
procedure thlcgobj.finalize_static_data(p: TObject; arg: pointer);
|
||||
var
|
||||
i : longint;
|
||||
pd : tprocdef;
|
||||
begin
|
||||
case tsym(p).typ of
|
||||
staticvarsym :
|
||||
begin
|
||||
{ local (procedure or unit) variables only need finalization
|
||||
if they are used
|
||||
}
|
||||
if ((tstaticvarsym(p).refs>0) or
|
||||
{ global (unit) variables always need finalization, since
|
||||
they may also be used in another unit
|
||||
}
|
||||
(tstaticvarsym(p).owner.symtabletype=globalsymtable)) and
|
||||
(
|
||||
(tstaticvarsym(p).varspez<>vs_const) or
|
||||
(vo_force_finalize in tstaticvarsym(p).varoptions)
|
||||
) and
|
||||
not(vo_is_funcret in tstaticvarsym(p).varoptions) and
|
||||
not(vo_is_external in tstaticvarsym(p).varoptions) and
|
||||
is_managed_type(tstaticvarsym(p).vardef) then
|
||||
finalize_sym(TAsmList(arg),tsym(p));
|
||||
end;
|
||||
procsym :
|
||||
begin
|
||||
for i:=0 to tprocsym(p).ProcdefList.Count-1 do
|
||||
begin
|
||||
pd:=tprocdef(tprocsym(p).ProcdefList[i]);
|
||||
if assigned(pd.localst) and
|
||||
(pd.procsym=tprocsym(p)) and
|
||||
(pd.localst.symtabletype<>staticsymtable) then
|
||||
pd.localst.SymList.ForEachCall(@finalize_static_data,arg);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure thlcgobj.final_paras(p: TObject; arg: pointer);
|
||||
var
|
||||
list : TAsmList;
|
||||
href : treference;
|
||||
hsym : tparavarsym;
|
||||
eldef : tdef;
|
||||
highloc : tlocation;
|
||||
begin
|
||||
if not(tsym(p).typ=paravarsym) then
|
||||
exit;
|
||||
list:=TAsmList(arg);
|
||||
if is_managed_type(tparavarsym(p).vardef) then
|
||||
begin
|
||||
if (tparavarsym(p).varspez=vs_value) then
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
|
||||
if is_open_array(tparavarsym(p).vardef) then
|
||||
begin
|
||||
if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then
|
||||
begin
|
||||
hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
|
||||
if not assigned(hsym) then
|
||||
internalerror(201003032);
|
||||
highloc:=hsym.initialloc
|
||||
end
|
||||
else
|
||||
highloc.loc:=LOC_INVALID;
|
||||
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
|
||||
g_array_rtti_helper(list,eldef,href,highloc,'FPC_DECREF_ARRAY');
|
||||
end
|
||||
else
|
||||
g_decrrefcount(list,tparavarsym(p).vardef,href);
|
||||
end;
|
||||
end;
|
||||
{ open arrays can contain elements requiring init/final code, so the else has been removed here }
|
||||
if (tparavarsym(p).varspez=vs_value) and
|
||||
(is_open_array(tparavarsym(p).vardef) or
|
||||
is_array_of_const(tparavarsym(p).vardef)) then
|
||||
begin
|
||||
{ cdecl functions don't have a high pointer so it is not possible to generate
|
||||
a local copy }
|
||||
if not(current_procinfo.procdef.proccalloption in cdecl_pocalls) then
|
||||
g_releasevaluepara_openarray(list,tarraydef(tparavarsym(p).vardef),tparavarsym(p).localloc);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
{ generates the code for incrementing the reference count of parameters and
|
||||
initialize out parameters }
|
||||
{ generates the code for incrementing the reference count of parameters and
|
||||
|
@ -90,8 +90,6 @@ interface
|
||||
procedure gen_stack_check_call(list:TAsmList);
|
||||
procedure gen_save_used_regs(list:TAsmList);
|
||||
procedure gen_restore_used_regs(list:TAsmList);
|
||||
procedure gen_initialize_code(list:TAsmList);
|
||||
procedure gen_finalize_code(list:TAsmList);
|
||||
procedure gen_entry_code(list:TAsmList);
|
||||
procedure gen_exit_code(list:TAsmList);
|
||||
procedure gen_load_para_value(list:TAsmList);
|
||||
@ -1399,153 +1397,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{ initializes the regvars from staticsymtable with 0 }
|
||||
procedure initialize_regvars(p:TObject;arg:pointer);
|
||||
var
|
||||
href : treference;
|
||||
begin
|
||||
if (tsym(p).typ=staticvarsym) then
|
||||
begin
|
||||
{ Static variables can have the initialloc only set to LOC_CxREGISTER
|
||||
or LOC_INVALID, for explaination see gen_alloc_symtable (PFV) }
|
||||
case tstaticvarsym(p).initialloc.loc of
|
||||
LOC_CREGISTER :
|
||||
begin
|
||||
{$ifndef cpu64bitalu}
|
||||
if (tstaticvarsym(p).initialloc.size in [OS_64,OS_S64]) then
|
||||
cg64.a_load64_const_reg(TAsmList(arg),0,tstaticvarsym(p).initialloc.register64)
|
||||
else
|
||||
{$endif not cpu64bitalu}
|
||||
cg.a_load_const_reg(TAsmList(arg),reg_cgsize(tstaticvarsym(p).initialloc.register),0,
|
||||
tstaticvarsym(p).initialloc.register);
|
||||
end;
|
||||
LOC_CMMREGISTER :
|
||||
{ clear the whole register }
|
||||
cg.a_opmm_reg_reg(TAsmList(arg),OP_XOR,reg_cgsize(tstaticvarsym(p).initialloc.register),
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
tstaticvarsym(p).initialloc.register,
|
||||
nil);
|
||||
LOC_CFPUREGISTER :
|
||||
begin
|
||||
{ initialize fpu regvar by loading from memory }
|
||||
reference_reset_symbol(href,
|
||||
current_asmdata.RefAsmSymbol(tstaticvarsym(p).mangledname), 0,
|
||||
var_align(tstaticvarsym(p).vardef.alignment));
|
||||
cg.a_loadfpu_ref_reg(TAsmList(arg), tstaticvarsym(p).initialloc.size,
|
||||
tstaticvarsym(p).initialloc.size, href, tstaticvarsym(p).initialloc.register);
|
||||
end;
|
||||
LOC_INVALID :
|
||||
;
|
||||
else
|
||||
internalerror(200410124);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ generates the code for initialisation of local data }
|
||||
procedure initialize_data(p:TObject;arg:pointer);
|
||||
var
|
||||
OldAsmList : TAsmList;
|
||||
hp : tnode;
|
||||
begin
|
||||
if (tsym(p).typ = localvarsym) and
|
||||
{ local (procedure or unit) variables only need initialization if
|
||||
they are used }
|
||||
((tabstractvarsym(p).refs>0) or
|
||||
{ managed return symbols must be inited }
|
||||
((tsym(p).typ=localvarsym) and (vo_is_funcret in tlocalvarsym(p).varoptions))
|
||||
) and
|
||||
not(vo_is_typed_const in tabstractvarsym(p).varoptions) and
|
||||
not(vo_is_external in tabstractvarsym(p).varoptions) and
|
||||
(is_managed_type(tabstractvarsym(p).vardef) or
|
||||
((m_iso in current_settings.modeswitches) and (tabstractvarsym(p).vardef.typ=filedef))
|
||||
) then
|
||||
begin
|
||||
OldAsmList:=current_asmdata.CurrAsmList;
|
||||
current_asmdata.CurrAsmList:=TAsmList(arg);
|
||||
hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner));
|
||||
firstpass(hp);
|
||||
secondpass(hp);
|
||||
hp.free;
|
||||
current_asmdata.CurrAsmList:=OldAsmList;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure finalize_sym(asmlist:TAsmList;sym:tsym);
|
||||
var
|
||||
hp : tnode;
|
||||
OldAsmList : TAsmList;
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
OldAsmList:=current_asmdata.CurrAsmList;
|
||||
current_asmdata.CurrAsmList:=asmlist;
|
||||
hp:=cloadnode.create(sym,sym.owner);
|
||||
if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
|
||||
include(hp.flags,nf_isinternal_ignoreconst);
|
||||
hp:=cnodeutils.finalize_data_node(hp);
|
||||
firstpass(hp);
|
||||
secondpass(hp);
|
||||
hp.free;
|
||||
current_asmdata.CurrAsmList:=OldAsmList;
|
||||
end;
|
||||
|
||||
|
||||
{ generates the code for finalisation of local variables }
|
||||
procedure finalize_local_vars(p:TObject;arg:pointer);
|
||||
begin
|
||||
if (tsym(p).typ=localvarsym) and
|
||||
(tlocalvarsym(p).refs>0) and
|
||||
not(vo_is_external in tlocalvarsym(p).varoptions) and
|
||||
not(vo_is_funcret in tlocalvarsym(p).varoptions) and
|
||||
is_managed_type(tlocalvarsym(p).vardef) then
|
||||
finalize_sym(TAsmList(arg),tsym(p));
|
||||
end;
|
||||
|
||||
|
||||
{ generates the code for finalization of static symtable and
|
||||
all local (static) typed consts }
|
||||
procedure finalize_static_data(p:TObject;arg:pointer);
|
||||
var
|
||||
i : longint;
|
||||
pd : tprocdef;
|
||||
begin
|
||||
case tsym(p).typ of
|
||||
staticvarsym :
|
||||
begin
|
||||
{ local (procedure or unit) variables only need finalization
|
||||
if they are used
|
||||
}
|
||||
if ((tstaticvarsym(p).refs>0) or
|
||||
{ global (unit) variables always need finalization, since
|
||||
they may also be used in another unit
|
||||
}
|
||||
(tstaticvarsym(p).owner.symtabletype=globalsymtable)) and
|
||||
(
|
||||
(tstaticvarsym(p).varspez<>vs_const) or
|
||||
(vo_force_finalize in tstaticvarsym(p).varoptions)
|
||||
) and
|
||||
not(vo_is_funcret in tstaticvarsym(p).varoptions) and
|
||||
not(vo_is_external in tstaticvarsym(p).varoptions) and
|
||||
is_managed_type(tstaticvarsym(p).vardef) then
|
||||
finalize_sym(TAsmList(arg),tsym(p));
|
||||
end;
|
||||
procsym :
|
||||
begin
|
||||
for i:=0 to tprocsym(p).ProcdefList.Count-1 do
|
||||
begin
|
||||
pd:=tprocdef(tprocsym(p).ProcdefList[i]);
|
||||
if assigned(pd.localst) and
|
||||
(pd.procsym=tprocsym(p)) and
|
||||
(pd.localst.symtabletype<>staticsymtable) then
|
||||
pd.localst.SymList.ForEachCall(@finalize_static_data,arg);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ generates the code for incrementing the reference count of parameters and
|
||||
initialize out parameters }
|
||||
procedure init_paras(p:TObject;arg:pointer);
|
||||
@ -1646,95 +1497,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
{ generates the code for decrementing the reference count of parameters }
|
||||
procedure final_paras(p:TObject;arg:pointer);
|
||||
var
|
||||
list : TAsmList;
|
||||
href : treference;
|
||||
hsym : tparavarsym;
|
||||
eldef : tdef;
|
||||
highloc : tlocation;
|
||||
begin
|
||||
if not(tsym(p).typ=paravarsym) then
|
||||
exit;
|
||||
list:=TAsmList(arg);
|
||||
if is_managed_type(tparavarsym(p).vardef) then
|
||||
begin
|
||||
if (tparavarsym(p).varspez=vs_value) then
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
|
||||
if is_open_array(tparavarsym(p).vardef) then
|
||||
begin
|
||||
if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then
|
||||
begin
|
||||
hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
|
||||
if not assigned(hsym) then
|
||||
internalerror(201003032);
|
||||
highloc:=hsym.initialloc
|
||||
end
|
||||
else
|
||||
highloc.loc:=LOC_INVALID;
|
||||
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
|
||||
hlcg.g_array_rtti_helper(list,eldef,href,highloc,'FPC_DECREF_ARRAY');
|
||||
end
|
||||
else
|
||||
hlcg.g_decrrefcount(list,tparavarsym(p).vardef,href);
|
||||
end;
|
||||
end;
|
||||
{ open arrays can contain elements requiring init/final code, so the else has been removed here }
|
||||
if (tparavarsym(p).varspez=vs_value) and
|
||||
(is_open_array(tparavarsym(p).vardef) or
|
||||
is_array_of_const(tparavarsym(p).vardef)) then
|
||||
begin
|
||||
{ cdecl functions don't have a high pointer so it is not possible to generate
|
||||
a local copy }
|
||||
if not(current_procinfo.procdef.proccalloption in cdecl_pocalls) then
|
||||
hlcg.g_releasevaluepara_openarray(list,tarraydef(tparavarsym(p).vardef),tparavarsym(p).localloc);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
{ Initialize temp ansi/widestrings,interfaces }
|
||||
procedure inittempvariables(list:TAsmList);
|
||||
var
|
||||
hp : ptemprecord;
|
||||
href : treference;
|
||||
begin
|
||||
hp:=tg.templist;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if assigned(hp^.def) and
|
||||
is_managed_type(hp^.def) then
|
||||
begin
|
||||
reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint));
|
||||
hlcg.g_initialize(list,hp^.def,href);
|
||||
end;
|
||||
hp:=hp^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure finalizetempvariables(list:TAsmList);
|
||||
var
|
||||
hp : ptemprecord;
|
||||
href : treference;
|
||||
begin
|
||||
hp:=tg.templist;
|
||||
while assigned(hp) do
|
||||
begin
|
||||
if assigned(hp^.def) and
|
||||
is_managed_type(hp^.def) then
|
||||
begin
|
||||
include(current_procinfo.flags,pi_needs_implicit_finally);
|
||||
reference_reset_base(href,current_procinfo.framepointer,hp^.pos,sizeof(pint));
|
||||
hlcg.g_finalize(list,hp^.def,href);
|
||||
end;
|
||||
hp:=hp^.next;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_alloc_regloc(list:TAsmList;var loc: tlocation);
|
||||
begin
|
||||
case loc.loc of
|
||||
@ -2080,73 +1842,6 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_initialize_code(list:TAsmList);
|
||||
begin
|
||||
{ initialize local data like ansistrings }
|
||||
case current_procinfo.procdef.proctypeoption of
|
||||
potype_unitinit:
|
||||
begin
|
||||
{ this is also used for initialization of variables in a
|
||||
program which does not have a globalsymtable }
|
||||
if assigned(current_module.globalsymtable) then
|
||||
TSymtable(current_module.globalsymtable).SymList.ForEachCall(@initialize_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_regvars,list);
|
||||
end;
|
||||
{ units have seperate code for initilization and finalization }
|
||||
potype_unitfinalize: ;
|
||||
{ program init/final is generated in separate procedure }
|
||||
potype_proginit:
|
||||
begin
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@initialize_regvars,list);
|
||||
end;
|
||||
else
|
||||
current_procinfo.procdef.localst.SymList.ForEachCall(@initialize_data,list);
|
||||
end;
|
||||
|
||||
{ initialisizes temp. ansi/wide string data }
|
||||
inittempvariables(list);
|
||||
|
||||
{$ifdef OLDREGVARS}
|
||||
load_regvars(list,nil);
|
||||
{$endif OLDREGVARS}
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_finalize_code(list:TAsmList);
|
||||
begin
|
||||
{$ifdef OLDREGVARS}
|
||||
cleanup_regvars(list);
|
||||
{$endif OLDREGVARS}
|
||||
|
||||
{ finalize temporary data }
|
||||
finalizetempvariables(list);
|
||||
|
||||
{ finalize local data like ansistrings}
|
||||
case current_procinfo.procdef.proctypeoption of
|
||||
potype_unitfinalize:
|
||||
begin
|
||||
{ this is also used for initialization of variables in a
|
||||
program which does not have a globalsymtable }
|
||||
if assigned(current_module.globalsymtable) then
|
||||
TSymtable(current_module.globalsymtable).SymList.ForEachCall(@finalize_static_data,list);
|
||||
TSymtable(current_module.localsymtable).SymList.ForEachCall(@finalize_static_data,list);
|
||||
end;
|
||||
{ units/progs have separate code for initialization and finalization }
|
||||
potype_unitinit: ;
|
||||
{ program init/final is generated in separate procedure }
|
||||
potype_proginit: ;
|
||||
else
|
||||
current_procinfo.procdef.localst.SymList.ForEachCall(@finalize_local_vars,list);
|
||||
end;
|
||||
|
||||
{ finalize paras data }
|
||||
if assigned(current_procinfo.procdef.parast) and
|
||||
not(po_assembler in current_procinfo.procdef.procoptions) then
|
||||
current_procinfo.procdef.parast.SymList.ForEachCall(@final_paras,list);
|
||||
end;
|
||||
|
||||
|
||||
procedure gen_entry_code(list:TAsmList);
|
||||
begin
|
||||
{ the actual profile code can clobber some registers,
|
||||
|
@ -1077,7 +1077,7 @@ implementation
|
||||
|
||||
gen_entry_code(templist);
|
||||
aktproccode.insertlistafter(entry_asmnode.currenttai,templist);
|
||||
gen_initialize_code(templist);
|
||||
hlcg.gen_initialize_code(templist);
|
||||
aktproccode.insertlistafter(init_asmnode.currenttai,templist);
|
||||
|
||||
{ now generate finalize and exit code with the correct position
|
||||
@ -1087,7 +1087,7 @@ implementation
|
||||
|
||||
cg.set_regalloc_live_range_direction(rad_forward);
|
||||
|
||||
gen_finalize_code(templist);
|
||||
hlcg.gen_finalize_code(templist);
|
||||
{ the finalcode must be concated if there was no position available,
|
||||
using insertlistafter will result in an insert at the start
|
||||
when currentai=nil }
|
||||
|
Loading…
Reference in New Issue
Block a user