Browse Source

* converted generation of class and fields table to the typed constant builder

git-svn-id: branches/hlcgllvm@28772 -
Jonas Maebe 10 years ago
parent
commit
8fa4c69f1f
1 changed files with 67 additions and 20 deletions
  1. 67 20
      compiler/ncgvmt.pas

+ 67 - 20
compiler/ncgvmt.pas

@@ -600,6 +600,11 @@ implementation
         classindex,
         fieldcount : longint;
         classtablelist : TFPList;
+        tcb: ttai_typedconstbuilder;
+        packrecords: longint;
+        classdef: tobjectdef;
+        classtabledef,
+        fieldtabledef: trecorddef;
       begin
         classtablelist:=TFPList.Create;
         { retrieve field info fields }
@@ -624,39 +629,81 @@ implementation
             current_asmdata.getlabel(fieldtable,alt_data);
             current_asmdata.getlabel(classtable,alt_data);
 
-            list.concat(cai_align.create(const_align(sizeof(pint))));
-            { write fields }
-            list.concat(Tai_label.Create(fieldtable));
-            list.concat(Tai_const.Create_16bit(fieldcount));
             if (tf_requires_proper_alignment in target_info.flags) then
-              list.concat(cai_align.Create(sizeof(TConstPtrUInt)));
-            list.concat(Tai_const.Create_sym(classtable));
+              packrecords:=0
+            else
+              packrecords:=1;
+
+            { generate the class table }
+            tcb:=ctai_typedconstbuilder.create;
+            tcb.begin_anonymous_record('$fpc_intern_classtable_'+tostr(classtablelist.Count-1),packrecords);
+            tcb.emit_tai(Tai_const.Create_16bit(classtablelist.count),u16inttype);
+            for i:=0 to classtablelist.Count-1 do
+              begin
+                classdef:=tobjectdef(classtablelist[i]);
+                { type of the field }
+                tcb.queue_init(voidpointertype);
+                { reference to the vmt }
+                tcb.queue_emit_asmsym(
+                  current_asmdata.RefAsmSymbol(classdef.vmt_mangledname,AT_DATA),
+                  tfieldvarsym(classdef.vmt_field).vardef);
+              end;
+            classtabledef:=tcb.end_anonymous_record;
+            list.concatlist(tcb.get_final_asmlist(classtable,classtabledef,sec_rodata,'',sizeof(pint),[tcalo_is_lab]));
+            tcb.free;
+
+            { write fields }
+            {
+              TFieldTable =
+             $ifndef FPC_REQUIRES_PROPER_ALIGNMENT
+              packed
+             $endif FPC_REQUIRES_PROPER_ALIGNMENT
+              record
+                FieldCount: Word;
+                ClassTable: Pointer;
+                Fields: array[0..0] of TFieldInfo
+              end;
+            }
+            tcb:=ctai_typedconstbuilder.create;
+            { can't easily specify a name here for reuse of the constructed def,
+              since it's full of variable length shortstrings (-> all of those
+              lengths and their order would have to incorporated in the name,
+              plus there would be very little chance that it could actually be
+              reused }
+            tcb.begin_anonymous_record('',packrecords);
+            tcb.emit_tai(Tai_const.Create_16bit(fieldcount),u16inttype);
+            tcb.emit_tai(Tai_const.Create_sym(classtable),getpointerdef(classtabledef));
             for i:=0 to _class.symtable.SymList.Count-1 do
               begin
                 sym:=tsym(_class.symtable.SymList[i]);
                 if (sym.typ=fieldvarsym) and
                   (sym.visibility=vis_published) then
                   begin
-                    if (tf_requires_proper_alignment in target_info.flags) then
-                      list.concat(cai_align.Create(sizeof(pint)));
-                    list.concat(Tai_const.Create_pint(tfieldvarsym(sym).fieldoffset));
+                    {
+                      TFieldInfo =
+                     $ifndef FPC_REQUIRES_PROPER_ALIGNMENT
+                      packed
+                     $endif FPC_REQUIRES_PROPER_ALIGNMENT
+                      record
+                        FieldOffset: PtrUInt;
+                        ClassTypeIndex: Word;
+                        Name: ShortString;
+                      end;
+                    }
+                    tcb.begin_anonymous_record('$fpc_intern_fieldinfo_'+tostr(length(tfieldvarsym(sym).realname)),packrecords);
+                    tcb.emit_tai(Tai_const.Create_pint(tfieldvarsym(sym).fieldoffset),ptruinttype);
                     classindex:=classtablelist.IndexOf(tfieldvarsym(sym).vardef);
                     if classindex=-1 then
                       internalerror(200611033);
-                    list.concat(Tai_const.Create_16bit(classindex+1));
-                    list.concat(Tai_const.Create_8bit(length(tfieldvarsym(sym).realname)));
-                    list.concat(Tai_string.Create(tfieldvarsym(sym).realname));
+                    tcb.emit_tai(Tai_const.Create_16bit(classindex+1),u16inttype);
+                    tcb.emit_shortstring_const(tfieldvarsym(sym).realname);
+                    tcb.end_anonymous_record;
                   end;
               end;
+            fieldtabledef:=tcb.end_anonymous_record;
+            list.concatlist(tcb.get_final_asmlist(fieldtable,fieldtabledef,sec_rodata,'',sizeof(pint),[tcalo_is_lab]));
+            tcb.free;
 
-            { generate the class table }
-            list.concat(cai_align.create(const_align(sizeof(pint))));
-            list.concat(Tai_label.Create(classtable));
-            list.concat(Tai_const.Create_16bit(classtablelist.count));
-            if (tf_requires_proper_alignment in target_info.flags) then
-              list.concat(cai_align.Create(sizeof(TConstPtrUInt)));
-            for i:=0 to classtablelist.Count-1 do
-              list.concat(Tai_const.Createname(tobjectdef(classtablelist[i]).vmt_mangledname,AT_DATA,0));
             result:=fieldtable;
           end
         else