Browse Source

+ add a method to emit a reference to a pooled shortstring constant (aka one per unit); very useful for new RTTI tables to avoid poluting the binary with string constants

git-svn-id: trunk@39683 -
svenbarth 7 years ago
parent
commit
8bf3661f7f
1 changed files with 53 additions and 0 deletions
  1. 53 0
      compiler/aasmcnst.pas

+ 53 - 0
compiler/aasmcnst.pas

@@ -365,6 +365,9 @@ type
      { emit an ordinal constant }
      { emit an ordinal constant }
      procedure emit_ord_const(value: int64; def: tdef);
      procedure emit_ord_const(value: int64; def: tdef);
 
 
+     { emit a reference to a pooled shortstring constant }
+     procedure emit_pooled_shortstring_const_ref(const str:shortstring);
+
      { begin a potential aggregate type. Must be called for any type
      { begin a potential aggregate type. Must be called for any type
        that consists of multiple tai constant data entries, or that
        that consists of multiple tai constant data entries, or that
        represents an aggregate at the Pascal level (a record, a non-dynamic
        represents an aggregate at the Pascal level (a record, a non-dynamic
@@ -1846,6 +1849,56 @@ implementation
      end;
      end;
 
 
 
 
+   procedure ttai_typedconstbuilder.emit_pooled_shortstring_const_ref(const str:shortstring);
+     var
+       pool : thashset;
+       entry : phashsetitem;
+       strlab : tasmlabel;
+       l : longint;
+       pc : pansichar;
+       datadef : tdef;
+       strtcb : ttai_typedconstbuilder;
+     begin
+       pool:=current_asmdata.ConstPools[sp_shortstr];
+
+       entry:=pool.FindOrAdd(@str[1],length(str));
+
+       { :-(, we must generate a new entry }
+       if not assigned(entry^.Data) then
+         begin
+           current_asmdata.getglobaldatalabel(strlab);
+
+           { include length and terminating zero for quick conversion to pchar }
+           l:=length(str);
+           getmem(pc,l+2);
+           move(str[1],pc[1],l);
+           pc[0]:=chr(l);
+           pc[l+1]:=#0;
+
+           datadef:=carraydef.getreusable(cansichartype,l+2);
+
+           { we start a new constbuilder as we don't know whether we're called
+             from inside an internal constbuilder }
+           strtcb:=ctai_typedconstbuilder.create([tcalo_is_lab,tcalo_make_dead_strippable,tcalo_apply_constalign]);
+
+           strtcb.maybe_begin_aggregate(datadef);
+           strtcb.emit_tai(Tai_string.Create_pchar(pc,l+2),datadef);
+           strtcb.maybe_end_aggregate(datadef);
+
+           current_asmdata.asmlists[al_typedconsts].concatList(
+             strtcb.get_final_asmlist(strlab,datadef,sec_rodata_norel,strlab.name,const_align(sizeof(pint)))
+           );
+           strtcb.free;
+
+           entry^.Data:=strlab;
+         end
+       else
+         strlab:=tasmlabel(entry^.Data);
+
+       emit_tai(tai_const.Create_sym(strlab),charpointertype);
+     end;
+
+
    procedure ttai_typedconstbuilder.maybe_begin_aggregate(def: tdef);
    procedure ttai_typedconstbuilder.maybe_begin_aggregate(def: tdef);
      begin
      begin
        begin_aggregate_internal(def,false);
        begin_aggregate_internal(def,false);