mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-27 12:30:31 +02:00
* 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 -
This commit is contained in:
parent
ddc7c6ed35
commit
5691da116f
@ -191,12 +191,14 @@ function tobjcmessagesendnode.pass_1: tnode;
|
|||||||
var
|
var
|
||||||
msgsendname: string;
|
msgsendname: string;
|
||||||
newparas,
|
newparas,
|
||||||
lastpara: tcallparanode;
|
para: tcallparanode;
|
||||||
block: tblocknode;
|
block: tblocknode;
|
||||||
statements: tstatementnode;
|
statements: tstatementnode;
|
||||||
temp: ttempcreatenode;
|
temp: ttempcreatenode;
|
||||||
objcsupertype: tdef;
|
objcsupertype: tdef;
|
||||||
field: tfieldvarsym;
|
field: tfieldvarsym;
|
||||||
|
selfpara,
|
||||||
|
msgselpara: tcallparanode;
|
||||||
begin
|
begin
|
||||||
{ pass1 of left has already run, see constructor }
|
{ pass1 of left has already run, see constructor }
|
||||||
|
|
||||||
@ -228,12 +230,22 @@ function tobjcmessagesendnode.pass_1: tnode;
|
|||||||
msgsendname:='OBJC_MSGSENDSUPER';
|
msgsendname:='OBJC_MSGSENDSUPER';
|
||||||
|
|
||||||
newparas:=tcallparanode(tcallnode(left).left);
|
newparas:=tcallparanode(tcallnode(left).left);
|
||||||
{ parameters are chained from right to left, and we have to insert the two
|
{ Find the self and msgsel parameters. }
|
||||||
first parameters (self and selector) -> walk to the end of the chain
|
para:=newparas;
|
||||||
}
|
selfpara:=nil;
|
||||||
lastpara:=newparas;
|
msgselpara:=nil;
|
||||||
while assigned(lastpara.right) do
|
while assigned(para) do
|
||||||
lastpara:=tcallparanode(lastpara.right);
|
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 }
|
{ Handle self }
|
||||||
{ 1) If we're calling a class method, use a class ref. }
|
{ 1) If we're calling a class method, use a class ref. }
|
||||||
if (po_classmethod in tcallnode(left).procdefinition.procoptions) and
|
if (po_classmethod in tcallnode(left).procdefinition.procoptions) and
|
||||||
@ -283,12 +295,15 @@ function tobjcmessagesendnode.pass_1: tnode;
|
|||||||
tcallnode(left).methodpointer:=block;
|
tcallnode(left).methodpointer:=block;
|
||||||
typecheckpass(block);
|
typecheckpass(block);
|
||||||
end;
|
end;
|
||||||
lastpara.right:=ccallparanode.create(tcallnode(left).methodpointer,nil);
|
{ replace self parameter }
|
||||||
{ insert selector }
|
selfpara.left.free;
|
||||||
lastpara.right:=ccallparanode.create(
|
selfpara.left:=tcallnode(left).methodpointer;
|
||||||
|
{ replace selector parameter }
|
||||||
|
msgselpara.left.Free;
|
||||||
|
msgselpara.left:=
|
||||||
cobjcselectornode.create(
|
cobjcselectornode.create(
|
||||||
cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^)),
|
cstringconstnode.createstr(tprocdef(tcallnode(left).procdefinition).messageinf.str^)
|
||||||
lastpara.right);
|
);
|
||||||
{ parameters are reused -> make sure they don't get freed }
|
{ parameters are reused -> make sure they don't get freed }
|
||||||
tcallnode(left).left:=nil;
|
tcallnode(left).left:=nil;
|
||||||
{ methodpointer is also reused }
|
{ methodpointer is also reused }
|
||||||
|
Loading…
Reference in New Issue
Block a user