From 5691da116f099d5f68391d423e2ff447b329adc4 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 18 May 2009 15:13:36 +0000 Subject: [PATCH] * replace the contents of the dummy self and msgsel parameters when transforming objc-calls, rather than adding new such parameters (fixes calling objc-methods on ppc) git-svn-id: branches/objc@13174 - --- compiler/nobjc.pas | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/compiler/nobjc.pas b/compiler/nobjc.pas index 9ecb266c29..7e40435e99 100644 --- a/compiler/nobjc.pas +++ b/compiler/nobjc.pas @@ -191,12 +191,14 @@ function tobjcmessagesendnode.pass_1: tnode; var msgsendname: string; newparas, - lastpara: tcallparanode; + para: tcallparanode; block: tblocknode; statements: tstatementnode; temp: ttempcreatenode; objcsupertype: tdef; field: tfieldvarsym; + selfpara, + msgselpara: tcallparanode; begin { pass1 of left has already run, see constructor } @@ -228,12 +230,22 @@ function tobjcmessagesendnode.pass_1: tnode; msgsendname:='OBJC_MSGSENDSUPER'; newparas:=tcallparanode(tcallnode(left).left); - { parameters are chained from right to left, and we have to insert the two - first parameters (self and selector) -> walk to the end of the chain - } - lastpara:=newparas; - while assigned(lastpara.right) do - lastpara:=tcallparanode(lastpara.right); + { Find the self and msgsel parameters. } + para:=newparas; + selfpara:=nil; + msgselpara:=nil; + while assigned(para) do + begin + if (vo_is_self in para.parasym.varoptions) then + selfpara:=para + else if (vo_is_msgsel in para.parasym.varoptions) then + msgselpara:=para; + para:=tcallparanode(para.right); + end; + if not assigned(selfpara) then + internalerror(2009051801); + if not assigned(msgselpara) then + internalerror(2009051802); { Handle self } { 1) If we're calling a class method, use a class ref. } if (po_classmethod in tcallnode(left).procdefinition.procoptions) and @@ -283,12 +295,15 @@ function tobjcmessagesendnode.pass_1: tnode; tcallnode(left).methodpointer:=block; typecheckpass(block); end; - lastpara.right:=ccallparanode.create(tcallnode(left).methodpointer,nil); - { insert selector } - lastpara.right:=ccallparanode.create( + { replace self parameter } + selfpara.left.free; + selfpara.left:=tcallnode(left).methodpointer; + { replace selector parameter } + msgselpara.left.Free; + msgselpara.left:= cobjcselectornode.create( - cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^)), - lastpara.right); + cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^) + ); { parameters are reused -> make sure they don't get freed } tcallnode(left).left:=nil; { methodpointer is also reused }