From f42c1b3720b873eee5ed60fa62d8d5c37a37848a Mon Sep 17 00:00:00 2001 From: sergei Date: Wed, 4 Dec 2013 13:43:22 +0000 Subject: [PATCH] * 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 - --- compiler/paramgr.pas | 2 +- rtl/inc/compproc.inc | 5 +++-- rtl/inc/dynarr.inc | 14 +++++++------- rtl/inc/variant.inc | 6 +++--- rtl/java/jcompproc.inc | 3 ++- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/compiler/paramgr.pas b/compiler/paramgr.pas index 32d43a7e5d..cea633e733 100644 --- a/compiler/paramgr.pas +++ b/compiler/paramgr.pas @@ -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 diff --git a/rtl/inc/compproc.inc b/rtl/inc/compproc.inc index dc4cdd9d9e..ee9bbc382c 100644 --- a/rtl/inc/compproc.inc +++ b/rtl/inc/compproc.inc @@ -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; diff --git a/rtl/inc/dynarr.inc b/rtl/inc/dynarr.inc index 1f29c39046..76771c15d1 100644 --- a/rtl/inc/dynarr.inc +++ b/rtl/inc/dynarr.inc @@ -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; diff --git a/rtl/inc/variant.inc b/rtl/inc/variant.inc index 8c48b6afd9..e31cc911c1 100644 --- a/rtl/inc/variant.inc +++ b/rtl/inc/variant.inc @@ -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; diff --git a/rtl/java/jcompproc.inc b/rtl/java/jcompproc.inc index 20fe410447..f02656ceda 100644 --- a/rtl/java/jcompproc.inc +++ b/rtl/java/jcompproc.inc @@ -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;