Browse Source

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

Jonas Maebe 14 years ago
parent
commit
6a7ff1cf75
2 changed files with 46 additions and 17 deletions
  1. 22 2
      compiler/jvm/njvmcal.pas
  2. 24 15
      compiler/ncal.pas

+ 22 - 2
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

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