* converted generting published method tables to the typed constant builder

git-svn-id: branches/hlcgllvm@28770 -
This commit is contained in:
Jonas Maebe 2014-10-06 20:54:04 +00:00
parent 5ecb2faf93
commit f8cda69446

View File

@ -487,12 +487,22 @@ implementation
end; end;
type
tvmtasmoutput = record
pubmethodstcb: ttai_typedconstbuilder;
list: tasmlist;
methodnamerec: trecorddef;
end;
pvmtasmoutput = ^tvmtasmoutput;
procedure TVMTWriter.do_gen_published_methods(p:TObject;arg:pointer); procedure TVMTWriter.do_gen_published_methods(p:TObject;arg:pointer);
var var
i : longint; i : longint;
l : tasmlabel; l : tasmlabel;
pd : tprocdef; pd : tprocdef;
lists: ^TAsmList absolute arg; lists: pvmtasmoutput absolute arg;
tcb : ttai_typedconstbuilder;
namedef : tdef;
begin begin
if (tsym(p).typ<>procsym) then if (tsym(p).typ<>procsym) then
exit; exit;
@ -503,16 +513,31 @@ implementation
(pd.visibility=vis_published) then (pd.visibility=vis_published) then
begin begin
current_asmdata.getlabel(l,alt_data); current_asmdata.getlabel(l,alt_data);
lists[1].concat(cai_align.Create(const_align(sizeof(pint)))); { l: name_of_method }
lists[1].concat(Tai_label.Create(l)); tcb:=ctai_typedconstbuilder.create;
lists[1].concat(Tai_const.Create_8bit(length(tsym(p).realname))); namedef:=getarraydef(cansichartype,length(tsym(p).realname)+1);
lists[1].concat(Tai_string.Create(tsym(p).realname)); tcb.maybe_begin_aggregate(namedef);
tcb.emit_tai(Tai_const.Create_8bit(length(tsym(p).realname)),u8inttype);
lists[0].concat(Tai_const.Create_sym(l)); tcb.emit_tai(Tai_string.Create(tsym(p).realname),getarraydef(cansichartype,length(tsym(p).realname)));
tcb.maybe_end_aggregate(namedef);
lists^.list.concatList(tcb.get_final_asmlist(l,namedef,sec_rodata_norel,'',sizeof(pint),[tcalo_is_lab]));
tcb.free;
{ the tmethodnamerec }
lists^.pubmethodstcb.maybe_begin_aggregate(lists^.methodnamerec);
{ convert the pointer to the name into a generic pshortstring,
so all entries can share the same recorddef }
lists^.pubmethodstcb.queue_init(charpointertype);
lists^.pubmethodstcb.queue_emit_asmsym(l,namedef);
if po_abstractmethod in pd.procoptions then if po_abstractmethod in pd.procoptions then
lists[0].concat(Tai_const.Create_nil_codeptr) lists^.pubmethodstcb.emit_tai(Tai_const.Create_nil_codeptr,voidcodepointertype)
else else
lists[0].concat(Tai_const.Createname(pd.mangledname,AT_FUNCTION,0)); begin
{ convert the procdef in a generic voidcodepointer, same
reason as above }
lists^.pubmethodstcb.queue_init(voidcodepointertype);
lists^.pubmethodstcb.queue_emit_proc(pd);
end;
lists^.pubmethodstcb.maybe_end_aggregate(lists^.methodnamerec);
end; end;
end; end;
end; end;
@ -523,21 +548,45 @@ implementation
var var
l : tasmlabel; l : tasmlabel;
count : longint; count : longint;
lists : array[0..1] of TAsmList; lists : tvmtasmoutput;
pubmethodsdef: trecorddef;
pubmethodsarraydef: tarraydef;
begin begin
count:=0; count:=0;
_class.symtable.SymList.ForEachCall(@do_count_published_methods,@count); _class.symtable.SymList.ForEachCall(@do_count_published_methods,@count);
if count>0 then if count>0 then
begin begin
lists[0]:=list; lists.list:=list;
lists[1]:=TAsmList.Create; { in the list of the published methods (from objpas.inc):
tmethodnamerec = packed record
name : pshortstring;
addr : codepointer;
end;
}
lists.methodnamerec:=getrecorddef('fpc_intern_tmethodnamerec',[getpointerdef(cshortstringtype),voidcodepointertype],1);
{ from objpas.inc:
tmethodnametable = packed record
count : dword;
entries : packed array[0..0] of tmethodnamerec;
end;
}
lists.pubmethodstcb:=ctai_typedconstbuilder.create;
current_asmdata.getlabel(l,alt_data); current_asmdata.getlabel(l,alt_data);
list.concat(cai_align.create(const_align(sizeof(pint)))); gettabledef('fpc_intern_tmethodnametable_',u32inttype,lists.methodnamerec,count,1,pubmethodsdef,pubmethodsarraydef);
list.concat(Tai_label.Create(l)); { begin tmethodnametable }
list.concat(Tai_const.Create_32bit(count)); lists.pubmethodstcb.maybe_begin_aggregate(pubmethodsdef);
{ emit count field }
lists.pubmethodstcb.emit_tai(Tai_const.Create_32bit(count),u32inttype);
{ begin entries field (array) }
lists.pubmethodstcb.maybe_begin_aggregate(pubmethodsarraydef);
{ add all entries elements }
_class.symtable.SymList.ForEachCall(@do_gen_published_methods,@lists); _class.symtable.SymList.ForEachCall(@do_gen_published_methods,@lists);
list.concatlist(lists[1]); { end entries field (array) }
lists[1].Free; lists.pubmethodstcb.maybe_end_aggregate(pubmethodsarraydef);
{ end methodnametable }
lists.pubmethodstcb.maybe_end_aggregate(pubmethodsdef);
list.concatlist(lists.pubmethodstcb.get_final_asmlist(l,pubmethodsdef,sec_rodata,'',sizeof(pint),[tcalo_is_lab]));
lists.pubmethodstcb.free;
genpublishedmethodstable:=l; genpublishedmethodstable:=l;
end end
else else
@ -738,7 +787,7 @@ implementation
arrdef:=tarraydef(trecordsymtable(recdef.symtable).findfieldbyoffset(countdef.size).vardef); arrdef:=tarraydef(trecordsymtable(recdef.symtable).findfieldbyoffset(countdef.size).vardef);
exit exit
end; end;
recdef:=crecorddef.create_global_internal('$'+basename+tostr(count),0); recdef:=crecorddef.create_global_internal('$'+basename+tostr(count),packrecords);
fields:=tfplist.create; fields:=tfplist.create;
fields.add(countdef); fields.add(countdef);
if count>0 then if count>0 then