* changed getprocaddressprocvar() into a tprocvardef.getreusableprocaddr()

class method

git-svn-id: trunk@31148 -
This commit is contained in:
Jonas Maebe 2015-06-23 21:23:22 +00:00
parent f40ea04540
commit 508828958c
7 changed files with 38 additions and 38 deletions

View File

@ -1274,7 +1274,7 @@ implementation
procedure ttai_typedconstbuilder.emit_procdef_const(pd: tprocdef); procedure ttai_typedconstbuilder.emit_procdef_const(pd: tprocdef);
begin begin
emit_tai(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0),getprocaddressprocvar(pd)); emit_tai(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0),cprocvardef.getreusableprocaddr(pd));
end; end;

View File

@ -319,7 +319,7 @@ implementation
begin begin
if (pd.typ=procdef) or if (pd.typ=procdef) or
not pd.is_addressonly then not pd.is_addressonly then
result:=getprocaddressprocvar(pd) result:=cprocvardef.getreusableprocaddr(pd)
else else
result:=pd result:=pd
end; end;
@ -420,7 +420,7 @@ implementation
{ if this is a complex procvar, get the non-tmethod-like equivalent } { if this is a complex procvar, get the non-tmethod-like equivalent }
if (pd.typ=procvardef) and if (pd.typ=procvardef) and
not pd.is_addressonly then not pd.is_addressonly then
pd:=tprocvardef(getprocaddressprocvar(pd)); pd:=tprocvardef(cprocvardef.getreusableprocaddr(pd));
{ if the function returns a function pointer type or is varargs, we { if the function returns a function pointer type or is varargs, we
must specify the full function signature, otherwise we can only must specify the full function signature, otherwise we can only
specify the return type } specify the return type }

View File

@ -236,7 +236,7 @@ implementation
procedure tllvmtai_typedconstbuilder.emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef); procedure tllvmtai_typedconstbuilder.emit_tai_procvar2procdef(p: tai; pvdef: tprocvardef);
begin begin
if not pvdef.is_addressonly then if not pvdef.is_addressonly then
pvdef:=getprocaddressprocvar(pvdef); pvdef:=cprocvardef.getreusableprocaddr(pvdef);
emit_tai(p,pvdef); emit_tai(p,pvdef);
end; end;
@ -444,7 +444,7 @@ implementation
the procdef } the procdef }
if (fromdef.typ=procdef) and if (fromdef.typ=procdef) and
(todef.typ<>procdef) then (todef.typ<>procdef) then
fromdef:=getprocaddressprocvar(tprocdef(fromdef)); fromdef:=cprocvardef.getreusableprocaddr(tprocdef(fromdef));
op:=llvmconvop(fromdef,todef); op:=llvmconvop(fromdef,todef);
case op of case op of
la_ptrtoint_to_x, la_ptrtoint_to_x,

View File

@ -820,7 +820,7 @@ implementation
of far calls where the procvardef was defined does not matter, of far calls where the procvardef was defined does not matter,
even though the procvardef constructor called by getcopyas looks at even though the procvardef constructor called by getcopyas looks at
it) } it) }
codeprocdef:=getprocaddressprocvar(procdefinition); codeprocdef:=cprocvardef.getreusableprocaddr(procdefinition);
result:=hlcg.getaddressregister(current_asmdata.CurrAsmList,codeprocdef); result:=hlcg.getaddressregister(current_asmdata.CurrAsmList,codeprocdef);
{ in case we have a method pointer on a big endian target in registers, { in case we have a method pointer on a big endian target in registers,
the method address is stored in registerhi (it's the first field the method address is stored in registerhi (it's the first field

View File

@ -722,7 +722,7 @@ implementation
hs:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+AImplIntf.IntfDef.objname^+'_$_'+ hs:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+AImplIntf.IntfDef.objname^+'_$_'+
tostr(i)+'_$_'+pd.mangledname); tostr(i)+'_$_'+pd.mangledname);
{ create reference } { create reference }
datatcb.emit_tai(Tai_const.Createname(hs,AT_FUNCTION,0),getprocaddressprocvar(pd)); datatcb.emit_tai(Tai_const.Createname(hs,AT_FUNCTION,0),cprocvardef.getreusableprocaddr(pd));
end; end;
end end
else else
@ -1015,7 +1015,7 @@ implementation
procname:='FPC_EMPTYMETHOD' procname:='FPC_EMPTYMETHOD'
else if not wpoinfomanager.optimized_name_for_vmt(_class,vmtpd,procname) then else if not wpoinfomanager.optimized_name_for_vmt(_class,vmtpd,procname) then
procname:=vmtpd.mangledname; procname:=vmtpd.mangledname;
tcb.emit_tai(Tai_const.Createname(procname,AT_FUNCTION,0),getprocaddressprocvar(vmtpd)); tcb.emit_tai(Tai_const.Createname(procname,AT_FUNCTION,0),cprocvardef.getreusableprocaddr(vmtpd));
{$ifdef vtentry} {$ifdef vtentry}
hs:='VTENTRY'+'_'+_class.vmt_mangledname+'$$'+tostr(_class.vmtmethodoffset(i) div sizeof(pint)); hs:='VTENTRY'+'_'+_class.vmt_mangledname+'$$'+tostr(_class.vmtmethodoffset(i) div sizeof(pint));
current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0)); current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));

View File

@ -864,7 +864,7 @@ implementation
{ now add the methods } { now add the methods }
for i:=0 to _class.vmtentries.count-1 do for i:=0 to _class.vmtentries.count-1 do
vmtdef.add_field_by_def( vmtdef.add_field_by_def(
getprocaddressprocvar(pvmtentry(_class.vmtentries[i])^.procdef) cprocvardef.getreusableprocaddr(pvmtentry(_class.vmtentries[i])^.procdef)
); );
{ the VMT ends with a nil pointer } { the VMT ends with a nil pointer }
vmtdef.add_field_by_def(voidcodepointertype); vmtdef.add_field_by_def(voidcodepointertype);

View File

@ -608,6 +608,8 @@ interface
tprocvardef = class(tabstractprocdef) tprocvardef = class(tabstractprocdef)
constructor create(level:byte);virtual; constructor create(level:byte);virtual;
{ returns a procvardef that represents the address of a proc(var)def }
class function getreusableprocaddr(def: tabstractprocdef): tprocvardef; virtual;
constructor ppuload(ppufile:tcompilerppufile); constructor ppuload(ppufile:tcompilerppufile);
function getcopy : tstoreddef;override; function getcopy : tstoreddef;override;
{ do not override this routine in platform-specific subclasses, { do not override this routine in platform-specific subclasses,
@ -1126,9 +1128,6 @@ interface
function use_vectorfpu(def : tdef) : boolean; function use_vectorfpu(def : tdef) : boolean;
{ returns a procvardef that represents the address of a procdef }
function getprocaddressprocvar(def: tabstractprocdef): tprocvardef;
function getansistringcodepage:tstringencoding; inline; function getansistringcodepage:tstringencoding; inline;
function getansistringdef:tstringdef; function getansistringdef:tstringdef;
function getparaencoding(def:tdef):tstringencoding; inline; function getparaencoding(def:tdef):tstringencoding; inline;
@ -5900,6 +5899,33 @@ implementation
end; end;
class function tprocvardef.getreusableprocaddr(def: tabstractprocdef): tprocvardef;
var
res: PHashSetItem;
oldsymtablestack: tsymtablestack;
begin
if not assigned(current_module) then
internalerror(2011081301);
res:=current_module.procaddrdefs.FindOrAdd(@def,sizeof(def));
if not assigned(res^.Data) then
begin
{ since these pointerdefs can be reused anywhere in the current
unit, add them to the global/staticsymtable }
oldsymtablestack:=symtablestack;
{ do not simply push/pop current_module.localsymtable, because
that can have side-effects (e.g., it removes helpers) }
symtablestack:=nil;
res^.Data:=def.getcopyas(procvardef,pc_address_only);
if assigned(current_module.localsymtable) then
current_module.localsymtable.insertdef(tdef(res^.Data))
else
current_module.globalsymtable.insertdef(tdef(res^.Data));
symtablestack:=oldsymtablestack;
end;
result:=tprocvardef(res^.Data);
end;
constructor tprocvardef.ppuload(ppufile:tcompilerppufile); constructor tprocvardef.ppuload(ppufile:tcompilerppufile);
begin begin
inherited ppuload(procvardef,ppufile); inherited ppuload(procvardef,ppufile);
@ -7661,30 +7687,4 @@ implementation
end; end;
function getprocaddressprocvar(def: tabstractprocdef): tprocvardef;
var
res: PHashSetItem;
oldsymtablestack: tsymtablestack;
begin
if not assigned(current_module) then
internalerror(2011081301);
res:=current_module.procaddrdefs.FindOrAdd(@def,sizeof(def));
if not assigned(res^.Data) then
begin
{ since these pointerdefs can be reused anywhere in the current
unit, add them to the global/staticsymtable }
oldsymtablestack:=symtablestack;
{ do not simply push/pop current_module.localsymtable, because
that can have side-effects (e.g., it removes helpers) }
symtablestack:=nil;
res^.Data:=def.getcopyas(procvardef,pc_address_only);
if assigned(current_module.localsymtable) then
current_module.localsymtable.insertdef(tdef(res^.Data))
else
current_module.globalsymtable.insertdef(tdef(res^.Data));
symtablestack:=oldsymtablestack;
end;
result:=tprocvardef(res^.Data);
end;
end. end.