mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 22:47:59 +02:00
* 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:
parent
5ada0ff373
commit
f42c1b3720
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user