Browse Source

+ support for copy(dynarray)

git-svn-id: branches/jvmbackend@18504 -
Jonas Maebe 14 years ago
parent
commit
7a5d334951
3 changed files with 111 additions and 0 deletions
  1. 72 0
      compiler/jvm/njvminl.pas
  2. 3 0
      rtl/java/jdynarrh.inc
  3. 36 0
      rtl/java/system.pp

+ 72 - 0
compiler/jvm/njvminl.pas

@@ -36,6 +36,8 @@ interface
           function typecheck_high(var handled: boolean): tnode;
           function typecheck_high(var handled: boolean): tnode;
           function typecheck_new(var handled: boolean): tnode;
           function typecheck_new(var handled: boolean): tnode;
 
 
+          function first_copy: tnode; override;
+
           function first_setlength_array: tnode;
           function first_setlength_array: tnode;
           function first_setlength_string: tnode;
           function first_setlength_string: tnode;
          public
          public
@@ -162,6 +164,76 @@ implementation
       end;
       end;
 
 
 
 
+    function tjvminlinenode.first_copy: tnode;
+      var
+        ppn: tcallparanode;
+        arr, len, start, kind: tnode;
+        eledef: tdef;
+        counter, ndims: longint;
+        finaltype: char;
+      begin
+        if is_dynamic_array(resultdef) then
+          begin
+            ppn:=tcallparanode(left);
+            counter:=1;
+            while assigned(ppn.right) do
+              begin
+                inc(counter);
+                ppn:=tcallparanode(ppn.right);
+              end;
+            if (counter=3) then
+              begin
+                len:=tcallparanode(left).left;
+                tcallparanode(left).left:=nil;
+                start:=tcallparanode(tcallparanode(left).right).left;
+                tcallparanode(tcallparanode(left).right).left:=nil;
+                { free the original start/len paras and remove them }
+                ppn:=tcallparanode(left);
+                left:=tcallparanode(tcallparanode(left).right).right;
+                tcallparanode(ppn.right).right:=nil;
+                ppn.free;
+              end
+            else
+              begin
+                { use special -1,-1 argument to copy the whole array }
+                len:=genintconstnode(-1);
+                start:=genintconstnode(-1);
+              end;
+            { currently there is one parameter left: the array itself }
+            arr:=tcallparanode(left).left;
+            tcallparanode(left).left:=nil;
+            { in case it's a dynamic array of static arrays, get the dimensions
+              of the static array components }
+            eledef:=tarraydef(resultdef).elementdef;
+            ndims:=1;
+            while (eledef.typ=arraydef) and
+                  not is_dynamic_array(eledef) do
+              begin
+                inc(ndims);
+                eledef:=tarraydef(eledef).elementdef;
+              end;
+            { get the final element kind }
+            finaltype:=jvmarrtype_setlength(eledef);
+            { construct the call to
+                fpc_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar) }
+            result:=ccallnode.createintern('FPC_DYNARRAY_COPY',
+              ccallparanode.create(cordconstnode.create(ord(finaltype),cwidechartype,false),
+                ccallparanode.create(genintconstnode(ndims),
+                  ccallparanode.create(len,
+                    ccallparanode.create(start,
+                      ccallparanode.create(ctypeconvnode.create_explicit(arr,java_jlobject),nil)
+                    )
+                  )
+                )
+              )
+            );
+            inserttypeconv_explicit(result,resultdef);
+          end
+        else
+          result:=inherited first_copy;
+      end;
+
+
     function tjvminlinenode.pass_typecheck: tnode;
     function tjvminlinenode.pass_typecheck: tnode;
       var
       var
         handled: boolean;
         handled: boolean;

+ 3 - 0
rtl/java/jdynarrh.inc

@@ -66,3 +66,6 @@ procedure fpc_copy_jrecord_array(src, dst: TJRecordArray; srcstart: jint = -1; s
 }
 }
 function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: boolean; ndim: longint; eletype: jchar): TJObjectArray;
 function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: boolean; ndim: longint; eletype: jchar): TJObjectArray;
 
 
+
+function fpc_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar): JLObject;
+

+ 36 - 0
rtl/java/system.pp

@@ -426,6 +426,42 @@ function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: bool
   end;
   end;
 
 
 
 
+function fpc_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar): JLObject;
+  var
+    i: longint;
+    srclen: longint;
+  begin
+    if not assigned(src) then
+      begin
+        result:=nil;
+        exit;
+      end;
+    srclen:=JLRArray.getLength(src);
+    if (start=-1) and
+       (len=-1) then
+      begin
+        len:=srclen;
+        start:=0;
+      end
+    else if (start+len>srclen) then
+      len:=srclen-start+1;
+    result:=JLRArray.newInstance(src.getClass.getComponentType,len);
+    if ndim=1 then
+      begin
+        case eletype of
+          FPCJDynArrTypeRecord:
+            fpc_copy_jrecord_array(TJRecordArray(src),TJRecordArray(result),start,len);
+          else
+            fpc_copy_shallow_array(src,result,start,len);
+        end
+      end
+    else
+      begin
+        for i:=0 to len-1 do
+          TJObjectArray(result)[i]:=fpc_dynarray_copy(TJObjectArray(src)[start+i],-1,-1,ndim-1,eletype);
+      end;
+  end;
+
 
 
 {i jdynarr.inc end}
 {i jdynarr.inc end}