浏览代码

* Fix methodpointer copy from callnode to loadnode

michael 20 年之前
父节点
当前提交
55e76063df
共有 5 个文件被更改,包括 60 次插入24 次删除
  1. 6 2
      compiler/cutils.pas
  2. 39 4
      compiler/ncal.pas
  3. 5 11
      compiler/ncnv.pas
  4. 5 5
      compiler/nutils.pas
  5. 5 2
      compiler/pexpr.pas

+ 6 - 2
compiler/cutils.pas

@@ -529,7 +529,8 @@ uses
       begin
       begin
         GetToken:='';
         GetToken:='';
         s:=TrimSpace(s);
         s:=TrimSpace(s);
-        if s[1]='''' then
+        if (length(s)>0) and
+           (s[1]='''') then
          begin
          begin
            i:=1;
            i:=1;
            while (i<length(s)) do
            while (i<length(s)) do
@@ -1239,7 +1240,10 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.50  2005-03-04 16:49:22  peter
+  Revision 1.51  2005-04-06 11:49:37  michael
+  * Fix methodpointer copy from callnode to loadnode
+
+  Revision 1.50  2005/03/04 16:49:22  peter
     * getheapstatus fixes
     * getheapstatus fixes
 
 
   Revision 1.49  2005/02/14 17:13:06  peter
   Revision 1.49  2005/02/14 17:13:06  peter

+ 39 - 4
compiler/ncal.pas

@@ -134,6 +134,7 @@ interface
           function  docompare(p: tnode): boolean; override;
           function  docompare(p: tnode): boolean; override;
           procedure printnodedata(var t:text);override;
           procedure printnodedata(var t:text);override;
           function  para_count:longint;
           function  para_count:longint;
+          function  get_load_methodpointer:tnode;
        private
        private
           AbstractMethodsList : TStringList;
           AbstractMethodsList : TStringList;
        end;
        end;
@@ -286,8 +287,17 @@ type
                 loadp));
                 loadp));
             { new tree is only a temp reference }
             { new tree is only a temp reference }
             p:=refp;
             p:=refp;
-            { temp release }
-            addstatement(newdonestatement,ctempdeletenode.create(ptemp));
+            { temp release. We need to return a reference to the methodpointer
+              otherwise the conversion from callnode to loadnode can't be done
+              for the methodpointer unless the loadnode will also get a methodpointerinit and
+              methodpointerdone node. For the moment we use register as temp and therefor
+              don't create a temp-leak in the stackframe (PFV) }
+            { the last statement should return the value as
+              location and type, this is done be referencing the
+              temp and converting it first from a persistent temp to
+              normal temp }
+            addstatement(newdonestatement,ctempdeletenode.create_normal_temp(ptemp));
+            addstatement(newdonestatement,ctemprefnode.create(ptemp));
             { call resulttypepass for new nodes }
             { call resulttypepass for new nodes }
             resulttypepass(p);
             resulttypepass(p);
             resulttypepass(aktcallnode.methodpointerinit);
             resulttypepass(aktcallnode.methodpointerinit);
@@ -1650,7 +1660,7 @@ type
                             begin
                             begin
                               hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
                               hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
                               if assigned(methodpointer) then
                               if assigned(methodpointer) then
-                                tloadnode(hpt).set_mp(methodpointer.getcopy);
+                                tloadnode(hpt).set_mp(get_load_methodpointer);
                               resulttypepass(hpt);
                               resulttypepass(hpt);
                               result:=hpt;
                               result:=hpt;
                             end
                             end
@@ -2510,6 +2520,28 @@ type
       end;
       end;
 
 
 
 
+    function tcallnode.get_load_methodpointer:tnode;
+      var
+        newstatement : tstatementnode;
+      begin
+        if assigned(methodpointerinit) then
+          begin
+            result:=internalstatements(newstatement);
+            addstatement(newstatement,methodpointerinit);
+            addstatement(newstatement,methodpointer);
+            addstatement(newstatement,methodpointerdone);
+            methodpointerinit:=nil;
+            methodpointer:=nil;
+            methodpointerdone:=nil;
+          end
+        else
+          begin
+            result:=methodpointer;
+            methodpointer:=nil;
+          end;
+      end;
+
+
     function tcallnode.docompare(p: tnode): boolean;
     function tcallnode.docompare(p: tnode): boolean;
       begin
       begin
         docompare :=
         docompare :=
@@ -2547,7 +2579,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.283  2005-04-05 21:07:43  peter
+  Revision 1.284  2005-04-06 11:49:37  michael
+  * Fix methodpointer copy from callnode to loadnode
+
+  Revision 1.283  2005/04/05 21:07:43  peter
     * load all complex loads of parameters that are needed multiple times
     * load all complex loads of parameters that are needed multiple times
       to a temp to prevent calling functions twice
       to a temp to prevent calling functions twice
 
 

+ 5 - 11
compiler/ncnv.pas

@@ -1509,16 +1509,7 @@ implementation
                             if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) then
                             if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) then
                              begin
                              begin
                                if assigned(tcallnode(left).methodpointer) then
                                if assigned(tcallnode(left).methodpointer) then
-                                 begin
-                                   { Under certain circumstances the methodpointer is a loadvmtaddrn
-                                     which isn't possible if it is used as a method pointer, so
-                                     fix this.
-                                     If you change this, ensure that tests/tbs/tw2669.pp still works }
-                                   if tcallnode(left).methodpointer.nodetype=loadvmtaddrn then
-                                     tloadnode(hp).set_mp(tloadvmtaddrnode(tcallnode(left).methodpointer).left.getcopy)
-                                   else
-                                     tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy);
-                                 end
+                                 tloadnode(hp).set_mp(tcallnode(left).get_load_methodpointer)
                                else
                                else
                                  tloadnode(hp).set_mp(load_self_node);
                                  tloadnode(hp).set_mp(load_self_node);
                              end;
                              end;
@@ -2654,7 +2645,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.180  2005-03-25 22:20:18  peter
+  Revision 1.181  2005-04-06 11:49:37  michael
+  * Fix methodpointer copy from callnode to loadnode
+
+  Revision 1.180  2005/03/25 22:20:18  peter
     * add hint when passing an uninitialized variable to a var parameter
     * add hint when passing an uninitialized variable to a var parameter
 
 
   Revision 1.179  2005/03/11 21:55:43  florian
   Revision 1.179  2005/03/11 21:55:43  florian

+ 5 - 5
compiler/nutils.pas

@@ -213,10 +213,7 @@ implementation
               method without a self pointer }
               method without a self pointer }
             if assigned(tcallnode(p1).methodpointer) and
             if assigned(tcallnode(p1).methodpointer) and
                (tcallnode(p1).methodpointer.nodetype<>typen) then
                (tcallnode(p1).methodpointer.nodetype<>typen) then
-             begin
-               tloadnode(p2).set_mp(tcallnode(p1).methodpointer);
-               tcallnode(p1).methodpointer:=nil;
-             end;
+              tloadnode(p2).set_mp(tcallnode(p1).get_load_methodpointer);
           end;
           end;
         resulttypepass(p2);
         resulttypepass(p2);
         p1.free;
         p1.free;
@@ -567,7 +564,10 @@ end.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.30  2005-02-14 17:13:06  peter
+  Revision 1.31  2005-04-06 11:49:37  michael
+  * Fix methodpointer copy from callnode to loadnode
+
+  Revision 1.30  2005/02/14 17:13:06  peter
     * truncate log
     * truncate log
 
 
   Revision 1.29  2005/01/04 16:39:46  peter
   Revision 1.29  2005/01/04 16:39:46  peter

+ 5 - 2
compiler/pexpr.pas

@@ -946,7 +946,7 @@ implementation
                begin
                begin
                  hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc);
                  hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc);
                  if (po_methodpointer in pv.procoptions) then
                  if (po_methodpointer in pv.procoptions) then
-                   tloadnode(hp2).set_mp(tnode(tcallnode(hp).methodpointer).getcopy);
+                   tloadnode(hp2).set_mp(tcallnode(hp).get_load_methodpointer);
                  hp.destroy;
                  hp.destroy;
                  { replace the old callnode with the new loadnode }
                  { replace the old callnode with the new loadnode }
                  hpp^:=hp2;
                  hpp^:=hp2;
@@ -2619,7 +2619,10 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.188  2005-03-28 14:14:52  florian
+  Revision 1.189  2005-04-06 11:49:37  michael
+  * Fix methodpointer copy from callnode to loadnode
+
+  Revision 1.188  2005/03/28 14:14:52  florian
     * fpc_variant_get call fixed
     * fpc_variant_get call fixed
 
 
   Revision 1.187  2005/03/27 20:19:21  florian
   Revision 1.187  2005/03/27 20:19:21  florian