View Issue Details

IDProjectCategoryView StatusLast Update
0016070FPCCompilerpublic2015-11-17 19:41
Reportermspiller Assigned To 
PrioritynormalSeverityminorReproducibilityalways
Status newResolutionopen 
Platform32 bitOSWindows XP 
Product Version2.5.1 
Summary0016070: Build and Build All do not produce the same results (dll exports)
DescriptionIt seems build from .o and .ppu ignores the exports directive from inside that pas file.

Create a simple library and new unit. Export some methods from that unit.
Build All (you can see dll exports), then just Build (dll export is gone).
TagsNo tags attached.
Fixed in Revision
FPCOldBugId
FPCTarget
Attached Files

Relationships

has duplicate 0030216 resolvedMarco van de Voort FPC windows library exports from unit 
related to 0025724 closedMattias Gaertner Lazarus Error: exports clause only allowed in libraries. 
child of 0018030 new FPC exports keyword incompatibility 

Activities

Jonas Maebe

2010-03-21 21:25

manager   ~0035888

The compiler has no "build" and "build all" parameters. Do you mean the text mode IDE?

Furthermore, please provide such a library and a test program that demonstrate the problem.

2010-03-21 22:55

 

test.zip (716 bytes)

mspiller

2010-03-21 23:01

reporter   ~0035894

Actually I meant Lazarus. Nevertheless it is a compiler bug. The difference between Build and Build All is the -B compiler parameter. Probably the same goes for text mode IDE, right?

If you don't have Delphi's tdump you can use http://www.emmestech.com/software/pexports-0.43/download_pexports.html

Clean compile exports sample with "a" and "test". Quick recompile exports only "a" that is exported inside a .lpr file but not test from uExports.

The provided sample works in Delphi.

Jonas Maebe

2010-10-05 23:53

manager   ~0041530

The exports section is indeed currently not stored in the ppu file.

Mike

2010-10-18 18:44

reporter   ~0041903

I also have this issue (and my customers too).

Lazarus lose exported names from one build to another.

Simple example:

I have a dll project, there is EXPORTS section. It contains some name:

exports
  SomeProcName;

I compile this project and I can see SomeProcName when I use resulting dll.
I compile this project once more (did not change anything) - and I can not see SomeProcName in resulting dll this time.

Can you please fix it? Because it is not possible to create dlls with your tool at all.

Lars

2011-12-13 00:24

reporter   ~0055002

If you add EXPORT keyword to each procedure does it help for you? For me, it requires a build all if I do not add export keyword. If I use the export keyword in addition to exports section, it doesn't require build all. This is on win32, haven't tried other yet.

Cyrax

2014-02-15 22:40

reporter  

unit_exports_support.patch (6,826 bytes)   
Index: compiler/export.pas
===================================================================
--- compiler/export.pas	(revision 26788)
+++ compiler/export.pas	(working copy)
@@ -92,7 +92,7 @@
 implementation
 
 uses
-  verbose,globals;
+  verbose,globals, fmodule;
 
 {****************************************************************************
                            TExported_procedure
@@ -100,7 +100,7 @@
 
 procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, copy_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -108,6 +108,16 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportprocedure(hp);
+
+    If current_module.is_unit Then Begin
+      copy_hp:=texported_item.create;
+      copy_hp.name:=stringdup(s);
+      copy_hp.sym:=sym;
+      copy_hp.options:=options or eo_name;
+      copy_hp.index:=index;
+      current_module._exports.Insert(copy_hp);
+    end;
+
   end;
 
 
Index: compiler/fppu.pas
===================================================================
--- compiler/fppu.pas	(revision 26788)
+++ compiler/fppu.pas	(working copy)
@@ -86,6 +86,7 @@
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeExportSymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -93,6 +94,7 @@
           procedure readderefmap;
           procedure readderefdata;
           procedure readImportSymbols;
+          procedure readExportSymbols;
           procedure readResources;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
@@ -116,7 +118,9 @@
   scanner,
   aasmbase,ogbase,
   parser,
-  comphook;
+  comphook,
+  export,
+  symdef;
 
 
 var
@@ -134,7 +138,7 @@
       end;
 
 
-    destructor tppumodule.Destroy;
+        destructor tppumodule.destroy;
       begin
         if assigned(ppufile) then
          ppufile.free;
@@ -668,7 +672,40 @@
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeExportSymbols;
+    Var
+      ExportSymbol : texported_item;
+      I : Integer;
+      AProcSym : TProcSym;
+      Aprocdef : Tprocdef;
+    begin
+      ExportSymbol := texported_item(Self._exports.First);
+      While Assigned(ExportSymbol) Do Begin
 
+        If Assigned(ExportSymbol.sym) Then Begin
+          If ExportSymbol.sym is TProcSym Then Begin
+            AProcSym := TProcSym(ExportSymbol.sym);
+            ppufile.putlongint(AProcSym.ProcdefList.Count);
+            For I := 0 To AProcSym.ProcdefList.Count - 1 Do Begin
+              Aprocdef := Tprocdef(AProcSym.ProcdefList[I]);
+              ppufile.putstring(Aprocdef.mangledname);
+            end;
+          end;
+        end;
+
+        ppufile.putstring(ExportSymbol.name^);
+        ppufile.putlongint(ExportSymbol.index);
+        ppufile.putword(ExportSymbol.options);
+        ppufile.putbyte(byte(ExportSymbol.is_var));
+
+        ExportSymbol := texported_item(ExportSymbol.Next);
+
+      end;
+
+      ppufile.writeentry(ibExportSymbols);
+    end;
+
+
     procedure tppumodule.writeResources;
       var
         res : TCmdStrListItem;
@@ -946,7 +983,86 @@
           end;
       end;
 
+    procedure tppumodule.readExportSymbols;
+    Var
+      ExportSymbol, copy_ExportSymbol : texported_item;
+      SymName, ExportSymName, AMangledName, AClassName : String;
+      sym, asym : tsym;
+      I, A, ACount : Integer;
+      AProcSym : TProcSym;
+      Aprocdef : Tprocdef;
+      AFound : Boolean;
+      AEntry : byte;
 
+
+        procedure FindSymbol(ASymTable : TSymtable);
+        Var
+          C : Integer;
+        begin
+          For C := 0 To ASymTable.DefList.Count - 1 Do Begin
+            AClassName := ASymTable.DefList[C].ClassName;
+            if ASymTable.DefList[C] is TProcDef Then Begin
+              Aprocdef := TProcDef(ASymTable.DefList[C]);
+              AMangledName := AProcDef.mangledname;
+              If SymName = AMangledName Then Begin
+                sym := AProcDef.procsym;
+                AFound := True;
+                break;
+              end;
+            end;
+          end;
+        end;
+
+    begin
+       ppufile.closefile;
+       ppufile.openfile;
+       If not ppufile.skipuntilentry(ibExportSymbols) then
+         exit;
+      while not ppufile.endofentry do
+        begin
+          ExportSymbol := texported_item.create;
+          copy_ExportSymbol := texported_item.create;
+
+          ACount := ppufile.getlongint;
+          AFound := False;
+
+          While ACount <> 0 Do Begin
+
+            SymName := ppufile.getstring;
+
+            sym := NIL;
+
+            FindSymbol(Self.localsymtable);
+            FindSymbol(Self.globalsymtable);
+
+            If AFound Then
+              Break;
+
+            Dec(ACount);
+          end;
+
+          ExportSymName := ppufile.getstring;
+
+          ExportSymbol.name := stringdup(ExportSymName);
+          ExportSymbol.index := ppufile.getlongint;
+          ExportSymbol.options := ppufile.getword;
+          ExportSymbol.is_var := Boolean(ppufile.getbyte);
+
+          ExportSymbol.sym := sym;
+
+          copy_ExportSymbol.name := stringdup(ExportSymName);
+          copy_ExportSymbol.index := ExportSymbol.index;
+          copy_ExportSymbol.options := ExportSymbol.options;
+          copy_ExportSymbol.is_var := ExportSymbol.is_var;
+
+          copy_ExportSymbol.sym := sym;
+
+          Self._exports.Insert(ExportSymbol);
+          exportlib.exportprocedure(copy_ExportSymbol);
+        end;
+    end;
+
+
     procedure tppumodule.readResources;
       begin
         while not ppufile.endofentry do
@@ -1223,6 +1339,9 @@
          { write whole program optimisation-related information }
          tunitwpoinfo(wpoinfo).ppuwrite(ppufile);
 
+         if (flags and uf_has_exports)<>0 then
+           Self.writeExportSymbols;
+
          { the last entry ibend is written automatically }
 
          { flush to be sure }
@@ -1467,6 +1586,9 @@
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;
          tunitwpoinfo(wpoinfo).derefimpl;
+
+        if (flags and uf_has_exports)<>0 then
+          Self.readExportSymbols;
       end;
 
 
Index: compiler/ppu.pas
===================================================================
--- compiler/ppu.pas	(revision 26788)
+++ compiler/ppu.pas	(working copy)
@@ -74,6 +74,7 @@
   iblinkotherstaticlibs  = 9;
   iblinkothersharedlibs  = 10;
   ibImportSymbols        = 11;
+  ibExportSymbols        = 102;
   ibsymref               = 12;
   ibdefref               = 13;
 //  ibendsymtablebrowser   = 14;
unit_exports_support.patch (6,826 bytes)   

Cyrax

2014-02-15 22:42

reporter   ~0073068

Attached patch which adds support for storing exports section in .ppu file.

Dennis Fehr

2014-02-16 02:45

reporter   ~0073069

Last edited: 2014-02-16 02:49

View 3 revisions

Dang, Cyrax, beat me to it! I was gonna do it, haha .. The only thing that I would be a stickler about is the casing for the if's and such.. Inconsistent to FPC coding. (and the Begin on the same line, etc). There also might be another issue if I'm not mistaken?

ppufile.putlongint(AProcSym.ProcdefList.Count);

You have a for-loop right after that is:
  For I := 0 To AProcSym.ProcdefList.Count - 1 Do Begin

What happens if the ProcDefList.Count is 0? It will be doing quite the big loop! Haha, it should probably just write the count, and skip the entire loop..

The other (small) issue is:

  FindSymbol(Self.localsymtable);
  FindSymbol(Self.globalsymtable);

  If AFound Then Break;

Why not just have findsymbol as a function, and do:

  if findsymbol(localsymtable) or findsymbol(globalsymbtable) then break;

Then it could be a bit faster if it finds it in findsymbol first, then you don't need the AFound variable. :)

Edit:
  You also may want to check for a 0 for ASymTable.DefList.Count in FindSymbol as well, juuuuust incase there may happen to somehow have nothing defined in there yet! (chances are no but...)

Other than those issues I haven't looked at it beyond that, but it looks like it would be okay. If you fixed those I would be willing to test it for you as well!

Cyrax

2014-02-16 03:24

reporter   ~0073070

>What happens if the ProcDefList.Count is 0?
Clause AProcSym.ProcdefList.Count - 1 would just become -1 and then the for loop wont be executed at all.

Thanks for the feedback, I will tidy it up a bit after I have tested it thoroughly.

Dennis Fehr

2014-02-16 05:52

reporter   ~0073072

I know :) .. In the past I have seen many errors and hard to debug code because of such accounts. "Count - 1" becomes -1 because of I being an integer and it converts it to the sign value of the source "For" argument (so to whatever "I" is)... If "I" were a 'dword' for example, the loop would then go on for quite some time (until $FFFFFFFF of course). But I thank you for taking it into consideration. I look forward to the edited patch. :)

Anton Kavalenka

2014-02-16 10:46

reporter   ~0073082

Please make this issue related to 0017805.
Because currently the only way exporting pointer to resource header from linux .SO - placing the following statements in main file (not unit):

library res_example;

var rh : pointer; external name 'FPC_RESLOCATION';

exports.
    rh;
end.

As soon linux binary can export symbol not only from main file -
patching intres.inc with these statements make Linux EXE and SO automatically export their resource header pointer.

Dennis Fehr

2014-02-19 20:35

reporter   ~0073166

Sorry to *bump*, but any word on the progress of this? It would be great to have symbols exported from any unit, instead of bothering the user to add your unit and export the necessary functions for you in the main Library File.

Cyrax

2014-02-26 02:56

reporter   ~0073305

Patch works as intended. I haven't encountered any bugs at all. I will rework patch and add support for exporting variables.

Cyrax

2014-02-26 05:21

reporter  

Cyrax

2014-02-26 05:37

reporter  

unit_exports_support_03.patch (9,511 bytes)   
Index: compiler/export.pas
===================================================================
--- compiler/export.pas	(revision 26882)
+++ compiler/export.pas	(working copy)
@@ -92,7 +92,7 @@
 implementation
 
 uses
-  verbose,globals;
+  verbose,globals, fmodule;
 
 {****************************************************************************
                            TExported_procedure
@@ -100,7 +100,7 @@
 
 procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, copy_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -108,12 +108,23 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportprocedure(hp);
+
+    if current_module.is_unit then
+      begin
+        copy_hp:=texported_item.create;
+        copy_hp.name:=stringdup(s);
+        copy_hp.sym:=sym;
+        copy_hp.options:=options or eo_name;
+        copy_hp.index:=index;
+        current_module._exports.insert(copy_hp);
+      end;
+
   end;
 
 
 procedure exportvarsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, copy_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -122,6 +133,18 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportvar(hp);
+
+    If current_module.is_unit then
+      begin
+        copy_hp:=texported_item.create;
+        copy_hp.name:=stringdup(s);
+        copy_hp.sym:=sym;
+        copy_hp.options:=options or eo_name;
+        copy_hp.index:=index;
+        copy_hp.is_var:=hp.is_var;
+        current_module._exports.insert(copy_hp);
+      end;
+
   end;
 
 
Index: compiler/fppu.pas
===================================================================
--- compiler/fppu.pas	(revision 26882)
+++ compiler/fppu.pas	(working copy)
@@ -86,6 +86,7 @@
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeExportSymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -93,6 +94,7 @@
           procedure readderefmap;
           procedure readderefdata;
           procedure readImportSymbols;
+          procedure readExportSymbols;
           procedure readResources;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
@@ -116,7 +118,9 @@
   scanner,
   aasmbase,ogbase,
   parser,
-  comphook;
+  comphook,
+  export,
+  symdef;
 
 
 var
@@ -134,7 +138,7 @@
       end;
 
 
-    destructor tppumodule.Destroy;
+        destructor tppumodule.destroy;
       begin
         if assigned(ppufile) then
          ppufile.free;
@@ -668,7 +672,54 @@
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeExportSymbols;
+    var
+      exportsymbol : texported_item;
+      i : integer;
+      aprocsym : tprocsym;
+      astaticvarsym : tstaticvarsym;
+      aprocdef : tprocdef;
+      aclassname : string;
+    begin
+      exportsymbol := texported_item(_exports.first);
+      while assigned(exportsymbol) do
+        begin
 
+          if assigned(exportsymbol.sym) then
+            begin
+              aclassname := exportsymbol.sym.classname;
+              if exportsymbol.sym is tprocsym then
+                begin
+                  aprocsym := tprocsym(exportsymbol.sym);
+                  ppufile.putbyte(0);
+                  ppufile.putlongint(aprocsym.procdeflist.count);
+                  for i := 0 to aprocsym.procdeflist.count - 1 do
+                    begin
+                      aprocdef := tprocdef(aprocsym.procdeflist[i]);
+                      ppufile.putstring(aprocdef.mangledname);
+                    end;
+                end;
+              if exportsymbol.sym is tstaticvarsym then
+                begin
+                  astaticvarsym := tstaticvarsym(exportsymbol.sym);
+                  ppufile.putbyte(1);
+                  ppufile.putstring(astaticvarsym.mangledname);
+                end;
+            end;
+
+          ppufile.putstring(exportsymbol.name^);
+          ppufile.putlongint(exportsymbol.index);
+          ppufile.putword(exportsymbol.options);
+          ppufile.putbyte(byte(exportsymbol.is_var));
+
+          exportsymbol := texported_item(exportsymbol.next);
+
+        end;
+
+      ppufile.writeentry(ibExportSymbols);
+    end;
+
+
     procedure tppumodule.writeResources;
       var
         res : TCmdStrListItem;
@@ -946,7 +997,124 @@
           end;
       end;
 
+    procedure tppumodule.readExportSymbols;
+    Var
+      exportsymbol, copy_exportsymbol : texported_item;
+      symname, exportsymname : string;
+      sym : tsym;
+      acount : integer;
+      atype : byte;
 
+        function findsymbolproc(ASymTable : TSymtable) : Boolean;
+        var
+          c : integer;
+          aclassname, amangledname : string;
+          aprocdef : tprocdef;
+        begin
+          result := false;
+          for c := 0 to asymtable.deflist.count - 1 do
+            begin
+              aclassname := asymtable.deflist[c].classname;
+              if asymtable.deflist[c] is tprocdef then
+                begin
+                  aprocdef := tprocdef(asymtable.deflist[c]);
+                  amangledname := aprocdef.mangledname;
+                  if symname = amangledname then
+                    begin
+                      sym := aprocdef.procsym;
+                      exit(true);
+                    end;
+                end;
+            end;
+        end;
+
+        function findsymbolvar(ASymTable : TSymtable) : Boolean;
+        var
+          c : integer;
+          aclassname, amangledname : string;
+          astaticvarsym : tstaticvarsym;
+        begin
+          result := false;
+          for c := 0 to asymtable.symlist.count - 1 do
+            begin
+              aclassname := asymtable.symlist[c].classname;
+              if asymtable.symlist[c] is tstaticvarsym then
+                begin
+                  astaticvarsym := tstaticvarsym(asymtable.symlist[c]);
+                  amangledname  := astaticvarsym.mangledname;
+                  if symname = amangledname then
+                    begin
+                      sym := astaticvarsym;
+                      exit(true);
+                    end;
+                end;
+            end;
+        end;
+
+    begin
+       ppufile.closefile;
+       ppufile.openfile;
+       if not ppufile.skipuntilentry(ibExportSymbols) then
+         exit;
+      while not ppufile.endofentry do
+        begin
+          exportsymbol := texported_item.create;
+          copy_exportsymbol := texported_item.create;
+
+          atype := ppufile.getbyte;
+          case atype of
+            0 : begin // exported procedure/function
+                  acount := ppufile.getlongint;
+
+                  while acount <> 0 do
+                    begin
+
+                      symname := ppufile.getstring;
+
+                      sym := nil;
+
+                      if findsymbolproc(localsymtable) or findsymbolproc(globalsymtable) then
+                        break;
+
+                      dec(acount);
+                    end;
+
+                 end;
+            1 : begin // exported variable
+                  symname := ppufile.getstring;
+
+                  sym := nil;
+
+                  if findsymbolvar(localsymtable) or findsymbolvar(globalsymtable) then;
+
+                end;
+          end;
+
+          exportsymname := ppufile.getstring;
+
+          exportsymbol.name := stringdup(exportsymname);
+          exportsymbol.index := ppufile.getlongint;
+          exportsymbol.options := ppufile.getword;
+          exportsymbol.is_var := boolean(ppufile.getbyte);
+
+          exportsymbol.sym := sym;
+
+          copy_exportsymbol.name := stringdup(exportsymname);
+          copy_exportsymbol.index := exportsymbol.index;
+          copy_exportsymbol.options := exportsymbol.options;
+          copy_exportsymbol.is_var := exportsymbol.is_var;
+
+          copy_exportsymbol.sym := sym;
+
+          _exports.insert(exportsymbol);
+          if copy_exportsymbol.is_var then
+             exportlib.exportvar(copy_exportsymbol)
+          else
+             exportlib.exportprocedure(copy_exportsymbol);
+        end;
+    end;
+
+
     procedure tppumodule.readResources;
       begin
         while not ppufile.endofentry do
@@ -1223,6 +1391,9 @@
          { write whole program optimisation-related information }
          tunitwpoinfo(wpoinfo).ppuwrite(ppufile);
 
+         if (flags and uf_has_exports)<>0 then
+           writeExportSymbols;
+
          { the last entry ibend is written automatically }
 
          { flush to be sure }
@@ -1467,6 +1638,9 @@
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;
          tunitwpoinfo(wpoinfo).derefimpl;
+
+        if (flags and uf_has_exports)<>0 then
+          readExportSymbols;
       end;
 
 
Index: compiler/ppu.pas
===================================================================
--- compiler/ppu.pas	(revision 26882)
+++ compiler/ppu.pas	(working copy)
@@ -74,6 +74,7 @@
   iblinkotherstaticlibs  = 9;
   iblinkothersharedlibs  = 10;
   ibImportSymbols        = 11;
+  ibExportSymbols        = 102;
   ibsymref               = 12;
   ibdefref               = 13;
 //  ibendsymtablebrowser   = 14;
unit_exports_support_03.patch (9,511 bytes)   

Cyrax

2015-08-25 02:06

reporter  

unit_exports_support_04.patch (8,675 bytes)   
Index: compiler/export.pas
===================================================================
--- compiler/export.pas	(revision 31412)
+++ compiler/export.pas	(working copy)
@@ -92,7 +92,7 @@
 implementation
 
 uses
-  verbose,globals;
+  verbose,globals,fmodule;
 
 {****************************************************************************
                            TExported_procedure
@@ -100,7 +100,7 @@
 
 procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, module_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -107,13 +107,17 @@
     hp.sym:=sym;
     hp.options:=options or eo_name;
     hp.index:=index;
+    module_hp:=texported_item(hp.getcopy);
+    module_hp.name:=stringdup(s);
     exportlib.exportprocedure(hp);
+    if current_module.is_unit then
+      current_module._exports.concat(module_hp);
   end;
 
 
 procedure exportvarsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, module_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -121,7 +125,11 @@
     hp.is_var:=true;
     hp.options:=options or eo_name;
     hp.index:=index;
+    module_hp:=texported_item(hp.getcopy);
+    module_hp.name:=stringdup(s);
     exportlib.exportvar(hp);
+    if current_module.is_unit then
+      current_module._exports.concat(module_hp);
   end;
 
 
Index: compiler/fppu.pas
===================================================================
--- compiler/fppu.pas	(revision 31412)
+++ compiler/fppu.pas	(working copy)
@@ -88,6 +88,7 @@
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeExportSymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -95,6 +96,7 @@
           procedure readderefmap;
           procedure readderefdata;
           procedure readImportSymbols;
+          procedure readExportSymbols;
           procedure readResources;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
@@ -118,7 +120,10 @@
   scanner,
   aasmbase,ogbase,
   parser,
-  comphook;
+  comphook,
+  export,
+  symdef,
+  symconst;
 
 
 var
@@ -136,7 +141,7 @@
       end;
 
 
-    destructor tppumodule.Destroy;
+    destructor tppumodule.destroy;
       begin
         if assigned(ppufile) then
          ppufile.free;
@@ -678,7 +683,46 @@
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeExportSymbols;
 
+      procedure writeprocsym(procsym : tprocsym);
+      var
+        i : integer;
+        procdef : tprocdef;
+      begin
+        ppufile.putlongint(procsym.procdeflist.count);
+        for i := 0 to procsym.procdeflist.count - 1 do begin
+          procdef:=tprocdef(procsym.procdeflist[i]);
+          ppufile.putstring(procdef.mangledname);
+        end;
+      end;
+
+      procedure writestaticvarsym(staticvarsym : tstaticvarsym);
+      begin
+        ppufile.putstring(staticvarsym.mangledname);
+      end;
+
+    var
+      exportsymbol : texported_item;
+    begin
+      exportsymbol := texported_item(_exports.first);
+      while exportsymbol<>nil do
+        begin
+          ppufile.putbyte(byte(exportsymbol.sym.typ));
+          case exportsymbol.sym.typ of
+            procsym : writeprocsym(tprocsym(exportsymbol.sym));
+            staticvarsym : writestaticvarsym(tstaticvarsym(exportsymbol.sym));
+          end;
+          ppufile.putstring(exportsymbol.name^);
+          ppufile.putlongint(exportsymbol.index);
+          ppufile.putword(exportsymbol.options);
+          ppufile.putbyte(byte(exportsymbol.is_var));
+          exportsymbol:=texported_item(exportsymbol.next);
+        end;
+      ppufile.writeentry(ibExportSymbols);
+    end;
+
+
     procedure tppumodule.writeResources;
       var
         res : TCmdStrListItem;
@@ -962,7 +1006,96 @@
           end;
       end;
 
+    procedure tppumodule.readExportSymbols;
 
+        function findsymbolproc(symname : tsymstr;symtable : tsymtable) : tsym;
+        var
+          i : integer;
+          procdef : tprocdef;
+        begin
+          result:=nil;
+          for i := 0 to symtable.deflist.count - 1 do
+            begin
+              if symtable.deflist[i] is tprocdef then
+                begin
+                  procdef:=tprocdef(symtable.deflist[i]);
+                  if procdef.mangledname = symname then
+                    exit(procdef.procsym);
+                end;
+            end;
+        end;
+
+        function findsymbolvar(symname : tsymstr;symtable : tsymtable) : tsym;
+        var
+          i : integer;
+          staticvarsym : tstaticvarsym;
+        begin
+          result:=nil;
+          for i := 0 to symtable.symlist.count - 1 do
+            begin
+              if symtable.symlist[i] is tstaticvarsym then
+                begin
+                  staticvarsym:=tstaticvarsym(symtable.symlist[i]);
+                  if staticvarsym.mangledname = symname then
+                    exit(staticvarsym);
+                end;
+            end;
+        end;
+
+    var
+      symtyp : tsymtyp;
+      count, i : longint;
+      symname, exportsymname : tsymstr;
+      exportsymbol, copy_exportsymbol : texported_item;
+      sym : tsym;
+    begin
+      ppufile.closefile;
+      ppufile.openfile;
+      if not ppufile.skipuntilentry(ibExportSymbols) then
+        exit;
+      while not ppufile.endofentry do
+        begin
+          sym:=nil;
+          symtyp:=tsymtyp(ppufile.getbyte);
+          case symtyp of
+            procsym : begin
+                        count:=ppufile.getlongint;
+                        for i := 0 to count - 1 do
+                          begin
+                            symname:=ppufile.getstring;
+                            sym:=findsymbolproc(symname,localsymtable);
+                            if sym<>nil then
+                              break;
+                            sym:=findsymbolproc(symname,globalsymtable);
+                            if sym<>nil then
+                              break;
+                          end;
+                      end;
+            staticvarsym : begin
+                             symname:=ppufile.getstring;
+                             sym:=findsymbolvar(symname,localsymtable);
+                             if sym=nil then
+                               sym:=findsymbolvar(symname,globalsymtable);
+                           end;
+          end;
+          exportsymname:=ppufile.getstring;
+          exportsymbol:=texported_item.create;
+          exportsymbol.name:=stringdup(exportsymname);
+          exportsymbol.index:=ppufile.getlongint;
+          exportsymbol.options:=ppufile.getword;
+          exportsymbol.is_var:=boolean(ppufile.getbyte);
+          exportsymbol.sym:=sym;
+          copy_exportsymbol:=texported_item(exportsymbol.getcopy);
+          copy_exportsymbol.name:=stringdup(exportsymname);
+          _exports.concat(exportsymbol);
+          if copy_exportsymbol.is_var then
+            exportlib.exportvar(copy_exportsymbol)
+          else
+            exportlib.exportprocedure(copy_exportsymbol);
+        end;
+    end;
+
+
     procedure tppumodule.readResources;
       begin
         while not ppufile.endofentry do
@@ -1241,6 +1374,10 @@
          { write whole program optimisation-related information }
          tunitwpoinfo(wpoinfo).ppuwrite(ppufile);
 
+         { if unit has exports section, write it in ppu file }
+         if (flags and uf_has_exports)<>0 then
+           writeExportSymbols;
+
          { the last entry ibend is written automatically }
 
          { flush to be sure }
@@ -1485,6 +1622,9 @@
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;
          tunitwpoinfo(wpoinfo).derefimpl;
+
+        if (flags and uf_has_exports)<>0 then
+          readExportSymbols;
       end;
 
 
Index: compiler/ppu.pas
===================================================================
--- compiler/ppu.pas	(revision 31412)
+++ compiler/ppu.pas	(working copy)
@@ -43,7 +43,7 @@
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 177;
+  CurrentPPUVersion = 178;
 
 { buffer sizes }
   maxentrysize = 1024;
@@ -74,6 +74,7 @@
   iblinkotherstaticlibs  = 9;
   iblinkothersharedlibs  = 10;
   ibImportSymbols        = 11;
+  ibExportSymbols        = 102;
   ibsymref               = 12;
   ibdefref               = 13;
 //  ibendsymtablebrowser   = 14;
unit_exports_support_04.patch (8,675 bytes)   

Cyrax

2015-08-25 02:06

reporter   ~0085526

New patch (unit_exports_support_04.patch) attached. Others are now obsolete.

Jonas Maebe

2015-08-26 13:32

manager   ~0085540

I looked at the patch yesterday, and there are some problems:
* export.pas: module_hp is leaked if the current module is not a unit (2x)
* export.pas: you should override texported_item.getcopy and copy the string there, instead of doing it a
* fppu.pas: that unit cannot/must not depend on symdef.pas. As an aside, we try to never use the "is" operator in the compiler. Every tdef/tsym has a "typ" field that you can use instead. You shouldn't need either this typ field either though, see the next point.
* fppu.pas: storing the mangled name and then searching for a procdef/varsym with that mangled name when loading is not good. Saving/restoring tdefs and tsyms should happen via the tderef type. It's not immediately clear how to integrate that in fppu.pas though, because you will probably have to call tdef/tsym.buildderef earlier than where you are currently writing the exported symbols (maybe right after the buildderef for the symtables).

Cyrax

2015-08-26 22:43

reporter  

unit_exports_support_05.patch (7,598 bytes)   
Index: compiler/export.pas
===================================================================
--- compiler/export.pas	(revision 31428)
+++ compiler/export.pas	(working copy)
@@ -38,6 +38,9 @@
    eo_name     = $4;
 
 type
+
+   { texported_item }
+
    texported_item = class(TLinkedListItem)
       sym : tsym;
       index : longint;
@@ -45,6 +48,7 @@
       options : word;
       is_var : boolean;
       constructor create;
+      function getcopy:TLinkedListItem;override;
       destructor destroy;override;
    end;
 
@@ -92,7 +96,7 @@
 implementation
 
 uses
-  verbose,globals;
+  verbose,globals,fmodule;
 
 {****************************************************************************
                            TExported_procedure
@@ -100,7 +104,7 @@
 
 procedure exportprocsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, module_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -108,12 +112,17 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportprocedure(hp);
+    if current_module.is_unit then
+      begin
+        module_hp:=texported_item(hp.getcopy);
+        current_module._exports.concat(module_hp);
+      end;
   end;
 
 
 procedure exportvarsym(sym: tsym; const s : string; index: longint; options: word);
   var
-    hp : texported_item;
+    hp, module_hp : texported_item;
   begin
     hp:=texported_item.create;
     hp.name:=stringdup(s);
@@ -122,6 +131,11 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportvar(hp);
+    if current_module.is_unit then
+      begin
+        module_hp:=texported_item(hp.getcopy);
+        current_module._exports.concat(module_hp);
+      end;
   end;
 
 
@@ -161,7 +175,7 @@
                            TExported_procedure
 ****************************************************************************}
 
-constructor texported_item.Create;
+constructor texported_item.create;
 begin
   inherited Create;
   sym:=nil;
@@ -171,7 +185,13 @@
   is_var:=false;
 end;
 
+function texported_item.getcopy: TLinkedListItem;
+begin
+  Result:=inherited getcopy;
+  texported_item(Result).name:=stringdup(texported_item(Result).name^);
+end;
 
+
 destructor texported_item.destroy;
 begin
   stringdispose(name);
Index: compiler/fppu.pas
===================================================================
--- compiler/fppu.pas	(revision 31428)
+++ compiler/fppu.pas	(working copy)
@@ -88,6 +88,7 @@
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeExportSymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -95,6 +96,7 @@
           procedure readderefmap;
           procedure readderefdata;
           procedure readImportSymbols;
+          procedure readExportSymbols;
           procedure readResources;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
@@ -118,7 +120,9 @@
   scanner,
   aasmbase,ogbase,
   parser,
-  comphook;
+  comphook,
+  export,
+  symconst;
 
 
 var
@@ -136,7 +140,7 @@
       end;
 
 
-    destructor tppumodule.Destroy;
+    destructor tppumodule.destroy;
       begin
         if assigned(ppufile) then
          ppufile.free;
@@ -678,7 +682,27 @@
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeExportSymbols;
+    var
+      exportsymbol : texported_item;
+      deref : tderef;
+    begin
+      exportsymbol := texported_item(_exports.first);
+      while exportsymbol<>nil do
+        begin
+          ppufile.putbyte(byte(exportsymbol.sym.typ));
+          deref.build(exportsymbol.sym);
+          ppufile.putlongint(deref.dataidx);
+          ppufile.putstring(exportsymbol.name^);
+          ppufile.putlongint(exportsymbol.index);
+          ppufile.putword(exportsymbol.options);
+          ppufile.putbyte(byte(exportsymbol.is_var));
+          exportsymbol:=texported_item(exportsymbol.next);
+        end;
+      ppufile.writeentry(ibExportSymbols);
+    end;
 
+
     procedure tppumodule.writeResources;
       var
         res : TCmdStrListItem;
@@ -962,7 +986,32 @@
           end;
       end;
 
+    procedure tppumodule.readExportSymbols;
+    var
+      symtyp : tsymtyp;
+      exportsymname : tsymstr;
+      exportsymbol : texported_item;
+      sym : tsym;
+      dataidx : longint;
+    begin
+      while not ppufile.endofentry do
+        begin
+          sym:=nil;
+          symtyp:=tsymtyp(ppufile.getbyte);
+          dataidx:=ppufile.getlongint;
+          sym:=tsym(dataidx);
+          exportsymname:=ppufile.getstring;
+          exportsymbol:=texported_item.create;
+          exportsymbol.name:=stringdup(exportsymname);
+          exportsymbol.index:=ppufile.getlongint;
+          exportsymbol.options:=ppufile.getword;
+          exportsymbol.is_var:=boolean(ppufile.getbyte);
+          exportsymbol.sym:=sym;
+          _exports.concat(exportsymbol);
+        end;
+    end;
 
+
     procedure tppumodule.readResources;
       begin
         while not ppufile.endofentry do
@@ -1053,6 +1102,8 @@
                end;
              ibImportSymbols :
                readImportSymbols;
+             ibExportSymbols :
+               readExportSymbols;
              ibderefmap :
                readderefmap;
              ibderefdata :
@@ -1204,6 +1255,11 @@
            end;
          tunitwpoinfo(wpoinfo).buildderef;
          tunitwpoinfo(wpoinfo).buildderefimpl;
+
+         { if unit has exports section, write it in ppu file }
+         if (flags and uf_has_exports)<>0 then
+           writeExportSymbols;
+
          writederefmap;
          writederefdata;
 
@@ -1371,6 +1427,10 @@
     procedure tppumodule.load_usedunits;
       var
         pu           : tused_unit;
+        exported_item,
+        copy_exported_item : texported_item;
+        dataidx : longint;
+        deref : tderef;
       begin
         if current_module<>self then
          internalerror(200212284);
@@ -1485,6 +1545,23 @@
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;
          tunitwpoinfo(wpoinfo).derefimpl;
+
+        { resolve exported symbols }
+        if (flags and uf_has_exports)<>0 then
+          begin
+            exported_item:=texported_item(_exports.first);
+            while exported_item<>nil do
+              begin
+                deref.dataidx:=longint(exported_item.sym);
+                exported_item.sym:=tsym(deref.resolve);
+                copy_exported_item:=texported_item(exported_item.getcopy);
+                if copy_exported_item.is_var then
+                  exportlib.exportvar(copy_exported_item)
+                else
+                  exportlib.exportprocedure(copy_exported_item);
+                exported_item:=texported_item(exported_item.next);
+              end;
+          end;
       end;
 
 
Index: compiler/ppu.pas
===================================================================
--- compiler/ppu.pas	(revision 31428)
+++ compiler/ppu.pas	(working copy)
@@ -43,7 +43,7 @@
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 177;
+  CurrentPPUVersion = 178;
 
 { buffer sizes }
   maxentrysize = 1024;
@@ -74,6 +74,7 @@
   iblinkotherstaticlibs  = 9;
   iblinkothersharedlibs  = 10;
   ibImportSymbols        = 11;
+  ibExportSymbols        = 102;
   ibsymref               = 12;
   ibdefref               = 13;
 //  ibendsymtablebrowser   = 14;
unit_exports_support_05.patch (7,598 bytes)   

Cyrax

2015-08-26 22:46

reporter   ~0085546

Uploaded new patch (unit_exports_support_05.patch) which contains fixes/modifications as suggested by Jonas.

Cyrax

2015-11-17 19:40

reporter  

unit_exports_support_06.patch (9,346 bytes)   
Index: compiler/export.pas
===================================================================
--- compiler/export.pas	(revision 32353)
+++ compiler/export.pas	(working copy)
@@ -38,6 +38,9 @@
    eo_name     = $4;
 
 type
+
+   { texported_item }
+
    texported_item = class(TLinkedListItem)
       sym : tsym;
       index : longint;
@@ -46,6 +49,7 @@
       is_var : boolean;
       constructor create;
       destructor destroy;override;
+      Function GetCopy:TLinkedListItem;override;
    end;
 
    texportlib=class
@@ -92,7 +96,7 @@
 implementation
 
 uses
-  verbose,globals;
+  verbose,globals,fmodule;
 
 {****************************************************************************
                            TExported_procedure
@@ -108,6 +112,8 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportprocedure(hp);
+    if current_module.is_unit then
+      current_module._exports.Concat(hp.GetCopy);
   end;
 
 
@@ -122,6 +128,8 @@
     hp.options:=options or eo_name;
     hp.index:=index;
     exportlib.exportvar(hp);
+    if current_module.is_unit then
+      current_module._exports.Concat(hp.GetCopy);
   end;
 
 
@@ -161,7 +169,7 @@
                            TExported_procedure
 ****************************************************************************}
 
-constructor texported_item.Create;
+constructor texported_item.create;
 begin
   inherited Create;
   sym:=nil;
@@ -178,7 +186,13 @@
   inherited destroy;
 end;
 
+function texported_item.GetCopy: TLinkedListItem;
+begin
+  Result:=inherited GetCopy;
+  texported_item(Result).name:=stringdup(texported_item(Result).name^);
+end;
 
+
 {****************************************************************************
                               TExportLib
 ****************************************************************************}
Index: compiler/fppu.pas
===================================================================
--- compiler/fppu.pas	(revision 32353)
+++ compiler/fppu.pas	(working copy)
@@ -88,6 +88,8 @@
           procedure writederefmap;
           procedure writederefdata;
           procedure writeImportSymbols;
+          procedure writeExportSymbols;
+          procedure createderefExportSymbols;
           procedure writeResources;
           procedure readsourcefiles;
           procedure readloadunit;
@@ -95,6 +97,7 @@
           procedure readderefmap;
           procedure readderefdata;
           procedure readImportSymbols;
+          procedure readExportSymbols;
           procedure readResources;
           procedure readwpofile;
 {$IFDEF MACRO_DIFF_HINT}
@@ -118,7 +121,9 @@
   scanner,
   aasmbase,ogbase,
   parser,
-  comphook;
+  comphook,
+  export,
+  symconst;
 
 
 var
@@ -136,7 +141,7 @@
       end;
 
 
-    destructor tppumodule.Destroy;
+        destructor tppumodule.destroy;
       begin
         if assigned(ppufile) then
          ppufile.free;
@@ -678,7 +683,50 @@
         ppufile.writeentry(ibImportSymbols);
       end;
 
+    procedure tppumodule.writeExportSymbols;
+    var
+      exportsymbol : texported_item;
+      dataidx : longint;
+      apderef : pderef;
+    begin
+      exportsymbol := texported_item(_exports.first);
+      while exportsymbol<>nil do
+        begin
+          dataidx:=-1;
+          apderef := exportsymbol.sym._pderef;
+          if apderef<>nil then
+            dataidx := apderef^.dataidx;
+          ppufile.putbyte(byte(exportsymbol.sym.typ));
+          ppufile.putlongint(dataidx);
+          ppufile.putstring(exportsymbol.name^);
+          ppufile.putlongint(exportsymbol.index);
+          ppufile.putword(exportsymbol.options);
+          ppufile.putbyte(byte(exportsymbol.is_var));
+          exportsymbol:=texported_item(exportsymbol.next);
+        end;
+      ppufile.writeentry(ibExportSymbols);
+    end;
 
+    procedure tppumodule.createderefExportSymbols;
+    var
+      exportsymbol : texported_item;
+      apderef : pderef;
+    begin
+      exportsymbol := texported_item(_exports.first);
+      while exportsymbol<>nil do
+        begin
+          apderef:=exportsymbol.sym._pderef;
+          if apderef<>nil then
+            dispose(apderef);
+          exportsymbol.sym.buildderef;
+          new(apderef);
+          apderef^.build(exportsymbol.sym);
+          exportsymbol.sym._pderef := apderef;
+          exportsymbol:=texported_item(exportsymbol.next);
+        end;
+    end;
+
+
     procedure tppumodule.writeResources;
       var
         res : TCmdStrListItem;
@@ -962,7 +1010,44 @@
           end;
       end;
 
+    procedure tppumodule.readExportSymbols;
+    var
+      exportsymbol : texported_item;
+      aderef : tderef;
+      symtyp : byte;
+      asym : tsym;
+    begin
+      ppufile.closefile;
+      ppufile.openfile;
+      if not ppufile.skipuntilentry(ibExportSymbols) then
+        exit;
+      while not ppufile.endofentry do
+        begin
+          asym:=nil;
+          symtyp := ppufile.getbyte;
+          aderef.dataidx := ppufile.getlongint;
+          exportsymbol := texported_item.create;
+          exportsymbol.name:=stringdup(ppufile.getstring);
+          exportsymbol.index:=ppufile.getlongint;
+          exportsymbol.options:=ppufile.getword;
+          exportsymbol.is_var:=boolean(ppufile.getbyte);
+          if aderef.dataidx<>-1 then
+            asym:=tsym(aderef.resolve);
+          if asym<>nil then
+            begin
+              exportsymbol.sym:=asym;
+              _exports.concat(exportsymbol);
+              if exportsymbol.is_var then
+                exportlib.exportvar(texported_item(exportsymbol.GetCopy))
+              else
+                exportlib.exportprocedure(texported_item(exportsymbol.GetCopy));
+            end
+            else
+              exportsymbol.free;
+        end;
+    end;
 
+
     procedure tppumodule.readResources;
       begin
         while not ppufile.endofentry do
@@ -1053,6 +1138,8 @@
                end;
              ibImportSymbols :
                readImportSymbols;
+             ibExportSymbols :  // we read export symbols later on
+               ;
              ibderefmap :
                readderefmap;
              ibderefdata :
@@ -1185,6 +1272,10 @@
          writeResources;
          ppufile.do_crc:=true;
 
+         { if unit has exports section, write it in ppu file }
+         if (flags and uf_has_exports)<>0 then
+            createderefExportSymbols;
+
          { generate implementation deref data, the interface deref data is
            already generated when calculating the interface crc }
          if (cs_compilesystem in current_settings.moduleswitches) then
@@ -1201,9 +1292,14 @@
          tunitwpoinfo(wpoinfo).buildderefimpl;
          if (flags and uf_local_symtable)<>0 then
            tstoredsymtable(localsymtable).buildderef_registered;
+
          writederefmap;
          writederefdata;
 
+         { if unit has exports section, write it in ppu file }
+         if (flags and uf_has_exports)<>0 then
+           writeExportSymbols;
+
          ppufile.writeentry(ibendinterface);
 
          { write the symtable entries }
@@ -1485,6 +1581,7 @@
          wpoinfo:=tunitwpoinfo.ppuload(ppufile);
          tunitwpoinfo(wpoinfo).deref;
          tunitwpoinfo(wpoinfo).derefimpl;
+
       end;
 
 
@@ -1688,7 +1785,11 @@
                   begin
                     load_usedunits;
                     if not do_compile then
+                     begin
+                      if (flags and uf_has_exports)<>0 then
+                        readExportSymbols;
                       Message1(unit_u_finished_loading_unit,modulename^);
+                     end;
                   end;
                end;
               { PPU is not needed anymore }
Index: compiler/ppu.pas
===================================================================
--- compiler/ppu.pas	(revision 32353)
+++ compiler/ppu.pas	(working copy)
@@ -43,7 +43,7 @@
 {$endif Test_Double_checksum}
 
 const
-  CurrentPPUVersion = 179;
+  CurrentPPUVersion = 180;
 
 { buffer sizes }
   maxentrysize = 1024;
@@ -74,6 +74,7 @@
   iblinkotherstaticlibs  = 9;
   iblinkothersharedlibs  = 10;
   ibImportSymbols        = 11;
+  ibExportSymbols        = 102;
   ibsymref               = 12;
   ibdefref               = 13;
 //  ibendsymtablebrowser   = 14;
Index: compiler/symtype.pas
===================================================================
--- compiler/symtype.pas	(revision 32353)
+++ compiler/symtype.pas	(working copy)
@@ -121,6 +121,7 @@
          reflist    : TLinkedList;
          { deprecated optionally can have a message }
          deprecatedmsg: pshortstring;
+         _pderef : pointer;
          constructor create(st:tsymtyp;const aname:string);
          destructor  destroy;override;
          function  mangledname:TSymStr; virtual;
@@ -457,10 +458,18 @@
          visibility:=vis_public;
          deprecatedmsg:=nil;
          symid:=symid_not_registered;
+         _pderef:=nil;
       end;
 
     destructor  Tsym.destroy;
+      var
+        apderef : pderef;
       begin
+        apderef := _pderef;
+        if apderef<>nil then begin
+          dispose(apderef);
+          _pderef:=nil;
+        end;
         stringdispose(deprecatedmsg);
         if assigned(RefList) then
           RefList.Free;
unit_exports_support_06.patch (9,346 bytes)   

Cyrax

2015-11-17 19:41

reporter   ~0087367

Uploaded newer patch (unit_exports_support_06.patch)

Issue History

Date Modified Username Field Change
2010-03-21 20:38 mspiller New Issue
2010-03-21 21:25 Jonas Maebe Note Added: 0035888
2010-03-21 21:25 Jonas Maebe Status new => feedback
2010-03-21 22:55 mspiller File Added: test.zip
2010-03-21 23:01 mspiller Note Added: 0035894
2010-03-22 00:20 Jonas Maebe Status feedback => new
2010-10-05 23:53 Jonas Maebe Note Added: 0041530
2010-10-18 18:44 Mike Note Added: 0041903
2010-11-24 00:18 Jonas Maebe Relationship added child of 0018030
2011-12-13 00:24 Lars Note Added: 0055002
2014-02-15 22:40 Cyrax File Added: unit_exports_support.patch
2014-02-15 22:42 Cyrax Note Added: 0073068
2014-02-16 02:45 Dennis Fehr Note Added: 0073069
2014-02-16 02:48 Dennis Fehr Note Edited: 0073069 View Revisions
2014-02-16 02:49 Dennis Fehr Note Edited: 0073069 View Revisions
2014-02-16 03:24 Cyrax Note Added: 0073070
2014-02-16 05:52 Dennis Fehr Note Added: 0073072
2014-02-16 10:46 Anton Kavalenka Note Added: 0073082
2014-02-19 20:35 Dennis Fehr Note Added: 0073166
2014-02-26 02:56 Cyrax Note Added: 0073305
2014-02-26 05:21 Cyrax File Added: demo_library_unit_exports.zip
2014-02-26 05:37 Cyrax File Added: unit_exports_support_03.patch
2014-06-10 22:14 Mattias Gaertner Relationship added related to 0025724
2015-08-25 02:06 Cyrax File Added: unit_exports_support_04.patch
2015-08-25 02:06 Cyrax Note Added: 0085526
2015-08-26 13:32 Jonas Maebe Note Added: 0085540
2015-08-26 22:43 Cyrax File Added: unit_exports_support_05.patch
2015-08-26 22:46 Cyrax Note Added: 0085546
2015-11-17 19:40 Cyrax File Added: unit_exports_support_06.patch
2015-11-17 19:41 Cyrax Note Added: 0087367
2018-02-24 21:35 Marco van de Voort Relationship added has duplicate 0030216