* Fix methodpointer copy from callnode to loadnode

This commit is contained in:
michael 2005-04-06 11:49:37 +00:00
parent cdafbb3288
commit 55e76063df
5 changed files with 60 additions and 24 deletions

View File

@ -529,7 +529,8 @@ uses
begin begin
GetToken:=''; GetToken:='';
s:=TrimSpace(s); s:=TrimSpace(s);
if s[1]='''' then if (length(s)>0) and
(s[1]='''') then
begin begin
i:=1; i:=1;
while (i<length(s)) do while (i<length(s)) do
@ -1239,7 +1240,10 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.50 2005-03-04 16:49:22 peter Revision 1.51 2005-04-06 11:49:37 michael
* Fix methodpointer copy from callnode to loadnode
Revision 1.50 2005/03/04 16:49:22 peter
* getheapstatus fixes * getheapstatus fixes
Revision 1.49 2005/02/14 17:13:06 peter Revision 1.49 2005/02/14 17:13:06 peter

View File

@ -134,6 +134,7 @@ interface
function docompare(p: tnode): boolean; override; function docompare(p: tnode): boolean; override;
procedure printnodedata(var t:text);override; procedure printnodedata(var t:text);override;
function para_count:longint; function para_count:longint;
function get_load_methodpointer:tnode;
private private
AbstractMethodsList : TStringList; AbstractMethodsList : TStringList;
end; end;
@ -286,8 +287,17 @@ type
loadp)); loadp));
{ new tree is only a temp reference } { new tree is only a temp reference }
p:=refp; p:=refp;
{ temp release } { temp release. We need to return a reference to the methodpointer
addstatement(newdonestatement,ctempdeletenode.create(ptemp)); otherwise the conversion from callnode to loadnode can't be done
for the methodpointer unless the loadnode will also get a methodpointerinit and
methodpointerdone node. For the moment we use register as temp and therefor
don't create a temp-leak in the stackframe (PFV) }
{ the last statement should return the value as
location and type, this is done be referencing the
temp and converting it first from a persistent temp to
normal temp }
addstatement(newdonestatement,ctempdeletenode.create_normal_temp(ptemp));
addstatement(newdonestatement,ctemprefnode.create(ptemp));
{ call resulttypepass for new nodes } { call resulttypepass for new nodes }
resulttypepass(p); resulttypepass(p);
resulttypepass(aktcallnode.methodpointerinit); resulttypepass(aktcallnode.methodpointerinit);
@ -1650,7 +1660,7 @@ type
begin begin
hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc); hpt:=cloadnode.create(tprocsym(symtableprocentry),symtableproc);
if assigned(methodpointer) then if assigned(methodpointer) then
tloadnode(hpt).set_mp(methodpointer.getcopy); tloadnode(hpt).set_mp(get_load_methodpointer);
resulttypepass(hpt); resulttypepass(hpt);
result:=hpt; result:=hpt;
end end
@ -2510,6 +2520,28 @@ type
end; end;
function tcallnode.get_load_methodpointer:tnode;
var
newstatement : tstatementnode;
begin
if assigned(methodpointerinit) then
begin
result:=internalstatements(newstatement);
addstatement(newstatement,methodpointerinit);
addstatement(newstatement,methodpointer);
addstatement(newstatement,methodpointerdone);
methodpointerinit:=nil;
methodpointer:=nil;
methodpointerdone:=nil;
end
else
begin
result:=methodpointer;
methodpointer:=nil;
end;
end;
function tcallnode.docompare(p: tnode): boolean; function tcallnode.docompare(p: tnode): boolean;
begin begin
docompare := docompare :=
@ -2547,7 +2579,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.283 2005-04-05 21:07:43 peter Revision 1.284 2005-04-06 11:49:37 michael
* Fix methodpointer copy from callnode to loadnode
Revision 1.283 2005/04/05 21:07:43 peter
* load all complex loads of parameters that are needed multiple times * load all complex loads of parameters that are needed multiple times
to a temp to prevent calling functions twice to a temp to prevent calling functions twice

View File

@ -1509,16 +1509,7 @@ implementation
if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) then if (tcallnode(left).symtableprocentry.owner.symtabletype=objectsymtable) then
begin begin
if assigned(tcallnode(left).methodpointer) then if assigned(tcallnode(left).methodpointer) then
begin tloadnode(hp).set_mp(tcallnode(left).get_load_methodpointer)
{ Under certain circumstances the methodpointer is a loadvmtaddrn
which isn't possible if it is used as a method pointer, so
fix this.
If you change this, ensure that tests/tbs/tw2669.pp still works }
if tcallnode(left).methodpointer.nodetype=loadvmtaddrn then
tloadnode(hp).set_mp(tloadvmtaddrnode(tcallnode(left).methodpointer).left.getcopy)
else
tloadnode(hp).set_mp(tcallnode(left).methodpointer.getcopy);
end
else else
tloadnode(hp).set_mp(load_self_node); tloadnode(hp).set_mp(load_self_node);
end; end;
@ -2654,7 +2645,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.180 2005-03-25 22:20:18 peter Revision 1.181 2005-04-06 11:49:37 michael
* Fix methodpointer copy from callnode to loadnode
Revision 1.180 2005/03/25 22:20:18 peter
* add hint when passing an uninitialized variable to a var parameter * add hint when passing an uninitialized variable to a var parameter
Revision 1.179 2005/03/11 21:55:43 florian Revision 1.179 2005/03/11 21:55:43 florian

View File

@ -213,10 +213,7 @@ implementation
method without a self pointer } method without a self pointer }
if assigned(tcallnode(p1).methodpointer) and if assigned(tcallnode(p1).methodpointer) and
(tcallnode(p1).methodpointer.nodetype<>typen) then (tcallnode(p1).methodpointer.nodetype<>typen) then
begin tloadnode(p2).set_mp(tcallnode(p1).get_load_methodpointer);
tloadnode(p2).set_mp(tcallnode(p1).methodpointer);
tcallnode(p1).methodpointer:=nil;
end;
end; end;
resulttypepass(p2); resulttypepass(p2);
p1.free; p1.free;
@ -567,7 +564,10 @@ end.
{ {
$Log$ $Log$
Revision 1.30 2005-02-14 17:13:06 peter Revision 1.31 2005-04-06 11:49:37 michael
* Fix methodpointer copy from callnode to loadnode
Revision 1.30 2005/02/14 17:13:06 peter
* truncate log * truncate log
Revision 1.29 2005/01/04 16:39:46 peter Revision 1.29 2005/01/04 16:39:46 peter

View File

@ -946,7 +946,7 @@ implementation
begin begin
hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc); hp2:=cloadnode.create_procvar(tprocsym(tcallnode(hp).symtableprocentry),currprocdef,tcallnode(hp).symtableproc);
if (po_methodpointer in pv.procoptions) then if (po_methodpointer in pv.procoptions) then
tloadnode(hp2).set_mp(tnode(tcallnode(hp).methodpointer).getcopy); tloadnode(hp2).set_mp(tcallnode(hp).get_load_methodpointer);
hp.destroy; hp.destroy;
{ replace the old callnode with the new loadnode } { replace the old callnode with the new loadnode }
hpp^:=hp2; hpp^:=hp2;
@ -2619,7 +2619,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.188 2005-03-28 14:14:52 florian Revision 1.189 2005-04-06 11:49:37 michael
* Fix methodpointer copy from callnode to loadnode
Revision 1.188 2005/03/28 14:14:52 florian
* fpc_variant_get call fixed * fpc_variant_get call fixed
Revision 1.187 2005/03/27 20:19:21 florian Revision 1.187 2005/03/27 20:19:21 florian