+ support for copy(dynarray)

git-svn-id: branches/jvmbackend@18504 -
This commit is contained in:
Jonas Maebe 2011-08-20 08:05:23 +00:00
parent ecba07c6a8
commit 7a5d334951
3 changed files with 111 additions and 0 deletions

View File

@ -36,6 +36,8 @@ interface
function typecheck_high(var handled: boolean): tnode;
function typecheck_new(var handled: boolean): tnode;
function first_copy: tnode; override;
function first_setlength_array: tnode;
function first_setlength_string: tnode;
public
@ -162,6 +164,76 @@ implementation
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;
var
handled: boolean;

View File

@ -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_dynarray_copy(src: JLObject; start, len: longint; ndim: longint; eletype: jchar): JLObject;

View File

@ -426,6 +426,42 @@ function fpc_setlength_dynarr_multidim(aorg, anew: TJObjectArray; deepcopy: bool
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}