mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 21:50:18 +02:00
* Generate direct order of indexes passed to fpc_dynarray_setlength at compile time, eliminates the need of reversing them at runtime (in DynArraySetLength).
* 'dimcount' parameter is now of type sizeint everywhere (was dword in fpc_dynarray_setlength and longint generated by compiler). Since multi-dimensional dynarrays are not used in compiler code, this change does not break cycling. git-svn-id: trunk@20041 -
This commit is contained in:
parent
4788645aae
commit
40f29ffd7a
@ -559,14 +559,14 @@ implementation
|
||||
|
||||
{ load array of lengths }
|
||||
ppn:=tcallparanode(paras);
|
||||
counter:=0;
|
||||
counter:=dims-1;
|
||||
while assigned(ppn.right) do
|
||||
begin
|
||||
addstatement(newstatement,cassignmentnode.create(
|
||||
ctemprefnode.create_offset(temp,counter*sinttype.size),
|
||||
ppn.left));
|
||||
ppn.left:=nil;
|
||||
inc(counter);
|
||||
dec(counter);
|
||||
ppn:=tcallparanode(ppn.right);
|
||||
end;
|
||||
{ destppn is also reused }
|
||||
@ -576,7 +576,7 @@ implementation
|
||||
npara:=ccallparanode.create(caddrnode.create_internal
|
||||
(ctemprefnode.create(temp)),
|
||||
ccallparanode.create(cordconstnode.create
|
||||
(counter,s32inttype,true),
|
||||
(dims,sinttype,true),
|
||||
ccallparanode.create(caddrnode.create_internal
|
||||
(crttinode.create(tstoreddef(destppn.resultdef),initrtti,rdt_normal)),
|
||||
ccallparanode.create(ctypeconvnode.create_internal(destppn,voidpointertype),nil))));
|
||||
|
@ -63,7 +63,7 @@ function fpc_dynarray_high(p : pointer) : tdynarrayindex; compilerproc;
|
||||
procedure fpc_dynarray_clear(var p : pointer;ti : pointer); compilerproc;
|
||||
procedure fpc_dynarray_decr_ref(var p : pointer;ti : pointer); compilerproc;
|
||||
procedure fpc_dynarray_incr_ref(p : pointer); compilerproc;
|
||||
procedure fpc_dynarray_setlength(var p : pointer;pti : pointer; dimcount : dword;dims : pdynarrayindex); compilerproc;
|
||||
procedure fpc_dynarray_setlength(var p : pointer;pti : pointer; dimcount : sizeint;dims : pdynarrayindex); compilerproc;
|
||||
{$endif FPC_HAS_FEATURE_DYNARRAYS}
|
||||
|
||||
{ Str() support }
|
||||
|
@ -130,12 +130,11 @@ procedure fpc_dynarray_incr_ref(p : pointer);[Public,Alias:'FPC_DYNARRAY_INCR_RE
|
||||
procedure fpc_dynarray_incr_ref(p : pointer); [external name 'FPC_DYNARRAY_INCR_REF'];
|
||||
|
||||
|
||||
{ provide local access to dynarr_setlength }
|
||||
procedure int_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
dimcount : dword;dims : pdynarrayindex);[external name 'FPC_DYNARR_SETLENGTH'];
|
||||
procedure DynArraySetLength(var a : pointer; typeInfo : pointer;
|
||||
dimCnt : sizeint; lengthVec : psizeint);[external name 'FPC_DYNARR_SETLENGTH'];
|
||||
|
||||
procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
dimcount : dword;dims : pdynarrayindex);[Public,Alias:'FPC_DYNARR_SETLENGTH']; compilerproc;
|
||||
dimcount : sizeint;dims : pdynarrayindex);[Public,Alias:'FPC_DYNARR_SETLENGTH']; compilerproc;
|
||||
|
||||
var
|
||||
i : tdynarrayindex;
|
||||
@ -161,17 +160,16 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
eletype:=pdynarraytypeinfo(pointer(pdynarraytypeinfo(pointer(ti)+sizeof(sizeint)))^);
|
||||
|
||||
{ determine new memory size }
|
||||
{ dims[dimcount-1] because the dimensions are in reverse order! (JM) }
|
||||
size:=elesize*dims[dimcount-1]+sizeof(tdynarray);
|
||||
size:=elesize*dims[0]+sizeof(tdynarray);
|
||||
updatep := false;
|
||||
|
||||
{ not assigned yet? }
|
||||
if not(assigned(p)) then
|
||||
begin
|
||||
if dims[dimcount-1]<0 then
|
||||
if dims[0]<0 then
|
||||
HandleErrorFrame(201,get_frame);
|
||||
{ do we have to allocate memory? }
|
||||
if dims[dimcount-1] = 0 then
|
||||
if dims[0] = 0 then
|
||||
exit;
|
||||
getmem(newp,size);
|
||||
fillchar(newp^,size,0);
|
||||
@ -183,9 +181,9 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
newp := realp;
|
||||
|
||||
{ if the new dimension is 0, we've to release all data }
|
||||
if dims[dimcount-1]<=0 then
|
||||
if dims[0]<=0 then
|
||||
begin
|
||||
if dims[dimcount-1]<0 then
|
||||
if dims[0]<0 then
|
||||
HandleErrorFrame(201,get_frame);
|
||||
if declocked(realp^.refcount) then
|
||||
fpc_dynarray_clear_internal(realp,pdynarraytypeinfo(pti));
|
||||
@ -199,10 +197,10 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
{ make an unique copy }
|
||||
getmem(newp,size);
|
||||
fillchar(newp^,size,0);
|
||||
if realp^.high < dims[dimcount-1] then
|
||||
if realp^.high < dims[0] then
|
||||
movelen := realp^.high+1
|
||||
else
|
||||
movelen := dims[dimcount-1];
|
||||
movelen := dims[0];
|
||||
move(p^,(pointer(newp)+sizeof(tdynarray))^,elesize*movelen);
|
||||
|
||||
{ increment ref. count of members }
|
||||
@ -220,7 +218,7 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
if declocked(realp^.refcount) then
|
||||
fpc_dynarray_clear_internal(realp,pdynarraytypeinfo(ti));
|
||||
end
|
||||
else if dims[dimcount-1]<>realp^.high+1 then
|
||||
else if dims[0]<>realp^.high+1 then
|
||||
begin
|
||||
{ range checking is quite difficult ... }
|
||||
{ if size overflows then it is less than }
|
||||
@ -236,18 +234,18 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
if realp^.refcount=1 then
|
||||
begin
|
||||
{ shrink the array? }
|
||||
if dims[dimcount-1]<realp^.high+1 then
|
||||
if dims[0]<realp^.high+1 then
|
||||
begin
|
||||
int_finalizearray(pointer(realp)+sizeof(tdynarray)+
|
||||
elesize*dims[dimcount-1],
|
||||
eletype,realp^.high-dims[dimcount-1]+1);
|
||||
elesize*dims[0],
|
||||
eletype,realp^.high-dims[0]+1);
|
||||
reallocmem(realp,size);
|
||||
end
|
||||
else if dims[dimcount-1]>realp^.high+1 then
|
||||
else if dims[0]>realp^.high+1 then
|
||||
begin
|
||||
reallocmem(realp,size);
|
||||
fillchar((pointer(realp)+sizeof(tdynarray)+elesize*(realp^.high+1))^,
|
||||
(dims[dimcount-1]-realp^.high-1)*elesize,0);
|
||||
(dims[0]-realp^.high-1)*elesize,0);
|
||||
end;
|
||||
newp := realp;
|
||||
updatep := true;
|
||||
@ -257,15 +255,15 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
|
||||
{ handle nested arrays }
|
||||
if dimcount>1 then
|
||||
begin
|
||||
for i:=0 to dims[dimcount-1]-1 do
|
||||
int_dynarray_setlength(pointer((pointer(newp)+sizeof(tdynarray)+i*elesize)^),
|
||||
eletype,dimcount-1,dims);
|
||||
for i:=0 to dims[0]-1 do
|
||||
DynArraySetLength(pointer((pointer(newp)+sizeof(tdynarray)+i*elesize)^),
|
||||
eletype,dimcount-1,@dims[1]);
|
||||
end;
|
||||
if updatep then
|
||||
begin
|
||||
p:=pointer(newp)+sizeof(tdynarray);
|
||||
newp^.refcount:=1;
|
||||
newp^.high:=dims[dimcount-1]-1;
|
||||
newp^.high:=dims[0]-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -332,20 +330,3 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
|
||||
end;
|
||||
|
||||
|
||||
procedure DynArraySetLength(var a: Pointer; typeInfo: Pointer; dimCnt: SizeInt; lengthVec: PSizeInt);
|
||||
var
|
||||
preallocated : array[0..10] of SizeInt;
|
||||
i : SizeInt;
|
||||
p : PSizeInt;
|
||||
begin
|
||||
if dimCnt<=high(preallocated)+1 then
|
||||
p:=@preallocated[0]
|
||||
else
|
||||
getmem(p,sizeof(SizeInt)*dimCnt);
|
||||
for i:=0 to dimCnt-1 do
|
||||
p[i]:=lengthVec[dimCnt-1-i];
|
||||
int_dynarray_setlength(a,typeInfo,dimCnt,p);
|
||||
if p<>@preallocated[0] then
|
||||
freemem(p);
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user