mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-05 10:46:19 +02:00
* nobj.pas, finished refactoring VMT generation code, now all child structures except RTTI are written to same data section with VMT itself and their labels are local (since child structures are accessible only through VMT, smartlinking them into different sections is useless).
* Reference GUID/string labels of implemented interfaces instead of duplicating them on every occurrence. git-svn-id: trunk@20344 -
This commit is contained in:
parent
8fc1fb5e15
commit
429af6f40b
@ -89,7 +89,7 @@ interface
|
|||||||
function intf_get_vtbl_name(AImplIntf:TImplementedInterface): string;
|
function intf_get_vtbl_name(AImplIntf:TImplementedInterface): string;
|
||||||
procedure intf_create_vtbl(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
procedure intf_create_vtbl(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
||||||
procedure intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
procedure intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
||||||
function intf_write_table:TAsmLabel;
|
function intf_write_table(list : TAsmList):TAsmLabel;
|
||||||
{ generates the message tables for a class }
|
{ generates the message tables for a class }
|
||||||
function genstrmsgtab(list : TAsmList) : tasmlabel;
|
function genstrmsgtab(list : TAsmList) : tasmlabel;
|
||||||
function genintmsgtab(list : TAsmList) : tasmlabel;
|
function genintmsgtab(list : TAsmList) : tasmlabel;
|
||||||
@ -978,7 +978,7 @@ implementation
|
|||||||
writenames(list,root);
|
writenames(list,root);
|
||||||
|
|
||||||
{ now start writing of the message string table }
|
{ now start writing of the message string table }
|
||||||
current_asmdata.getdatalabel(result);
|
current_asmdata.getlabel(result,alt_data);
|
||||||
list.concat(cai_align.create(const_align(sizeof(pint))));
|
list.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
list.concat(Tai_label.Create(result));
|
list.concat(Tai_label.Create(result));
|
||||||
list.concat(cai_align.create(const_align(sizeof(longint))));
|
list.concat(cai_align.create(const_align(sizeof(longint))));
|
||||||
@ -1019,7 +1019,7 @@ implementation
|
|||||||
_class.symtable.SymList.ForEachCall(@insertmsgint,@count);
|
_class.symtable.SymList.ForEachCall(@insertmsgint,@count);
|
||||||
|
|
||||||
{ now start writing of the message string table }
|
{ now start writing of the message string table }
|
||||||
current_asmdata.getdatalabel(r);
|
current_asmdata.getlabel(r,alt_data);
|
||||||
list.concat(cai_align.create(const_align(sizeof(pint))));
|
list.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
list.concat(Tai_label.Create(r));
|
list.concat(Tai_label.Create(r));
|
||||||
genintmsgtab:=r;
|
genintmsgtab:=r;
|
||||||
@ -1183,7 +1183,7 @@ implementation
|
|||||||
begin
|
begin
|
||||||
lists[0]:=list;
|
lists[0]:=list;
|
||||||
lists[1]:=TAsmList.Create;
|
lists[1]:=TAsmList.Create;
|
||||||
current_asmdata.getdatalabel(l);
|
current_asmdata.getlabel(l,alt_data);
|
||||||
list.concat(cai_align.create(const_align(sizeof(pint))));
|
list.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
list.concat(Tai_label.Create(l));
|
list.concat(Tai_label.Create(l));
|
||||||
list.concat(Tai_const.Create_32bit(count));
|
list.concat(Tai_const.Create_32bit(count));
|
||||||
@ -1227,11 +1227,10 @@ implementation
|
|||||||
|
|
||||||
if fieldcount>0 then
|
if fieldcount>0 then
|
||||||
begin
|
begin
|
||||||
current_asmdata.getdatalabel(fieldtable);
|
current_asmdata.getlabel(fieldtable,alt_data);
|
||||||
current_asmdata.getdatalabel(classtable);
|
current_asmdata.getlabel(classtable,alt_data);
|
||||||
maybe_new_object_file(list);
|
|
||||||
new_section(list,sec_rodata,classtable.name,const_align(sizeof(pint)));
|
|
||||||
|
|
||||||
|
list.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
{ write fields }
|
{ write fields }
|
||||||
list.concat(Tai_label.Create(fieldtable));
|
list.concat(Tai_label.Create(fieldtable));
|
||||||
list.concat(Tai_const.Create_16bit(fieldcount));
|
list.concat(Tai_const.Create_16bit(fieldcount));
|
||||||
@ -1291,7 +1290,8 @@ implementation
|
|||||||
i : longint;
|
i : longint;
|
||||||
begin
|
begin
|
||||||
vtblstr:=intf_get_vtbl_name(AImplIntf);
|
vtblstr:=intf_get_vtbl_name(AImplIntf);
|
||||||
section_symbol_start(rawdata,vtblstr,AT_DATA,true,sec_data,const_align(sizeof(pint)));
|
rawdata.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
|
rawdata.concat(tai_symbol.createname(vtblstr,AT_DATA,0));
|
||||||
if assigned(AImplIntf.procdefs) then
|
if assigned(AImplIntf.procdefs) then
|
||||||
begin
|
begin
|
||||||
for i:=0 to AImplIntf.procdefs.count-1 do
|
for i:=0 to AImplIntf.procdefs.count-1 do
|
||||||
@ -1303,104 +1303,73 @@ implementation
|
|||||||
rawdata.concat(Tai_const.Createname(hs,0));
|
rawdata.concat(Tai_const.Createname(hs,0));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
section_symbol_end(rawdata,vtblstr);
|
rawdata.concat(tai_symbol_end.createname(vtblstr));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TVMTWriter.intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
procedure TVMTWriter.intf_gen_intf_ref(rawdata: TAsmList;AImplIntf:TImplementedInterface);
|
||||||
var
|
var
|
||||||
iidlabel,
|
|
||||||
guidlabel : tasmlabel;
|
|
||||||
i: longint;
|
|
||||||
pd: tprocdef;
|
pd: tprocdef;
|
||||||
begin
|
begin
|
||||||
{ GUID }
|
{ GUID (or nil for Corba interfaces) }
|
||||||
if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then
|
if AImplIntf.IntfDef.objecttype in [odt_interfacecom] then
|
||||||
begin
|
rawdata.concat(Tai_const.CreateName(
|
||||||
{ label for GUID }
|
make_mangledname('IID',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),0))
|
||||||
current_asmdata.getdatalabel(guidlabel);
|
|
||||||
rawdata.concat(cai_align.create(const_align(sizeof(pint))));
|
|
||||||
rawdata.concat(Tai_label.Create(guidlabel));
|
|
||||||
with AImplIntf.IntfDef.iidguid^ do
|
|
||||||
begin
|
|
||||||
rawdata.concat(Tai_const.Create_32bit(longint(D1)));
|
|
||||||
rawdata.concat(Tai_const.Create_16bit(D2));
|
|
||||||
rawdata.concat(Tai_const.Create_16bit(D3));
|
|
||||||
for i:=Low(D4) to High(D4) do
|
|
||||||
rawdata.concat(Tai_const.Create_8bit(D4[i]));
|
|
||||||
end;
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(guidlabel));
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
begin
|
rawdata.concat(Tai_const.Create_sym(nil));
|
||||||
{ nil for Corba interfaces }
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil));
|
|
||||||
end;
|
|
||||||
{ VTable }
|
{ VTable }
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
|
rawdata.concat(Tai_const.Createname(intf_get_vtbl_name(AImplIntf.VtblImplIntf),0));
|
||||||
{ IOffset field }
|
{ IOffset field }
|
||||||
case AImplIntf.VtblImplIntf.IType of
|
case AImplIntf.VtblImplIntf.IType of
|
||||||
etFieldValue, etFieldValueClass,
|
etFieldValue, etFieldValueClass,
|
||||||
etStandard:
|
etStandard:
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
|
rawdata.concat(Tai_const.Create_pint(AImplIntf.VtblImplIntf.IOffset));
|
||||||
etStaticMethodResult, etStaticMethodClass:
|
etStaticMethodResult, etStaticMethodClass:
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Createname(
|
rawdata.concat(Tai_const.Createname(
|
||||||
tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef).mangledname,
|
tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef).mangledname,
|
||||||
0
|
0
|
||||||
));
|
));
|
||||||
etVirtualMethodResult, etVirtualMethodClass:
|
etVirtualMethodResult, etVirtualMethodClass:
|
||||||
begin
|
begin
|
||||||
pd := tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef);
|
pd := tprocdef(tpropertysym(AImplIntf.ImplementsGetter).propaccesslist[palt_read].procdef);
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(tobjectdef(pd.struct).vmtmethodoffset(pd.extnumber)));
|
rawdata.concat(Tai_const.Create_pint(tobjectdef(pd.struct).vmtmethodoffset(pd.extnumber)));
|
||||||
end;
|
end;
|
||||||
else
|
else
|
||||||
internalerror(200802162);
|
internalerror(200802162);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ IIDStr }
|
{ IIDStr }
|
||||||
current_asmdata.getdatalabel(iidlabel);
|
rawdata.concat(Tai_const.CreateName(
|
||||||
rawdata.concat(cai_align.create(const_align(sizeof(pint))));
|
make_mangledname('IIDSTR',AImplIntf.IntfDef.owner,AImplIntf.IntfDef.objname^),0));
|
||||||
rawdata.concat(Tai_label.Create(iidlabel));
|
|
||||||
rawdata.concat(Tai_const.Create_8bit(length(AImplIntf.IntfDef.iidstr^)));
|
|
||||||
if AImplIntf.IntfDef.objecttype=odt_interfacecom then
|
|
||||||
rawdata.concat(Tai_string.Create(upper(AImplIntf.IntfDef.iidstr^)))
|
|
||||||
else
|
|
||||||
rawdata.concat(Tai_string.Create(AImplIntf.IntfDef.iidstr^));
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(iidlabel));
|
|
||||||
{ IType }
|
{ IType }
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(aint(AImplIntf.VtblImplIntf.IType)));
|
rawdata.concat(Tai_const.Create_pint(aint(AImplIntf.VtblImplIntf.IType)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function TVMTWriter.intf_write_table:TAsmLabel;
|
function TVMTWriter.intf_write_table(list : TAsmList):TAsmLabel;
|
||||||
var
|
var
|
||||||
rawdata : TAsmList;
|
|
||||||
i : longint;
|
i : longint;
|
||||||
ImplIntf : TImplementedInterface;
|
ImplIntf : TImplementedInterface;
|
||||||
intftablelab : tasmlabel;
|
|
||||||
begin
|
begin
|
||||||
current_asmdata.getdatalabel(intftablelab);
|
current_asmdata.getlabel(result,alt_data);
|
||||||
current_asmdata.asmlists[al_globals].concat(cai_align.create(const_align(sizeof(pint))));
|
list.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_label.Create(intftablelab));
|
list.concat(Tai_label.Create(result));
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_pint(_class.ImplementedInterfaces.count));
|
list.concat(Tai_const.Create_pint(_class.ImplementedInterfaces.count));
|
||||||
rawdata:=TAsmList.Create;
|
{ Write vtbl references }
|
||||||
|
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
||||||
|
begin
|
||||||
|
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
||||||
|
intf_gen_intf_ref(list,ImplIntf);
|
||||||
|
end;
|
||||||
|
|
||||||
{ Write vtbls }
|
{ Write vtbls }
|
||||||
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
||||||
begin
|
begin
|
||||||
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
||||||
if ImplIntf.VtblImplIntf=ImplIntf then
|
if ImplIntf.VtblImplIntf=ImplIntf then
|
||||||
intf_create_vtbl(rawdata,ImplIntf);
|
intf_create_vtbl(list,ImplIntf);
|
||||||
end;
|
end;
|
||||||
{ Write vtbl references }
|
|
||||||
for i:=0 to _class.ImplementedInterfaces.count-1 do
|
|
||||||
begin
|
|
||||||
ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
|
|
||||||
intf_gen_intf_ref(rawdata,ImplIntf);
|
|
||||||
end;
|
|
||||||
{ Write interface table }
|
|
||||||
current_asmdata.asmlists[al_globals].concatlist(rawdata);
|
|
||||||
rawdata.free;
|
|
||||||
result:=intftablelab;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -1475,36 +1444,37 @@ implementation
|
|||||||
dmtlabel : tasmlabel;
|
dmtlabel : tasmlabel;
|
||||||
{$endif WITHDMT}
|
{$endif WITHDMT}
|
||||||
interfacetable : tasmlabel;
|
interfacetable : tasmlabel;
|
||||||
|
templist : TAsmList;
|
||||||
begin
|
begin
|
||||||
{$ifdef WITHDMT}
|
{$ifdef WITHDMT}
|
||||||
dmtlabel:=gendmt;
|
dmtlabel:=gendmt;
|
||||||
{$endif WITHDMT}
|
{$endif WITHDMT}
|
||||||
|
templist:=TAsmList.Create;
|
||||||
|
|
||||||
{ write tables for classes, this must be done before the actual
|
{ write tables for classes, this must be done before the actual
|
||||||
class is written, because we need the labels defined }
|
class is written, because we need the labels defined }
|
||||||
if is_class(_class) then
|
if is_class(_class) then
|
||||||
begin
|
begin
|
||||||
current_asmdata.getdatalabel(classnamelabel);
|
{ write class name }
|
||||||
maybe_new_object_file(current_asmdata.asmlists[al_globals]);
|
current_asmdata.getlabel(classnamelabel,alt_data);
|
||||||
new_section(current_asmdata.asmlists[al_globals],sec_rodata,classnamelabel.name,const_align(sizeof(pint)));
|
templist.concat(cai_align.create(const_align(sizeof(pint))));
|
||||||
|
templist.concat(Tai_label.Create(classnamelabel));
|
||||||
|
hs:=_class.RttiName;
|
||||||
|
templist.concat(Tai_const.Create_8bit(length(hs)));
|
||||||
|
templist.concat(Tai_string.Create(hs));
|
||||||
|
|
||||||
{ interface table }
|
{ interface table }
|
||||||
if _class.ImplementedInterfaces.count>0 then
|
if _class.ImplementedInterfaces.count>0 then
|
||||||
interfacetable:=intf_write_table;
|
interfacetable:=intf_write_table(templist);
|
||||||
|
|
||||||
methodnametable:=genpublishedmethodstable(current_asmdata.asmlists[al_globals]);
|
methodnametable:=genpublishedmethodstable(templist);
|
||||||
fieldtablelabel:=generate_field_table(current_asmdata.asmlists[al_rtti]);
|
fieldtablelabel:=generate_field_table(templist);
|
||||||
{ write class name }
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_label.Create(classnamelabel));
|
|
||||||
hs:=_class.RttiName;
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_const.Create_8bit(length(hs)));
|
|
||||||
current_asmdata.asmlists[al_globals].concat(Tai_string.Create(hs));
|
|
||||||
|
|
||||||
{ generate message and dynamic tables }
|
{ generate message and dynamic tables }
|
||||||
if (oo_has_msgstr in _class.objectoptions) then
|
if (oo_has_msgstr in _class.objectoptions) then
|
||||||
strmessagetable:=genstrmsgtab(current_asmdata.asmlists[al_globals]);
|
strmessagetable:=genstrmsgtab(templist);
|
||||||
if (oo_has_msgint in _class.objectoptions) then
|
if (oo_has_msgint in _class.objectoptions) then
|
||||||
intmessagetable:=genintmsgtab(current_asmdata.asmlists[al_globals]);
|
intmessagetable:=genintmsgtab(templist);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ write debug info }
|
{ write debug info }
|
||||||
@ -1585,6 +1555,9 @@ implementation
|
|||||||
hs:=hs+_class.vmt_mangledname;
|
hs:=hs+_class.vmt_mangledname;
|
||||||
current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
|
current_asmdata.asmlists[al_globals].concat(tai_symbol.CreateName(hs,AT_DATA,0));
|
||||||
{$endif vtentry}
|
{$endif vtentry}
|
||||||
|
if is_class(_class) then
|
||||||
|
current_asmdata.asmlists[al_globals].concatlist(templist);
|
||||||
|
templist.Free;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user