Browse Source

* moved support for copy() from pinline to ninl, so it can be (partially)
overridden for targets that require it

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

Jonas Maebe 14 years ago
parent
commit
622107c605
2 changed files with 138 additions and 89 deletions
  1. 133 0
      compiler/ninl.pas
  2. 5 89
      compiler/pinline.pas

+ 133 - 0
compiler/ninl.pas

@@ -66,6 +66,7 @@ interface
           function first_int_real: tnode; virtual;
           function first_int_real: tnode; virtual;
           function first_abs_long: tnode; virtual;
           function first_abs_long: tnode; virtual;
           function first_setlength: tnode; virtual;
           function first_setlength: tnode; virtual;
+          function first_copy: tnode; virtual;
           { This one by default generates an internal error, because such
           { This one by default generates an internal error, because such
             nodes are not generated by the parser. It's however used internally
             nodes are not generated by the parser. It's however used internally
             by the JVM backend to create new dynamic arrays. }
             by the JVM backend to create new dynamic arrays. }
@@ -79,6 +80,7 @@ interface
           function handle_read_write: tnode;
           function handle_read_write: tnode;
           function handle_val: tnode;
           function handle_val: tnode;
           function handle_setlength: tnode;
           function handle_setlength: tnode;
+          function handle_copy: tnode;
        end;
        end;
        tinlinenodeclass = class of tinlinenode;
        tinlinenodeclass = class of tinlinenode;
 
 
@@ -1429,6 +1431,68 @@ implementation
         result:=nil;
         result:=nil;
       end;
       end;
 
 
+
+    function tinlinenode.handle_copy: tnode;
+      var
+        lowppn,
+        highppn,
+        npara,
+        paras   : tnode;
+        ppn     : tcallparanode;
+        paradef : tdef;
+        counter : integer;
+      begin
+        result:=nil;
+        { determine copy function to use based on the first argument,
+          also count the number of arguments in this loop }
+        counter:=1;
+        paras:=left;
+        ppn:=tcallparanode(paras);
+        while assigned(ppn.right) do
+         begin
+           inc(counter);
+           ppn:=tcallparanode(ppn.right);
+         end;
+        paradef:=ppn.left.resultdef;
+        if is_ansistring(paradef) or
+           (is_chararray(paradef) and
+            (paradef.size>255)) or
+           ((cs_ansistrings in current_settings.localswitches) and
+            is_pchar(paradef)) then
+          resultdef:=cansistringtype
+        else
+         if is_widestring(paradef) then
+           resultdef:=cwidestringtype
+        else
+         if is_unicodestring(paradef) or
+            is_widechararray(paradef) or
+            is_pwidechar(paradef) then
+           resultdef:=cunicodestringtype
+        else
+         if is_char(paradef) then
+           resultdef:=cshortstringtype
+        else
+         if is_dynamic_array(paradef) then
+          begin
+            { Only allow 1 or 3 arguments }
+            if (counter<>1) and (counter<>3) then
+             begin
+               CGMessage1(parser_e_wrong_parameter_size,'Copy');
+               exit;
+             end;
+            resultdef:=paradef;
+          end
+        else
+         begin
+           { generic fallback that will give an error if a wrong
+             type is passed }
+           if (counter=3) then
+             resultdef:=cshortstringtype
+           else
+             CGMessagePos(ppn.left.fileinfo,type_e_mismatch);
+         end;
+      end;
+
 {$maxfpuregisters 0}
 {$maxfpuregisters 0}
 
 
     function getpi : bestreal;
     function getpi : bestreal;
@@ -2481,6 +2545,9 @@ implementation
                      end;
                      end;
                 end;
                 end;
 
 
+              in_copy_x:
+                result:=handle_copy;
+
               in_initialize_x,
               in_initialize_x,
               in_finalize_x:
               in_finalize_x:
                 begin
                 begin
@@ -2964,6 +3031,8 @@ implementation
 
 
           in_setlength_x:
           in_setlength_x:
             result:=first_setlength;
             result:=first_setlength;
+          in_copy_x:
+            result:=first_copy;
           in_initialize_x,
           in_initialize_x,
           in_finalize_x:
           in_finalize_x:
             begin
             begin
@@ -3417,6 +3486,70 @@ implementation
         result:=newblock;
         result:=newblock;
       end;
       end;
 
 
+    function tinlinenode.first_copy: tnode;
+      var
+        lowppn,
+        highppn,
+        npara,
+        paras   : tnode;
+        ppn     : tcallparanode;
+        paradef : tdef;
+        counter : integer;
+      begin
+        { determine copy function to use based on the first argument,
+          also count the number of arguments in this loop }
+        counter:=1;
+        paras:=left;
+        ppn:=tcallparanode(paras);
+        while assigned(ppn.right) do
+          begin
+            inc(counter);
+            ppn:=tcallparanode(ppn.right);
+          end;
+        paradef:=ppn.left.resultdef;
+        if is_ansistring(resultdef) then
+          result:=ccallnode.createintern('fpc_ansistr_copy',paras)
+        else if is_widestring(resultdef) then
+          result:=ccallnode.createintern('fpc_widestr_copy',paras)
+        else if is_unicodestring(resultdef) then
+          result:=ccallnode.createintern('fpc_unicodestr_copy',paras)
+          { can't check for resultdef = cchartype, because resultdef=
+            cshortstringtype here }
+        else if is_char(paradef) then
+          result:=ccallnode.createintern('fpc_char_copy',paras)
+        else if is_dynamic_array(resultdef) then
+          begin
+            { create statements with call }
+            if (counter=3) then
+             begin
+               highppn:=tcallparanode(paras).left.getcopy;
+               lowppn:=tcallparanode(tcallparanode(paras).right).left.getcopy;
+             end
+            else
+             begin
+               { use special -1,-1 argument to copy the whole array }
+               highppn:=cordconstnode.create(int64(-1),s32inttype,false);
+               lowppn:=cordconstnode.create(int64(-1),s32inttype,false);
+             end;
+
+            { create call to fpc_dynarray_copy }
+            npara:=ccallparanode.create(highppn,
+                   ccallparanode.create(lowppn,
+                   ccallparanode.create(caddrnode.create_internal
+                      (crttinode.create(tstoreddef(ppn.left.resultdef),initrtti,rdt_normal)),
+                   ccallparanode.create
+                      (ctypeconvnode.create_internal(ppn.left,voidpointertype),nil))));
+            result:=ccallnode.createinternres('fpc_dynarray_copy',npara,ppn.left.resultdef);
+
+            ppn.left:=nil;
+            paras.free;
+          end
+        else
+          result:=ccallnode.createintern('fpc_shortstr_copy',paras);
+        { parameters are reused }
+        left:=nil;
+     end;
+
      function tinlinenode.first_new: tnode;
      function tinlinenode.first_new: tnode;
        begin
        begin
          internalerror(2011012201);
          internalerror(2011012201);

+ 5 - 89
compiler/pinline.pas

@@ -543,105 +543,21 @@ implementation
 
 
     function inline_copy : tnode;
     function inline_copy : tnode;
       var
       var
-        copynode,
-        lowppn,
-        highppn,
-        npara,
         paras   : tnode;
         paras   : tnode;
-        ppn     : tcallparanode;
-        paradef : tdef;
-        counter : integer;
-      begin
         { for easy exiting if something goes wrong }
         { for easy exiting if something goes wrong }
+      begin
         result := cerrornode.create;
         result := cerrornode.create;
 
 
         consume(_LKLAMMER);
         consume(_LKLAMMER);
         paras:=parse_paras(false,false,_RKLAMMER);
         paras:=parse_paras(false,false,_RKLAMMER);
         consume(_RKLAMMER);
         consume(_RKLAMMER);
         if not assigned(paras) then
         if not assigned(paras) then
-         begin
-           CGMessage1(parser_e_wrong_parameter_size,'Copy');
-           exit;
-         end;
-
-        { determine copy function to use based on the first argument,
-          also count the number of arguments in this loop }
-        counter:=1;
-        ppn:=tcallparanode(paras);
-        while assigned(ppn.right) do
-         begin
-           inc(counter);
-           ppn:=tcallparanode(ppn.right);
-         end;
-        paradef:=ppn.left.resultdef;
-        if is_ansistring(paradef) or
-           (is_chararray(paradef) and
-            (paradef.size>255)) or
-           ((cs_ansistrings in current_settings.localswitches) and
-            is_pchar(paradef)) then
-          copynode:=ccallnode.createintern('fpc_ansistr_copy',paras)
-        else
-         if is_widestring(paradef) then
-           copynode:=ccallnode.createintern('fpc_widestr_copy',paras)
-        else
-         if is_unicodestring(paradef) or
-            is_widechararray(paradef) or
-            is_pwidechar(paradef) then
-           copynode:=ccallnode.createintern('fpc_unicodestr_copy',paras)
-        else
-         if is_char(paradef) then
-           copynode:=ccallnode.createintern('fpc_char_copy',paras)
-        else
-         if is_dynamic_array(paradef) then
           begin
           begin
-            { Only allow 1 or 3 arguments }
-            if (counter<>1) and (counter<>3) then
-             begin
-               CGMessage1(parser_e_wrong_parameter_size,'Copy');
-               exit;
-             end;
-
-            { create statements with call }
-
-            if (counter=3) then
-             begin
-               highppn:=tcallparanode(paras).left.getcopy;
-               lowppn:=tcallparanode(tcallparanode(paras).right).left.getcopy;
-             end
-            else
-             begin
-               { use special -1,-1 argument to copy the whole array }
-               highppn:=cordconstnode.create(int64(-1),s32inttype,false);
-               lowppn:=cordconstnode.create(int64(-1),s32inttype,false);
-             end;
-
-            { create call to fpc_dynarray_copy }
-            npara:=ccallparanode.create(highppn,
-                   ccallparanode.create(lowppn,
-                   ccallparanode.create(caddrnode.create_internal
-                      (crttinode.create(tstoreddef(ppn.left.resultdef),initrtti,rdt_normal)),
-                   ccallparanode.create
-                      (ctypeconvnode.create_internal(ppn.left,voidpointertype),nil))));
-            copynode:=ccallnode.createinternres('fpc_dynarray_copy',npara,ppn.left.resultdef);
-
-            ppn.left:=nil;
-            paras.free;
-          end
-        else
-         begin
-           { generic fallback that will give an error if a wrong
-             type is passed }
-           if (counter=3) then
-             copynode:=ccallnode.createintern('fpc_shortstr_copy',paras)
-           else
-             begin
-               CGMessagePos(ppn.left.fileinfo,type_e_mismatch);
-               copynode:=cerrornode.create;
-             end
-         end;
-
+            CGMessage1(parser_e_wrong_parameter_size,'Copy');
+            exit;
+          end;
         result.free;
         result.free;
-        result:=copynode;
+        result:=cinlinenode.create(in_copy_x,false,paras);
       end;
       end;
 
 
 end.
 end.