Browse Source

* 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 -

sergei 11 năm trước cách đây
mục cha
commit
f42c1b3720
5 tập tin đã thay đổi với 16 bổ sung14 xóa
  1. 1 1
      compiler/paramgr.pas
  2. 3 2
      rtl/inc/compproc.inc
  3. 7 7
      rtl/inc/dynarr.inc
  4. 3 3
      rtl/inc/variant.inc
  5. 2 1
      rtl/java/jcompproc.inc

+ 1 - 1
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

+ 3 - 2
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;

+ 7 - 7
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;
 
 

+ 3 - 3
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;
 
 

+ 2 - 1
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;