* 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 -
This commit is contained in:
Jonas Maebe 2011-08-29 22:58:55 +00:00
parent 49817c9a0e
commit 6a7ff1cf75
2 changed files with 46 additions and 17 deletions

View File

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

View File

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