From 40cf2cefa06d7d276af15daa2f0be75f9dd29b61 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 20 Aug 2011 08:23:16 +0000 Subject: [PATCH] * when the user calls initialize(), force initialization to happen on the JVM platform (normally it's not necessary because all types are automatically initialized) git-svn-id: branches/jvmbackend@18672 - --- compiler/hlcgobj.pas | 2 +- compiler/jvm/njvmutil.pas | 66 ++++++++++++++++++++++++++++++++++++--- compiler/ngenutil.pas | 4 +-- compiler/pinline.pas | 4 +-- rtl/java/compproc.inc | 1 + 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas index 8fac739385..9044aaa585 100644 --- a/compiler/hlcgobj.pas +++ b/compiler/hlcgobj.pas @@ -2103,7 +2103,7 @@ implementation begin OldAsmList:=current_asmdata.CurrAsmList; current_asmdata.CurrAsmList:=TAsmList(arg); - hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner)); + hp:=cnodeutils.initialize_data_node(cloadnode.create(tsym(p),tsym(p).owner),false); firstpass(hp); secondpass(hp); hp.free; diff --git a/compiler/jvm/njvmutil.pas b/compiler/jvm/njvmutil.pas index 9de3feacec..0952eacf62 100644 --- a/compiler/jvm/njvmutil.pas +++ b/compiler/jvm/njvmutil.pas @@ -33,7 +33,7 @@ interface type tjvmnodeutils = class(tnodeutils) - class function initialize_data_node(p:tnode):tnode; override; + class function initialize_data_node(p:tnode; force: boolean):tnode; override; class function finalize_data_node(p:tnode):tnode; override; class function force_init: boolean; override; class procedure insertbssdata(sym: tstaticvarsym); override; @@ -54,14 +54,21 @@ interface implementation uses - verbose,cutils,globals,constexp,fmodule, + verbose,cutils,globtype,globals,constexp,fmodule, aasmdata,aasmtai,cpubase,aasmcpu, symdef,symbase,symtable,defutil,jvmdef, - nbas,ncnv,ncon,ninl,ncal, + nbas,ncnv,ncon,ninl,ncal,nld,nmem, ppu, pass_1; - class function tjvmnodeutils.initialize_data_node(p:tnode):tnode; + class function tjvmnodeutils.initialize_data_node(p:tnode; force: boolean):tnode; + var + normaldim: longint; + temp: ttempcreatenode; + stat: tstatementnode; + def: tdef; + paras: tcallparanode; + proc: string; begin if not assigned(p.resultdef) then typecheckpass(p); @@ -85,6 +92,57 @@ implementation ccallparanode.create(genintconstnode(0), ccallparanode.create(p,nil))); end + else if force then + begin + { an explicit call to initialize() } + if p.resultdef.typ=recorddef then + result:=ccallnode.createinternmethod(p,'FPCINITIALIZEREC',nil) + else if p.resultdef.typ=arraydef then + begin + stat:=nil; + { 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; + def:=tarraydef(p.resultdef).elementdef; + while (def.typ=arraydef) and + not is_dynamic_array(def) do + begin + inc(normaldim); + def:=tarraydef(def).elementdef; + end; + if jvmimplicitpointertype(p.resultdef) then + begin + p:=caddrnode.create(p); + include(p.flags,nf_typedaddr); + end; + paras:=ccallparanode.create(ctypeconvnode.create_explicit(p, + search_system_type('TJOBJECTARRAY').typedef),nil); + paras:=ccallparanode.create(genintconstnode(normaldim),paras); + if is_wide_or_unicode_string(def) then + proc:='fpc_initialize_array_unicodestring' + else if is_ansistring(def) then + proc:='fpc_initialize_array_ansistring' + else if is_dynamic_array(def) then + proc:='fpc_initialize_array_dynarr' + else if is_record(def) then + begin + result:=internalstatements(stat); + temp:=ctempcreatenode.create(def,def.size,tt_persistent,true); + addstatement(stat,temp); + paras:=ccallparanode.create(ctemprefnode.create(temp),paras); + proc:='fpc_initialize_array_record' + end; + if assigned(stat) then + begin + addstatement(stat,ccallnode.createintern(proc,paras)); + addstatement(stat,ctempdeletenode.create(temp)); + end + else + result:=ccallnode.createintern(proc,paras); + end + else + result:=cassignmentnode.create(p,cnilnode.create); + end else begin p.free; diff --git a/compiler/ngenutil.pas b/compiler/ngenutil.pas index b6b1f13b7d..82b08537f0 100644 --- a/compiler/ngenutil.pas +++ b/compiler/ngenutil.pas @@ -33,7 +33,7 @@ interface type tnodeutils = class class function call_fail_node:tnode; virtual; - class function initialize_data_node(p:tnode):tnode; virtual; + class function initialize_data_node(p:tnode; force: boolean):tnode; virtual; class function finalize_data_node(p:tnode):tnode; virtual; { returns true if the unit requires an initialisation section (e.g., to force class constructors for the JVM target to initialise global @@ -143,7 +143,7 @@ implementation end; - class function tnodeutils.initialize_data_node(p:tnode):tnode; + class function tnodeutils.initialize_data_node(p:tnode; force: boolean):tnode; begin if not assigned(p.resultdef) then typecheckpass(p); diff --git a/compiler/pinline.pas b/compiler/pinline.pas index 2d2f63417c..0245137db5 100644 --- a/compiler/pinline.pas +++ b/compiler/pinline.pas @@ -314,7 +314,7 @@ implementation { create call to fpc_initialize } if is_managed_type(tpointerdef(p.resultdef).pointeddef) or ((m_iso in current_settings.modeswitches) and (tpointerdef(p.resultdef).pointeddef.typ=filedef)) then - addstatement(newstatement,cnodeutils.initialize_data_node(cderefnode.create(ctemprefnode.create(temp)))); + addstatement(newstatement,cnodeutils.initialize_data_node(cderefnode.create(ctemprefnode.create(temp)),false)); { copy the temp to the destination } addstatement(newstatement,cassignmentnode.create( @@ -518,7 +518,7 @@ implementation else begin if isinit then - newblock:=cnodeutils.initialize_data_node(ppn.left) + newblock:=cnodeutils.initialize_data_node(ppn.left,true) else newblock:=cnodeutils.finalize_data_node(ppn.left); end; diff --git a/rtl/java/compproc.inc b/rtl/java/compproc.inc index d194029af2..4c7994dd6a 100644 --- a/rtl/java/compproc.inc +++ b/rtl/java/compproc.inc @@ -607,6 +607,7 @@ Procedure fpc_Copy_proc (Src, Dest, TypeInfo : Pointer); compilerproc; inline; -> normalarrdim will be 2 } procedure fpc_initialize_array_unicodestring(arr: TJObjectArray; normalarrdim: longint);compilerproc; +procedure fpc_initialize_array_ansistring(arr: TJObjectArray; normalarrdim: longint);compilerproc; { normalarrdim contains the number of dimensions a regular array, if any, that contains these unicodestrings. E.g.: type