* write full/init rtti and VMTs separately instead of at the same time

o this allows us to write the VMTs earlier (before the synthetic method
     implementations are generated), which means we can create new synthetic
     methods while generating the VMTs (for interface trampolines)

git-svn-id: trunk@31635 -
This commit is contained in:
Jonas Maebe 2015-09-12 23:32:38 +00:00
parent cabb16efdb
commit be2ec5be59
3 changed files with 79 additions and 29 deletions

View File

@ -64,6 +64,9 @@ interface
function get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol; function get_rtti_label_str2ord(def:tdef;rt:trttitype):tasmsymbol;
end; end;
{ generate RTTI and init tables }
procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
var var
RTTIWriter : TRTTIWriter; RTTIWriter : TRTTIWriter;
@ -95,6 +98,61 @@ implementation
end; end;
procedure write_persistent_type_info(st: tsymtable; is_global: boolean);
var
i : longint;
def : tdef;
begin
{ no Delphi-style RTTI for managed platforms }
if target_info.system in systems_managed_vm then
exit;
for i:=0 to st.DefList.Count-1 do
begin
def:=tdef(st.DefList[i]);
case def.typ of
recorddef:
write_persistent_type_info(trecorddef(def).symtable,is_global);
objectdef :
begin
{ Skip generics and forward defs }
if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
(oo_is_forward in tobjectdef(def).objectoptions) then
continue;
write_persistent_type_info(tobjectdef(def).symtable,is_global);
end;
procdef :
begin
if assigned(tprocdef(def).localst) and
(tprocdef(def).localst.symtabletype=localsymtable) then
write_persistent_type_info(tprocdef(def).localst,false);
if assigned(tprocdef(def).parast) then
write_persistent_type_info(tprocdef(def).parast,false);
end;
end;
{ always generate persistent tables for types in the interface so
they can be reused in other units and give always the same pointer
location. }
{ Init }
if (
assigned(def.typesym) and
is_global and
not is_objc_class_or_protocol(def)
) or
is_managed_type(def) or
(ds_init_table_used in def.defstates) then
RTTIWriter.write_rtti(def,initrtti);
{ RTTI }
if (
assigned(def.typesym) and
is_global and
not is_objc_class_or_protocol(def)
) or
(ds_rtti_table_used in def.defstates) then
RTTIWriter.write_rtti(def,fullrtti);
end;
end;
{*************************************************************************** {***************************************************************************
TRTTIWriter TRTTIWriter
***************************************************************************} ***************************************************************************}

View File

@ -98,8 +98,8 @@ interface
end; end;
TVMTWriterClass = class of TVMTWriter; TVMTWriterClass = class of TVMTWriter;
{ generate persistent type information like VMT, RTTI and inittables } { generate VMTs }
procedure write_persistent_type_info(st:tsymtable;is_global:boolean); procedure write_vmts(st:tsymtable;is_global:boolean);
var var
CVMTWriter: TVMTWriterClass = TVMTWriter; CVMTWriter: TVMTWriterClass = TVMTWriter;
@ -1268,7 +1268,7 @@ implementation
end; end;
procedure do_write_persistent_type_info(st:tsymtable;is_global:boolean); procedure do_write_vmts(st:tsymtable;is_global:boolean);
var var
i : longint; i : longint;
def : tdef; def : tdef;
@ -1281,14 +1281,14 @@ implementation
def:=tdef(st.DefList[i]); def:=tdef(st.DefList[i]);
case def.typ of case def.typ of
recorddef : recorddef :
do_write_persistent_type_info(trecorddef(def).symtable,is_global); do_write_vmts(trecorddef(def).symtable,is_global);
objectdef : objectdef :
begin begin
{ Skip generics and forward defs } { Skip generics and forward defs }
if ([df_generic,df_genconstraint]*def.defoptions<>[]) or if ([df_generic,df_genconstraint]*def.defoptions<>[]) or
(oo_is_forward in tobjectdef(def).objectoptions) then (oo_is_forward in tobjectdef(def).objectoptions) then
continue; continue;
do_write_persistent_type_info(tobjectdef(def).symtable,is_global); do_write_vmts(tobjectdef(def).symtable,is_global);
{ Write also VMT if not done yet } { Write also VMT if not done yet }
if not(ds_vmt_written in def.defstates) then if not(ds_vmt_written in def.defstates) then
begin begin
@ -1307,37 +1307,18 @@ implementation
begin begin
if assigned(tprocdef(def).localst) and if assigned(tprocdef(def).localst) and
(tprocdef(def).localst.symtabletype=localsymtable) then (tprocdef(def).localst.symtabletype=localsymtable) then
do_write_persistent_type_info(tprocdef(def).localst,false); do_write_vmts(tprocdef(def).localst,false);
if assigned(tprocdef(def).parast) then if assigned(tprocdef(def).parast) then
do_write_persistent_type_info(tprocdef(def).parast,false); do_write_vmts(tprocdef(def).parast,false);
end; end;
end; end;
{ generate always persistent tables for types in the interface so it can
be reused in other units and give always the same pointer location. }
{ Init }
if (
assigned(def.typesym) and
is_global and
not is_objc_class_or_protocol(def)
) or
is_managed_type(def) or
(ds_init_table_used in def.defstates) then
RTTIWriter.write_rtti(def,initrtti);
{ RTTI }
if (
assigned(def.typesym) and
is_global and
not is_objc_class_or_protocol(def)
) or
(ds_rtti_table_used in def.defstates) then
RTTIWriter.write_rtti(def,fullrtti);
end; end;
end; end;
procedure write_persistent_type_info(st:tsymtable;is_global:boolean); procedure write_vmts(st:tsymtable;is_global:boolean);
begin begin
create_hlcodegen; create_hlcodegen;
do_write_persistent_type_info(st,is_global); do_write_vmts(st,is_global);
destroy_hlcodegen; destroy_hlcodegen;
end; end;

View File

@ -46,7 +46,7 @@ implementation
pexports, pexports,
objcgutl, objcgutl,
wpobase, wpobase,
scanner,pbase,pexpr,psystem,psub,pdecsub,ncgvmt, scanner,pbase,pexpr,psystem,psub,pdecsub,ncgvmt,ncgrtti,
cpuinfo; cpuinfo;
@ -1070,6 +1070,13 @@ type
{ Generate specializations of objectdefs methods } { Generate specializations of objectdefs methods }
generate_specialization_procs; generate_specialization_procs;
{ Generate VMTs }
if Errorcount=0 then
begin
write_vmts(current_module.globalsymtable,true);
write_vmts(current_module.localsymtable,false);
end;
{ add implementations for synthetic method declarations added by { add implementations for synthetic method declarations added by
the compiler } the compiler }
add_synthetic_method_implementations(current_module.globalsymtable); add_synthetic_method_implementations(current_module.globalsymtable);
@ -2144,6 +2151,10 @@ type
{ Generate specializations of objectdefs methods } { Generate specializations of objectdefs methods }
generate_specialization_procs; generate_specialization_procs;
{ Generate VMTs }
if Errorcount=0 then
write_vmts(current_module.localsymtable,false);
{ add implementations for synthetic method declarations added by { add implementations for synthetic method declarations added by
the compiler } the compiler }
add_synthetic_method_implementations(current_module.localsymtable); add_synthetic_method_implementations(current_module.localsymtable);