Răsfoiți Sursa

+ thlcgobj support of the managed open array initialization fixes of
svn r17068,17071,17081,17136
* changed all init_paras code in both thlcgobj and ncgutil to use
location_get_data_ref() instead of direct a_load_loc_reg()/
ref.base:=reg so it also works with the JVM target
* changed all init_paras code so it works with targets that do
not pass an implicit high parameter for open array (and a similar
fix in ncgcal)
+ added support for initializing array (both regular and open)
"out" parameters of reference counted types on the JVM target
(the arrays will be initialised with nil rather than an empty
array for implementation reasons, see comments in compproc.inc)
* factored out calling of functions in the system unit directly
from hlcgobj

git-svn-id: branches/jvmbackend@18421 -

Jonas Maebe 14 ani în urmă
părinte
comite
5abf6d0aa4

+ 2 - 0
.gitattributes

@@ -7346,10 +7346,12 @@ rtl/inc/wstrings.inc svneol=native#text/plain
 rtl/inc/wustrings.inc svneol=native#text/plain
 rtl/inc/wustrings.inc svneol=native#text/plain
 rtl/java/Makefile svneol=native#text/plain
 rtl/java/Makefile svneol=native#text/plain
 rtl/java/Makefile.fpc svneol=native#text/plain
 rtl/java/Makefile.fpc svneol=native#text/plain
+rtl/java/compproc.inc svneol=native#text/plain
 rtl/java/jdynarrh.inc svneol=native#text/plain
 rtl/java/jdynarrh.inc svneol=native#text/plain
 rtl/java/jmathh.inc svneol=native#text/plain
 rtl/java/jmathh.inc svneol=native#text/plain
 rtl/java/objpas.pp svneol=native#text/plain
 rtl/java/objpas.pp svneol=native#text/plain
 rtl/java/rtl.cfg svneol=native#text/plain
 rtl/java/rtl.cfg svneol=native#text/plain
+rtl/java/rtti.inc svneol=native#text/plain
 rtl/java/system.pp svneol=native#text/plain
 rtl/java/system.pp svneol=native#text/plain
 rtl/jvm/makefile.cpu svneol=native#text/plain
 rtl/jvm/makefile.cpu svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain
 rtl/linux/Makefile svneol=native#text/plain

+ 7 - 0
compiler/hlcg2ll.pas

@@ -333,6 +333,8 @@ unit hlcg2ll;
 
 
           procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
           procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
           procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
           procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
+          procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation;
+            const name: string);override;
           procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);override;
           procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);override;
           procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);override;
           procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);override;
 
 
@@ -1083,6 +1085,11 @@ procedure thlcg2ll.a_loadaddr_ref_reg(list: TAsmList; fromsize, tosize: tdef; co
       cg.g_decrrefcount(list,t,ref);
       cg.g_decrrefcount(list,t,ref);
     end;
     end;
 
 
+  procedure thlcg2ll.g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string);
+    begin
+      cg.g_array_rtti_helper(list, t, ref, highloc, name);
+    end;
+
   procedure thlcg2ll.g_initialize(list: TAsmList; t: tdef; const ref: treference);
   procedure thlcg2ll.g_initialize(list: TAsmList; t: tdef; const ref: treference);
     begin
     begin
       cg.g_initialize(list,t,ref);
       cg.g_initialize(list,t,ref);

+ 47 - 9
compiler/hlcgobj.pas

@@ -361,6 +361,8 @@ unit hlcgobj;
           procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);virtual;abstract;
           procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);virtual;abstract;
           procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);virtual;abstract;
           procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);virtual;abstract;
           procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);virtual;abstract;
           procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);virtual;abstract;
+          procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation;
+            const name: string);virtual;abstract;
 
 
           {# Generates range checking code. It is to note
           {# Generates range checking code. It is to note
              that this routine does not need to be overridden,
              that this routine does not need to be overridden,
@@ -1887,13 +1889,17 @@ implementation
         end;
         end;
     end;
     end;
 
 
+{ generates the code for incrementing the reference count of parameters and
+  initialize out parameters }
   { generates the code for incrementing the reference count of parameters and
   { generates the code for incrementing the reference count of parameters and
     initialize out parameters }
     initialize out parameters }
   procedure thlcgobj.init_paras(p:TObject;arg:pointer);
   procedure thlcgobj.init_paras(p:TObject;arg:pointer);
     var
     var
       href : treference;
       href : treference;
-      tmpreg : tregister;
+      hsym : tparavarsym;
+      eldef : tdef;
       list : TAsmList;
       list : TAsmList;
+      highloc : tlocation;
       needs_inittable (*,
       needs_inittable (*,
       do_trashing     *)  : boolean;
       do_trashing     *)  : boolean;
     begin
     begin
@@ -1917,7 +1923,26 @@ implementation
                    paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then
                    paramanager.push_addr_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption)) then
                    begin
                    begin
                      location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
                      location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
-                     hlcg.g_incrrefcount(list,tparavarsym(p).vardef,href);
+                     if is_open_array(tparavarsym(p).vardef) then
+                       begin
+                         if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then
+                           begin
+                             hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+                             if not assigned(hsym) then
+                               internalerror(201003032);
+                             highloc:=hsym.initialloc
+                           end
+                         else
+                           highloc.loc:=LOC_INVALID;
+                         { open arrays do not contain correct element count in their rtti,
+                           the actual count must be passed separately. }
+                         eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
+                         if not assigned(hsym) then
+                           internalerror(201003031);
+                         g_array_rtti_helper(list,eldef,href,highloc,'FPC_ADDREF_ARRAY');
+                       end
+                     else
+                      g_incrrefcount(list,tparavarsym(p).vardef,href);
                    end;
                    end;
                end;
                end;
            vs_out :
            vs_out :
@@ -1925,12 +1950,10 @@ implementation
                if needs_inittable (*or
                if needs_inittable (*or
                   do_trashing*) then
                   do_trashing*) then
                  begin
                  begin
-                   tmpreg:=cg.getaddressregister(list);
-                   hlcg.a_load_loc_reg(list,tparavarsym(p).vardef,tparavarsym(p).vardef,tparavarsym(p).initialloc,tmpreg);
                    { we have no idea about the alignment at the callee side,
                    { we have no idea about the alignment at the callee side,
                      and the user also cannot specify "unaligned" here, so
                      and the user also cannot specify "unaligned" here, so
                      assume worst case }
                      assume worst case }
-                   reference_reset_base(href,tmpreg,0,1);
+                   location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);
 (*
 (*
                    if do_trashing and
                    if do_trashing and
                       { needs separate implementation to trash open arrays }
                       { needs separate implementation to trash open arrays }
@@ -1944,21 +1967,36 @@ implementation
                        trash_reference(list,href,2);
                        trash_reference(list,href,2);
 *)
 *)
                    if needs_inittable then
                    if needs_inittable then
-                     hlcg.g_initialize(list,tparavarsym(p).vardef,href);
+                     begin
+                       if is_open_array(tparavarsym(p).vardef) then
+                         begin
+                           if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then
+                             begin
+                               hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+                               if not assigned(hsym) then
+                                 internalerror(201003032);
+                               highloc:=hsym.initialloc
+                             end
+                           else
+                             highloc.loc:=LOC_INVALID;
+                           eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
+                           g_array_rtti_helper(list,eldef,href,highloc,'FPC_INITIALIZE_ARRAY');
+                         end
+                       else
+                         g_initialize(list,tparavarsym(p).vardef,href);
+                     end;
                  end;
                  end;
              end;
              end;
 (*
 (*
            else if do_trashing and
            else if do_trashing and
                    ([vo_is_funcret,vo_is_hidden_para] * tparavarsym(p).varoptions = [vo_is_funcret,vo_is_hidden_para]) then
                    ([vo_is_funcret,vo_is_hidden_para] * tparavarsym(p).varoptions = [vo_is_funcret,vo_is_hidden_para]) then
                  begin
                  begin
-                   tmpreg:=cg.getaddressregister(list);
-                   a_load_loc_reg(list,tparavarsym(p).vardef,tparavarsym(p).vardef,tparavarsym(p).initialloc,tmpreg);
                    { should always have standard alignment. If a function is assigned
                    { should always have standard alignment. If a function is assigned
                      to a non-aligned variable, the optimisation to pass this variable
                      to a non-aligned variable, the optimisation to pass this variable
                      directly as hidden function result must/cannot be performed
                      directly as hidden function result must/cannot be performed
                      (see tcallnode.funcret_can_be_reused)
                      (see tcallnode.funcret_can_be_reused)
                    }
                    }
-                   reference_reset_base(href,tmpreg,0,
+                   location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,
                      used_align(tparavarsym(p).vardef.alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax));
                      used_align(tparavarsym(p).vardef.alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax));
                    { may be an open string, even if is_open_string() returns }
                    { may be an open string, even if is_open_string() returns }
                    { false (for some helpers in the system unit)             }
                    { false (for some helpers in the system unit)             }

+ 55 - 9
compiler/jvm/hlcgcpu.pas

@@ -88,6 +88,7 @@ uses
 
 
       procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
       procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
       procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
       procedure g_decrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
+      procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string); override;
       procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);override;
       procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);override;
       procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);override;
       procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);override;
 
 
@@ -172,6 +173,8 @@ uses
       { concatcopy helpers }
       { concatcopy helpers }
       procedure concatcopy_normal_array(list: TAsmList; size: tdef; const source, dest: treference);
       procedure concatcopy_normal_array(list: TAsmList; size: tdef; const source, dest: treference);
 
 
+      { generate a call to a routine in the system unit }
+      procedure g_call_system_proc(list: TAsmList; const procname: string);
     end;
     end;
 
 
   procedure create_hlcodegen;
   procedure create_hlcodegen;
@@ -1020,8 +1023,6 @@ implementation
     var
     var
       procname: string;
       procname: string;
       eledef: tdef;
       eledef: tdef;
-      pd: tprocdef;
-      srsym: tsym;
       ndim: longint;
       ndim: longint;
     begin
     begin
       { load copy helper parameters on the stack }
       { load copy helper parameters on the stack }
@@ -1089,12 +1090,7 @@ implementation
         else
         else
           procname:='FPC_COPY_JOBJECT_ARRAY';
           procname:='FPC_COPY_JOBJECT_ARRAY';
       end;
       end;
-     srsym:=tsym(systemunit.find(procname));
-     if not assigned(srsym) or
-        (srsym.typ<>procsym) then
-       Message1(cg_f_unknown_compilerproc,procname);
-     pd:=tprocdef(tprocsym(srsym).procdeflist[0]);
-     a_call_name(list,pd,pd.mangledname,false);
+     g_call_system_proc(list,procname);
      if ndim=1 then
      if ndim=1 then
        decstack(list,2)
        decstack(list,2)
      else
      else
@@ -1235,9 +1231,46 @@ implementation
       // do nothing
       // do nothing
     end;
     end;
 
 
+  procedure thlcgjvm.g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string);
+    var
+      normaldim: longint;
+    begin
+      { only in case of initialisation, we have to set all elements to "empty" }
+      if name<>'FPC_INITIALIZE_ARRAY' then
+        exit;
+      { put array on the stack }
+      a_load_ref_stack(list,java_jlobject,ref,prepare_stack_for_ref(list,ref,false));
+      { in case it's an open array whose elements are regular arrays, put the
+        dimension of the regular arrays on the stack (otherwise pass 0) }
+      normaldim:=0;
+      while (t.typ=arraydef) and
+            not is_dynamic_array(t) do
+        begin
+          inc(normaldim);
+          t:=tarraydef(t).elementdef;
+        end;
+      a_load_const_stack(list,s32inttype,normaldim,R_INTREGISTER);
+      { highloc is invalid, the length is part of the array in Java }
+      if is_wide_or_unicode_string(t) then
+        g_call_system_proc(list,'fpc_initialize_array_unicodestring')
+      else if is_dynamic_array(t) then
+        g_call_system_proc(list,'fpc_initialize_array_dynarr')
+      else
+        internalerror(2011031901);
+    end;
+
   procedure thlcgjvm.g_initialize(list: TAsmList; t: tdef; const ref: treference);
   procedure thlcgjvm.g_initialize(list: TAsmList; t: tdef; const ref: treference);
+    var
+      dummyloc: tlocation;
     begin
     begin
-      a_load_const_ref(list,t,0,ref);
+      if (t.typ=arraydef) and
+         not is_dynamic_array(t) then
+        begin
+          dummyloc.loc:=LOC_INVALID;
+          g_array_rtti_helper(list,tarraydef(t).elementdef,ref,dummyloc,'FPC_INITIALIZE_ARRAY')
+        end
+      else
+        a_load_const_ref(list,t,0,ref);
     end;
     end;
 
 
   procedure thlcgjvm.g_finalize(list: TAsmList; t: tdef; const ref: treference);
   procedure thlcgjvm.g_finalize(list: TAsmList; t: tdef; const ref: treference);
@@ -1649,6 +1682,19 @@ implementation
       list.concat(taicpu.op_sym(opc,current_asmdata.RefAsmSymbol(s)));
       list.concat(taicpu.op_sym(opc,current_asmdata.RefAsmSymbol(s)));
     end;
     end;
 
 
+  procedure thlcgjvm.g_call_system_proc(list: TAsmList; const procname: string);
+    var
+      srsym: tsym;
+      pd: tprocdef;
+    begin
+      srsym:=tsym(systemunit.find(procname));
+      if not assigned(srsym) or
+         (srsym.typ<>procsym) then
+        Message1(cg_f_unknown_compilerproc,procname);
+      pd:=tprocdef(tprocsym(srsym).procdeflist[0]);
+      a_call_name(list,pd,pd.mangledname,false);
+    end;
+
   procedure create_hlcodegen;
   procedure create_hlcodegen;
     begin
     begin
       hlcg:=thlcgjvm.create;
       hlcg:=thlcgjvm.create;

+ 2 - 1
compiler/ncgcal.pas

@@ -172,7 +172,8 @@ implementation
 
 
              { release memory for refcnt out parameters }
              { release memory for refcnt out parameters }
              if (parasym.varspez=vs_out) and
              if (parasym.varspez=vs_out) and
-                is_managed_type(left.resultdef) then
+                is_managed_type(left.resultdef) and
+                not(target_info.system in systems_garbage_collected_managed_types) then
                begin
                begin
                  hlcg.location_get_data_ref(current_asmdata.CurrAsmList,left.resultdef,left.location,href,false,sizeof(pint));
                  hlcg.location_get_data_ref(current_asmdata.CurrAsmList,left.resultdef,left.location,href,false,sizeof(pint));
                  if is_open_array(resultdef) then
                  if is_open_array(resultdef) then

+ 13 - 11
compiler/ncgutil.pas

@@ -1553,7 +1553,6 @@ implementation
         href : treference;
         href : treference;
         hsym : tparavarsym;
         hsym : tparavarsym;
         eldef : tdef;
         eldef : tdef;
-        tmpreg : tregister;
         list : TAsmList;
         list : TAsmList;
         needs_inittable,
         needs_inittable,
         do_trashing       : boolean;
         do_trashing       : boolean;
@@ -1595,12 +1594,10 @@ implementation
                  if needs_inittable or
                  if needs_inittable or
                     do_trashing then
                     do_trashing then
                    begin
                    begin
-                     tmpreg:=cg.getaddressregister(list);
-                     cg.a_load_loc_reg(list,OS_ADDR,tparavarsym(p).initialloc,tmpreg);
                      { we have no idea about the alignment at the callee side,
                      { we have no idea about the alignment at the callee side,
                        and the user also cannot specify "unaligned" here, so
                        and the user also cannot specify "unaligned" here, so
                        assume worst case }
                        assume worst case }
-                     reference_reset_base(href,tmpreg,0,1);
+                     hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,1);
                      if do_trashing and
                      if do_trashing and
                         { needs separate implementation to trash open arrays }
                         { needs separate implementation to trash open arrays }
                         { since their size is only known at run time         }
                         { since their size is only known at run time         }
@@ -1629,14 +1626,12 @@ implementation
              else if do_trashing and
              else if do_trashing and
                      ([vo_is_funcret,vo_is_hidden_para] * tparavarsym(p).varoptions = [vo_is_funcret,vo_is_hidden_para]) then
                      ([vo_is_funcret,vo_is_hidden_para] * tparavarsym(p).varoptions = [vo_is_funcret,vo_is_hidden_para]) then
                    begin
                    begin
-                     tmpreg:=cg.getaddressregister(list);
-                     cg.a_load_loc_reg(list,OS_ADDR,tparavarsym(p).initialloc,tmpreg);
                      { should always have standard alignment. If a function is assigned
                      { should always have standard alignment. If a function is assigned
                        to a non-aligned variable, the optimisation to pass this variable
                        to a non-aligned variable, the optimisation to pass this variable
                        directly as hidden function result must/cannot be performed
                        directly as hidden function result must/cannot be performed
                        (see tcallnode.funcret_can_be_reused)
                        (see tcallnode.funcret_can_be_reused)
                      }
                      }
-                     reference_reset_base(href,tmpreg,0,
+                     hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).initialloc,href,true,
                        used_align(tparavarsym(p).vardef.alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax));
                        used_align(tparavarsym(p).vardef.alignment,current_settings.alignment.localalignmin,current_settings.alignment.localalignmax));
                      { may be an open string, even if is_open_string() returns }
                      { may be an open string, even if is_open_string() returns }
                      { false (for some helpers in the system unit)             }
                      { false (for some helpers in the system unit)             }
@@ -1658,6 +1653,7 @@ implementation
         href : treference;
         href : treference;
         hsym : tparavarsym;
         hsym : tparavarsym;
         eldef : tdef;
         eldef : tdef;
+        highloc : tlocation;
       begin
       begin
         if not(tsym(p).typ=paravarsym) then
         if not(tsym(p).typ=paravarsym) then
           exit;
           exit;
@@ -1670,11 +1666,17 @@ implementation
               hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
               hlcg.location_get_data_ref(list,tparavarsym(p).vardef,tparavarsym(p).localloc,href,is_open_array(tparavarsym(p).vardef),sizeof(pint));
               if is_open_array(tparavarsym(p).vardef) then
               if is_open_array(tparavarsym(p).vardef) then
                 begin
                 begin
-                  hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+                  if paramanager.push_high_param(tparavarsym(p).varspez,tparavarsym(p).vardef,current_procinfo.procdef.proccalloption) then
+                    begin
+                      hsym:=tparavarsym(tsym(p).owner.Find('high'+tsym(p).name));
+                      if not assigned(hsym) then
+                        internalerror(201003032);
+                      highloc:=hsym.initialloc
+                    end
+                  else
+                    highloc.loc:=LOC_INVALID;
                   eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
                   eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
-                  if not assigned(hsym) then
-                    internalerror(201003032);
-                  cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_DECREF_ARRAY');
+                  hlcg.g_array_rtti_helper(list,eldef,href,highloc,'FPC_DECREF_ARRAY');
                 end
                 end
               else
               else
                 hlcg.g_decrrefcount(list,tparavarsym(p).vardef,href);
                 hlcg.g_decrrefcount(list,tparavarsym(p).vardef,href);

+ 55 - 0
rtl/java/compproc.inc

@@ -0,0 +1,55 @@
+{
+    This file is part of the Free Pascal Run time library.
+    Copyright (c) 1999-2000 by the Free Pascal development team
+
+    This file contains the declarations of internal compiler helper
+    routines. That means you can *NOT* call these directly, as they may
+    be changed or even removed at any time. The only reason they are
+    included in the interface of the system unit, is so that the
+    compiler doesn't need special code to access their parameter
+    list information etc.
+
+    Note that due to the "compilerproc" directive, it isn't even possible
+    to use these routines in your programs.
+
+    See the File COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+{$ifdef FPC_HAS_FEATURE_RTTI}
+Procedure fpc_Initialize (Data,TypeInfo : pointer); compilerproc;
+Procedure fpc_finalize (Data,TypeInfo: Pointer); compilerproc;
+Procedure fpc_Addref (Data,TypeInfo : Pointer); compilerproc;
+Procedure fpc_DecRef (Data,TypeInfo : Pointer);  compilerproc;
+procedure fpc_initialize_array(data,typeinfo : pointer;count : SizeInt); compilerproc;
+procedure fpc_finalize_array(data,typeinfo : pointer;count : SizeInt); compilerproc;
+procedure fpc_addref_array(data,typeinfo: pointer; count: SizeInt); compilerproc;
+procedure fpc_decref_array(data,typeinfo: pointer; count: sizeint); compilerproc;
+Function fpc_Copy (Src, Dest, TypeInfo : Pointer) : SizeInt; compilerproc;
+Procedure fpc_Copy_proc (Src, Dest, TypeInfo : Pointer); compilerproc; inline;
+{$endif FPC_HAS_FEATURE_RTTI}
+{ normalarrdim contains the number of dimensions
+  a regular array, if any, that contains these unicodestrings. E.g.:
+   type
+     tarr = array[1..10,2..9] of unicodestring;
+
+   procedure test(out arr: array of tarr);
+    -> normalarrdim will be 2
+
+  Initialises with nil rather than with empty arrays, because there does not
+  appear to be a generic way to pass an iniitialised (empty) array object and
+  then clone it for every array position, except for slow serialization (array
+  instances are clonable in Java, but they don't inherit from a base class other
+  than java.lang.Object (in which clone is protected) and they only implement
+  the formal interfaces Clonable and Serializeable (which don't expose any
+  particular methods). This means that we cannot cast arrays to a generic class
+  type that supports cloning (except if we add support for calling methods on
+  dynamic array types, and add an extra parameter to determine the first
+  level elements types of the array) }
+procedure fpc_initialize_array_dynarr(arr: TJObjectArray; normalarrdim: longint);compilerproc;
+

+ 32 - 0
rtl/java/rtti.inc

@@ -0,0 +1,32 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2011 by Jonas Maebe
+    member of the Free Pascal development team
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+ **********************************************************************}
+
+procedure fpc_initialize_array_dynarr_intern(arr: TJObjectArray; normalarrdim: longint); external name 'fpc_initialize_array_dynarr';
+
+procedure fpc_initialize_array_dynarr(arr: TJObjectArray; normalarrdim: longint);compilerproc;
+  var
+    i: longint;
+  begin
+    if normalarrdim > 0 then
+      begin
+        for i:=low(arr) to high(arr) do
+          fpc_initialize_array_dynarr_intern(TJObjectArray(arr[i]),normalarrdim-1);
+      end
+    else
+      begin
+        for i:=low(arr) to high(arr) do
+          arr[i]:=nil;
+      end;
+  end;
+

+ 6 - 0
rtl/java/system.pp

@@ -26,6 +26,8 @@ Unit system;
 {$implicitexceptions off}
 {$implicitexceptions off}
 {$mode objfpc}
 {$mode objfpc}
 
 
+{$undef FPC_HAS_FEATURE_RTTI}
+
 Type
 Type
   { The compiler has all integer types defined internally. Here
   { The compiler has all integer types defined internally. Here
     we define only aliases }
     we define only aliases }
@@ -122,6 +124,8 @@ type
 {$i jmathh.inc}
 {$i jmathh.inc}
 {$i jdynarrh.inc}
 {$i jdynarrh.inc}
 
 
+{$i compproc.inc}
+
 {*****************************************************************************}
 {*****************************************************************************}
                                  implementation
                                  implementation
 {*****************************************************************************}
 {*****************************************************************************}
@@ -144,6 +148,8 @@ type
  **********************************************************************
  **********************************************************************
 }
 }
 
 
+{$i rtti.inc}
+
 function min(a,b : longint) : longint;
 function min(a,b : longint) : longint;
   begin
   begin
      if a<=b then
      if a<=b then