Browse Source

* Don't release methodpointer. It is maybe still needed when we need to
convert the calln to loadn

peter 20 years ago
parent
commit
a15f1c3283
2 changed files with 46 additions and 46 deletions
  1. 12 13
      compiler/ncal.pas
  2. 34 33
      compiler/ncgcal.pas

+ 12 - 13
compiler/ncal.pas

@@ -1803,25 +1803,20 @@ type
          { bind parasyms to the callparanodes and insert hidden parameters }
          { bind parasyms to the callparanodes and insert hidden parameters }
          bind_parasym;
          bind_parasym;
 
 
-         { methodpointer is only needed for virtual calls, and
-           it should then be loaded with the VMT }
-         if (po_virtualmethod in procdefinition.procoptions) and
-            not(assigned(methodpointer) and
-                (methodpointer.nodetype=typen)) then
+         { methodpointer needs to be a pointer to the VMT for virtual calls.
+           Note: We need to keep the methodpointer in the callnode for TP
+           procvar support, because this calln still maybe converted to a loadn,
+           see tw3499 }
+         if (po_virtualmethod in procdefinition.procoptions) then
           begin
           begin
             if not assigned(methodpointer) then
             if not assigned(methodpointer) then
               internalerror(200305063);
               internalerror(200305063);
-            if (methodpointer.resulttype.def.deftype<>classrefdef) then
+            if (methodpointer.nodetype<>typen) and
+               (methodpointer.resulttype.def.deftype<>classrefdef) then
               begin
               begin
                 methodpointer:=cloadvmtaddrnode.create(methodpointer);
                 methodpointer:=cloadvmtaddrnode.create(methodpointer);
                 resulttypepass(methodpointer);
                 resulttypepass(methodpointer);
               end;
               end;
-          end
-         else
-          begin
-            { not needed anymore }
-            methodpointer.free;
-            methodpointer:=nil;
           end;
           end;
 
 
          { insert type conversions for parameters }
          { insert type conversions for parameters }
@@ -2450,7 +2445,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.273  2004-12-27 16:36:10  peter
+  Revision 1.274  2005-01-02 16:58:48  peter
+    * Don't release methodpointer. It is maybe still needed when we need to
+     convert the calln to loadn
+
+  Revision 1.273  2004/12/27 16:36:10  peter
     * fix crash with callnode.ppuload when symtableproc=nil
     * fix crash with callnode.ppuload when symtableproc=nil
 
 
   Revision 1.272  2004/12/26 16:22:01  peter
   Revision 1.272  2004/12/26 16:22:01  peter

+ 34 - 33
compiler/ncgcal.pas

@@ -852,8 +852,11 @@ implementation
          { procedure variable or normal function call ? }
          { procedure variable or normal function call ? }
          if (right=nil) then
          if (right=nil) then
            begin
            begin
+             { When methodpointer is typen we don't need (and can't) load
+               a pointer. We can directly call the correct procdef (PFV) }
              if (po_virtualmethod in procdefinition.procoptions) and
              if (po_virtualmethod in procdefinition.procoptions) and
-                assigned(methodpointer) then
+                assigned(methodpointer) and
+                (methodpointer.nodetype<>typen) then
                begin
                begin
                  secondpass(methodpointer);
                  secondpass(methodpointer);
                  location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
                  location_force_reg(exprasmlist,methodpointer.location,OS_ADDR,false);
@@ -869,40 +872,34 @@ implementation
                  if not(is_interface(tprocdef(procdefinition)._class)) and
                  if not(is_interface(tprocdef(procdefinition)._class)) and
                     not(is_cppclass(tprocdef(procdefinition)._class)) then
                     not(is_cppclass(tprocdef(procdefinition)._class)) then
                    cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
                    cg.g_maybe_testvmt(exprasmlist,methodpointer.location.register,tprocdef(procdefinition)._class);
-               end;
-               {$warning fixme regvars}
-{              rg.saveotherregvars(exprasmlist,regs_to_push_other);}
 
 
-              if (po_virtualmethod in procdefinition.procoptions) and
-                 assigned(methodpointer) then
-                begin
-                   vmtreg:=methodpointer.location.register;
-                   pvreg:=cg.getintregister(exprasmlist,OS_ADDR);
-                   reference_reset_base(href,vmtreg,
-                      tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
-                   cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,pvreg);
-
-                   { Load parameters that are in temporary registers in the
-                     correct parameter register }
-                   if assigned(left) then
-                     begin
-                       pushparas;
-                       { free the resources allocated for the parameters }
-                       freeparas;
-                     end;
+                 vmtreg:=methodpointer.location.register;
+                 pvreg:=cg.getintregister(exprasmlist,OS_ADDR);
+                 reference_reset_base(href,vmtreg,
+                    tprocdef(procdefinition)._class.vmtmethodoffset(tprocdef(procdefinition).extnumber));
+                 cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,href,pvreg);
 
 
-                   cg.alloccpuregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
-                   if cg.uses_registers(R_FPUREGISTER) then
-                     cg.alloccpuregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
-                   if cg.uses_registers(R_MMREGISTER) then
-                     cg.alloccpuregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
+                 { Load parameters that are in temporary registers in the
+                   correct parameter register }
+                 if assigned(left) then
+                   begin
+                     pushparas;
+                     { free the resources allocated for the parameters }
+                     freeparas;
+                   end;
 
 
-                   { call method }
-                   extra_call_code;
-                   cg.a_call_reg(exprasmlist,pvreg);
-                end
-              else
-                begin
+                 cg.alloccpuregisters(exprasmlist,R_INTREGISTER,regs_to_save_int);
+                 if cg.uses_registers(R_FPUREGISTER) then
+                   cg.alloccpuregisters(exprasmlist,R_FPUREGISTER,regs_to_save_fpu);
+                 if cg.uses_registers(R_MMREGISTER) then
+                   cg.alloccpuregisters(exprasmlist,R_MMREGISTER,regs_to_save_mm);
+
+                 { call method }
+                 extra_call_code;
+                 cg.a_call_reg(exprasmlist,pvreg);
+               end
+             else
+               begin
                   { Load parameters that are in temporary registers in the
                   { Load parameters that are in temporary registers in the
                     correct parameter register }
                     correct parameter register }
                   if assigned(left) then
                   if assigned(left) then
@@ -1253,7 +1250,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.190  2004-12-05 12:28:11  peter
+  Revision 1.191  2005-01-02 16:58:48  peter
+    * Don't release methodpointer. It is maybe still needed when we need to
+     convert the calln to loadn
+
+  Revision 1.190  2004/12/05 12:28:11  peter
     * procvar handling for tp procvar mode fixed
     * procvar handling for tp procvar mode fixed
     * proc to procvar moved from addrnode to typeconvnode
     * proc to procvar moved from addrnode to typeconvnode
     * inlininginfo is now allocated only for inline routines that
     * inlininginfo is now allocated only for inline routines that