* Return dynamic arrays in parameter, this was the only managed type still returned in register. Returning managed types in registers requires catching and re-raising exceptions at callee side in order to finalize result and avoid memory leaks. While such behavior makes little difference with generic setjmp-based exception handling, it becomes very inefficient as SEH-styled exception handling is being introduced.

The new behavior is also Delphi-compatible.

git-svn-id: trunk@26180 -
This commit is contained in:
sergei 2013-12-04 13:43:22 +00:00
parent 5ada0ff373
commit f42c1b3720
5 changed files with 16 additions and 14 deletions

View File

@ -181,7 +181,7 @@ implementation
begin
if handle_common_ret_in_param(def,pd,result) then
exit;
ret_in_param:=((def.typ=arraydef) and not(is_dynamic_array(def))) or
ret_in_param:=(def.typ=arraydef) or
(def.typ=recorddef) or
(def.typ=stringdef) or
((def.typ=procvardef) and not tprocvardef(def).is_addressonly) or

View File

@ -27,6 +27,7 @@ type
fpc_normal_set = bitpacked array[0..255] of 0..1;
fpc_normal_set_byte = array[0..31] of byte;
fpc_normal_set_long = array[0..7] of longint;
fpc_stub_dynarray = array of byte;
{$ifdef FPC_HAS_FEATURE_HEAP}
@ -62,7 +63,7 @@ function fpc_char_copy(c:char;index : SizeInt;count : SizeInt): shortstring;com
{$ifdef FPC_HAS_FEATURE_DYNARRAYS}
function fpc_dynarray_copy(psrc : pointer;ti : pointer;
lowidx,count:tdynarrayindex) : pointer;compilerproc;
lowidx,count:tdynarrayindex) : fpc_stub_dynarray;compilerproc;
function fpc_dynarray_length(p : pointer) : tdynarrayindex; compilerproc;
function fpc_dynarray_high(p : pointer) : tdynarrayindex; compilerproc;
procedure fpc_dynarray_clear(var p : pointer;ti : pointer); compilerproc;
@ -457,7 +458,7 @@ procedure fpc_variant_copy(d,s : pointer);compilerproc;
procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc;
{$endif FPC_VARIANTCOPY_FIXED}
procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); compilerproc;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : fpc_stub_dynarray;compilerproc;
function fpc_dynarray_to_variant(dynarr : pointer;typeinfo : pointer) : variant;compilerproc;
function fpc_variant_to_interface(const v : variant) : iinterface;compilerproc;
function fpc_interface_to_variant(const i : iinterface) : variant;compilerproc;

View File

@ -243,17 +243,17 @@ procedure fpc_dynarray_setlength(var p : pointer;pti : pointer;
{ provide local access to dynarr_copy }
function int_dynarray_copy(psrc : pointer;ti : pointer;
lowidx,count:tdynarrayindex) : pointer;[external name 'FPC_DYNARR_COPY'];
lowidx,count:tdynarrayindex) : fpc_stub_dynarray;[external name 'FPC_DYNARR_COPY'];
function fpc_dynarray_copy(psrc : pointer;ti : pointer;
lowidx,count:tdynarrayindex) : pointer;[Public,Alias:'FPC_DYNARR_COPY'];compilerproc;
lowidx,count:tdynarrayindex) : fpc_stub_dynarray;[Public,Alias:'FPC_DYNARR_COPY'];compilerproc;
var
realpsrc : pdynarray;
i,size : sizeint;
elesize : sizeint;
eletype : pointer;
begin
result:=nil;
fpc_dynarray_clear(pointer(result),ti);
if psrc=nil then
exit;
{$ifndef FPC_DYNARRAYCOPY_FIXED}
@ -286,17 +286,17 @@ function fpc_dynarray_copy(psrc : pointer;ti : pointer;
{ create new array }
size:=elesize*count;
getmem(result,size+sizeof(tdynarray));
getmem(pointer(result),size+sizeof(tdynarray));
pdynarray(result)^.refcount:=1;
pdynarray(result)^.high:=count-1;
inc(result,sizeof(tdynarray));
inc(pointer(result),sizeof(tdynarray));
{ copy data }
move(pointer(psrc+elesize*lowidx)^,result^,size);
move(pointer(psrc+elesize*lowidx)^,pointer(result)^,size);
{ increment ref. count of members? }
if PByte(eletype)^ in tkManagedTypes then
for i:=0 to count-1 do
int_addref(pointer(result+elesize*i),eletype);
int_addref(pointer(pointer(result)+elesize*i),eletype);
end;

View File

@ -105,10 +105,10 @@ procedure fpc_vararray_put(var d : variant;const s : variant;indices : plongint;
end;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : fpc_stub_dynarray;compilerproc;
begin
result:=nil;
variantmanager.vartodynarray(result,v,typeinfo);
fpc_dynarray_clear(pointer(result),typeinfo);
variantmanager.vartodynarray(pointer(result),v,typeinfo);
end;

View File

@ -27,6 +27,7 @@ type
fpc_normal_set = bitpacked array[0..255] of 0..1;
fpc_normal_set_byte = array[0..31] of byte;
fpc_normal_set_long = array[0..7] of longint;
fpc_stub_dynarray = array of byte;
{ used by Default() in code blocks }
//procedure fpc_zeromem(p:pointer;len:ptruint);compilerproc;
@ -374,7 +375,7 @@ procedure fpc_variant_copy(d,s : pointer);compilerproc;
procedure fpc_variant_copy_overwrite(source, dest : pointer);compilerproc;
{$endif FPC_VARIANTCOPY_FIXED}
procedure fpc_write_text_variant(Len : Longint;var f : Text;const v : variant); compilerproc;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : pointer;compilerproc;
function fpc_variant_to_dynarray(const v : variant;typeinfo : pointer) : fpc_stub_dynarray;compilerproc;
function fpc_dynarray_to_variant(dynarr : pointer;typeinfo : pointer) : variant;compilerproc;
function fpc_variant_to_interface(const v : variant) : iinterface;compilerproc;
function fpc_interface_to_variant(const i : iinterface) : variant;compilerproc;