Parcourir la source

* turned call_fail_node, initialize_data_node, and finalize_data_node from
nutils.pas into virtual class methods of a new tnodeutils class defined
in ngenutil (global factory: cnodeutils), so they can be overridden by
architecture-specific implementations (required by the JVM backend)

git-svn-id: branches/jvmbackend@18364 -

Jonas Maebe il y a 14 ans
Parent
commit
ab5b1fb686
7 fichiers modifiés avec 222 ajouts et 172 suppressions
  1. 1 0
      .gitattributes
  2. 3 3
      compiler/ncgutil.pas
  3. 208 0
      compiler/ngenutil.pas
  4. 0 159
      compiler/nutils.pas
  5. 5 5
      compiler/pinline.pas
  6. 2 2
      compiler/pstatmnt.pas
  7. 3 3
      compiler/psub.pas

+ 1 - 0
.gitattributes

@@ -352,6 +352,7 @@ compiler/ncgutil.pas svneol=native#text/plain
 compiler/ncnv.pas svneol=native#text/plain
 compiler/ncon.pas svneol=native#text/plain
 compiler/nflw.pas svneol=native#text/plain
+compiler/ngenutil.pas svneol=native#text/plain
 compiler/ninl.pas svneol=native#text/plain
 compiler/nld.pas svneol=native#text/plain
 compiler/nmat.pas svneol=native#text/plain

+ 3 - 3
compiler/ncgutil.pas

@@ -172,7 +172,7 @@ implementation
     procinfo,paramgr,fmodule,
     regvars,dbgbase,
     pass_1,pass_2,
-    nbas,ncon,nld,nmem,nutils,
+    nbas,ncon,nld,nmem,nutils,ngenutil,
     tgobj,cgobj,cgcpu,hlcgobj,hlcgcpu
 {$ifdef powerpc}
     , cpupi
@@ -1494,7 +1494,7 @@ implementation
           begin
             OldAsmList:=current_asmdata.CurrAsmList;
             current_asmdata.CurrAsmList:=TAsmList(arg);
-            hp:=initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner));
+            hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner));
             firstpass(hp);
             secondpass(hp);
             hp.free;
@@ -1514,7 +1514,7 @@ implementation
         hp:=cloadnode.create(sym,sym.owner);
         if (sym.typ=staticvarsym) and (vo_force_finalize in tstaticvarsym(sym).varoptions) then
           include(hp.flags,nf_isinternal_ignoreconst);
-        hp:=finalize_data_node(hp);
+        hp:=cnodeutils.finalize_data_node(hp);
         firstpass(hp);
         secondpass(hp);
         hp.free;

+ 208 - 0
compiler/ngenutil.pas

@@ -0,0 +1,208 @@
+{
+    Copyright (c) 1998-20011 by Florian Klaempfl
+
+    Generic version of some node tree helper routines that can be overridden
+    by cpu-specific versions
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit ngenutil;
+
+{$i fpcdefs.inc}
+
+interface
+
+  uses
+    node;
+
+
+  type
+    tnodeutils = class
+      class function call_fail_node:tnode; virtual;
+      class function initialize_data_node(p:tnode):tnode; virtual;
+      class function finalize_data_node(p:tnode):tnode; virtual;
+    end;
+    tnodeutilsclass = class of tnodeutils;
+
+  const
+    cnodeutils: tnodeutilsclass = tnodeutils;
+
+
+implementation
+
+    uses
+      verbose,constexp,
+      symconst,symtype,symdef,symsym,symbase,symtable,defutil,
+      nadd,nbas,ncal,ncnv,ncon,nflw,nld,nmem,nobj,nutils,
+      pass_1;
+
+  class function tnodeutils.call_fail_node:tnode;
+    var
+      para : tcallparanode;
+      newstatement : tstatementnode;
+      srsym : tsym;
+    begin
+      result:=internalstatements(newstatement);
+
+      { call fail helper and exit normal }
+      if is_class(current_structdef) then
+        begin
+          srsym:=search_struct_member(current_structdef,'FREEINSTANCE');
+          if assigned(srsym) and
+             (srsym.typ=procsym) then
+            begin
+              { if self<>0 and vmt<>0 then freeinstance }
+              addstatement(newstatement,cifnode.create(
+                  caddnode.create(andn,
+                      caddnode.create(unequaln,
+                          load_self_pointer_node,
+                          cnilnode.create),
+                      caddnode.create(unequaln,
+                          load_vmt_pointer_node,
+                          cnilnode.create)),
+                  ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
+                  nil));
+            end
+          else
+            internalerror(200305108);
+        end
+      else
+        if is_object(current_structdef) then
+          begin
+            { parameter 3 : vmt_offset }
+            { parameter 2 : pointer to vmt }
+            { parameter 1 : self pointer }
+            para:=ccallparanode.create(
+                      cordconstnode.create(tobjectdef(current_structdef).vmt_offset,s32inttype,false),
+                  ccallparanode.create(
+                      ctypeconvnode.create_internal(
+                          load_vmt_pointer_node,
+                          voidpointertype),
+                  ccallparanode.create(
+                      ctypeconvnode.create_internal(
+                          load_self_pointer_node,
+                          voidpointertype),
+                  nil)));
+            addstatement(newstatement,
+                ccallnode.createintern('fpc_help_fail',para));
+          end
+      else
+        internalerror(200305132);
+      { self:=nil }
+      addstatement(newstatement,cassignmentnode.create(
+          load_self_pointer_node,
+          cnilnode.create));
+      { exit }
+      addstatement(newstatement,cexitnode.create(nil));
+    end;
+
+
+  class function tnodeutils.initialize_data_node(p:tnode):tnode;
+    begin
+      if not assigned(p.resultdef) then
+        typecheckpass(p);
+      if is_ansistring(p.resultdef) or
+         is_wide_or_unicode_string(p.resultdef) or
+         is_interfacecom_or_dispinterface(p.resultdef) or
+         is_dynamic_array(p.resultdef) then
+        begin
+          result:=cassignmentnode.create(
+             ctypeconvnode.create_internal(p,voidpointertype),
+             cnilnode.create
+             );
+        end
+      else
+        begin
+          result:=ccallnode.createintern('fpc_initialize',
+                ccallparanode.create(
+                    caddrnode.create_internal(
+                        crttinode.create(
+                            tstoreddef(p.resultdef),initrtti,rdt_normal)),
+                ccallparanode.create(
+                    caddrnode.create_internal(p),
+                nil)));
+        end;
+    end;
+
+
+  class function tnodeutils.finalize_data_node(p:tnode):tnode;
+    var
+      newstatement : tstatementnode;
+    begin
+      if not assigned(p.resultdef) then
+        typecheckpass(p);
+      if is_ansistring(p.resultdef) then
+        begin
+          result:=internalstatements(newstatement);
+          addstatement(newstatement,ccallnode.createintern('fpc_ansistr_decr_ref',
+                ccallparanode.create(
+                  ctypeconvnode.create_internal(p,voidpointertype),
+                nil)));
+          addstatement(newstatement,cassignmentnode.create(
+             ctypeconvnode.create_internal(p.getcopy,voidpointertype),
+             cnilnode.create
+             ));
+        end
+      else if is_widestring(p.resultdef) then
+        begin
+          result:=internalstatements(newstatement);
+          addstatement(newstatement,ccallnode.createintern('fpc_widestr_decr_ref',
+                ccallparanode.create(
+                  ctypeconvnode.create_internal(p,voidpointertype),
+                nil)));
+          addstatement(newstatement,cassignmentnode.create(
+             ctypeconvnode.create_internal(p.getcopy,voidpointertype),
+             cnilnode.create
+             ));
+        end
+      else if is_unicodestring(p.resultdef) then
+        begin
+          result:=internalstatements(newstatement);
+          addstatement(newstatement,ccallnode.createintern('fpc_unicodestr_decr_ref',
+                ccallparanode.create(
+                  ctypeconvnode.create_internal(p,voidpointertype),
+                nil)));
+          addstatement(newstatement,cassignmentnode.create(
+             ctypeconvnode.create_internal(p.getcopy,voidpointertype),
+             cnilnode.create
+             ));
+        end
+      else if is_interfacecom_or_dispinterface(p.resultdef) then
+        begin
+          result:=internalstatements(newstatement);
+          addstatement(newstatement,ccallnode.createintern('fpc_intf_decr_ref',
+                ccallparanode.create(
+                  ctypeconvnode.create_internal(p,voidpointertype),
+                nil)));
+          addstatement(newstatement,cassignmentnode.create(
+             ctypeconvnode.create_internal(p.getcopy,voidpointertype),
+             cnilnode.create
+             ));
+        end
+      else
+        result:=ccallnode.createintern('fpc_finalize',
+              ccallparanode.create(
+                  caddrnode.create_internal(
+                      crttinode.create(
+                          tstoreddef(p.resultdef),initrtti,rdt_normal)),
+              ccallparanode.create(
+                  caddrnode.create_internal(p),
+              nil)));
+    end;
+
+
+end.

+ 0 - 159
compiler/nutils.pas

@@ -72,10 +72,6 @@ interface
     function load_vmt_pointer_node:tnode;
     function is_self_node(p:tnode):boolean;
 
-    function call_fail_node:tnode;
-    function initialize_data_node(p:tnode):tnode;
-    function finalize_data_node(p:tnode):tnode;
-
     function node_complexity(p: tnode): cardinal;
     function node_resources_fpu(p: tnode): cardinal;
     procedure node_tree_set_filepos(var n:tnode;const filepos:tfileposinfo);
@@ -525,161 +521,6 @@ implementation
       end;
 
 
-    function call_fail_node:tnode;
-      var
-        para : tcallparanode;
-        newstatement : tstatementnode;
-        srsym : tsym;
-      begin
-        result:=internalstatements(newstatement);
-
-        { call fail helper and exit normal }
-        if is_class(current_structdef) then
-          begin
-            srsym:=search_struct_member(current_structdef,'FREEINSTANCE');
-            if assigned(srsym) and
-               (srsym.typ=procsym) then
-              begin
-                { if self<>0 and vmt<>0 then freeinstance }
-                addstatement(newstatement,cifnode.create(
-                    caddnode.create(andn,
-                        caddnode.create(unequaln,
-                            load_self_pointer_node,
-                            cnilnode.create),
-                        caddnode.create(unequaln,
-                            load_vmt_pointer_node,
-                            cnilnode.create)),
-                    ccallnode.create(nil,tprocsym(srsym),srsym.owner,load_self_node,[]),
-                    nil));
-              end
-            else
-              internalerror(200305108);
-          end
-        else
-          if is_object(current_structdef) then
-            begin
-              { parameter 3 : vmt_offset }
-              { parameter 2 : pointer to vmt }
-              { parameter 1 : self pointer }
-              para:=ccallparanode.create(
-                        cordconstnode.create(tobjectdef(current_structdef).vmt_offset,s32inttype,false),
-                    ccallparanode.create(
-                        ctypeconvnode.create_internal(
-                            load_vmt_pointer_node,
-                            voidpointertype),
-                    ccallparanode.create(
-                        ctypeconvnode.create_internal(
-                            load_self_pointer_node,
-                            voidpointertype),
-                    nil)));
-              addstatement(newstatement,
-                  ccallnode.createintern('fpc_help_fail',para));
-            end
-        else
-          internalerror(200305132);
-        { self:=nil }
-        addstatement(newstatement,cassignmentnode.create(
-            load_self_pointer_node,
-            cnilnode.create));
-        { exit }
-        addstatement(newstatement,cexitnode.create(nil));
-      end;
-
-
-    function initialize_data_node(p:tnode):tnode;
-      begin
-        if not assigned(p.resultdef) then
-          typecheckpass(p);
-        if is_ansistring(p.resultdef) or
-           is_wide_or_unicode_string(p.resultdef) or
-           is_interfacecom_or_dispinterface(p.resultdef) or
-           is_dynamic_array(p.resultdef) then
-          begin
-            result:=cassignmentnode.create(
-               ctypeconvnode.create_internal(p,voidpointertype),
-               cnilnode.create
-               );
-          end
-        else
-          begin
-            result:=ccallnode.createintern('fpc_initialize',
-                  ccallparanode.create(
-                      caddrnode.create_internal(
-                          crttinode.create(
-                              tstoreddef(p.resultdef),initrtti,rdt_normal)),
-                  ccallparanode.create(
-                      caddrnode.create_internal(p),
-                  nil)));
-          end;
-      end;
-
-
-    function finalize_data_node(p:tnode):tnode;
-      var
-        newstatement : tstatementnode;
-      begin
-        if not assigned(p.resultdef) then
-          typecheckpass(p);
-        if is_ansistring(p.resultdef) then
-          begin
-            result:=internalstatements(newstatement);
-            addstatement(newstatement,ccallnode.createintern('fpc_ansistr_decr_ref',
-                  ccallparanode.create(
-                    ctypeconvnode.create_internal(p,voidpointertype),
-                  nil)));
-            addstatement(newstatement,cassignmentnode.create(
-               ctypeconvnode.create_internal(p.getcopy,voidpointertype),
-               cnilnode.create
-               ));
-          end
-        else if is_widestring(p.resultdef) then
-          begin
-            result:=internalstatements(newstatement);
-            addstatement(newstatement,ccallnode.createintern('fpc_widestr_decr_ref',
-                  ccallparanode.create(
-                    ctypeconvnode.create_internal(p,voidpointertype),
-                  nil)));
-            addstatement(newstatement,cassignmentnode.create(
-               ctypeconvnode.create_internal(p.getcopy,voidpointertype),
-               cnilnode.create
-               ));
-          end
-        else if is_unicodestring(p.resultdef) then
-          begin
-            result:=internalstatements(newstatement);
-            addstatement(newstatement,ccallnode.createintern('fpc_unicodestr_decr_ref',
-                  ccallparanode.create(
-                    ctypeconvnode.create_internal(p,voidpointertype),
-                  nil)));
-            addstatement(newstatement,cassignmentnode.create(
-               ctypeconvnode.create_internal(p.getcopy,voidpointertype),
-               cnilnode.create
-               ));
-          end
-        else if is_interfacecom_or_dispinterface(p.resultdef) then
-          begin
-            result:=internalstatements(newstatement);
-            addstatement(newstatement,ccallnode.createintern('fpc_intf_decr_ref',
-                  ccallparanode.create(
-                    ctypeconvnode.create_internal(p,voidpointertype),
-                  nil)));
-            addstatement(newstatement,cassignmentnode.create(
-               ctypeconvnode.create_internal(p.getcopy,voidpointertype),
-               cnilnode.create
-               ));
-          end
-        else
-          result:=ccallnode.createintern('fpc_finalize',
-                ccallparanode.create(
-                    caddrnode.create_internal(
-                        crttinode.create(
-                            tstoreddef(p.resultdef),initrtti,rdt_normal)),
-                ccallparanode.create(
-                    caddrnode.create_internal(p),
-                nil)));
-      end;
-
-
     { this function must return a very high value ("infinity") for   }
     { trees containing a call, the rest can be balanced more or less }
     { at will, probably best mainly in terms of required memory      }

+ 5 - 5
compiler/pinline.pas

@@ -52,7 +52,7 @@ implementation
        symbase,symconst,symdef,symsym,symtable,defutil,
        { pass 1 }
        pass_1,htypechk,
-       nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
+       nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,ngenutil,
        { parser }
        scanner,
        pbase,pexpr,
@@ -314,7 +314,7 @@ implementation
                      { create call to fpc_initialize }
                      if is_managed_type(tpointerdef(p.resultdef).pointeddef) or
                        ((m_iso in current_settings.modeswitches) and (tpointerdef(p.resultdef).pointeddef.typ=filedef)) then
-                       addstatement(newstatement,initialize_data_node(cderefnode.create(ctemprefnode.create(temp))));
+                       addstatement(newstatement,cnodeutils.initialize_data_node(cderefnode.create(ctemprefnode.create(temp))));
 
                      { copy the temp to the destination }
                      addstatement(newstatement,cassignmentnode.create(
@@ -328,7 +328,7 @@ implementation
                    begin
                      { create call to fpc_finalize }
                      if is_managed_type(tpointerdef(p.resultdef).pointeddef) then
-                       addstatement(newstatement,finalize_data_node(cderefnode.create(p.getcopy)));
+                       addstatement(newstatement,cnodeutils.finalize_data_node(cderefnode.create(p.getcopy)));
 
                      { create call to fpc_freemem }
                      para := ccallparanode.create(p,nil);
@@ -635,9 +635,9 @@ implementation
         else
          begin
            if isinit then
-             newblock:=initialize_data_node(ppn.left)
+             newblock:=cnodeutils.initialize_data_node(ppn.left)
            else
-             newblock:=finalize_data_node(ppn.left);
+             newblock:=cnodeutils.finalize_data_node(ppn.left);
          end;
         ppn.left:=nil;
         paras.free;

+ 2 - 2
compiler/pstatmnt.pas

@@ -50,7 +50,7 @@ implementation
        paramgr,symutil,
        { pass 1 }
        pass_1,htypechk,
-       nutils,nbas,nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
+       nutils,ngenutil,nbas,nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,
        { parser }
        scanner,
        pbase,pexpr,
@@ -1145,7 +1145,7 @@ implementation
                 if (current_procinfo.procdef.proctypeoption<>potype_constructor) then
                   Message(parser_e_fail_only_in_constructor);
                 consume(_FAIL);
-                code:=call_fail_node;
+                code:=cnodeutils.call_fail_node;
              end;
            _ASM :
              code:=_asm_statement;

+ 3 - 3
compiler/psub.pas

@@ -85,7 +85,7 @@ implementation
        paramgr,
        ppu,fmodule,
        { pass 1 }
-       nutils,nld,ncal,ncon,nflw,nadd,ncnv,nmem,
+       nutils,ngenutil,nld,ncal,ncon,nflw,nadd,ncnv,nmem,
        pass_1,
     {$ifdef state_tracking}
        nstate,
@@ -467,7 +467,7 @@ implementation
                             caddnode.create(unequaln,
                               ctypeconvnode.create_internal(load_vmt_pointer_node,voidpointertype),
                               cnilnode.create),
-                            finalize_data_node(load_self_node),
+                            cnodeutils.finalize_data_node(load_self_node),
                             nil));
                         end;
                       { parameter 3 : vmt_offset }
@@ -515,7 +515,7 @@ implementation
                is_managed_type(current_procinfo.procdef.returndef) and
                (not paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption)) and
                (not is_class(current_procinfo.procdef.returndef)) then
-              addstatement(newstatement,finalize_data_node(load_result_node));
+              addstatement(newstatement,cnodeutils.finalize_data_node(load_result_node));
 {$if defined(x86) or defined(arm)}
             { safecall handling }
             if (tf_safecall_exceptions in target_info.flags) and