diff --git a/.gitattributes b/.gitattributes index f07d00a1ad..759a9c84a5 100644 --- a/.gitattributes +++ b/.gitattributes @@ -74,6 +74,7 @@ compiler/arm/rarmsta.inc svneol=native#text/plain compiler/arm/rarmstd.inc svneol=native#text/plain compiler/arm/rarmsup.inc svneol=native#text/plain compiler/arm/rgcpu.pas svneol=native#text/plain +compiler/asmutils.pas svneol=native#text/plain compiler/assemble.pas svneol=native#text/plain compiler/avr/aasmcpu.pas svneol=native#text/plain compiler/avr/agavrgas.pas svneol=native#text/plain diff --git a/compiler/aasmdata.pas b/compiler/aasmdata.pas index fa895d221f..6b27bb9ec0 100644 --- a/compiler/aasmdata.pas +++ b/compiler/aasmdata.pas @@ -152,6 +152,7 @@ interface { Assembler lists } AsmLists : array[TAsmListType] of TAsmList; CurrAsmList : TAsmList; + WideInits : TLinkedList; { hash tables for reusing constant storage } ConstPools : array[TConstPoolType] of THashSet; constructor create(const n:string); @@ -174,6 +175,13 @@ interface property AsmCFI:TAsmCFI read FAsmCFI; end; + TTCInitItem = class(TLinkedListItem) + sym: tsym; + offset: aint; + datalabel: TAsmLabel; + constructor Create(asym: tsym; aoffset: aint; alabel: TAsmLabel); + end; + var CAsmCFI : TAsmCFIClass; current_asmdata : TAsmData; @@ -241,6 +249,18 @@ implementation begin end; +{***************************************************************************** + TTCInitItem +*****************************************************************************} + + + constructor TTCInitItem.Create(asym: tsym; aoffset: aint; alabel: TAsmLabel); + begin + inherited Create; + sym:=asym; + offset:=aoffset; + datalabel:=alabel; + end; {***************************************************************************** TAsmList @@ -311,6 +331,7 @@ implementation CurrAsmList:=TAsmList.create; for hal:=low(TAsmListType) to high(TAsmListType) do AsmLists[hal]:=TAsmList.create; + WideInits :=TLinkedList.create; { PIC data } if (target_info.system in [system_powerpc_darwin,system_powerpc64_darwin,system_i386_darwin,system_arm_darwin]) then AsmLists[al_picdata].concat(tai_section.create(sec_data_nonlazy,'',sizeof(pint))); @@ -345,6 +366,7 @@ implementation {$ifdef MEMDEBUG} memasmlists.start; {$endif} + WideInits.free; for hal:=low(TAsmListType) to high(TAsmListType) do AsmLists[hal].free; CurrAsmList.free; diff --git a/compiler/asmutils.pas b/compiler/asmutils.pas new file mode 100644 index 0000000000..28570893d0 --- /dev/null +++ b/compiler/asmutils.pas @@ -0,0 +1,118 @@ +{ + Copyright (c) 1998-2006 by Florian Klaempfl + + This unit contains utility functions for assembler output + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit asmutils; + +interface + +{$i fpcdefs.inc} + +uses + aasmbase, + aasmdata; + + + function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;NewSection:Boolean=True):TAsmLabel; + function emit_unicodestring_const(list:TAsmList;data:Pointer;Winlike:Boolean):TAsmLabel; + + +implementation + +uses + globals, + globtype, + systems, + verbose, + aasmtai, + widestr, + symdef; + + function emit_ansistring_const(list:TAsmList;data:PChar;len:LongInt;NewSection:Boolean): TAsmLabel; + var + referencelab: TAsmLabel; + s: PChar; + begin + current_asmdata.getdatalabel(result); + if NewSection then + new_section(list,sec_rodata,result.name,const_align(sizeof(pint))); + referencelab := nil; + if target_info.system in systems_darwin then + begin + current_asmdata.getdatalabel(referencelab); + list.concat(tai_label.create(referencelab)); + end; + list.concat(tai_const.create_pint(-1)); + list.concat(tai_const.create_pint(len)); + { make sure the string doesn't get dead stripped if the header is referenced } + if target_info.system in systems_darwin then + list.concat(tai_directive.create(asd_reference,result.name)); + list.concat(tai_label.create(result)); + { and vice versa } + if target_info.system in systems_darwin then + list.concat(tai_directive.create(asd_reference,referencelab.name)); + + getmem(s,len+1); + move(data^,s^,len); + s[len]:=#0; + list.concat(tai_string.create_pchar(s,len+1)); { terminating zero included } + end; + + function emit_unicodestring_const(list:TAsmList;data:Pointer;Winlike:Boolean):TAsmLabel; + var + referencelab: TAsmLabel; + i, strlength: SizeInt; + begin + current_asmdata.getdatalabel(result); + new_section(list,sec_rodata,result.name,const_align(sizeof(pint))); + referencelab := nil; + if target_info.system in systems_darwin then + begin + current_asmdata.getdatalabel(referencelab); + list.concat(tai_label.create(referencelab)); + end; + strlength := getlengthwidestring(pcompilerwidestring(data)); + if Winlike then + list.concat(Tai_const.Create_32bit(strlength*cwidechartype.size)) + else + begin + list.concat(Tai_const.Create_pint(-1)); + list.concat(Tai_const.Create_pint(strlength*cwidechartype.size)); + end; + { make sure the string doesn't get dead stripped if the header is referenced } + if (target_info.system in systems_darwin) then + list.concat(tai_directive.create(asd_reference,result.name)); + list.concat(Tai_label.Create(result)); + { ... and vice versa } + if (target_info.system in systems_darwin) then + list.concat(tai_directive.create(asd_reference,referencelab.name)); + if cwidechartype.size = 2 then + begin + for i:=0 to strlength-1 do + list.concat(Tai_const.Create_16bit(pcompilerwidestring(data)^.data[i])); + { ending #0 } + list.concat(Tai_const.Create_16bit(0)); + end + else + InternalError(200904271); { codegeneration for other sizes must be written } + end; + + +end. diff --git a/compiler/cresstr.pas b/compiler/cresstr.pas index 9b4de64e91..84fd58b584 100644 --- a/compiler/cresstr.pas +++ b/compiler/cresstr.pas @@ -37,7 +37,7 @@ uses symconst,symtype,symdef,symsym, verbose,fmodule,ppu, aasmbase,aasmtai,aasmdata, - aasmcpu; + aasmcpu,asmutils; Type { These are used to form a singly-linked list, ordered by hash value } @@ -127,31 +127,6 @@ uses procedure Tresourcestrings.CreateResourceStringData; - - function WriteValueString(p:pchar;len:longint):TasmLabel; - var - s : pchar; - referencelab: TAsmLabel; - begin - if (target_info.system in systems_darwin) then - begin - current_asmdata.getdatalabel(referencelab); - current_asmdata.asmlists[al_const].concat(tai_label.create(referencelab)); - end; - current_asmdata.getdatalabel(result); - current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint)))); - current_asmdata.asmlists[al_const].concat(tai_const.create_pint(-1)); - current_asmdata.asmlists[al_const].concat(tai_const.create_pint(len)); - current_asmdata.asmlists[al_const].concat(tai_label.create(result)); - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,referencelab.name)); - getmem(s,len+1); - move(p^,s^,len); - s[len]:=#0; - current_asmdata.asmlists[al_const].concat(tai_string.create_pchar(s,len)); - current_asmdata.asmlists[al_const].concat(tai_const.create_8bit(0)); - end; - Var namelab, valuelab : tasmlabel; @@ -163,13 +138,15 @@ uses makes the linking too dependent on the linker script requiring a SORT(*) for the data sections } maybe_new_object_file(current_asmdata.asmlists[al_const]); + new_section(current_asmdata.asmlists[al_const],sec_data,make_mangledname('RESSTRTABLE',current_module.localsymtable,''),sizeof(pint)); + maybe_new_object_file(current_asmdata.asmlists[al_resourcestrings]); new_section(current_asmdata.asmlists[al_resourcestrings],sec_data,make_mangledname('RESSTR',current_module.localsymtable,'1_START'),sizeof(pint)); current_asmdata.AsmLists[al_resourcestrings].concat(tai_symbol.createname_global( make_mangledname('RESSTR',current_module.localsymtable,'START'),AT_DATA,0)); { Write unitname entry } - namelab:=WriteValueString(@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^)); + namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@current_module.localsymtable.name^[1],length(current_module.localsymtable.name^),False); current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(namelab)); current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(nil)); current_asmdata.asmlists[al_resourcestrings].concat(tai_const.create_sym(nil)); @@ -185,11 +162,12 @@ uses new_section(current_asmdata.asmlists[al_const],sec_rodata,make_mangledname('RESSTR',current_module.localsymtable,'d_'+r.name),sizeof(pint)); { Write default value } if assigned(R.value) and (R.len<>0) then - valuelab:=WriteValueString(R.Value,R.Len) + valuelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],R.Value,R.Len,False) else valuelab:=nil; { Append the name as a ansistring. } - namelab:=WriteValueString(@R.Name[1],length(R.name)); + current_asmdata.asmlists[al_const].concat(cai_align.Create(const_align(sizeof(pint)))); + namelab:=emit_ansistring_const(current_asmdata.asmlists[al_const],@R.Name[1],length(R.name),False); { Resourcestring index: diff --git a/compiler/ncgcon.pas b/compiler/ncgcon.pas index a245e6b2de..fc14001959 100644 --- a/compiler/ncgcon.pas +++ b/compiler/ncgcon.pas @@ -71,7 +71,7 @@ implementation symconst,symdef,aasmbase,aasmtai,aasmdata,aasmcpu,defutil, cpuinfo,cpubase, cgbase,cgobj,cgutils, - ncgutil, cclasses + ncgutil, cclasses,asmutils ; @@ -306,41 +306,13 @@ implementation { :-(, we must generate a new entry } if not assigned(entry^.Data) then begin - current_asmdata.getdatalabel(lastlabel); - lab_str:=lastlabel; - entry^.Data := lastlabel; - maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]); - if (len=0) or - not(cst_type in [cst_ansistring,cst_widestring,cst_unicodestring]) then - new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint))) - else - new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata,lastlabel.name,const_align(sizeof(pint))); - { generate an ansi string ? } case cst_type of cst_ansistring: begin if len=0 then InternalError(2008032301) { empty string should be handled above } else - begin - current_asmdata.getdatalabel(l1); - current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1)); - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(-1)); - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(len)); - - { make sure the string doesn't get dead stripped if the header is referenced } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lastlabel.name)); - current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel)); - { ... and vice versa } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name)); - { include also terminating zero } - getmem(pc,len+1); - move(value_str^,pc^,len); - pc[len]:=#0; - current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1)); - end; + lastlabel:=emit_ansistring_const(current_asmdata.AsmLists[al_typedconsts],value_str,len); end; cst_unicodestring, cst_widestring: @@ -348,35 +320,16 @@ implementation if len=0 then InternalError(2008032302) { empty string should be handled above } else - begin - current_asmdata.getdatalabel(l1); - current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(l1)); - { we use always UTF-16 coding for constants } - { at least for now } - { Consts.concat(Tai_const.Create_8bit(2)); } - if (cst_type=cst_widestring) and (tf_winlikewidestring in target_info.flags) then - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_32bit(len*cwidechartype.size)) - else - begin - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(-1)); - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_pint(len*cwidechartype.size)); - end; - - { make sure the string doesn't get dead stripped if the header is referenced } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,lastlabel.name)); - current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel)); - { ... and vice versa } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_typedconsts].concat(tai_directive.create(asd_reference,l1.name)); - for i:=0 to len-1 do - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(pcompilerwidestring(value_str)^.data[i])); - { terminating zero } - current_asmdata.asmlists[al_typedconsts].concat(Tai_const.Create_16bit(0)); - end; + lastlabel := emit_unicodestring_const(current_asmdata.AsmLists[al_typedconsts], + value_str, + (cst_type=cst_widestring) and (tf_winlikewidestring in target_info.flags)); end; cst_shortstring: begin + current_asmdata.getdatalabel(lastlabel); + maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]); + new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint))); + current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel)); { truncate strings larger than 255 chars } if len>255 then @@ -392,6 +345,10 @@ implementation end; cst_conststring: begin + current_asmdata.getdatalabel(lastlabel); + maybe_new_object_file(current_asmdata.asmlists[al_typedconsts]); + new_section(current_asmdata.asmlists[al_typedconsts],sec_rodata_norel,lastlabel.name,const_align(sizeof(pint))); + current_asmdata.asmlists[al_typedconsts].concat(Tai_label.Create(lastlabel)); { include terminating zero } getmem(pc,len+1); @@ -400,6 +357,8 @@ implementation current_asmdata.asmlists[al_typedconsts].concat(Tai_string.Create_pchar(pc,len+1)); end; end; + lab_str:=lastlabel; + entry^.Data:=lastlabel; end; end; if cst_type in [cst_ansistring, cst_widestring, cst_unicodestring] then diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 6c39a1abee..a4497a40aa 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -236,6 +236,66 @@ implementation ltvTable.Free; end; + procedure InsertWideInits; + var + s: string; + item: TTCInitItem; + begin + item:=TTCInitItem(current_asmdata.WideInits.First); + if item=nil then + exit; + s:=make_mangledname('WIDEINITS',current_module.localsymtable,''); + maybe_new_object_file(current_asmdata.asmlists[al_globals]); + new_section(current_asmdata.asmlists[al_globals],sec_data,s,sizeof(pint)); + current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global(s,AT_DATA,0)); + repeat + { address to initialize } + current_asmdata.asmlists[al_globals].concat(Tai_const.createname(item.sym.mangledname, item.offset)); + { value with which to initialize } + current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(item.datalabel)); + item:=TTCInitItem(item.Next); + until item=nil; + { end-of-list marker } + current_asmdata.asmlists[al_globals].concat(Tai_const.Create_sym(nil)); + current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname(s)); + current_module.flags:=current_module.flags or uf_wideinits; + end; + + procedure InsertWideInitsTablesTable; + var + hp: tused_unit; + lwiTables: TAsmList; + count: longint; + begin + lwiTables:=TAsmList.Create; + count:=0; + hp:=tused_unit(usedunits.first); + while assigned(hp) do + begin + if (hp.u.flags and uf_wideinits)=uf_wideinits then + begin + lwiTables.concat(Tai_const.Createname(make_mangledname('WIDEINITS',hp.u.globalsymtable,''),0)); + inc(count); + end; + hp:=tused_unit(hp.next); + end; + { Add program widestring consts, if any } + if (current_module.flags and uf_wideinits)=uf_wideinits then + begin + lwiTables.concat(Tai_const.Createname(make_mangledname('WIDEINITS',current_module.localsymtable,''),0)); + inc(count); + end; + { Insert TableCount at start } + lwiTables.insert(Tai_const.Create_32bit(count)); + { insert in data segment } + maybe_new_object_file(current_asmdata.asmlists[al_globals]); + new_section(current_asmdata.asmlists[al_globals],sec_data,'FPC_WIDEINITTABLES',sizeof(pint)); + current_asmdata.asmlists[al_globals].concat(Tai_symbol.Createname_global('FPC_WIDEINITTABLES',AT_DATA,0)); + current_asmdata.asmlists[al_globals].concatlist(lwiTables); + current_asmdata.asmlists[al_globals].concat(Tai_symbol_end.Createname('FPC_WIDEINITTABLES')); + lwiTables.free; + end; + Function CheckResourcesUsed : boolean; var @@ -1225,6 +1285,9 @@ implementation { Resource strings } GenerateResourceStrings; + { Widestring typed constants } + InsertWideInits; + { generate debuginfo } if (cs_debuginfo in current_settings.moduleswitches) then current_debuginfo.inserttypeinfo; @@ -2193,10 +2256,14 @@ implementation { Resource strings } GenerateResourceStrings; + { Windows widestring needing initialization } + InsertWideInits; + { insert Tables and StackLength } insertinitfinaltable; InsertThreadvarTablesTable; InsertResourceTablesTable; + InsertWideInitsTablesTable; insertmemorysizes; { Insert symbol to resource info } diff --git a/compiler/ppu.pas b/compiler/ppu.pas index e1ac0f7439..7527dffb51 100644 --- a/compiler/ppu.pas +++ b/compiler/ppu.pas @@ -43,7 +43,7 @@ type {$endif Test_Double_checksum} const - CurrentPPUVersion = 106; + CurrentPPUVersion = 107; { buffer sizes } maxentrysize = 1024; @@ -156,6 +156,7 @@ const uf_has_resourcefiles = $80000; { this unit has external resources (using $R directive)} uf_has_exports = $100000; { this module or a used unit has exports } uf_has_dwarf_debuginfo = $200000; { this unit has dwarf debuginfo generated } + uf_wideinits = $400000; { this unit has winlike widestring typed constants } type diff --git a/compiler/ptconst.pas b/compiler/ptconst.pas index 929c302781..151cc07db6 100644 --- a/compiler/ptconst.pas +++ b/compiler/ptconst.pas @@ -45,7 +45,7 @@ implementation pbase,pexpr,pdecvar, { codegen } cpuinfo,cgbase,dbgbase, - wpobase + wpobase,asmutils ; {$maxfpuregisters 0} @@ -166,9 +166,16 @@ implementation read typed const *****************************************************************************} + type + { context used for parsing complex types (arrays/records/objects) } + threc = record + list : tasmlist; + origsym: tstaticvarsym; + offset: aint; + end; { this procedure reads typed constants } - procedure read_typed_const_data(list:tasmlist;def:tdef); + procedure read_typed_const_data(var hr:threc;def:tdef); forward; procedure parse_orddef(list:tasmlist;def:torddef); var @@ -408,7 +415,7 @@ implementation else varalign:=0; varalign:=const_align(varalign); - current_asmdata.asmlists[al_const].concat(Tai_align.Create(varalign)); + new_section(current_asmdata.asmlists[al_const], sec_rodata, ll.name, varalign); current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll)); if p.nodetype=stringconstn then begin @@ -635,15 +642,15 @@ implementation end; - procedure parse_stringdef(list:tasmlist;def:tstringdef); + procedure parse_stringdef(const hr:threc;def:tstringdef); var n : tnode; - i : longint; strlength : aint; strval : pchar; strch : char; - ll,ll2 : tasmlabel; + ll : tasmlabel; ca : pchar; + winlike : boolean; begin n:=comp_expr(true); { load strval and strlength of the constant tree } @@ -690,12 +697,12 @@ implementation message2(parser_w_string_too_long,strpas(strval),tostr(def.size-1)); strlength:=def.size-1; end; - list.concat(Tai_const.Create_8bit(strlength)); + hr.list.concat(Tai_const.Create_8bit(strlength)); { this can also handle longer strings } getmem(ca,strlength+1); move(strval^,ca^,strlength); ca[strlength]:=#0; - list.concat(Tai_string.Create_pchar(ca,strlength)); + hr.list.concat(Tai_string.Create_pchar(ca,strlength)); { fillup with spaces if size is shorter } if def.size>strlength then begin @@ -705,69 +712,41 @@ implementation fillchar(ca[0],def.size-strlength-1,' '); ca[def.size-strlength-1]:=#0; { this can also handle longer strings } - list.concat(Tai_string.Create_pchar(ca,def.size-strlength-1)); + hr.list.concat(Tai_string.Create_pchar(ca,def.size-strlength-1)); end; end; st_ansistring: begin { an empty ansi string is nil! } if (strlength=0) then - list.concat(Tai_const.Create_sym(nil)) + ll := nil else - begin - current_asmdata.getdatalabel(ll); - list.concat(Tai_const.Create_sym(ll)); - current_asmdata.getdatalabel(ll2); - current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint)))); - current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2)); - current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(-1)); - current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(strlength)); - { make sure the string doesn't get dead stripped if the header is referenced } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll.name)); - current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll)); - { ... and vice versa } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll2.name)); - getmem(ca,strlength+1); - move(strval^,ca^,strlength); - { The terminating #0 to be stored in the .data section (JM) } - ca[strlength]:=#0; - current_asmdata.asmlists[al_const].concat(Tai_string.Create_pchar(ca,strlength+1)); - end; + ll := emit_ansistring_const(current_asmdata.asmlists[al_const],strval,strlength); + hr.list.concat(Tai_const.Create_sym(ll)); end; st_unicodestring, st_widestring: begin - { an empty ansi string is nil! } + { an empty wide/unicode string is nil! } if (strlength=0) then - list.concat(Tai_const.Create_sym(nil)) + ll := nil else + begin + winlike := (def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags); + ll := emit_unicodestring_const(current_asmdata.asmlists[al_const], + strval, + winlike); + + { collect global Windows widestrings } + if winlike and (hr.origsym.owner.symtablelevel <= main_program_level) then begin - current_asmdata.getdatalabel(ll); - list.concat(Tai_const.Create_sym(ll)); - current_asmdata.getdatalabel(ll2); - current_asmdata.asmlists[al_const].concat(tai_align.create(const_align(sizeof(pint)))); - current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll2)); - if (def.stringtype=st_widestring) and (tf_winlikewidestring in target_info.flags) then - current_asmdata.asmlists[al_const].concat(Tai_const.Create_32bit(strlength*cwidechartype.size)) - else - begin - current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(-1)); - current_asmdata.asmlists[al_const].concat(Tai_const.Create_pint(strlength*cwidechartype.size)); - end; - { make sure the string doesn't get dead stripped if the header is referenced } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll.name)); - current_asmdata.asmlists[al_const].concat(Tai_label.Create(ll)); - { ... and vice versa } - if (target_info.system in systems_darwin) then - current_asmdata.asmlists[al_const].concat(tai_directive.create(asd_reference,ll2.name)); - for i:=0 to strlength-1 do - current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(pcompilerwidestring(strval)^.data[i])); - { ending #0 } - current_asmdata.asmlists[al_const].concat(Tai_const.Create_16bit(0)) + current_asmdata.WideInits.Concat( + TTCInitItem.Create(hr.origsym, hr.offset, ll) + ); + ll := nil; end; + end; + hr.list.concat(Tai_const.Create_sym(ll)); end; else internalerror(200107081); @@ -838,7 +817,7 @@ implementation end; - procedure parse_arraydef(list:tasmlist;def:tarraydef); + procedure parse_arraydef(hr:threc;def:tarraydef); var n : tnode; i : longint; @@ -851,24 +830,26 @@ implementation begin { Only allow nil initialization } consume(_NIL); - list.concat(Tai_const.Create_sym(nil)); + hr.list.concat(Tai_const.Create_sym(nil)); end { packed array constant } else if is_packed_array(def) and ((def.elepackedbitsize mod 8 <> 0) or not ispowerof2(def.elepackedbitsize div 8,i)) then begin - parse_packed_array_def(list,def); + parse_packed_array_def(hr.list,def); end { normal array const between brackets } else if try_to_consume(_LKLAMMER) then begin + hr.offset:=0; for i:=def.lowrange to def.highrange-1 do begin - read_typed_const_data(list,def.elementdef); + read_typed_const_data(hr,def.elementdef); + Inc(hr.offset,def.elementdef.size); consume(_COMMA); end; - read_typed_const_data(list,def.elementdef); + read_typed_const_data(hr,def.elementdef); consume(_RKLAMMER); end { if array of char then we allow also a string } @@ -902,12 +883,12 @@ implementation begin if i+1-def.lowrange<=len then begin - list.concat(Tai_const.Create_8bit(byte(ca^))); + hr.list.concat(Tai_const.Create_8bit(byte(ca^))); inc(ca); end else {Fill the remaining positions with #0.} - list.concat(Tai_const.Create_8bit(0)); + hr.list.concat(Tai_const.Create_8bit(0)); end; n.free; end @@ -983,7 +964,7 @@ implementation n.free; end; - procedure parse_recorddef(list:tasmlist;def:trecorddef); + procedure parse_recorddef(hr:threc;def:trecorddef); var n : tnode; symidx : longint; @@ -997,6 +978,7 @@ implementation bp : tbitpackedval; error, is_packed: boolean; + startoffset: aint; procedure handle_stringconstn; var @@ -1005,11 +987,11 @@ implementation hs:=strpas(tstringconstnode(n).value_str); if string2guid(hs,tmpguid) then begin - list.concat(Tai_const.Create_32bit(longint(tmpguid.D1))); - list.concat(Tai_const.Create_16bit(tmpguid.D2)); - list.concat(Tai_const.Create_16bit(tmpguid.D3)); + hr.list.concat(Tai_const.Create_32bit(longint(tmpguid.D1))); + hr.list.concat(Tai_const.Create_16bit(tmpguid.D2)); + hr.list.concat(Tai_const.Create_16bit(tmpguid.D3)); for i:=Low(tmpguid.D4) to High(tmpguid.D4) do - list.concat(Tai_const.Create_8bit(tmpguid.D4[i])); + hr.list.concat(Tai_const.Create_8bit(tmpguid.D4[i])); end else Message(parser_e_improper_guid_syntax); @@ -1031,11 +1013,11 @@ implementation if n.nodetype=guidconstn then begin tmpguid:=tguidconstnode(n).value; - list.concat(Tai_const.Create_32bit(longint(tmpguid.D1))); - list.concat(Tai_const.Create_16bit(tmpguid.D2)); - list.concat(Tai_const.Create_16bit(tmpguid.D3)); + hr.list.concat(Tai_const.Create_32bit(longint(tmpguid.D1))); + hr.list.concat(Tai_const.Create_16bit(tmpguid.D2)); + hr.list.concat(Tai_const.Create_16bit(tmpguid.D3)); for i:=Low(tmpguid.D4) to High(tmpguid.D4) do - list.concat(Tai_const.Create_8bit(tmpguid.D4[i])); + hr.list.concat(Tai_const.Create_8bit(tmpguid.D4[i])); end else Message(parser_e_illegal_expression); @@ -1071,6 +1053,7 @@ implementation sorg:=''; srsym:=tsym(def.symtable.SymList[symidx]); recsym := nil; + startoffset:=hr.offset; while token<>_RKLAMMER do begin s:=pattern; @@ -1136,14 +1119,14 @@ implementation fillbytes:=tfieldvarsym(srsym).fieldoffset-curroffset else begin - flush_packed_value(list,bp); + flush_packed_value(hr.list,bp); { curoffset is now aligned to the next byte } curroffset:=align(curroffset,8); { offsets are in bits in this case } fillbytes:=(tfieldvarsym(srsym).fieldoffset-curroffset) div 8; end; for i:=1 to fillbytes do - list.concat(Tai_const.Create_8bit(0)) + hr.list.concat(Tai_const.Create_8bit(0)) end; { new position } @@ -1160,15 +1143,16 @@ implementation begin if is_packed then begin - flush_packed_value(list,bp); + flush_packed_value(hr.list,bp); curroffset:=align(curroffset,8); end; - read_typed_const_data(list,tfieldvarsym(srsym).vardef); + hr.offset:=startoffset+tfieldvarsym(srsym).fieldoffset; + read_typed_const_data(hr,tfieldvarsym(srsym).vardef); end else begin bp.packedbitsize:=tfieldvarsym(srsym).vardef.packedbitsize; - parse_single_packed_const(list,tfieldvarsym(srsym).vardef,bp); + parse_single_packed_const(hr.list,tfieldvarsym(srsym).vardef,bp); end; { keep previous field for checking whether whole } @@ -1201,18 +1185,18 @@ implementation fillbytes:=def.size-curroffset else begin - flush_packed_value(list,bp); + flush_packed_value(hr.list,bp); curroffset:=align(curroffset,8); fillbytes:=def.size-(curroffset div 8); end; for i:=1 to fillbytes do - list.concat(Tai_const.Create_8bit(0)); + hr.list.concat(Tai_const.Create_8bit(0)); consume(_RKLAMMER); end; - - procedure parse_objectdef(list:tasmlist;def:tobjectdef); + { note: hr is passed by value } + procedure parse_objectdef(hr:threc;def:tobjectdef); var n : tnode; i : longint; @@ -1222,6 +1206,7 @@ implementation curroffset : aint; s,sorg : TIDString; vmtwritten : boolean; + startoffset:aint; begin { no support for packed object } if is_packed_record_or_object(def) then @@ -1240,7 +1225,7 @@ implementation consume_all_until(_SEMICOLON); end else - list.concat(Tai_const.Create_sym(nil)); + hr.list.concat(Tai_const.Create_sym(nil)); n.free; exit; end; @@ -1254,6 +1239,7 @@ implementation end; consume(_LKLAMMER); + startoffset:=hr.offset; curroffset:=0; vmtwritten:=false; while token<>_RKLAMMER do @@ -1295,8 +1281,8 @@ implementation (def.vmt_offsetcurroffset then for i:=1 to fieldoffset-curroffset do - list.concat(Tai_const.Create_8bit(0)); + hr.list.concat(Tai_const.Create_8bit(0)); { new position } curroffset:=fieldoffset+vardef.size; { read the data } - read_typed_const_data(list,vardef); + hr.offset:=startoffset+fieldoffset; + read_typed_const_data(hr,vardef); if not try_to_consume(_SEMICOLON) then break; @@ -1322,16 +1309,17 @@ implementation (def.vmt_offset>=curroffset) then begin for i:=1 to def.vmt_offset-curroffset do - list.concat(tai_const.create_8bit(0)); - list.concat(tai_const.createname(def.vmt_mangledname,0)); + hr.list.concat(tai_const.create_8bit(0)); + hr.list.concat(tai_const.createname(def.vmt_mangledname,0)); { this is more general } curroffset:=def.vmt_offset + sizeof(pint); end; for i:=1 to def.size-curroffset do - list.concat(Tai_const.Create_8bit(0)); + hr.list.concat(Tai_const.Create_8bit(0)); consume(_RKLAMMER); end; + procedure read_typed_const_data(var hr:threc;def:tdef); var old_block_type : tblock_type; begin @@ -1339,27 +1327,27 @@ implementation block_type:=bt_const; case def.typ of orddef : - parse_orddef(list,torddef(def)); + parse_orddef(hr.list,torddef(def)); floatdef : - parse_floatdef(list,tfloatdef(def)); + parse_floatdef(hr.list,tfloatdef(def)); classrefdef : - parse_classrefdef(list,tclassrefdef(def)); + parse_classrefdef(hr.list,tclassrefdef(def)); pointerdef : - parse_pointerdef(list,tpointerdef(def)); + parse_pointerdef(hr.list,tpointerdef(def)); setdef : - parse_setdef(list,tsetdef(def)); + parse_setdef(hr.list,tsetdef(def)); enumdef : - parse_enumdef(list,tenumdef(def)); + parse_enumdef(hr.list,tenumdef(def)); stringdef : - parse_stringdef(list,tstringdef(def)); + parse_stringdef(hr,tstringdef(def)); arraydef : - parse_arraydef(list,tarraydef(def)); + parse_arraydef(hr,tarraydef(def)); procvardef: - parse_procvardef(list,tprocvardef(def)); + parse_procvardef(hr.list,tprocvardef(def)); recorddef: - parse_recorddef(list,trecorddef(def)); + parse_recorddef(hr,trecorddef(def)); objectdef: - parse_objectdef(list,tobjectdef(def)); + parse_objectdef(hr,tobjectdef(def)); errordef: begin { try to consume something useful } @@ -1380,7 +1368,7 @@ implementation var storefilepos : tfileposinfo; cursectype : TAsmSectionType; - valuelist : tasmlist; + hrec : threc; begin { mark the staticvarsym as typedconst } include(sym.varoptions,vo_is_typed_const); @@ -1397,8 +1385,10 @@ implementation else cursectype:=sec_data; maybe_new_object_file(list); - valuelist:=tasmlist.create; - read_typed_const_data(valuelist,sym.vardef); + hrec.list:=tasmlist.create; + hrec.origsym:=sym; + hrec.offset:=0; + read_typed_const_data(hrec,sym.vardef); { Parse hints } try_consume_hintdirective(sym.symoptions,sym.deprecatedmsg); @@ -1435,8 +1425,8 @@ implementation list.concat(Tai_symbol.Createname(sym.mangledname,AT_DATA,0)); { add the parsed value } - list.concatlist(valuelist); - valuelist.free; + list.concatlist(hrec.list); + hrec.list.free; list.concat(tai_symbol_end.Createname(sym.mangledname)); current_filepos:=storefilepos; end;