* when creating wrappers, add a prefix to parameter names to prevent them

hiding the method name of the wrapped routine
   o also add a few more '&' prefixes to the generated wrapper code to
     prevent issues when keywords are used as identifiers

git-svn-id: trunk@40634 -
This commit is contained in:
Jonas Maebe 2018-12-24 22:10:06 +00:00
parent 377d4e1b58
commit acf02ab64b
14 changed files with 60 additions and 44 deletions

View File

@ -101,7 +101,7 @@ type
{ library symbol for AROS }
libsym : tsym;
libsymderef : tderef;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
procedure buildderef; override;
procedure deref; override;
end;
@ -208,7 +208,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
if newtyp=procdef then

View File

@ -207,7 +207,7 @@ implementation
exit;
end;
{ bare copy, so that self etc are not inserted }
result:=tprocdef(orgpd.getcopyas(procdef,pc_bareproc));
result:=tprocdef(orgpd.getcopyas(procdef,pc_bareproc,''));
{ will be called accoding to the ABI conventions }
result.proccalloption:=pocall_cdecl;
{ add po_is_block so that a block "self" pointer gets added (of the type

View File

@ -97,7 +97,7 @@ type
{ library symbol for AROS }
libsym : tsym;
libsymderef : tderef;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
procedure buildderef; override;
procedure deref; override;
end;
@ -203,7 +203,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
if newtyp=procdef then

View File

@ -110,7 +110,7 @@ type
tcpuprocvardef = class(ti86procvardef)
constructor create(level:byte);override;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp):tstoreddef;override;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp;const paraprefix:string):tstoreddef;override;
function address_type:tdef;override;
function ofs_address_type:tdef;override;
function size:asizeint;override;
@ -133,7 +133,7 @@ type
procedure Setinterfacedef(AValue: boolean);override;
public
constructor create(level:byte;doregister:boolean);override;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp):tstoreddef;override;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp;const paraprefix:string):tstoreddef;override;
function address_type:tdef;override;
function ofs_address_type:tdef;override;
function size:asizeint;override;
@ -334,7 +334,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp):tstoreddef;
function tcpuprocdef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp;const paraprefix:string):tstoreddef;
begin
result:=inherited;
if is_far then
@ -428,7 +428,7 @@ implementation
end;
function tcpuprocvardef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp):tstoreddef;
function tcpuprocvardef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp;const paraprefix:string):tstoreddef;
begin
result:=inherited;
if is_far then

View File

@ -505,7 +505,7 @@ implementation
{ add a method to call the procvar using unwrapped arguments, which
then wraps them and calls through to JLRMethod.invoke }
methoddef:=tprocdef(tprocvardef(def).getcopyas(procdef,pc_bareproc));
methoddef:=tprocdef(tprocvardef(def).getcopyas(procdef,pc_bareproc,''));
finish_copied_procdef(methoddef,'invoke',pvclass.symtable,pvclass);
insert_self_and_vmt_para(methoddef);
insert_funcret_para(methoddef);
@ -540,7 +540,7 @@ implementation
{ add a method prototype matching the procvar (like the invoke
in the procvarclass itself) }
symtablestack.push(pvintf.symtable);
methoddef:=tprocdef(tprocvardef(def).getcopyas(procdef,pc_bareproc));
methoddef:=tprocdef(tprocvardef(def).getcopyas(procdef,pc_bareproc,''));
finish_copied_procdef(methoddef,name+'Callback',pvintf.symtable,pvintf);
insert_self_and_vmt_para(methoddef);
insert_funcret_para(methoddef);
@ -639,7 +639,7 @@ implementation
wrapperpd.synthetickind:=tsk_jvm_virtual_clmethod;
wrapperpd.skpara:=pd;
{ also create procvar type that we can use in the implementation }
wrapperpv:=tcpuprocvardef(pd.getcopyas(procvardef,pc_normal));
wrapperpv:=tcpuprocvardef(pd.getcopyas(procvardef,pc_normal,''));
wrapperpv.calcparas;
{ no use in creating a callback wrapper here, this procvar type isn't
for public consumption }
@ -667,7 +667,7 @@ implementation
{ wrapper is part of the same symtable as the original procdef }
symtablestack.push(pd.owner);
{ get a copy of the constructor }
wrapperpd:=tprocdef(pd.getcopyas(procdef,pc_bareproc));
wrapperpd:=tprocdef(pd.getcopyas(procdef,pc_bareproc,''));
{ this one is a class method rather than a constructor }
include(wrapperpd.procoptions,po_classmethod);
wrapperpd.proctypeoption:=potype_function;

View File

@ -180,7 +180,7 @@ procedure tllvmtypeconvnode.second_proc_to_procvar;
if location.loc<>LOC_REFERENCE then
internalerror(2015111902);
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,
cpointerdef.getreusable(tprocdef(left.resultdef).getcopyas(procvardef,pc_normal)),
cpointerdef.getreusable(tprocdef(left.resultdef).getcopyas(procvardef,pc_normal,'')),
cpointerdef.getreusable(resultdef),
location.reference);
end;

View File

@ -90,7 +90,7 @@ procedure tllvmloadnode.pass_generate_code;
(resultdef.typ in [symconst.procdef,procvardef]) and
not tabstractprocdef(resultdef).is_addressonly then
begin
pvdef:=tprocvardef(procdef.getcopyas(procvardef,pc_normal));
pvdef:=tprocvardef(procdef.getcopyas(procvardef,pc_normal,''));
{ on little endian, location.register contains proc and
location.registerhi contains self; on big endian, it's the
other way around }

View File

@ -97,7 +97,7 @@ type
{ library symbol for AmigaOS/MorphOS }
libsym : tsym;
libsymderef : tderef;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
procedure buildderef; override;
procedure deref; override;
end;
@ -203,7 +203,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
if newtyp=procdef then

View File

@ -574,7 +574,7 @@ interface
begin
location.register:=hlcg.getaddressregister(current_asmdata.CurrAsmList,resultdef);
{ code field is the first one }
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(tprocvardef(tprocdef(left.resultdef).getcopyas(procvardef,pc_normal))),cpointerdef.getreusable(resultdef),left.location.reference);
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(tprocvardef(tprocdef(left.resultdef).getcopyas(procvardef,pc_normal,''))),cpointerdef.getreusable(resultdef),left.location.reference);
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,resultdef,resultdef,left.location.reference,location.register);
end;
LOC_REGISTER,LOC_CREGISTER:

View File

@ -2269,7 +2269,7 @@ implementation
copytype:=pc_address_only
else
copytype:=pc_normal;
resultdef:=pd.getcopyas(procvardef,copytype);
resultdef:=pd.getcopyas(procvardef,copytype,'');
end;
end;

View File

@ -97,7 +97,7 @@ type
{ library symbol for AmigaOS/MorphOS }
libsym : tsym;
libsymderef : tderef;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
procedure buildderef; override;
procedure deref; override;
end;
@ -203,7 +203,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
if newtyp=procdef then

View File

@ -515,7 +515,7 @@ implementation
end;
procedure addvisibibleparameters(var str: ansistring; pd: tprocdef);
procedure addvisibleparameters(var str: ansistring; pd: tprocdef);
var
currpara: tparavarsym;
i: longint;
@ -530,7 +530,7 @@ implementation
if not firstpara then
str:=str+',';
firstpara:=false;
str:=str+currpara.realname;
str:=str+'&'+currpara.realname;
end;
end;
end;
@ -554,7 +554,7 @@ implementation
mnetion this program/unit name to avoid accidentally calling other
same-named routines that may be in scope }
str:=str+def_unit_name_prefix_if_toplevel(callpd)+callpd.procsym.realname+'(';
addvisibibleparameters(str,pd);
addvisibleparameters(str,pd);
str:=str+') end;';
str_parse_method_impl(str,pd,isclassmethod);
end;
@ -862,7 +862,7 @@ implementation
not is_void(pd.returndef) then
str:=str+'result:=';
str:=str+'pv(';
addvisibibleparameters(str,pd);
addvisibleparameters(str,pd);
str:=str+') end;';
str_parse_method_impl(str,pd,true)
end;
@ -964,7 +964,7 @@ implementation
if pd.returndef<>voidtype then
str:=str+'result:=';
str:=str+'__FPC_BLOCK_INVOKE_PV_TYPE(PFPC_Block_literal_complex_procvar(FPC_Block_Self)^.pv)(';
addvisibibleparameters(str,pd);
addvisibleparameters(str,pd);
str:=str+') end;';
str_parse_method_impl(str,pd,false);
end;
@ -988,8 +988,8 @@ implementation
{ now call through to the actual method }
if pd.returndef<>voidtype then
str:=str+'result:=';
str:=str+callthroughpd.procsym.realname+'(';
addvisibibleparameters(str,callthroughpd);
str:=str+'&'+callthroughpd.procsym.realname+'(';
addvisibleparameters(str,pd);
str:=str+') end;';
{ add dummy file info so we can step in/through it }
if pd.owner.iscurrentunit then
@ -1147,8 +1147,11 @@ implementation
function create_procdef_alias(pd: tprocdef; const newrealname: string; const newmangledname: TSymStr; newparentst: tsymtable; newstruct: tabstractrecorddef;
sk: tsynthetickind; skpara: pointer): tprocdef;
begin
{ bare copy so we don't copy the aliasnames }
result:=tprocdef(pd.getcopyas(procdef,pc_bareproc));
{ bare copy so we don't copy the aliasnames (specify prefix for
parameter names so we don't get issues in the body in case
we e.g. reference system.initialize and one of the parameters
is called "system") }
result:=tprocdef(pd.getcopyas(procdef,pc_bareproc,'__FPCW_'));
{ set the mangled name to the wrapper name }
result.setmangledname(newmangledname);
{ finish creating the copy }
@ -1481,7 +1484,10 @@ implementation
because there may already be references to the mangled name for the
non-external "test".
}
newpd:=tprocdef(orgpd.getcopyas(procdef,pc_bareproc));
{ prefixing the parameters here is useless, because the new procdef will
just be an external declaration without a body }
newpd:=tprocdef(orgpd.getcopyas(procdef,pc_bareproc,''));
insert_funcret_para(newpd);
newpd.procoptions:=newpd.procoptions+orgpd.procoptions*[po_external,po_has_importname,po_has_importdll];
newpd.import_name:=orgpd.import_name;
@ -1493,6 +1499,9 @@ implementation
newpd.setmangledname(newname);
finish_copied_procdef(newpd,'__FPC_IMPL_EXTERNAL_REDIRECT_'+newname,current_module.localsymtable,nil);
newpd.forwarddef:=false;
{ ideally we would prefix the parameters of the original routine here, but since it
can be an interface definition, we cannot do that without risking to change the
interface crc }
orgpd.skpara:=newpd;
orgpd.synthetickind:=tsk_callthrough;
orgpd.procoptions:=orgpd.procoptions-[po_external,po_has_importname,po_has_importdll];

View File

@ -630,7 +630,7 @@ interface
function is_addressonly:boolean;virtual;
function no_self_node:boolean;
{ get either a copy as a procdef or procvardef }
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp): tstoreddef; virtual;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp; const paraprefix: string): tstoreddef; virtual;
function compatible_with_pointerdef_size(ptr: tpointerdef): boolean; virtual;
procedure check_mark_as_nested;
procedure init_paraloc_info(side: tcallercallee);
@ -668,7 +668,7 @@ interface
function is_methodpointer:boolean;override;
function is_addressonly:boolean;override;
function getmangledparaname:TSymStr;override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
end;
tprocvardefclass = class of tprocvardef;
@ -813,7 +813,7 @@ interface
needs to be finalised afterwards by calling
symcreat.finish_copied_procdef() afterwards
}
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp): tstoreddef; override;
function getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp; const paraprefix: string): tstoreddef; override;
function getcopy: tstoreddef; override;
function GetTypeName : string;override;
function mangledname : TSymStr; virtual;
@ -5154,7 +5154,7 @@ implementation
end;
function tabstractprocdef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp): tstoreddef;
function tabstractprocdef.getcopyas(newtyp:tdeftyp;copytyp:tproccopytyp; const paraprefix: string): tstoreddef;
var
j, nestinglevel: longint;
pvs, npvs: tparavarsym;
@ -5187,8 +5187,15 @@ implementation
if (copytyp=pc_bareproc) and
(([vo_is_self,vo_is_vmt,vo_is_parentfp,vo_is_result,vo_is_funcret]*pvs.varoptions)<>[]) then
continue;
npvs:=cparavarsym.create(pvs.realname,pvs.paranr,pvs.varspez,
pvs.vardef,pvs.varoptions);
if paraprefix='' then
npvs:=cparavarsym.create(pvs.realname,pvs.paranr,pvs.varspez,
pvs.vardef,pvs.varoptions)
else if not(vo_is_high_para in pvs.varoptions) then
npvs:=cparavarsym.create(paraprefix+pvs.realname,pvs.paranr,pvs.varspez,
pvs.vardef,pvs.varoptions)
else
npvs:=cparavarsym.create('$high'+paraprefix+copy(pvs.name,5,length(pvs.name)),pvs.paranr,pvs.varspez,
pvs.vardef,pvs.varoptions);
npvs.defaultconstsym:=pvs.defaultconstsym;
tabstractprocdef(result).parast.insert(npvs);
end;
@ -6070,11 +6077,11 @@ implementation
end;
function tprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
var
j : longint;
begin
result:=inherited getcopyas(newtyp,copytyp);
result:=inherited;
if newtyp=procvardef then
begin
{ create new paralist }
@ -6141,7 +6148,7 @@ implementation
function tprocdef.getcopy: tstoreddef;
begin
result:=getcopyas(procdef,pc_normal);
result:=getcopyas(procdef,pc_normal,'');
end;
@ -6504,7 +6511,7 @@ implementation
{ do not simply push/pop current_module.localsymtable, because
that can have side-effects (e.g., it removes helpers) }
symtablestack:=nil;
result:=tprocvardef(def.getcopyas(procvardef,pc_address_only));
result:=tprocvardef(def.getcopyas(procvardef,pc_address_only,''));
setup_reusable_def(def,result,res,oldsymtablestack);
{ res^.Data may still be nil -> don't overwrite result }
exit;
@ -6643,7 +6650,7 @@ implementation
end;
function tprocvardef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tprocvardef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
tabstractprocdef(result).calcparas;

View File

@ -97,7 +97,7 @@ type
{ library symbol for AROS }
libsym : tsym;
libsymderef : tderef;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef; override;
function getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef; override;
procedure buildderef; override;
procedure deref; override;
end;
@ -203,7 +203,7 @@ implementation
end;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp): tstoreddef;
function tcpuprocdef.getcopyas(newtyp: tdeftyp; copytyp: tproccopytyp; const paraprefix: string): tstoreddef;
begin
result:=inherited;
if newtyp=procdef then