mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 08:29:29 +02:00
* 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:
parent
cabb16efdb
commit
be2ec5be59
@ -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
|
||||
***************************************************************************}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user