* 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;
end;
{ generate RTTI and init tables }
procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
var
RTTIWriter : TRTTIWriter;
@ -95,6 +98,61 @@ implementation
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
***************************************************************************}

View File

@ -98,8 +98,8 @@ interface
end;
TVMTWriterClass = class of TVMTWriter;
{ generate persistent type information like VMT, RTTI and inittables }
procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
{ generate VMTs }
procedure write_vmts(st:tsymtable;is_global:boolean);
var
CVMTWriter: TVMTWriterClass = TVMTWriter;
@ -1268,7 +1268,7 @@ implementation
end;
procedure do_write_persistent_type_info(st:tsymtable;is_global:boolean);
procedure do_write_vmts(st:tsymtable;is_global:boolean);
var
i : longint;
def : tdef;
@ -1281,14 +1281,14 @@ implementation
def:=tdef(st.DefList[i]);
case def.typ of
recorddef :
do_write_persistent_type_info(trecorddef(def).symtable,is_global);
do_write_vmts(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;
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 }
if not(ds_vmt_written in def.defstates) then
begin
@ -1307,37 +1307,18 @@ implementation
begin
if assigned(tprocdef(def).localst) and
(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
do_write_persistent_type_info(tprocdef(def).parast,false);
do_write_vmts(tprocdef(def).parast,false);
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;
procedure write_persistent_type_info(st:tsymtable;is_global:boolean);
procedure write_vmts(st:tsymtable;is_global:boolean);
begin
create_hlcodegen;
do_write_persistent_type_info(st,is_global);
do_write_vmts(st,is_global);
destroy_hlcodegen;
end;

View File

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