From 6a7ff1cf75d3a0c5616ecd9b4273653462e9b59e Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 29 Aug 2011 22:58:55 +0000 Subject: [PATCH] * use temp-reference nodes rather than addrnodes to create references to complex parameters passed to inlined routines on the JVM target, because it is not possible to take the address of any kind of node on the JVM target (temp-reference nodes work for any kind of LOC_(C)REFERENCE, but are currently only implemented for the JVM platform) git-svn-id: branches/jvmbackend@18905 - --- compiler/jvm/njvmcal.pas | 24 ++++++++++++++++++++++-- compiler/ncal.pas | 39 ++++++++++++++++++++++++--------------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/compiler/jvm/njvmcal.pas b/compiler/jvm/njvmcal.pas index ddd9320ee7..c77ca166cc 100644 --- a/compiler/jvm/njvmcal.pas +++ b/compiler/jvm/njvmcal.pas @@ -28,7 +28,7 @@ interface uses cgbase, symtype,symdef, - node,ncgcal; + node,ncal,ncgcal; type tjvmcallparanode = class(tcgcallparanode) @@ -43,6 +43,7 @@ interface tjvmcallnode = class(tcgcallnode) protected + procedure wrapcomplexinlinepara(para: tcallparanode); override; procedure extra_pre_call_code; override; procedure set_result_location(realresdef: tstoreddef); override; procedure do_release_unused_return_value;override; @@ -59,7 +60,6 @@ implementation uses verbose,globtype,constexp,cutils, symconst,symtable,symsym,defutil, - ncal, cgutils,tgobj,procinfo,htypechk, cpubase,aasmdata,aasmcpu, hlcgobj,hlcgcpu, @@ -311,6 +311,26 @@ implementation TJVMCALLNODE *****************************************************************************} + procedure tjvmcallnode.wrapcomplexinlinepara(para: tcallparanode); + var + tempnode: ttempcreatenode; + begin + { don't use caddrnodes for the JVM target, because we can't take the + address of every kind of type (e.g., of ansistrings). A temp-reference + node does work for any kind of memory reference (and the expectloc + is LOC_(C)REFERENCE when this routine is called), but is not (yet) + supported for other targets } + tempnode:=ctempcreatenode.create_reference(para.parasym.vardef,para.parasym.vardef.size, + tt_persistent,tparavarsym(para.parasym).is_regvar(false),para.left,false); + addstatement(inlineinitstatement,tempnode); + addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode)); + para.left:=ctemprefnode.create(tempnode); + { inherit addr_taken flag } + if (tabstractvarsym(para.parasym).addr_taken) then + include(tempnode.tempinfo^.flags,ti_addr_taken); + end; + + procedure tjvmcallnode.extra_pre_call_code; begin { when calling a constructor, first create a new instance, except diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 01efb47856..6829b7495f 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -80,12 +80,13 @@ interface protected procedure objc_convert_to_message_send;virtual; - private + protected { inlining support } inlinelocals : TFPObjectList; inlineinitstatement, inlinecleanupstatement : tstatementnode; procedure createinlineparas; + procedure wrapcomplexinlinepara(para: tcallparanode); virtual; function replaceparaload(var n: tnode; arg: pointer): foreachnoderesult; procedure createlocaltemps(p:TObject;arg:pointer); function optimize_funcret_assignment(inlineblock: tblocknode): tnode; @@ -3667,8 +3668,6 @@ implementation para: tcallparanode; tempnode: ttempcreatenode; n: tnode; - paraaddr: taddrnode; - ptrtype: tpointerdef; paracomplexity: longint; pushconstaddr: boolean; begin @@ -3802,18 +3801,7 @@ implementation { temp } else if (paracomplexity > 1) then begin - ptrtype:=getpointerdef(para.left.resultdef); - tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true)); - addstatement(inlineinitstatement,tempnode); - addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode)); - { inherit addr_taken flag } - if (tabstractvarsym(para.parasym).addr_taken) then - include(tempnode.tempinfo^.flags,ti_addr_taken); - paraaddr:=caddrnode.create_internal(para.left); - include(paraaddr.flags,nf_typedaddr); - addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode), - paraaddr)); - para.left:=cderefnode.create(ctemprefnode.create(tempnode)); + wrapcomplexinlinepara(para); end; end; para := tcallparanode(para.right); @@ -3827,6 +3815,27 @@ implementation end; + procedure tcallnode.wrapcomplexinlinepara(para: tcallparanode); + var + ptrtype: tdef; + tempnode: ttempcreatenode; + paraaddr: taddrnode; + begin + ptrtype:=getpointerdef(para.left.resultdef); + tempnode := ctempcreatenode.create(ptrtype,ptrtype.size,tt_persistent,tparavarsym(para.parasym).is_regvar(true)); + addstatement(inlineinitstatement,tempnode); + addstatement(inlinecleanupstatement,ctempdeletenode.create(tempnode)); + { inherit addr_taken flag } + if (tabstractvarsym(para.parasym).addr_taken) then + include(tempnode.tempinfo^.flags,ti_addr_taken); + paraaddr:=caddrnode.create_internal(para.left); + include(paraaddr.flags,nf_typedaddr); + addstatement(inlineinitstatement,cassignmentnode.create(ctemprefnode.create(tempnode), + paraaddr)); + para.left:=cderefnode.create(ctemprefnode.create(tempnode)); + end; + + function tcallnode.optimize_funcret_assignment(inlineblock: tblocknode): tnode; var hp : tstatementnode;