Jelajahi Sumber

* moved implicit exception frame from ncgutil to psub
* constructor/destructor helpers moved from cobj/ncgutil to psub

peter 22 tahun lalu
induk
melakukan
26d78ff5c9

+ 5 - 144
compiler/cgobj.pas

@@ -307,7 +307,6 @@ unit cgobj;
           }
           }
          procedure g_exception_reason_load(list : taasmoutput; const href : treference);virtual;
          procedure g_exception_reason_load(list : taasmoutput; const href : treference);virtual;
 
 
-          function g_load_self(list : taasmoutput):tregister;
           procedure g_maybe_testself(list : taasmoutput;reg:tregister);
           procedure g_maybe_testself(list : taasmoutput;reg:tregister);
           procedure g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
           procedure g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef);
           {# This should emit the opcode to copy len bytes from the source
           {# This should emit the opcode to copy len bytes from the source
@@ -405,8 +404,6 @@ unit cgobj;
              @param(parasize  Number of bytes of parameters to deallocate from stack)
              @param(parasize  Number of bytes of parameters to deallocate from stack)
           }
           }
           procedure g_return_from_proc(list : taasmoutput;parasize : aword);virtual; abstract;
           procedure g_return_from_proc(list : taasmoutput;parasize : aword);virtual; abstract;
-          procedure g_call_constructor_helper(list : taasmoutput);virtual;
-          procedure g_call_destructor_helper(list : taasmoutput);virtual;
           procedure g_call_fail_helper(list : taasmoutput);virtual;
           procedure g_call_fail_helper(list : taasmoutput);virtual;
           {# This routine is called when generating the code for the entry point
           {# This routine is called when generating the code for the entry point
              of a routine. It should save all registers which are not used in this
              of a routine. It should save all registers which are not used in this
@@ -1594,38 +1591,6 @@ unit cgobj;
       end;
       end;
 
 
 
 
-    function tcg.g_load_self(list : taasmoutput):tregister;
-      var
-         hp : treference;
-         p  : tprocinfo;
-         self_reg : tregister;
-      begin
-         if not assigned(current_procdef._class) then
-           internalerror(200303211);
-         self_reg:=rg.getaddressregister(list);
-         if current_procdef.parast.symtablelevel>normal_function_level then
-           begin
-             reference_reset_base(hp,current_procinfo.framepointer,current_procinfo.framepointer_offset);
-             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
-             p:=current_procinfo.parent;
-             while (p.procdef.parast.symtablelevel>normal_function_level) do
-              begin
-                reference_reset_base(hp,self_reg,p.framepointer_offset);
-                a_load_ref_reg(list,OS_ADDR,hp,self_reg);
-                p:=p.parent;
-              end;
-             reference_reset_base(hp,self_reg,p.selfpointer_offset);
-             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
-           end
-         else
-           begin
-             reference_reset_base(hp,current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-             a_load_ref_reg(list,OS_ADDR,hp,self_reg);
-           end;
-        g_load_self:=self_reg;
-      end;
-
-
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
     procedure tcg.g_maybe_testself(list : taasmoutput;reg:tregister);
       var
       var
         OKLabel : tasmlabel;
         OKLabel : tasmlabel;
@@ -1666,114 +1631,6 @@ unit cgobj;
                             Entry/Exit Code Functions
                             Entry/Exit Code Functions
 *****************************************************************************}
 *****************************************************************************}
 
 
-    procedure tcg.g_call_constructor_helper(list : taasmoutput);
-     var
-       href : treference;
-       acc : Tregister;
-     begin
-        if current_procinfo.vmtpointer_offset=0 then
-         internalerror(200303251);
-        if current_procinfo.selfpointer_offset=0 then
-         internalerror(200303252);
-        acc.enum:=R_INTREGISTER;
-        acc.number:=NR_ACCUMULATOR;
-        if is_class(current_procdef._class) then
-          begin
-            if (cs_implicit_exceptions in aktmoduleswitches) then
-              include(current_procinfo.flags,pi_needs_implicit_finally);
-            { parameter 2 : vmt pointer, 0 when called by inherited }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
-            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(2));
-            { parameter 1 : self pointer }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-            a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
-            a_call_name(list,'FPC_NEW_CLASS');
-            { save the self pointer }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-            a_load_reg_ref(list,OS_ADDR,acc,href);
-            { fail? }
-            a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
-          end
-        else if is_object(current_procdef._class) then
-          begin
-            { parameter 3 : vmt_offset }
-            a_param_const(list, OS_32, current_procdef._class.vmt_offset, paramanager.getintparaloc(3));
-            { parameter 2 : address of pointer to vmt,
-              this is required to allow setting the vmt to -1 to indicate
-              that memory was allocated }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
-            a_paramaddr_ref(list,href,paramanager.getintparaloc(2));
-            { parameter 1 : self pointer }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-            a_param_ref(list,OS_ADDR,href,paramanager.getintparaloc(1));
-            a_call_name(list,'FPC_HELP_CONSTRUCTOR');
-            { save the self pointer }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-            a_load_reg_ref(list,OS_ADDR,acc,href);
-            { fail? }
-            a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,acc,faillabel);
-          end
-        else
-          internalerror(200006161);
-     end;
-
-
-    procedure tcg.g_call_destructor_helper(list : taasmoutput);
-      var
-        nofinal : tasmlabel;
-        href : treference;
-        reg  : tregister;
-     begin
-        if is_class(current_procdef._class) then
-         begin
-           if current_procinfo.selfpointer_offset=0 then
-            internalerror(200303253);
-           { parameter 2 : flag }
-           if current_procinfo.inheritedflag_offset=0 then
-            internalerror(200303251);
-           reference_reset_base(href, current_procinfo.framepointer,current_procinfo.inheritedflag_offset);
-           a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(2));
-           { parameter 1 : self }
-           if current_procinfo.selfpointer_offset=0 then
-            internalerror(200303252);
-           reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-           a_param_ref(list, OS_ADDR,href,paramanager.getintparaloc(1));
-           a_call_name(list,'FPC_DISPOSE_CLASS')
-         end
-        else if is_object(current_procdef._class) then
-         begin
-            if current_procinfo.selfpointer_offset=0 then
-             internalerror(200303254);
-            if current_procinfo.vmtpointer_offset=0 then
-             internalerror(200303255);
-            { must the object be finalized ? }
-            if current_procdef._class.needs_inittable then
-             begin
-               objectlibrary.getlabel(nofinal);
-               reference_reset_base(href,current_procinfo.framepointer,target_info.first_parm_offset);
-               a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nofinal);
-               reg:=g_load_self(list);
-               reference_reset_base(href,reg,0);
-               g_finalize(list,current_procdef._class,href,false);
-               reference_release(list,href);
-               a_label(list,nofinal);
-             end;
-            { actually call destructor }
-            { parameter 3 : vmt_offset }
-            a_param_const(list, OS_32, current_procdef._class.vmt_offset, paramanager.getintparaloc(3));
-            { parameter 2 : pointer to vmt }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
-            a_param_ref(list, OS_ADDR, href ,paramanager.getintparaloc(2));
-            { parameter 1 : address of self pointer }
-            reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-            a_param_ref(list, OS_ADDR, href ,paramanager.getintparaloc(1));
-            a_call_name(list,'FPC_HELP_DESTRUCTOR');
-         end
-        else
-         internalerror(200006162);
-      end;
-
-
     procedure tcg.g_call_fail_helper(list : taasmoutput);
     procedure tcg.g_call_fail_helper(list : taasmoutput);
       var
       var
         href : treference;
         href : treference;
@@ -1880,7 +1737,11 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.95  2003-05-09 17:47:02  peter
+  Revision 1.96  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.95  2003/05/09 17:47:02  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn
 
 

+ 58 - 7
compiler/ncal.pas

@@ -91,6 +91,7 @@ interface
           { only the processor specific nodes need to override this }
           { only the processor specific nodes need to override this }
           { constructor                                             }
           { constructor                                             }
           constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
           constructor create(l:tnode; v : tprocsym;st : tsymtable; mp : tnode);virtual;
+          constructor create_def(l:tnode;def:tprocdef;mp:tnode);virtual;
           constructor create_procvar(l,r:tnode);
           constructor create_procvar(l,r:tnode);
           constructor createintern(const name: string; params: tnode);
           constructor createintern(const name: string; params: tnode);
           constructor createinternres(const name: string; params: tnode; const res: ttype);
           constructor createinternres(const name: string; params: tnode; const res: ttype);
@@ -173,6 +174,8 @@ interface
        end;
        end;
        tprocinlinenodeclass = class of tprocinlinenode;
        tprocinlinenodeclass = class of tprocinlinenode;
 
 
+    function initialize_data_node(p:tnode):tnode;
+    function finalize_data_node(p:tnode):tnode;
     function reverseparameters(p: tcallparanode): tcallparanode;
     function reverseparameters(p: tcallparanode): tcallparanode;
 
 
 
 
@@ -222,6 +225,36 @@ type
       end;
       end;
 
 
 
 
+    function initialize_data_node(p:tnode):tnode;
+      begin
+        result:=ccallnode.createintern('fpc_initialize',
+              ccallparanode.create(
+                  caddrnode.create(
+                      crttinode.create(
+                          tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
+              ccallparanode.create(
+                  p,
+              nil)));
+      end;
+
+
+    function finalize_data_node(p:tnode):tnode;
+      begin
+        if not assigned(p.resulttype.def) then
+          resulttypepass(p);
+        if p.resulttype.def.deftype<>pointerdef then
+          internalerror(2003051010);
+        result:=ccallnode.createintern('fpc_finalize',
+              ccallparanode.create(
+                  caddrnode.create(
+                      crttinode.create(
+                          tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
+              ccallparanode.create(
+                  p,
+              nil)));
+      end;
+
+
     function gen_high_tree(p:tnode;openstring:boolean):tnode;
     function gen_high_tree(p:tnode;openstring:boolean):tnode;
       var
       var
         temp: tnode;
         temp: tnode;
@@ -535,8 +568,9 @@ type
 
 
       begin
       begin
          inherited create(callparan,expr,next);
          inherited create(callparan,expr,next);
-         if assigned(expr) then
-          expr.set_file_line(self);
+         if not assigned(expr) then
+           internalerror(200305091);
+         expr.set_file_line(self);
          callparaflags:=[];
          callparaflags:=[];
       end;
       end;
 
 
@@ -876,7 +910,6 @@ type
  ****************************************************************************}
  ****************************************************************************}
 
 
     constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
     constructor tcallnode.create(l:tnode;v : tprocsym;st : tsymtable; mp : tnode);
-
       begin
       begin
          inherited create(calln,l,nil);
          inherited create(calln,l,nil);
          symtableprocentry:=v;
          symtableprocentry:=v;
@@ -890,6 +923,20 @@ type
       end;
       end;
 
 
 
 
+    constructor tcallnode.create_def(l:tnode;def:tprocdef;mp:tnode);
+      begin
+         inherited create(calln,l,nil);
+         symtableprocentry:=nil;
+         symtableproc:=nil;
+         include(flags,nf_return_value_used);
+         methodpointer:=mp;
+         procdefinition:=def;
+         restypeset:=false;
+         funcretnode:=nil;
+         paralength:=-1;
+      end;
+
+
     constructor tcallnode.create_procvar(l,r:tnode);
     constructor tcallnode.create_procvar(l,r:tnode);
       begin
       begin
          inherited create(calln,l,r);
          inherited create(calln,l,r);
@@ -1601,13 +1648,13 @@ type
                 else
                 else
                   begin
                   begin
                     if methodpointer.nodetype=typen then
                     if methodpointer.nodetype=typen then
-                      selftree:=load_self
+                      selftree:=load_self_node
                     else
                     else
                       selftree:=methodpointer.getcopy;
                       selftree:=methodpointer.getcopy;
                   end;
                   end;
               end
               end
             else
             else
-              selftree:=load_self;
+              selftree:=load_self_node;
           end
           end
         else
         else
           begin
           begin
@@ -1639,7 +1686,7 @@ type
             else
             else
               begin
               begin
                 if methodpointer.nodetype=typen then
                 if methodpointer.nodetype=typen then
-                  selftree:=load_self
+                  selftree:=load_self_node
                 else
                 else
                   selftree:=methodpointer.getcopy;
                   selftree:=methodpointer.getcopy;
               end;
               end;
@@ -2682,7 +2729,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.150  2003-05-11 14:45:12  peter
+  Revision 1.151  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.150  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 118 - 92
compiler/ncgflw.pas

@@ -1097,10 +1097,8 @@ implementation
 
 
          cg.a_label(exprasmlist,exceptlabel);
          cg.a_label(exprasmlist,exceptlabel);
 
 
-
          try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
          try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,endexceptlabel,false);
 
 
-
          cg.a_label(exprasmlist,doexceptlabel);
          cg.a_label(exprasmlist,doexceptlabel);
 
 
          { set control flow labels for the except block }
          { set control flow labels for the except block }
@@ -1119,110 +1117,134 @@ implementation
            secondpass(right);
            secondpass(right);
 
 
          cg.a_label(exprasmlist,lastonlabel);
          cg.a_label(exprasmlist,lastonlabel);
-         { default handling except handling }
-         if assigned(t1) then
+         if onlyreraise then
            begin
            begin
-              { FPC_CATCHES must be called with
-                'default handler' flag (=-1)
-              }
-              cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
-              cg.a_call_name(exprasmlist,'FPC_CATCHES');
-
-              { the destruction of the exception object must be also }
-              { guarded by an exception frame                        }
-              objectlibrary.getlabel(doobjectdestroy);
-              objectlibrary.getlabel(doobjectdestroyandreraise);
+             { implicit except frame to cleanup and reraise only }
+             if assigned(t1) then
+               secondpass(t1);
+             cg.a_call_name(exprasmlist,'FPC_RERAISE');
+             if fc_exit in tryflowcontrol then
+               begin
+                 cg.a_label(exprasmlist,exittrylabel);
+                 cg.a_jmp_always(exprasmlist,oldaktexitlabel);
+               end;
+             if fc_break in tryflowcontrol then
+               begin
+                 cg.a_label(exprasmlist,breaktrylabel);
+                 cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
+               end;
+             if fc_continue in tryflowcontrol then
+               begin
+                 cg.a_label(exprasmlist,continuetrylabel);
+                 cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
+               end;
+           end
+         else
+           begin
+             { default handling except handling }
+             if assigned(t1) then
+               begin
+                  { FPC_CATCHES must be called with
+                    'default handler' flag (=-1)
+                  }
+                  cg.a_param_const(exprasmlist,OS_ADDR,aword(-1),paramanager.getintparaloc(1));
+                  cg.a_call_name(exprasmlist,'FPC_CATCHES');
 
 
-              try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
+                  { the destruction of the exception object must be also }
+                  { guarded by an exception frame                        }
+                  objectlibrary.getlabel(doobjectdestroy);
+                  objectlibrary.getlabel(doobjectdestroyandreraise);
 
 
-              { here we don't have to reset flowcontrol           }
-              { the default and on flowcontrols are handled equal }
-              secondpass(t1);
-              exceptflowcontrol:=flowcontrol;
+                  try_new_exception(exprasmlist,tempbuf,tempaddr,href,1,doobjectdestroyandreraise);
 
 
-              cg.a_label(exprasmlist,doobjectdestroyandreraise);
+                  { here we don't have to reset flowcontrol           }
+                  { the default and on flowcontrols are handled equal }
+                  secondpass(t1);
+                  exceptflowcontrol:=flowcontrol;
 
 
-              try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
+                  cg.a_label(exprasmlist,doobjectdestroyandreraise);
 
 
-              cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
+                  try_free_exception(exprasmlist,tempbuf,tempaddr,href,0,doobjectdestroy,false);
 
 
-              r.enum:=R_INTREGISTER;
-              r.number:=NR_ACCUMULATOR;
-              cg.a_param_reg(exprasmlist, OS_ADDR, r, paramanager.getintparaloc(1));
-              cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
-              { we don't need to restore esi here because reraise never }
-              { returns                                                 }
-              cg.a_call_name(exprasmlist,'FPC_RERAISE');
+                  cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
 
 
-              cg.a_label(exprasmlist,doobjectdestroy);
-              cleanupobjectstack;
-              cg.a_jmp_always(exprasmlist,endexceptlabel);
-           end
-         else
-           begin
-              cg.a_call_name(exprasmlist,'FPC_RERAISE');
-              exceptflowcontrol:=flowcontrol;
-           end;
+                  r.enum:=R_INTREGISTER;
+                  r.number:=NR_ACCUMULATOR;
+                  cg.a_param_reg(exprasmlist, OS_ADDR, r, paramanager.getintparaloc(1));
+                  cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
+                  { we don't need to restore esi here because reraise never }
+                  { returns                                                 }
+                  cg.a_call_name(exprasmlist,'FPC_RERAISE');
+
+                  cg.a_label(exprasmlist,doobjectdestroy);
+                  cleanupobjectstack;
+                  cg.a_jmp_always(exprasmlist,endexceptlabel);
+               end
+             else
+               begin
+                  cg.a_call_name(exprasmlist,'FPC_RERAISE');
+                  exceptflowcontrol:=flowcontrol;
+               end;
 
 
-         if fc_exit in exceptflowcontrol then
-           begin
-              { do some magic for exit in the try block }
-              cg.a_label(exprasmlist,exitexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cleanupobjectstack;
-              cg.a_jmp_always(exprasmlist,oldaktexitlabel);
-           end;
+             if fc_exit in exceptflowcontrol then
+               begin
+                  { do some magic for exit in the try block }
+                  cg.a_label(exprasmlist,exitexceptlabel);
+                  { we must also destroy the address frame which guards }
+                  { exception object                                    }
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cleanupobjectstack;
+                  cg.a_jmp_always(exprasmlist,oldaktexitlabel);
+               end;
 
 
-         if fc_break in exceptflowcontrol then
-           begin
-              cg.a_label(exprasmlist,breakexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cleanupobjectstack;
-              cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
-           end;
+             if fc_break in exceptflowcontrol then
+               begin
+                  cg.a_label(exprasmlist,breakexceptlabel);
+                  { we must also destroy the address frame which guards }
+                  { exception object                                    }
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cleanupobjectstack;
+                  cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
+               end;
 
 
-         if fc_continue in exceptflowcontrol then
-           begin
-              cg.a_label(exprasmlist,continueexceptlabel);
-              { we must also destroy the address frame which guards }
-              { exception object                                    }
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cleanupobjectstack;
-              cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
-           end;
+             if fc_continue in exceptflowcontrol then
+               begin
+                  cg.a_label(exprasmlist,continueexceptlabel);
+                  { we must also destroy the address frame which guards }
+                  { exception object                                    }
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cleanupobjectstack;
+                  cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
+               end;
 
 
-         if fc_exit in tryflowcontrol then
-           begin
-              { do some magic for exit in the try block }
-              cg.a_label(exprasmlist,exittrylabel);
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cg.a_jmp_always(exprasmlist,oldaktexitlabel);
-           end;
+             if fc_exit in tryflowcontrol then
+               begin
+                  { do some magic for exit in the try block }
+                  cg.a_label(exprasmlist,exittrylabel);
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cg.a_jmp_always(exprasmlist,oldaktexitlabel);
+               end;
 
 
-         if fc_break in tryflowcontrol then
-           begin
-              cg.a_label(exprasmlist,breaktrylabel);
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
-           end;
+             if fc_break in tryflowcontrol then
+               begin
+                  cg.a_label(exprasmlist,breaktrylabel);
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cg.a_jmp_always(exprasmlist,oldaktbreaklabel);
+               end;
 
 
-         if fc_continue in tryflowcontrol then
-           begin
-              cg.a_label(exprasmlist,continuetrylabel);
-              cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
-              cg.g_exception_reason_load(exprasmlist,href);
-              cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
+             if fc_continue in tryflowcontrol then
+               begin
+                  cg.a_label(exprasmlist,continuetrylabel);
+                  cg.a_call_name(exprasmlist,'FPC_POPADDRSTACK');
+                  cg.g_exception_reason_load(exprasmlist,href);
+                  cg.a_jmp_always(exprasmlist,oldaktcontinuelabel);
+               end;
            end;
            end;
-
          cg.a_label(exprasmlist,endexceptlabel);
          cg.a_label(exprasmlist,endexceptlabel);
 
 
        errorexit:
        errorexit:
@@ -1534,7 +1556,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.58  2003-04-30 15:45:35  florian
+  Revision 1.59  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.58  2003/04/30 15:45:35  florian
     * merged more x86-64/i386 code
     * merged more x86-64/i386 code
 
 
   Revision 1.57  2003/04/29 07:29:14  michael
   Revision 1.57  2003/04/29 07:29:14  michael

+ 23 - 19
compiler/ncgld.pas

@@ -249,25 +249,25 @@ implementation
                          end;
                          end;
                     end;
                     end;
 
 
-                  { handle call by reference variables }
-                  if (symtabletype in [parasymtable,inlineparasymtable]) then
+                  { handle call by reference variables, ignore the reference
+                    when we need to load the self pointer for objects }
+                  if (symtabletype in [parasymtable,inlineparasymtable]) and
+                     not(nf_load_self_pointer in flags) and
+                     (
+                      (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
+                      paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,tprocdef(symtable.defowner).proccalloption)
+                     ) then
                     begin
                     begin
-                      { in case call by reference, then calculate. Open array
-                        is always an reference! }
-                      if (tvarsym(symtableentry).varspez in [vs_var,vs_out]) or
-                         paramanager.push_addr_param(tvarsym(symtableentry).vartype.def,tprocdef(symtable.defowner).proccalloption) then
-                        begin
-                           if hregister.enum=R_NO then
-                             hregister:=rg.getaddressregister(exprasmlist);
-                           { we need to load only an address }
-                           location.size:=OS_ADDR;
-                           cg.a_load_loc_reg(exprasmlist,location,hregister);
-                           if tvarsym(symtableentry).varspez=vs_const then
-                            location_reset(location,LOC_CREFERENCE,newsize)
-                           else
-                            location_reset(location,LOC_REFERENCE,newsize);
-                           location.reference.base:=hregister;
-                       end;
+                      if hregister.enum=R_NO then
+                        hregister:=rg.getaddressregister(exprasmlist);
+                      { we need to load only an address }
+                      location.size:=OS_ADDR;
+                      cg.a_load_loc_reg(exprasmlist,location,hregister);
+                      if tvarsym(symtableentry).varspez=vs_const then
+                       location_reset(location,LOC_CREFERENCE,newsize)
+                      else
+                       location_reset(location,LOC_REFERENCE,newsize);
+                      location.reference.base:=hregister;
                     end;
                     end;
                end;
                end;
             procsym:
             procsym:
@@ -936,7 +936,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.56  2003-05-11 14:45:12  peter
+  Revision 1.57  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.56  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 6 - 2
compiler/ncgmem.pas

@@ -464,7 +464,7 @@ implementation
             if not(current_procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
             if not(current_procdef.proccalloption in [pocall_cdecl,pocall_cppdecl]) then
              begin
              begin
                { Get high value }
                { Get high value }
-               hightree:=load_high_value(tvarsym(tloadnode(left).symtableentry));
+               hightree:=load_high_value_node(tvarsym(tloadnode(left).symtableentry));
                { it must be available }
                { it must be available }
                if not assigned(hightree) then
                if not assigned(hightree) then
                  internalerror(200212201);
                  internalerror(200212201);
@@ -824,7 +824,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.52  2003-05-11 14:45:12  peter
+  Revision 1.53  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.52  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 8 - 172
compiler/ncgutil.pas

@@ -1296,9 +1296,7 @@ implementation
         stackalloclist : taasmoutput;
         stackalloclist : taasmoutput;
         hp : tparaitem;
         hp : tparaitem;
         paraloc : tparalocation;
         paraloc : tparalocation;
-        rsp,
-        tmpreg : tregister;
-        inheriteddesctructorlabel : tasmlabel;
+        rsp : tregister;
       begin
       begin
         if not inlined then
         if not inlined then
            stackalloclist:=taasmoutput.Create;
            stackalloclist:=taasmoutput.Create;
@@ -1397,12 +1395,6 @@ implementation
               cg.g_profilecode(list);
               cg.g_profilecode(list);
           end;
           end;
 
 
-        { a constructor needs a help procedure }
-        if (current_procdef.proctypeoption=potype_constructor) then
-         begin
-           cg.g_call_constructor_helper(list);
-         end;
-
         if not is_void(current_procdef.rettype.def) then
         if not is_void(current_procdef.rettype.def) then
           begin
           begin
              { for now the pointer to the result can't be a register }
              { for now the pointer to the result can't be a register }
@@ -1497,57 +1489,15 @@ implementation
               cg.a_call_name(list,'FPC_INITIALIZEUNITS');
               cg.a_call_name(list,'FPC_INITIALIZEUNITS');
             end;
             end;
 
 
-           { do we need an exception frame because of ansi/widestrings/interfaces ? }
-           if (pi_needs_implicit_finally in current_procinfo.flags) and
-              { but it's useless in init/final code of units }
-              not(current_procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
-            begin
-              include(rg.usedinproc,accumulator);
-              tg.GetTemp(list,JMP_BUF_SIZE,tt_noreuse,current_procinfo.exception_jmp_ref);
-              tg.GetTemp(list,12,tt_noreuse,current_procinfo.exception_env_ref);
-              tg.GetTemp(list,sizeof(aword),tt_noreuse,current_procinfo.exception_result_ref);
-              new_exception(list,current_procinfo.exception_jmp_ref,
-                  current_procinfo.exception_env_ref,
-                  current_procinfo.exception_result_ref,1,aktexitlabel);
-            end;
-
 {$ifdef GDB}
 {$ifdef GDB}
            if (cs_debuginfo in aktmoduleswitches) then
            if (cs_debuginfo in aktmoduleswitches) then
             list.concat(Tai_force_line.Create);
             list.concat(Tai_force_line.Create);
 {$endif GDB}
 {$endif GDB}
          end;
          end;
 
 
-        { maybe call BeforeDestruction for classes }
-        if (current_procdef.proctypeoption=potype_destructor) and
-           is_class(current_procdef._class) then
-         begin
-           objectlibrary.getlabel(inheriteddesctructorlabel);
-           reference_reset_base(href,current_procinfo.framepointer,current_procinfo.inheritedflag_offset);
-           cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,inheriteddesctructorlabel);
-           reference_reset_base(href,current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-         {$ifdef newra}
-           tmpreg:=rg.getaddressregister(list);
-         {$else}
-           tmpreg:=cg.get_scratch_reg_address(list);
-         {$endif}
-           cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg);
-           cg.a_param_reg(list,OS_ADDR,tmpreg,paramanager.getintparaloc(1));
-           reference_reset_base(href,tmpreg,0);
-           cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg);
-           reference_reset_base(href,tmpreg,72);
-           cg.a_call_ref(list,href);
-         {$ifdef newra}
-           rg.ungetregisterint(list,tmpreg);
-         {$else}
-           cg.free_scratch_reg(list,tmpreg);
-         {$endif}
-           cg.a_label(list,inheriteddesctructorlabel);
-         end;
-
         if inlined then
         if inlined then
           load_regvars(list,nil);
           load_regvars(list,nil);
 
 
-
         {************************* Stack allocation **************************}
         {************************* Stack allocation **************************}
         { and symbol entry point as well as debug information                 }
         { and symbol entry point as well as debug information                 }
         { will be inserted in front of the rest of this list.                 }
         { will be inserted in front of the rest of this list.                 }
@@ -1647,15 +1597,12 @@ implementation
         p : pchar;
         p : pchar;
         st : string[2];
         st : string[2];
 {$endif GDB}
 {$endif GDB}
-        inheritedconstructorlabel,
-        okexitlabel,
-        noreraiselabel,nodestroycall : tasmlabel;
+        okexitlabel : tasmlabel;
         href : treference;
         href : treference;
         usesacc,
         usesacc,
         usesacchi,
         usesacchi,
         usesself,usesfpu : boolean;
         usesself,usesfpu : boolean;
-        pd : tprocdef;
-        rsp,tmpreg,r  : Tregister;
+        rsp,r  : Tregister;
       begin
       begin
         if aktexit2label.is_used and
         if aktexit2label.is_used and
            ((pi_needs_implicit_finally in current_procinfo.flags) or
            ((pi_needs_implicit_finally in current_procinfo.flags) or
@@ -1671,11 +1618,6 @@ implementation
 
 
         cleanup_regvars(list);
         cleanup_regvars(list);
 
 
-        { call the destructor help procedure }
-        if (current_procdef.proctypeoption=potype_destructor) and
-           assigned(current_procdef._class) then
-         cg.g_call_destructor_helper(list);
-
         { finalize temporary data }
         { finalize temporary data }
         finalizetempvariables(list);
         finalizetempvariables(list);
 
 
@@ -1701,89 +1643,6 @@ implementation
         if assigned(current_procdef.parast) then
         if assigned(current_procdef.parast) then
           current_procdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras,list);
           current_procdef.parast.foreach_static({$ifndef TP}@{$endif}final_paras,list);
 
 
-        { do we need to handle exceptions because of ansi/widestrings ? }
-        if not inlined and
-           (pi_needs_implicit_finally in current_procinfo.flags) and
-           { but it's useless in init/final code of units }
-           not(current_procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
-          begin
-             { the exception helper routines modify all registers }
-             current_procdef.usedintregisters:=all_intregisters;
-             current_procdef.usedotherregisters:=all_registers;
-             objectlibrary.getlabel(noreraiselabel);
-             free_exception(list,
-                  current_procinfo.exception_jmp_ref,
-                  current_procinfo.exception_env_ref,
-                  current_procinfo.exception_result_ref,0,
-                  noreraiselabel,false);
-             tg.Ungettemp(list,current_procinfo.exception_jmp_ref);
-             tg.Ungettemp(list,current_procinfo.exception_env_ref);
-             tg.Ungettemp(list,current_procinfo.exception_result_ref);
-
-             if (current_procdef.proctypeoption=potype_constructor) then
-               begin
-                  if assigned(current_procdef._class) then
-                    begin
-                       pd:=current_procdef._class.searchdestructor;
-                       if assigned(pd) then
-                         begin
-                            objectlibrary.getlabel(nodestroycall);
-                            { check VMT pointer if this is an inherited constructor }
-                            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
-                            cg.a_cmp_const_ref_label(list,OS_ADDR,OC_EQ,0,href,nodestroycall);
-{                            srsym:=pd.parast.searchsym('self');
-                            if not assigned(srsym) then
-                              internalerror(200305101);
-                            reference_reset_base(href,current_procinfo.framepointer,tvarsym(srsym).adjusted_address);
-                            cg.a_load_ref_reg( }
-                            r:=cg.g_load_self(list);
-                            if is_class(current_procdef._class) then
-                             begin
-                               cg.a_param_const(list,OS_INT,1,paramanager.getintparaloc(2));
-                               cg.a_param_reg(list,OS_ADDR,r,paramanager.getintparaloc(1));
-                             end
-                            else if is_object(current_procdef._class) then
-                             begin
-                               cg.a_param_reg(list,OS_ADDR,r,paramanager.getintparaloc(2));
-                               reference_reset_symbol(href,objectlibrary.newasmsymboldata(current_procdef._class.vmt_mangledname),0);
-                               cg.a_paramaddr_ref(list,href,paramanager.getintparaloc(1));
-                             end
-                            else
-                             Internalerror(200006164);
-                            if (po_virtualmethod in pd.procoptions) then
-                             begin
-                               reference_reset_base(href,r,0);
-                               cg.a_load_ref_reg(list,OS_ADDR,href,r);
-                               reference_reset_base(href,r,current_procdef._class.vmtmethodoffset(pd.extnumber));
-                               cg.a_call_ref(list,href);
-                             end
-                            else
-                             cg.a_call_name(list,pd.mangledname);
-                            rg.ungetregisterint(list,r);
-                            { not necessary because the result is never assigned in the
-                              case of an exception (FK) }
-                            cg.a_label(list,nodestroycall);
-                         end;
-                    end
-               end
-             else
-              begin
-                { no constructor }
-                { must be the return value finalized before reraising the exception? }
-                if (not is_void(current_procdef.rettype.def)) and
-                   (current_procdef.rettype.def.needs_inittable) and
-                   ((current_procdef.rettype.def.deftype<>objectdef) or
-                    not is_class(current_procdef.rettype.def)) then
-                  begin
-                     reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
-                     cg.g_finalize(list,current_procdef.rettype.def,href,paramanager.ret_in_param(current_procdef.rettype.def,current_procdef.proccalloption));
-                  end;
-              end;
-
-             cg.a_call_name(list,'FPC_RERAISE');
-             cg.a_label(list,noreraiselabel);
-          end;
-
         { call __EXIT for main program }
         { call __EXIT for main program }
         if (not DLLsource) and
         if (not DLLsource) and
            (not inlined) and
            (not inlined) and
@@ -1803,44 +1662,17 @@ implementation
           begin
           begin
             if (current_procdef.proctypeoption=potype_constructor) then
             if (current_procdef.proctypeoption=potype_constructor) then
               begin
               begin
-                objectlibrary.getlabel(inheritedconstructorlabel);
                 objectlibrary.getlabel(okexitlabel);
                 objectlibrary.getlabel(okexitlabel);
                 cg.a_jmp_always(list,okexitlabel);
                 cg.a_jmp_always(list,okexitlabel);
                 { Failure exit }
                 { Failure exit }
                 cg.a_label(list,faillabel);
                 cg.a_label(list,faillabel);
                 cg.g_call_fail_helper(list);
                 cg.g_call_fail_helper(list);
-                cg.a_jmp_always(list,inheritedconstructorlabel);
                 { Success exit }
                 { Success exit }
                 cg.a_label(list,okexitlabel);
                 cg.a_label(list,okexitlabel);
                 r.enum:=R_INTREGISTER;
                 r.enum:=R_INTREGISTER;
                 r.number:=NR_ACCUMULATOR;
                 r.number:=NR_ACCUMULATOR;
                 cg.a_reg_alloc(list,r);
                 cg.a_reg_alloc(list,r);
-                { maybe call AfterConstructor for classes }
-                if is_class(current_procdef._class) then
-                 begin
-                   reference_reset_base(href,current_procinfo.framepointer,current_procinfo.vmtpointer_offset);
-                   cg.a_load_ref_reg(list,OS_ADDR,href,r);
-                   cg.a_cmp_const_reg_label(list,OS_ADDR,OC_EQ,0,r,inheritedconstructorlabel);
-                   reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
-                   cg.a_load_ref_reg(list,OS_ADDR,href,r);
-                   cg.a_param_reg(list,OS_ADDR,r,paramanager.getintparaloc(1));
-                   reference_reset_base(href,r,0);
-                 {$ifdef newra}
-                   tmpreg:=rg.getaddressregister(list);
-                 {$else newra}
-                   tmpreg:=cg.get_scratch_reg_address(list);
-                 {$endif}
-                   cg.a_load_ref_reg(list,OS_ADDR,href,tmpreg);
-                   reference_reset_base(href,tmpreg,68);
-                   cg.a_call_ref(list,href);
-                 {$ifdef newra}
-                   rg.ungetregisterint(list,tmpreg);
-                 {$else}
-                   cg.free_scratch_reg(list,tmpreg);
-                 {$endif}
-                 end;
                 { return the self pointer }
                 { return the self pointer }
-                cg.a_label(list,inheritedconstructorlabel);
                 reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
                 reference_reset_base(href, current_procinfo.framepointer,current_procinfo.selfpointer_offset);
                 cg.a_load_ref_reg(list,OS_ADDR,href,r);
                 cg.a_load_ref_reg(list,OS_ADDR,href,r);
                 cg.a_reg_dealloc(list,r);
                 cg.a_reg_dealloc(list,r);
@@ -2018,7 +1850,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.98  2003-05-11 14:45:12  peter
+  Revision 1.99  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.98  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 6 - 2
compiler/ncnv.pas

@@ -1178,7 +1178,7 @@ implementation
                            if assigned(tcallnode(left).methodpointer) then
                            if assigned(tcallnode(left).methodpointer) then
                              tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
                              tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy)
                            else
                            else
-                             tloadnode(hp).set_mp(load_self);
+                             tloadnode(hp).set_mp(load_self_node);
                          end;
                          end;
                         resulttypepass(hp);
                         resulttypepass(hp);
                       end;
                       end;
@@ -2091,7 +2091,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.110  2003-05-09 17:47:02  peter
+  Revision 1.111  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.110  2003/05/09 17:47:02  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn
 
 

+ 26 - 3
compiler/nflw.pas

@@ -33,8 +33,13 @@ interface
        symppu,symtype,symbase,symdef,symsym;
        symppu,symtype,symbase,symdef,symsym;
 
 
     type
     type
+       { internal labels for gotonode.createintern }
+{       tgotolabel = (
+         gnl_fail
+       ); }
+
        { flags used by loop nodes }
        { flags used by loop nodes }
-       tloopflags = (
+       tloopflag = (
          { set if it is a for ... downto ... do loop }
          { set if it is a for ... downto ... do loop }
          lnf_backward,
          lnf_backward,
          { Do we need to parse childs to set var state? }
          { Do we need to parse childs to set var state? }
@@ -45,6 +50,8 @@ interface
          lnf_checknegate,
          lnf_checknegate,
          { Should the value of the loop variable on exit be correct. }
          { Should the value of the loop variable on exit be correct. }
          lnf_dont_mind_loopvar_on_exit);
          lnf_dont_mind_loopvar_on_exit);
+       tloopflags = set of tloopflag;
+
     const
     const
          { loop flags which must match to consider loop nodes equal regarding the flags }
          { loop flags which must match to consider loop nodes equal regarding the flags }
          loopflagsequal = [lnf_backward];
          loopflagsequal = [lnf_backward];
@@ -52,7 +59,7 @@ interface
     type
     type
        tloopnode = class(tbinarynode)
        tloopnode = class(tbinarynode)
           t1,t2 : tnode;
           t1,t2 : tnode;
-          loopflags : set of tloopflags;
+          loopflags : tloopflags;
           constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
           constructor create(tt : tnodetype;l,r,_t1,_t2 : tnode);virtual;
           destructor destroy;override;
           destructor destroy;override;
           function getcopy : tnode;override;
           function getcopy : tnode;override;
@@ -117,7 +124,9 @@ interface
        tgotonode = class(tnode)
        tgotonode = class(tnode)
           labsym : tlabelsym;
           labsym : tlabelsym;
           exceptionblock : integer;
           exceptionblock : integer;
+//          internlab : tinterngotolabel;
           constructor create(p : tlabelsym);virtual;
           constructor create(p : tlabelsym);virtual;
+//          constructor createintern(g:tinterngotolabel);
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           constructor ppuload(t:tnodetype;ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure ppuwrite(ppufile:tcompilerppufile);override;
           procedure derefimpl;override;
           procedure derefimpl;override;
@@ -159,7 +168,9 @@ interface
        traisenodeclass = class of traisenode;
        traisenodeclass = class of traisenode;
 
 
        ttryexceptnode = class(tloopnode)
        ttryexceptnode = class(tloopnode)
+          onlyreraise : boolean;
           constructor create(l,r,_t1 : tnode);virtual;
           constructor create(l,r,_t1 : tnode);virtual;
+          constructor createintern(l,_t1 : tnode);virtual;
           function det_resulttype:tnode;override;
           function det_resulttype:tnode;override;
           function pass_1 : tnode;override;
           function pass_1 : tnode;override;
        end;
        end;
@@ -1274,6 +1285,14 @@ implementation
     constructor ttryexceptnode.create(l,r,_t1 : tnode);
     constructor ttryexceptnode.create(l,r,_t1 : tnode);
       begin
       begin
          inherited create(tryexceptn,l,r,_t1,nil);
          inherited create(tryexceptn,l,r,_t1,nil);
+         onlyreraise:=false;
+      end;
+
+
+    constructor ttryexceptnode.createintern(l,_t1 : tnode);
+      begin
+         inherited create(tryexceptn,l,nil,_t1,nil);
+         onlyreraise:=true;
       end;
       end;
 
 
 
 
@@ -1503,7 +1522,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.72  2003-05-01 07:59:42  florian
+  Revision 1.73  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.72  2003/05/01 07:59:42  florian
     * introduced defaultordconsttype to decribe the default size of ordinal constants
     * introduced defaultordconsttype to decribe the default size of ordinal constants
       on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
       on 64 bit CPUs it's equal to cs64bitdef while on 32 bit CPUs it's equal to s32bitdef
     + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs
     + added defines CPU32 and CPU64 for 32 bit and 64 bit CPUs

+ 14 - 8
compiler/ninl.pas

@@ -924,10 +924,12 @@ implementation
             { create a temp codepara, but save the original code para to }
             { create a temp codepara, but save the original code para to }
             { assign the result to later on                              }
             { assign the result to later on                              }
             if assigned(codepara) then
             if assigned(codepara) then
-              orgcode := codepara.left
+              begin
+                orgcode := codepara.left;
+                codepara.left := ctemprefnode.create(tempcode);
+              end
             else
             else
-              codepara := ccallparanode.create(nil,nil);
-            codepara.left := ctemprefnode.create(tempcode);
+              codepara := ccallparanode.create(ctemprefnode.create(tempcode),nil);
             { we need its resulttype later on }
             { we need its resulttype later on }
             codepara.get_paratype;
             codepara.get_paratype;
           end
           end
@@ -1388,7 +1390,7 @@ implementation
                   set_varstate(left,false);
                   set_varstate(left,false);
                   if paramanager.push_high_param(left.resulttype.def,current_procdef.proccalloption) then
                   if paramanager.push_high_param(left.resulttype.def,current_procdef.proccalloption) then
                    begin
                    begin
-                     hightree:=load_high_value(tvarsym(tloadnode(left).symtableentry));
+                     hightree:=load_high_value_node(tvarsym(tloadnode(left).symtableentry));
                      if assigned(hightree) then
                      if assigned(hightree) then
                       begin
                       begin
                         hp:=caddnode.create(addn,hightree,
                         hp:=caddnode.create(addn,hightree,
@@ -1545,7 +1547,7 @@ implementation
                         if is_open_array(left.resulttype.def) or
                         if is_open_array(left.resulttype.def) or
                            is_array_of_const(left.resulttype.def) then
                            is_array_of_const(left.resulttype.def) then
                          begin
                          begin
-                           hightree:=load_high_value(tvarsym(tloadnode(left).symtableentry));
+                           hightree:=load_high_value_node(tvarsym(tloadnode(left).symtableentry));
                            if assigned(hightree) then
                            if assigned(hightree) then
                             begin
                             begin
                               hp:=caddnode.create(addn,hightree,
                               hp:=caddnode.create(addn,hightree,
@@ -1788,7 +1790,7 @@ implementation
                            if is_open_array(left.resulttype.def) or
                            if is_open_array(left.resulttype.def) or
                               is_array_of_const(left.resulttype.def) then
                               is_array_of_const(left.resulttype.def) then
                             begin
                             begin
-                              result:=load_high_value(tvarsym(tloadnode(left).symtableentry));
+                              result:=load_high_value_node(tvarsym(tloadnode(left).symtableentry));
                             end
                             end
                            else
                            else
                             if is_dynamic_array(left.resulttype.def) then
                             if is_dynamic_array(left.resulttype.def) then
@@ -1817,7 +1819,7 @@ implementation
                         else
                         else
                          begin
                          begin
                            if is_open_string(left.resulttype.def) then
                            if is_open_string(left.resulttype.def) then
-                            result:=load_high_value(tvarsym(tloadnode(left).symtableentry))
+                            result:=load_high_value_node(tvarsym(tloadnode(left).symtableentry))
                            else
                            else
                             result:=cordconstnode.create(tstringdef(left.resulttype.def).len,u8bittype,true);
                             result:=cordconstnode.create(tstringdef(left.resulttype.def).len,u8bittype,true);
                          end;
                          end;
@@ -2349,7 +2351,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.110  2003-05-09 17:47:02  peter
+  Revision 1.111  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.110  2003/05/09 17:47:02  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn
 
 

+ 89 - 18
compiler/nld.pas

@@ -127,8 +127,11 @@ interface
 
 
 
 
     procedure load_procvar_from_calln(var p1:tnode);
     procedure load_procvar_from_calln(var p1:tnode);
-    function load_high_value(vs:tvarsym):tnode;
-    function load_self:tnode;
+    function load_high_value_node(vs:tvarsym):tnode;
+    function load_self_node:tnode;
+    function load_result_node:tnode;
+    function load_self_pointer_node:tnode;
+    function load_vmt_pointer_node:tnode;
     function is_self_node(p:tnode):boolean;
     function is_self_node(p:tnode):boolean;
 
 
 
 
@@ -179,7 +182,7 @@ implementation
         end;
         end;
 
 
 
 
-    function load_high_value(vs:tvarsym):tnode;
+    function load_high_value_node(vs:tvarsym):tnode;
       var
       var
         srsym : tsym;
         srsym : tsym;
         srsymtable : tsymtable;
         srsymtable : tsymtable;
@@ -195,13 +198,16 @@ implementation
          end;
          end;
         srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
         srsym:=searchsymonlyin(srsymtable,'high'+vs.name);
         if assigned(srsym) then
         if assigned(srsym) then
-          result:=cloadnode.create(srsym,srsymtable)
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
         else
         else
           CGMessage(cg_e_illegal_expression);
           CGMessage(cg_e_illegal_expression);
       end;
       end;
 
 
 
 
-    function load_self:tnode;
+    function load_self_node:tnode;
       var
       var
         srsym : tsym;
         srsym : tsym;
         srsymtable : tsymtable;
         srsymtable : tsymtable;
@@ -209,7 +215,62 @@ implementation
         result:=nil;
         result:=nil;
         searchsym('self',srsym,srsymtable);
         searchsym('self',srsym,srsymtable);
         if assigned(srsym) then
         if assigned(srsym) then
-          result:=cloadnode.create(srsym,srsymtable)
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_result_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('result',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_self_pointer_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('self',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            include(result.flags,nf_load_self_pointer);
+            resulttypepass(result);
+          end
+        else
+          CGMessage(cg_e_illegal_expression);
+      end;
+
+
+    function load_vmt_pointer_node:tnode;
+      var
+        srsym : tsym;
+        srsymtable : tsymtable;
+      begin
+        result:=nil;
+        searchsym('vmt',srsym,srsymtable);
+        if assigned(srsym) then
+          begin
+            result:=cloadnode.create(srsym,srsymtable);
+            resulttypepass(result);
+          end
         else
         else
           CGMessage(cg_e_illegal_expression);
           CGMessage(cg_e_illegal_expression);
       end;
       end;
@@ -327,23 +388,29 @@ implementation
               begin
               begin
                 { if it's refered by absolute then it's used }
                 { if it's refered by absolute then it's used }
                 if nf_absolute in flags then
                 if nf_absolute in flags then
-                  tvarsym(symtableentry).varstate:=vs_used;
-
-                { fix self type which is declared as voidpointer in the
-                  definition }
-                if vo_is_self in tvarsym(symtableentry).varoptions then
+                  tvarsym(symtableentry).varstate:=vs_used
+                else
                   begin
                   begin
-                    if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
-                       (po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
+                    { fix self type which is declared as voidpointer in the
+                      definition }
+                    if vo_is_self in tvarsym(symtableentry).varoptions then
+                      begin
+                        resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
+                        if (po_classmethod in tprocdef(symtableentry.owner.defowner).procoptions) or
+                           (po_staticmethod in tprocdef(symtableentry.owner.defowner).procoptions) then
+                          resulttype.setdef(tclassrefdef.create(resulttype))
+                        else if is_object(resulttype.def) and
+                                (nf_load_self_pointer in flags) then
+                          resulttype.setdef(tpointerdef.create(resulttype));
+                      end
+                    else if vo_is_vmt in tvarsym(symtableentry).varoptions then
                       begin
                       begin
                         resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
                         resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
                         resulttype.setdef(tclassrefdef.create(resulttype));
                         resulttype.setdef(tclassrefdef.create(resulttype));
                       end
                       end
                     else
                     else
-                      resulttype.setdef(tprocdef(symtableentry.owner.defowner)._class);
-                  end
-                else
-                  resulttype:=tvarsym(symtableentry).vartype;
+                      resulttype:=tvarsym(symtableentry).vartype;
+                  end;
               end;
               end;
             typedconstsym :
             typedconstsym :
                 if not(nf_absolute in flags) then
                 if not(nf_absolute in flags) then
@@ -1148,7 +1215,11 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.92  2003-05-11 14:45:12  peter
+  Revision 1.93  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.92  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 6 - 4
compiler/node.pas

@@ -234,11 +234,9 @@ interface
          nf_memseg,
          nf_memseg,
          nf_callunique,
          nf_callunique,
 
 
-         { twithnode }
-         nf_islocal,
-
          { tloadnode }
          { tloadnode }
          nf_absolute,
          nf_absolute,
+         nf_load_self_pointer,
 
 
          { taddnode }
          { taddnode }
          nf_is_currency,
          nf_is_currency,
@@ -988,7 +986,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.59  2003-05-09 17:47:02  peter
+  Revision 1.60  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.59  2003/05/09 17:47:02  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn
 
 

+ 9 - 5
compiler/pexpr.pas

@@ -647,7 +647,7 @@ implementation
                end;
                end;
              objectsymtable :
              objectsymtable :
                begin
                begin
-                 p1:=load_self;
+                 p1:=load_self_node;
                  maybe_load_methodpointer:=true;
                  maybe_load_methodpointer:=true;
                end;
                end;
            end;
            end;
@@ -817,7 +817,7 @@ implementation
                         withsymtable :
                         withsymtable :
                           p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                           p1:=tnode(twithsymtable(st).withrefnode).getcopy;
                         objectsymtable :
                         objectsymtable :
-                          p1:=load_self;
+                          p1:=load_self_node;
                       end;
                       end;
                     end;
                     end;
                    if assigned(p1) then
                    if assigned(p1) then
@@ -1112,7 +1112,7 @@ implementation
 
 
                     case srsymtable.symtabletype of
                     case srsymtable.symtabletype of
                       objectsymtable :
                       objectsymtable :
-                        p1:=csubscriptnode.create(srsym,load_self);
+                        p1:=csubscriptnode.create(srsym,load_self_node);
                       withsymtable :
                       withsymtable :
                         p1:=csubscriptnode.create(srsym,tnode(twithsymtable(srsymtable).withrefnode).getcopy);
                         p1:=csubscriptnode.create(srsym,tnode(twithsymtable(srsymtable).withrefnode).getcopy);
                       else
                       else
@@ -1771,7 +1771,7 @@ implementation
                 end
                 end
                else
                else
                 begin
                 begin
-                  p1:=load_self;
+                  p1:=load_self_node;
                   postfixoperators(p1,again);
                   postfixoperators(p1,again);
                 end;
                 end;
              end;
              end;
@@ -2339,7 +2339,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.116  2003-05-11 14:45:12  peter
+  Revision 1.117  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.116  2003/05/11 14:45:12  peter
     * tloadnode does not support objectsymtable,withsymtable anymore
     * tloadnode does not support objectsymtable,withsymtable anymore
     * withnode cleanup
     * withnode cleanup
     * direct with rewritten to use temprefnode
     * direct with rewritten to use temprefnode

+ 269 - 9
compiler/psub.pas

@@ -56,7 +56,7 @@ implementation
        ppu,fmodule,
        ppu,fmodule,
        { pass 1 }
        { pass 1 }
        node,
        node,
-       nbas,nld,
+       nbas,nld,ncal,ncon,nflw,nadd,ncnv,nmem,
        pass_1,
        pass_1,
     {$ifdef state_tracking}
     {$ifdef state_tracking}
        nstate,
        nstate,
@@ -225,6 +225,259 @@ implementation
       end;
       end;
 
 
 
 
+    function generate_entry_block:tblocknode;
+      var
+        srsym        : tsym;
+        para         : tcallparanode;
+        newstatement : tstatementnode;
+        htype        : ttype;
+      begin
+        generate_entry_block:=internalstatements(newstatement,true);
+
+        { a constructor needs a help procedure }
+        if (current_procdef.proctypeoption=potype_constructor) then
+          begin
+            if is_class(current_procdef._class) then
+              begin
+                if (cs_implicit_exceptions in aktmoduleswitches) then
+                  include(current_procinfo.flags,pi_needs_implicit_finally);
+                srsym:=search_class_member(current_procdef._class,'NEWINSTANCE');
+                if assigned(srsym) and
+                   (srsym.typ=procsym) then
+                  begin
+                    { if vmt<>0 then newinstance }
+                    addstatement(newstatement,cifnode.create(
+                        caddnode.create(unequaln,
+                            load_vmt_pointer_node,
+                            cnilnode.create),
+                        cassignmentnode.create(
+                            ctypeconvnode.create_explicit(
+                                load_self_pointer_node,
+                                voidpointertype),
+                            ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_vmt_pointer_node)),
+                        nil));
+                  end
+                else
+                  internalerror(200305108);
+              end
+            else
+              if is_object(current_procdef._class) then
+                begin
+                  htype.setdef(current_procdef._class);
+                  htype.setdef(tpointerdef.create(htype));
+                  { parameter 3 : vmt_offset }
+                  { parameter 2 : address of pointer to vmt,
+                    this is required to allow setting the vmt to -1 to indicate
+                    that memory was allocated }
+                  { parameter 1 : self pointer }
+                  para:=ccallparanode.create(
+                            cordconstnode.create(current_procdef._class.vmt_offset,s32bittype,false),
+                        ccallparanode.create(
+                            ctypeconvnode.create_explicit(
+                                load_vmt_pointer_node,
+                                voidpointertype),
+                        ccallparanode.create(
+                            ctypeconvnode.create_explicit(
+                                load_self_pointer_node,
+                                voidpointertype),
+                        nil)));
+                  addstatement(newstatement,cassignmentnode.create(
+                      ctypeconvnode.create_explicit(
+                          load_self_pointer_node,
+                          voidpointertype),
+                      ccallnode.createintern('fpc_help_constructor',para)));
+                end
+            else
+              internalerror(200305103);
+            { if self=nil then fail }
+            addstatement(newstatement,cifnode.create(
+                caddnode.create(equaln,
+                    load_self_pointer_node,
+                    cnilnode.create),
+                cfailnode.create,
+                nil));
+          end;
+
+        { maybe call BeforeDestruction for classes }
+        if (current_procdef.proctypeoption=potype_destructor) and
+           is_class(current_procdef._class) then
+          begin
+            srsym:=search_class_member(current_procdef._class,'BEFOREDESTRUCTION');
+            if assigned(srsym) and
+               (srsym.typ=procsym) then
+              begin
+                { if vmt<>0 then beforedestruction }
+                addstatement(newstatement,cifnode.create(
+                    caddnode.create(unequaln,
+                        load_vmt_pointer_node,
+                        cnilnode.create),
+                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node),
+                    nil));
+              end
+            else
+              internalerror(200305104);
+          end;
+      end;
+
+
+    function generate_exit_block:tblocknode;
+      var
+        srsym : tsym;
+        para : tcallparanode;
+        newstatement : tstatementnode;
+      begin
+        generate_exit_block:=internalstatements(newstatement,true);
+
+        { maybe call AfterConstruction for classes }
+        if (current_procdef.proctypeoption=potype_constructor) and
+           is_class(current_procdef._class) then
+          begin
+            srsym:=search_class_member(current_procdef._class,'AFTERCONSTRUCTION');
+            if assigned(srsym) and
+               (srsym.typ=procsym) then
+              begin
+                { if vmt<>0 then afterconstruction }
+                addstatement(newstatement,cifnode.create(
+                    caddnode.create(unequaln,
+                        load_vmt_pointer_node,
+                        cnilnode.create),
+                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node),
+                    nil));
+              end
+            else
+              internalerror(200305106);
+          end;
+
+        { a destructor needs a help procedure }
+        if (current_procdef.proctypeoption=potype_destructor) then
+          begin
+            if is_class(current_procdef._class) then
+              begin
+                srsym:=search_class_member(current_procdef._class,'FREEINSTANCE');
+                if assigned(srsym) and
+                   (srsym.typ=procsym) then
+                  begin
+                    { if self<>0 and vmt=1 then freeinstance }
+                    addstatement(newstatement,cifnode.create(
+                        caddnode.create(andn,
+                            caddnode.create(unequaln,
+                                load_self_pointer_node,
+                                cnilnode.create),
+                            caddnode.create(equaln,
+                                ctypeconvnode.create(
+                                    load_vmt_pointer_node,
+                                    voidpointertype),
+                                cpointerconstnode.create(1,voidpointertype))),
+                        ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node),
+                        nil));
+                  end
+                else
+                  internalerror(200305108);
+              end
+            else
+              if is_object(current_procdef._class) then
+                begin
+                  { parameter 3 : vmt_offset }
+                  { parameter 2 : pointer to vmt }
+                  { parameter 1 : self pointer }
+                  para:=ccallparanode.create(
+                            cordconstnode.create(current_procdef._class.vmt_offset,s32bittype,false),
+                        ccallparanode.create(
+                            ctypeconvnode.create_explicit(
+                                load_vmt_pointer_node,
+                                voidpointertype),
+                        ccallparanode.create(
+                            ctypeconvnode.create_explicit(
+                                load_self_pointer_node,
+                                voidpointertype),
+                        nil)));
+                  addstatement(newstatement,
+                      ccallnode.createintern('fpc_help_destructor',para));
+                end
+            else
+              internalerror(200305105);
+          end;
+      end;
+
+
+    function generate_except_block:tblocknode;
+      var
+        pd : tprocdef;
+        newstatement : tstatementnode;
+      begin
+        generate_except_block:=internalstatements(newstatement,true);
+
+        { a constructor needs call destroy when it is not inherited }
+        if (current_procdef.proctypeoption=potype_constructor) then
+          begin
+            pd:=current_procdef._class.searchdestructor;
+            if assigned(pd) then
+              begin
+                { if vmt<>0 then call destructor }
+                addstatement(newstatement,cifnode.create(
+                    caddnode.create(unequaln,
+                        load_vmt_pointer_node,
+                        cnilnode.create),
+                    ccallnode.create(nil,tprocsym(pd.procsym),pd.procsym.owner,load_self_node),
+                    nil));
+              end
+            else
+              internalerror(200305107);
+          end
+        else
+          begin
+            { no constructor }
+            { must be the return value finalized before reraising the exception? }
+            if (not is_void(current_procdef.rettype.def)) and
+               (current_procdef.rettype.def.needs_inittable) and
+               (not is_class(current_procdef.rettype.def)) then
+              finalize_data_node(caddrnode.create(load_result_node));
+          end;
+      end;
+
+
+    procedure add_entry_exit_block(var code:tnode;const entrypos,exitpos:tfileposinfo);
+      var
+        entryblock,
+        exitblock,
+        newblock     : tblocknode;
+        newstatement : tstatementnode;
+        oldfilepos   : tfileposinfo;
+      begin
+        oldfilepos:=aktfilepos;
+        { Generate entry and exit }
+        aktfilepos:=entrypos;
+        entryblock:=generate_entry_block;
+        aktfilepos:=exitpos;
+        exitblock:=generate_exit_block;
+
+        { Generate procedure by combining entry+body+exit,
+          depending on the implicit finally we need to add
+          an try...finally...end wrapper }
+        newblock:=internalstatements(newstatement,true);
+        if (pi_needs_implicit_finally in current_procinfo.flags) and
+           { but it's useless in init/final code of units }
+           not(current_procdef.proctypeoption in [potype_unitfinalize,potype_unitinit]) then
+          begin
+            addstatement(newstatement,entryblock);
+            aktfilepos:=exitpos;
+            addstatement(newstatement,ctryexceptnode.createintern(
+               code,
+               generate_except_block));
+            addstatement(newstatement,exitblock);
+          end
+        else
+          begin
+            addstatement(newstatement,entryblock);
+            addstatement(newstatement,code);
+            addstatement(newstatement,exitblock);
+          end;
+        resulttypepass(newblock);
+        code:=newblock;
+        aktfilepos:=oldfilepos;
+      end;
+
+
     procedure compile_proc_body(pd:tprocdef;make_global,parent_has_class:boolean);
     procedure compile_proc_body(pd:tprocdef;make_global,parent_has_class:boolean);
       {
       {
         Compile the body of a procedure
         Compile the body of a procedure
@@ -325,13 +578,6 @@ implementation
          localmaxfpuregisters:=aktmaxfpuregisters;
          localmaxfpuregisters:=aktmaxfpuregisters;
          { parse the code ... }
          { parse the code ... }
          code:=block(current_module.islibrary);
          code:=block(current_module.islibrary);
-         { store a copy of the original tree for inline, for
-           normal procedures only store a reference to the
-           current tree }
-         if (current_procdef.proccalloption=pocall_inline) then
-           current_procdef.code:=code.getcopy
-         else
-           current_procdef.code:=code;
          { get a better entry point }
          { get a better entry point }
          if assigned(code) then
          if assigned(code) then
            entrypos:=code.fileinfo;
            entrypos:=code.fileinfo;
@@ -340,6 +586,16 @@ implementation
          exitpos:=last_endtoken_filepos;
          exitpos:=last_endtoken_filepos;
          { save current filepos }
          { save current filepos }
          savepos:=aktfilepos;
          savepos:=aktfilepos;
+         { add implicit entry and exit code }
+         if assigned(code) then
+           add_entry_exit_block(code,entrypos,exitpos);
+         { store a copy of the original tree for inline, for
+           normal procedures only store a reference to the
+           current tree }
+         if (current_procdef.proccalloption=pocall_inline) then
+           current_procdef.code:=code.getcopy
+         else
+           current_procdef.code:=code;
 
 
          {When we are called to compile the body of a unit, aktprocsym should
          {When we are called to compile the body of a unit, aktprocsym should
           point to the unit initialization. If the unit has no initialization,
           point to the unit initialization. If the unit has no initialization,
@@ -842,7 +1098,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.108  2003-05-09 17:47:03  peter
+  Revision 1.109  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.108  2003/05/09 17:47:03  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn
 
 

+ 11 - 8
compiler/symdef.pas

@@ -240,8 +240,6 @@ interface
 
 
        tobjectdef = class(tabstractrecorddef)
        tobjectdef = class(tabstractrecorddef)
        private
        private
-          sd : tprocdef;
-          procedure _searchdestructor(sym : tnamedindexitem;arg:pointer);
 {$ifdef GDB}
 {$ifdef GDB}
           procedure addprocname(p :tnamedindexitem;arg:pointer);
           procedure addprocname(p :tnamedindexitem;arg:pointer);
 {$endif GDB}
 {$endif GDB}
@@ -4607,26 +4605,27 @@ implementation
           end;
           end;
      end;*)
      end;*)
 
 
-    procedure Tobjectdef._searchdestructor(sym:Tnamedindexitem;arg:pointer);
+    procedure _searchdestructor(sym:Tnamedindexitem;sd:pointer);
 
 
     begin
     begin
         { if we found already a destructor, then we exit }
         { if we found already a destructor, then we exit }
-        if (sd=nil) and (Tsym(sym).typ=procsym) then
-            sd:=Tprocsym(sym).search_procdef_bytype(potype_destructor);
+        if (ppointer(sd)^=nil) and
+           (Tsym(sym).typ=procsym) then
+          ppointer(sd)^:=Tprocsym(sym).search_procdef_bytype(potype_destructor);
     end;
     end;
 
 
    function tobjectdef.searchdestructor : tprocdef;
    function tobjectdef.searchdestructor : tprocdef;
 
 
      var
      var
         o : tobjectdef;
         o : tobjectdef;
-
+        sd : tprocdef;
      begin
      begin
         searchdestructor:=nil;
         searchdestructor:=nil;
         o:=self;
         o:=self;
         sd:=nil;
         sd:=nil;
         while assigned(o) do
         while assigned(o) do
           begin
           begin
-             symtable.foreach({$ifdef FPCPROCVAR}@{$endif}_searchdestructor,nil);
+             o.symtable.foreach_static({$ifdef FPCPROCVAR}@{$endif}_searchdestructor,@sd);
              if assigned(sd) then
              if assigned(sd) then
                begin
                begin
                   searchdestructor:=sd;
                   searchdestructor:=sd;
@@ -5762,7 +5761,11 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.141  2003-05-09 17:47:03  peter
+  Revision 1.142  2003-05-11 21:37:03  peter
+    * moved implicit exception frame from ncgutil to psub
+    * constructor/destructor helpers moved from cobj/ncgutil to psub
+
+  Revision 1.141  2003/05/09 17:47:03  peter
     * self moved to hidden parameter
     * self moved to hidden parameter
     * removed hdisposen,hnewn,selfn
     * removed hdisposen,hnewn,selfn