Selaa lähdekoodia

* moved oo_copied into defoptions
* record symtables are now handled properly as well if a record is copied, resolves #9144
* fixed a memory leak when copying classes
* increased PPU version to 91

git-svn-id: trunk@11273 -

florian 17 vuotta sitten
vanhempi
commit
fca8883f27
6 muutettua tiedostoa jossa 88 lisäystä ja 30 poistoa
  1. 2 0
      .gitattributes
  2. 1 1
      compiler/ppu.pas
  3. 4 3
      compiler/symconst.pas
  4. 54 26
      compiler/symdef.pas
  5. 14 0
      tests/webtbs/tw9144a.pp
  6. 13 0
      tests/webtbs/tw9144b.pp

+ 2 - 0
.gitattributes

@@ -9205,6 +9205,8 @@ tests/webtbs/tw9128.pp svneol=native#text/plain
 tests/webtbs/tw9139.pp svneol=native#text/plain
 tests/webtbs/tw9139.pp svneol=native#text/plain
 tests/webtbs/tw9139a.pp svneol=native#text/plain
 tests/webtbs/tw9139a.pp svneol=native#text/plain
 tests/webtbs/tw9141.pp svneol=native#text/plain
 tests/webtbs/tw9141.pp svneol=native#text/plain
+tests/webtbs/tw9144a.pp svneol=native#text/plain
+tests/webtbs/tw9144b.pp svneol=native#text/plain
 tests/webtbs/tw9145.pp svneol=native#text/plain
 tests/webtbs/tw9145.pp svneol=native#text/plain
 tests/webtbs/tw9161.pp svneol=native#text/plain
 tests/webtbs/tw9161.pp svneol=native#text/plain
 tests/webtbs/tw9162.pp svneol=native#text/plain
 tests/webtbs/tw9162.pp svneol=native#text/plain

+ 1 - 1
compiler/ppu.pas

@@ -43,7 +43,7 @@ type
 {$endif Test_Double_checksum}
 {$endif Test_Double_checksum}
 
 
 const
 const
-  CurrentPPUVersion = 90;
+  CurrentPPUVersion = 91;
 
 
 { buffer sizes }
 { buffer sizes }
   maxentrysize = 1024;
   maxentrysize = 1024;

+ 4 - 3
compiler/symconst.pas

@@ -148,7 +148,9 @@ type
     { type is a generic }
     { type is a generic }
     df_generic,
     df_generic,
     { type is a specialization of a generic type }
     { type is a specialization of a generic type }
-    df_specialization
+    df_specialization,
+    { def has been copied from another def so symtable is not owned }
+    df_copied_def
   );
   );
   tdefoptions=set of tdefoption;
   tdefoptions=set of tdefoption;
 
 
@@ -301,8 +303,7 @@ type
     oo_has_msgint,
     oo_has_msgint,
     oo_can_have_published,{ the class has rtti, i.e. you can publish properties }
     oo_can_have_published,{ the class has rtti, i.e. you can publish properties }
     oo_has_default_property,
     oo_has_default_property,
-    oo_has_valid_guid,
-    oo_copied_class
+    oo_has_valid_guid
   );
   );
   tobjectoptions=set of tobjectoption;
   tobjectoptions=set of tobjectoption;
 
 

+ 54 - 26
compiler/symdef.pas

@@ -170,6 +170,8 @@ interface
 
 
        tabstractrecorddef= class(tstoreddef)
        tabstractrecorddef= class(tstoreddef)
           symtable : TSymtable;
           symtable : TSymtable;
+          cloneddef      : tabstractrecorddef;
+          cloneddefderef : tderef;
           procedure reset;override;
           procedure reset;override;
           function  GetSymtable(t:tGetSymtable):TSymtable;override;
           function  GetSymtable(t:tGetSymtable):TSymtable;override;
           function is_packed:boolean;
           function is_packed:boolean;
@@ -226,8 +228,6 @@ interface
           dwarf_struct_lab : tasmsymbol;
           dwarf_struct_lab : tasmsymbol;
           childof        : tobjectdef;
           childof        : tobjectdef;
           childofderef   : tderef;
           childofderef   : tderef;
-          cloneddef      : tobjectdef;
-          cloneddefderef : tderef;
 
 
           objname,
           objname,
           objrealname    : pshortstring;
           objrealname    : pshortstring;
@@ -2447,7 +2447,9 @@ implementation
       begin
       begin
          inherited create(recorddef);
          inherited create(recorddef);
          symtable:=p;
          symtable:=p;
-         symtable.defowner:=self;
+         { we can own the symtable only if nobody else owns a copy so far }
+         if symtable.refcount=1 then
+           symtable.defowner:=self;
          isunion:=false;
          isunion:=false;
       end;
       end;
 
 
@@ -2455,15 +2457,20 @@ implementation
     constructor trecorddef.ppuload(ppufile:tcompilerppufile);
     constructor trecorddef.ppuload(ppufile:tcompilerppufile);
       begin
       begin
          inherited ppuload(recorddef,ppufile);
          inherited ppuload(recorddef,ppufile);
-         symtable:=trecordsymtable.create(0);
-         trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
-         trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
-         trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
-         trecordsymtable(symtable).usefieldalignment:=shortint(ppufile.getbyte);
-         { requires usefieldalignment to be set }
-         trecordsymtable(symtable).datasize:=ppufile.getaint;
-         trecordsymtable(symtable).ppuload(ppufile);
-         symtable.defowner:=self;
+         if df_copied_def in defoptions then
+           ppufile.getderef(cloneddefderef)
+         else
+           begin
+             symtable:=trecordsymtable.create(0);
+             trecordsymtable(symtable).fieldalignment:=shortint(ppufile.getbyte);
+             trecordsymtable(symtable).recordalignment:=shortint(ppufile.getbyte);
+             trecordsymtable(symtable).padalignment:=shortint(ppufile.getbyte);
+             trecordsymtable(symtable).usefieldalignment:=shortint(ppufile.getbyte);
+             trecordsymtable(symtable).datasize:=ppufile.getaint;
+             trecordsymtable(symtable).ppuload(ppufile);
+             { requires usefieldalignment to be set }
+             symtable.defowner:=self;
+           end;
          isunion:=false;
          isunion:=false;
       end;
       end;
 
 
@@ -2483,6 +2490,7 @@ implementation
       begin
       begin
         result:=trecorddef.create(symtable.getcopy);
         result:=trecorddef.create(symtable.getcopy);
         trecorddef(result).isunion:=isunion;
         trecorddef(result).isunion:=isunion;
+        include(trecorddef(result).defoptions,df_copied_def);
       end;
       end;
 
 
 
 
@@ -2495,7 +2503,10 @@ implementation
     procedure trecorddef.buildderef;
     procedure trecorddef.buildderef;
       begin
       begin
          inherited buildderef;
          inherited buildderef;
-         tstoredsymtable(symtable).buildderef;
+         if df_copied_def in defoptions then
+           cloneddefderef.build(symtable.defowner)
+         else
+           tstoredsymtable(symtable).buildderef;
       end;
       end;
 
 
 
 
@@ -2503,7 +2514,13 @@ implementation
       begin
       begin
          inherited deref;
          inherited deref;
          { now dereference the definitions }
          { now dereference the definitions }
-         tstoredsymtable(symtable).deref;
+         if df_copied_def in defoptions then
+           begin
+             cloneddef:=trecorddef(cloneddefderef.resolve);
+             symtable:=cloneddef.symtable.getcopy;
+           end
+         else
+           tstoredsymtable(symtable).deref;
          { assign TGUID? load only from system unit }
          { assign TGUID? load only from system unit }
          if not(assigned(rec_tguid)) and
          if not(assigned(rec_tguid)) and
             (upper(typename)='TGUID') and
             (upper(typename)='TGUID') and
@@ -2517,13 +2534,21 @@ implementation
     procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
     procedure trecorddef.ppuwrite(ppufile:tcompilerppufile);
       begin
       begin
          inherited ppuwrite(ppufile);
          inherited ppuwrite(ppufile);
-         ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
-         ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
-         ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
-         ppufile.putbyte(byte(trecordsymtable(symtable).usefieldalignment));
-         ppufile.putaint(trecordsymtable(symtable).datasize);
+         if df_copied_def in defoptions then
+           ppufile.putderef(cloneddefderef)
+         else
+           begin
+             ppufile.putbyte(byte(trecordsymtable(symtable).fieldalignment));
+             ppufile.putbyte(byte(trecordsymtable(symtable).recordalignment));
+             ppufile.putbyte(byte(trecordsymtable(symtable).padalignment));
+             ppufile.putbyte(byte(trecordsymtable(symtable).usefieldalignment));
+             ppufile.putaint(trecordsymtable(symtable).datasize);
+           end;
+
          ppufile.writeentry(ibrecorddef);
          ppufile.writeentry(ibrecorddef);
-         trecordsymtable(symtable).ppuwrite(ppufile);
+
+         if not(df_copied_def in defoptions) then
+           trecordsymtable(symtable).ppuwrite(ppufile);
       end;
       end;
 
 
 
 
@@ -3702,7 +3727,7 @@ implementation
          else
          else
            ImplementedInterfaces:=nil;
            ImplementedInterfaces:=nil;
 
 
-         if oo_copied_class in objectoptions then
+         if df_copied_def in defoptions then
            ppufile.getderef(cloneddefderef)
            ppufile.getderef(cloneddefderef)
          else
          else
            tObjectSymtable(symtable).ppuload(ppufile);
            tObjectSymtable(symtable).ppuload(ppufile);
@@ -3756,12 +3781,15 @@ implementation
         i : longint;
         i : longint;
       begin
       begin
         result:=tobjectdef.create(objecttype,objname^,childof);
         result:=tobjectdef.create(objecttype,objname^,childof);
+        { the constructor allocates a symtable which we release to avoid memory leaks }
+        tobjectdef(result).symtable.free;
         tobjectdef(result).symtable:=symtable.getcopy;
         tobjectdef(result).symtable:=symtable.getcopy;
         if assigned(objname) then
         if assigned(objname) then
           tobjectdef(result).objname:=stringdup(objname^);
           tobjectdef(result).objname:=stringdup(objname^);
         if assigned(objrealname) then
         if assigned(objrealname) then
           tobjectdef(result).objrealname:=stringdup(objrealname^);
           tobjectdef(result).objrealname:=stringdup(objrealname^);
-        tobjectdef(result).objectoptions:=objectoptions+[oo_copied_class];
+        tobjectdef(result).objectoptions:=objectoptions;
+        include(tobjectdef(result).defoptions,df_copied_def);
         tobjectdef(result).vmt_offset:=vmt_offset;
         tobjectdef(result).vmt_offset:=vmt_offset;
         if assigned(iidguid) then
         if assigned(iidguid) then
           begin
           begin
@@ -3814,12 +3842,12 @@ implementation
                end;
                end;
            end;
            end;
 
 
-         if oo_copied_class in objectoptions then
+         if df_copied_def in defoptions then
            ppufile.putderef(cloneddefderef);
            ppufile.putderef(cloneddefderef);
 
 
          ppufile.writeentry(ibobjectdef);
          ppufile.writeentry(ibobjectdef);
 
 
-         if not(oo_copied_class in objectoptions) then
+         if not(df_copied_def in defoptions) then
            tObjectSymtable(symtable).ppuwrite(ppufile);
            tObjectSymtable(symtable).ppuwrite(ppufile);
       end;
       end;
 
 
@@ -3843,7 +3871,7 @@ implementation
       begin
       begin
          inherited buildderef;
          inherited buildderef;
          childofderef.build(childof);
          childofderef.build(childof);
-         if oo_copied_class in objectoptions then
+         if df_copied_def in defoptions then
            cloneddefderef.build(symtable.defowner)
            cloneddefderef.build(symtable.defowner)
          else
          else
            tstoredsymtable(symtable).buildderef;
            tstoredsymtable(symtable).buildderef;
@@ -3862,7 +3890,7 @@ implementation
       begin
       begin
          inherited deref;
          inherited deref;
          childof:=tobjectdef(childofderef.resolve);
          childof:=tobjectdef(childofderef.resolve);
-         if oo_copied_class in objectoptions then
+         if df_copied_def in defoptions then
            begin
            begin
              cloneddef:=tobjectdef(cloneddefderef.resolve);
              cloneddef:=tobjectdef(cloneddefderef.resolve);
              symtable:=cloneddef.symtable.getcopy;
              symtable:=cloneddef.symtable.getcopy;

+ 14 - 0
tests/webtbs/tw9144a.pp

@@ -0,0 +1,14 @@
+{ %norun }
+{$mode delphi}
+
+unit tw9144a;
+
+interface
+
+type
+  TnxGuid = TGuid;
+  TnxNotifierID = type TnxGuid;
+
+implementation
+
+end.

+ 13 - 0
tests/webtbs/tw9144b.pp

@@ -0,0 +1,13 @@
+{ %norun }
+{$mode delphi}
+
+unit tw9144b;
+
+interface
+
+uses
+  tw9144a;
+
+implementation
+
+end.