Quellcode durchsuchen

* better fix for new/dispose bug with init/final data

Jonas Maebe vor 23 Jahren
Ursprung
Commit
313e7a0053
1 geänderte Dateien mit 36 neuen und 21 gelöschten Zeilen
  1. 36 21
      compiler/i386/n386mem.pas

+ 36 - 21
compiler/i386/n386mem.pas

@@ -136,17 +136,27 @@ implementation
       var
          regstopush: tregisterset;
          pushed : tpushedsaved;
+         lefttemp: treference;
          r : preference;
-         oldleft: tnode;
+         left_needs_initfinal: boolean;
+
+        procedure saveleft;
+          begin
+            tg.gettempofsizereference(exprasmlist,target_info.size_of_pointer,
+              lefttemp);
+            cg.a_load_loc_ref(exprasmlist,OS_ADDR,left.location,lefttemp);
+            rg.del_location(exprasmlist,left.location);
+          end;
+
+
       begin
-         oldleft := nil;
-         if tpointerdef(left.resulttype.def).pointertype.def.needs_inittable then
-           { we need to secondpass left twice in this case -> get a copy }
-           oldleft := left.getcopy;
          secondpass(left);
          if codegenerror then
            exit;
 
+         left_needs_initfinal :=
+           tpointerdef(left.resulttype.def).pointertype.def.needs_inittable;
+
          regstopush := all_registers;
          remove_non_regvars_from_loc(left.location,regstopush);
          rg.saveusedregisters(exprasmlist,pushed,regstopush);
@@ -156,7 +166,7 @@ implementation
          case nodetype of
            simpledisposen:
              begin
-                if assigned(oldleft) then
+                if left_needs_initfinal then
                   begin
                      new(r);
                      reset_reference(r^);
@@ -165,14 +175,18 @@ implementation
                      dispose(r);
                      { push pointer adress }
                      emit_push_loc(left.location);
-                     rg.del_location(exprasmlist,left.location);
+                     { save left and free its registers }
+                     saveleft;
                      emitcall('FPC_FINALIZE');
-                     { reload registers for left!! }
-                     secondpass(oldleft);
-                     oldleft.free;
+                     { push left again as parameter for freemem }
+                     emit_push_mem(lefttemp);
+                     tg.ungetiftemp(exprasmlist,lefttemp);
+                  end
+                else
+                  begin
+                    emit_push_loc(left.location);
+                    rg.del_location(exprasmlist,left.location);
                   end;
-                emit_push_loc(left.location);
-                rg.del_location(exprasmlist,left.location);
                 emitcall('FPC_FREEMEM');
              end;
            simplenewn:
@@ -180,21 +194,19 @@ implementation
                 { determines the size of the mem block }
                 push_int(tpointerdef(left.resulttype.def).pointertype.def.size);
                 emit_push_lea_loc(left.location,true);
-                if not assigned(oldleft) then
-                  rg.del_location(exprasmlist,left.location);
+                { save left and free its registers }
+                if left_needs_initfinal then
+                  saveleft;
                 emitcall('FPC_GETMEM');
-                if assigned(oldleft) then
+                if left_needs_initfinal then
                   begin
-                     { reload registers for left!! }
-                     secondpass(oldleft);
-                     oldleft.free;
                      new(r);
                      reset_reference(r^);
                      r^.symbol:=tstoreddef(tpointerdef(left.resulttype.def).pointertype.def).get_rtti_label(initrtti);
                      emitpushreferenceaddr(r^);
                      dispose(r);
-                     emit_push_loc(left.location);
-                     rg.del_location(exprasmlist,left.location);
+                     emit_push_mem(lefttemp);
+                     tg.ungetiftemp(exprasmlist,lefttemp);
                      emitcall('FPC_INITIALIZE');
                   end;
              end;
@@ -722,7 +734,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.21  2002-03-31 20:26:39  jonas
+  Revision 1.22  2002-04-01 09:44:04  jonas
+    * better fix for new/dispose bug with init/final data
+
+  Revision 1.21  2002/03/31 20:26:39  jonas
     + a_loadfpu_* and a_loadmm_* methods in tcg
     * register allocation is now handled by a class and is mostly processor
       independent (+rgobj.pas and i386/rgcpu.pas)