Ver código fonte

* also keep track of captured def (necessary when functions are captured)

Sven/Sarah Barth 1 ano atrás
pai
commit
ab5c5a7e9a
5 arquivos alterados com 18 adições e 15 exclusões
  1. 1 1
      compiler/ncal.pas
  2. 3 3
      compiler/nld.pas
  3. 6 5
      compiler/procdefutil.pas
  4. 3 3
      compiler/procinfo.pas
  5. 5 3
      compiler/symdef.pas

+ 1 - 1
compiler/ncal.pas

@@ -4343,7 +4343,7 @@ implementation
              (procdefinition.parast.symtablelevel<=current_procinfo.procdef.parast.symtablelevel) and
              (procdefinition.parast.symtablelevel>normal_function_level) and
              (current_procinfo.procdef.parast.symtablelevel>normal_function_level) then
-           current_procinfo.add_captured_sym(tprocdef(procdefinition).procsym,fileinfo);
+           current_procinfo.add_captured_sym(tprocdef(procdefinition).procsym,procdefinition,fileinfo);
 
          finally
            aktcallnode:=oldcallnode;

+ 3 - 3
compiler/nld.pas

@@ -375,6 +375,7 @@ implementation
            localvarsym :
              begin
                tabstractvarsym(symtableentry).IncRefCountBy(1);
+               resultdef:=tabstractvarsym(symtableentry).vardef;
                { Nested variable? The we need to load the framepointer of
                  the parent procedure }
                if assigned(current_procinfo) and
@@ -386,7 +387,7 @@ implementation
                    left:=cloadparentfpnode.create(tprocdef(symtable.defowner),lpf_forload);
                    current_procinfo.set_needs_parentfp(tprocdef(symtable.defowner).parast.symtablelevel);
                    { reference this as a captured symbol }
-                   current_procinfo.add_captured_sym(symtableentry,fileinfo);
+                   current_procinfo.add_captured_sym(symtableentry,resultdef,fileinfo);
                    { reference in nested procedures, variable needs to be in memory }
                    { and behaves as if its address escapes its parent block         }
                    make_not_regable(self,[ra_different_scope]);
@@ -396,8 +397,7 @@ implementation
                else if assigned(current_procinfo) and
                    (vo_is_self in tabstractvarsym(symtableentry).varoptions) and
                    (symtable.symtablelevel>normal_function_level) then
-                 current_procinfo.add_captured_sym(symtableentry,fileinfo);
-               resultdef:=tabstractvarsym(symtableentry).vardef;
+                 current_procinfo.add_captured_sym(symtableentry,resultdef,fileinfo);
 
                { e.g. self for objects is passed as var-parameter on the caller
                  side, but on the callee-side we use it as a pointer ->

+ 6 - 5
compiler/procdefutil.pas

@@ -718,7 +718,7 @@ implementation
       if not (sym.owner.symtabletype in [parasymtable,localsymtable]) then
         exit;
       if sym.owner.symtablelevel>normal_function_level then begin
-        pd.add_captured_sym(sym,n.fileinfo);
+        pd.add_captured_sym(sym,tloadnode(n).resultdef,n.fileinfo);
         result:=fen_true;
       end;
     end;
@@ -1098,13 +1098,13 @@ implementation
               for i:=0 to capturesyms.count-1 do
                 begin
                   captured:=pcapturedsyminfo(capturesyms[i]);
-                  pi.add_captured_sym(captured^.sym,captured^.fileinfo);
+                  pi.add_captured_sym(captured^.sym,captured^.def,captured^.fileinfo);
                   dispose(captured);
                 end;
               capturesyms.clear;
             end;
           { the original nested function now needs to capture only the capturer }
-          pinested.procdef.add_captured_sym(capturer,n.fileinfo);
+          pinested.procdef.add_captured_sym(capturer,capturedef,n.fileinfo);
         end
       { does this need to capture Self? }
       else if not foreachnodestatic(pm_postprocess,n,@find_self_sym,@selfinfo) then
@@ -1128,7 +1128,7 @@ implementation
       if assigned(selfinfo.selfsym) and not assigned(fieldsym) then
         { this isn't a procdef that was captured into a field, so capture the
           self }
-        pd.add_captured_sym(selfinfo.selfsym,n.fileinfo);
+        pd.add_captured_sym(selfinfo.selfsym,tabstractvarsym(selfinfo.selfsym).vardef,n.fileinfo);
 
       print_procinfo(pi);
       if assigned(pinested) then
@@ -1272,9 +1272,10 @@ implementation
 
                       { update the captured symbol }
                       info^.sym:=outerself;
+                      info^.def:=tabstractvarsym(outerself).vardef;
                     end
                   else if info^.sym.owner.defowner<>owner.procdef then
-                    owner.procdef.add_captured_sym(info^.sym,info^.fileinfo);
+                    owner.procdef.add_captured_sym(info^.sym,info^.def,info^.fileinfo);
                 end;
             end;
           { delete the original self parameter }

+ 3 - 3
compiler/procinfo.pas

@@ -186,7 +186,7 @@ unit procinfo;
           procedure add_local_ref_def(def:tdef);
           procedure export_local_ref_defs;
 
-          procedure add_captured_sym(sym:tsym;const fileinfo:tfileposinfo);
+          procedure add_captured_sym(sym:tsym;def:tdef;const fileinfo:tfileposinfo);
 
           function create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;
 
@@ -376,9 +376,9 @@ implementation
           end;
       end;
 
-    procedure tprocinfo.add_captured_sym(sym:tsym;const fileinfo:tfileposinfo);
+    procedure tprocinfo.add_captured_sym(sym:tsym;def:tdef;const fileinfo:tfileposinfo);
       begin
-        procdef.add_captured_sym(sym,fileinfo);
+        procdef.add_captured_sym(sym,def,fileinfo);
       end;
 
     function tprocinfo.create_for_outlining(const basesymname: string; astruct: tabstractrecorddef; potype: tproctypeoption; resultdef: tdef; entrynodeinfo: tnode): tprocinfo;

+ 5 - 3
compiler/symdef.pas

@@ -784,6 +784,7 @@ interface
 
        tcapturedsyminfo = record
          sym : tsym;
+         def : tdef;
          { the location where the symbol was first encountered }
          fileinfo : tfileposinfo;
        end;
@@ -945,7 +946,7 @@ interface
           function get_funcretsym_info(out ressym: tsym; out resdef: tdef): boolean; virtual;
           function get_safecall_funcretsym_info(out ressym: tsym; out resdef: tdef): boolean; virtual;
 
-          procedure add_captured_sym(sym:tsym;const filepos:tfileposinfo);
+          procedure add_captured_sym(sym:tsym;def:tdef;const filepos:tfileposinfo);
 
           { returns whether the mangled name or any of its aliases is equal to
             s }
@@ -7009,7 +7010,7 @@ implementation
       end;
 
 
-    procedure tprocdef.add_captured_sym(sym:tsym;const filepos:tfileposinfo);
+    procedure tprocdef.add_captured_sym(sym:tsym;def:tdef;const filepos:tfileposinfo);
       var
         i : longint;
         capturedsym : pcapturedsyminfo;
@@ -7021,11 +7022,12 @@ implementation
         for i:=0 to implprocdefinfo^.capturedsyms.count-1 do
           begin
             capturedsym:=pcapturedsyminfo(implprocdefinfo^.capturedsyms[i]);
-            if capturedsym^.sym=sym then
+            if (capturedsym^.sym=sym) and (capturedsym^.def=def) then
               exit;
           end;
         new(capturedsym);
         capturedsym^.sym:=sym;
+        capturedsym^.def:=def;
         capturedsym^.fileinfo:=filepos;
         implprocdefinfo^.capturedsyms.add(capturedsym);
       end;