mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 18:30:18 +02:00
* support for implementing interface method wrappers at the node tree
level, used by LLVM git-svn-id: trunk@31636 -
This commit is contained in:
parent
be2ec5be59
commit
c7a418829b
@ -110,15 +110,14 @@ implementation
|
|||||||
cutils,cclasses,
|
cutils,cclasses,
|
||||||
globtype,globals,verbose,constexp,
|
globtype,globals,verbose,constexp,
|
||||||
systems,fmodule,
|
systems,fmodule,
|
||||||
symsym,symtable,defutil,
|
symsym,symtable,symcreat,defutil,
|
||||||
|
{$ifdef cpuhighleveltarget}
|
||||||
|
pparautl,
|
||||||
|
{$endif cpuhighleveltarget}
|
||||||
aasmtai,
|
aasmtai,
|
||||||
wpobase,
|
wpobase,
|
||||||
nobj,
|
nobj,
|
||||||
cgbase,parabase,paramgr,cgobj,cgcpu,hlcgobj,hlcgcpu,
|
cgbase,parabase,paramgr,cgobj,cgcpu,hlcgobj,hlcgcpu,
|
||||||
{$ifdef llvm}
|
|
||||||
{ override create_hlcodegen from hlcgcpu }
|
|
||||||
hlcgllvm,
|
|
||||||
{$endif}
|
|
||||||
ncgrtti;
|
ncgrtti;
|
||||||
|
|
||||||
|
|
||||||
@ -1239,6 +1238,10 @@ implementation
|
|||||||
tmps : string;
|
tmps : string;
|
||||||
pd : TProcdef;
|
pd : TProcdef;
|
||||||
ImplIntf : TImplementedInterface;
|
ImplIntf : TImplementedInterface;
|
||||||
|
{$ifdef cpuhighleveltarget}
|
||||||
|
wrapperpd: tprocdef;
|
||||||
|
wrapperinfo: pskpara_interface_wrapper;
|
||||||
|
{$endif cpuhighleveltarget}
|
||||||
begin
|
begin
|
||||||
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
||||||
begin
|
begin
|
||||||
@ -1257,11 +1260,34 @@ implementation
|
|||||||
tobjectdef(tprocdef(pd).struct).register_vmt_call(tprocdef(pd).extnumber);
|
tobjectdef(tprocdef(pd).struct).register_vmt_call(tprocdef(pd).extnumber);
|
||||||
tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+
|
tmps:=make_mangledname('WRPR',_class.owner,_class.objname^+'_$_'+
|
||||||
ImplIntf.IntfDef.objname^+'_$_'+tostr(j)+'_$_'+pd.mangledname);
|
ImplIntf.IntfDef.objname^+'_$_'+tostr(j)+'_$_'+pd.mangledname);
|
||||||
|
{$ifdef cpuhighleveltarget}
|
||||||
|
{ bare copy so we don't copy the aliasnames }
|
||||||
|
wrapperpd:=tprocdef(pd.getcopyas(procdef,pc_bareproc));
|
||||||
|
{ set the mangled name to the wrapper name }
|
||||||
|
wrapperpd.setmangledname(tmps);
|
||||||
|
{ insert the wrapper procdef in the current unit's local
|
||||||
|
symbol table, but set the owning "struct" to the current
|
||||||
|
class (so self will have the correct type) }
|
||||||
|
finish_copied_procdef(wrapperpd,tmps,current_module.localsymtable,_class);
|
||||||
|
{ now insert self/vmt }
|
||||||
|
insert_self_and_vmt_para(wrapperpd);
|
||||||
|
{ and the function result }
|
||||||
|
insert_funcret_para(wrapperpd);
|
||||||
|
{ recalculate the parameters now that we've added the above }
|
||||||
|
wrapperpd.calcparas;
|
||||||
|
{ set the info required to generate the implementation }
|
||||||
|
wrapperpd.synthetickind:=tsk_interface_wrapper;
|
||||||
|
new(wrapperinfo);
|
||||||
|
wrapperinfo^.pd:=pd;
|
||||||
|
wrapperinfo^.offset:=ImplIntf.ioffset;
|
||||||
|
wrapperpd.skpara:=wrapperinfo;
|
||||||
|
{$else cpuhighleveltarget}
|
||||||
{ create wrapper code }
|
{ create wrapper code }
|
||||||
new_section(list,sec_code,tmps,target_info.alignment.procalign);
|
new_section(list,sec_code,tmps,target_info.alignment.procalign);
|
||||||
hlcg.init_register_allocators;
|
hlcg.init_register_allocators;
|
||||||
hlcg.g_intf_wrapper(list,pd,tmps,ImplIntf.ioffset);
|
hlcg.g_intf_wrapper(list,pd,tmps,ImplIntf.ioffset);
|
||||||
hlcg.done_register_allocators;
|
hlcg.done_register_allocators;
|
||||||
|
{$endif cpuhighleveltarget}
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1317,9 +1343,15 @@ implementation
|
|||||||
|
|
||||||
procedure write_vmts(st:tsymtable;is_global:boolean);
|
procedure write_vmts(st:tsymtable;is_global:boolean);
|
||||||
begin
|
begin
|
||||||
|
{ high level targets use synthetic procdefs to create the inteface
|
||||||
|
wrappers }
|
||||||
|
{$ifndef cpuhighleveltarget}
|
||||||
create_hlcodegen;
|
create_hlcodegen;
|
||||||
|
{$endif}
|
||||||
do_write_vmts(st,is_global);
|
do_write_vmts(st,is_global);
|
||||||
|
{$ifndef cpuhighleveltarget}
|
||||||
destroy_hlcodegen;
|
destroy_hlcodegen;
|
||||||
|
{$endif}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
@ -401,9 +401,17 @@ type
|
|||||||
tsk_jvm_virtual_clmethod, // Java wrapper for virtual class method
|
tsk_jvm_virtual_clmethod, // Java wrapper for virtual class method
|
||||||
tsk_field_getter, // getter for a field (callthrough property is passed in skpara)
|
tsk_field_getter, // getter for a field (callthrough property is passed in skpara)
|
||||||
tsk_field_setter, // Setter for a field (callthrough property is passed in skpara)
|
tsk_field_setter, // Setter for a field (callthrough property is passed in skpara)
|
||||||
tsk_block_invoke_procvar // Call a procvar to invoke inside a block
|
tsk_block_invoke_procvar, // Call a procvar to invoke inside a block
|
||||||
|
tsk_interface_wrapper // Call through to a method from an interface wrapper
|
||||||
);
|
);
|
||||||
|
|
||||||
|
{ synthetic procdef supplementary information (tprocdef.skpara) }
|
||||||
|
tskpara_interface_wrapper = record
|
||||||
|
pd: pointer;
|
||||||
|
offset: longint;
|
||||||
|
end;
|
||||||
|
pskpara_interface_wrapper = ^tskpara_interface_wrapper;
|
||||||
|
|
||||||
{ options for objects and classes }
|
{ options for objects and classes }
|
||||||
tobjecttyp = (odt_none,
|
tobjecttyp = (odt_none,
|
||||||
odt_class,
|
odt_class,
|
||||||
|
@ -935,6 +935,32 @@ implementation
|
|||||||
str_parse_method_impl(str,pd,false);
|
str_parse_method_impl(str,pd,false);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure implement_interface_wrapper(pd: tprocdef);
|
||||||
|
var
|
||||||
|
wrapperinfo: pskpara_interface_wrapper;
|
||||||
|
callthroughpd: tprocdef;
|
||||||
|
str: ansistring;
|
||||||
|
begin
|
||||||
|
wrapperinfo:=pskpara_interface_wrapper(pd.skpara);
|
||||||
|
if not assigned(wrapperinfo) then
|
||||||
|
internalerror(2015090801);
|
||||||
|
callthroughpd:=tprocdef(wrapperinfo^.pd);
|
||||||
|
str:='begin ';
|
||||||
|
{ self right now points to the VMT of interface inside the instance ->
|
||||||
|
adjust so it points to the start of the instance }
|
||||||
|
str:=str+'pointer(self):=pointer(self) - '+tostr(wrapperinfo^.offset)+';';
|
||||||
|
{ 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+') end;';
|
||||||
|
str_parse_method_impl(str,pd,false);
|
||||||
|
dispose(wrapperinfo);
|
||||||
|
pd.skpara:=nil;
|
||||||
|
end;
|
||||||
|
|
||||||
procedure add_synthetic_method_implementations_for_st(st: tsymtable);
|
procedure add_synthetic_method_implementations_for_st(st: tsymtable);
|
||||||
var
|
var
|
||||||
i : longint;
|
i : longint;
|
||||||
@ -1007,6 +1033,8 @@ implementation
|
|||||||
implement_field_setter(pd);
|
implement_field_setter(pd);
|
||||||
tsk_block_invoke_procvar:
|
tsk_block_invoke_procvar:
|
||||||
implement_block_invoke_procvar(pd);
|
implement_block_invoke_procvar(pd);
|
||||||
|
tsk_interface_wrapper:
|
||||||
|
implement_interface_wrapper(pd);
|
||||||
else
|
else
|
||||||
internalerror(2011032801);
|
internalerror(2011032801);
|
||||||
end;
|
end;
|
||||||
|
@ -539,7 +539,8 @@ const
|
|||||||
'jvm enum fpcvalueof', 'jvm enum long2set',
|
'jvm enum fpcvalueof', 'jvm enum long2set',
|
||||||
'jvm enum bitset2set', 'jvm enum set2set',
|
'jvm enum bitset2set', 'jvm enum set2set',
|
||||||
'jvm procvar invoke', 'jvm procvar intf constructor',
|
'jvm procvar invoke', 'jvm procvar intf constructor',
|
||||||
'jvm virtual class method', 'jvm field getter', 'jvm field setter', 'block invoke');
|
'jvm virtual class method', 'jvm field getter', 'jvm field setter',
|
||||||
|
'block invoke','interface wrapper');
|
||||||
begin
|
begin
|
||||||
if w<=ord(high(syntheticName)) then
|
if w<=ord(high(syntheticName)) then
|
||||||
result:=syntheticName[tsynthetickind(w)]
|
result:=syntheticName[tsynthetickind(w)]
|
||||||
|
Loading…
Reference in New Issue
Block a user