* reversed offset calculation for caller side so it works

correctly for interfaces
This commit is contained in:
peter 2003-11-28 17:24:22 +00:00
parent d1dbdbd82f
commit b26e3c444a
3 changed files with 59 additions and 33 deletions

View File

@ -317,7 +317,15 @@ unit cpupara;
and we save 6 register + 4 selectors } and we save 6 register + 4 selectors }
if po_interrupt in p.procoptions then if po_interrupt in p.procoptions then
inc(parasize,8+6*4+4*2); inc(parasize,8+6*4+4*2);
{ Assign fields } { Offset is calculated like:
sub esp,12
mov [esp+8],para3
mov [esp+4],para2
mov [esp],para1
call function
That means the for pushes the para with the
highest offset (see para3) needs to be pushed first
}
hp:=tparaitem(p.para.first); hp:=tparaitem(p.para.first);
while assigned(hp) do while assigned(hp) do
begin begin
@ -338,39 +346,34 @@ unit cpupara;
hp.paraloc[side]:=paraloc; hp.paraloc[side]:=paraloc;
hp:=tparaitem(hp.next); hp:=tparaitem(hp.next);
end; end;
{ Adapt offsets, for right-to-left calling we need to reverse the { Adapt offsets for left-to-right calling }
offsets for the caller. For left-to-right calling we need to if p.proccalloption in pushleftright_pocalls then
reverse the offsets in the callee }
if (side=callerside) then
begin
if not(p.proccalloption in pushleftright_pocalls) then
begin
hp:=tparaitem(p.para.first);
while assigned(hp) do
begin
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
varalign:=used_align(size_2_align(l),paraalign,paraalign);
l:=align(l,varalign);
hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
hp:=tparaitem(hp.next);
end;
end;
end
else
begin begin
hp:=tparaitem(p.para.first); hp:=tparaitem(p.para.first);
while assigned(hp) do while assigned(hp) do
begin begin
if (p.proccalloption in pushleftright_pocalls) then l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption);
begin varalign:=used_align(size_2_align(l),paraalign,paraalign);
l:=push_size(hp.paratyp,hp.paratype.def,p.proccalloption); l:=align(l,varalign);
varalign:=used_align(size_2_align(l),paraalign,paraalign); hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l;
l:=align(l,varalign); if side=calleeside then
hp.paraloc[side].reference.offset:=parasize-hp.paraloc[side].reference.offset-l; inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
end;
inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
hp:=tparaitem(hp.next); hp:=tparaitem(hp.next);
end; end;
end
else
begin
{ Only need to adapt the callee side to include the
standard stackframe size }
if side=calleeside then
begin
hp:=tparaitem(p.para.first);
while assigned(hp) do
begin
inc(hp.paraloc[side].reference.offset,target_info.first_parm_offset);
hp:=tparaitem(hp.next);
end;
end;
end; end;
{ We need to return the size allocated } { We need to return the size allocated }
result:=parasize; result:=parasize;
@ -497,7 +500,11 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.44 2003-11-23 17:05:16 peter Revision 1.45 2003-11-28 17:24:22 peter
* reversed offset calculation for caller side so it works
correctly for interfaces
Revision 1.44 2003/11/23 17:05:16 peter
* register calling is left-right * register calling is left-right
* parameter ordering * parameter ordering
* left-right calling inserts result parameter last * left-right calling inserts result parameter last

View File

@ -2363,9 +2363,18 @@ type
case hp.paraitem.paraloc[callerside].loc of case hp.paraitem.paraloc[callerside].loc of
LOC_REFERENCE : LOC_REFERENCE :
begin begin
{ Offset is calculated like:
sub esp,12
mov [esp+8],para3
mov [esp+4],para2
mov [esp],para1
call function
That means the for pushes the para with the
highest offset (see para3) needs to be pushed first
}
if (hpcurr.registers32>hp.registers32) if (hpcurr.registers32>hp.registers32)
{$ifdef x86} {$ifdef x86}
or (hpcurr.paraitem.paraloc[callerside].reference.offset<hp.paraitem.paraloc[callerside].reference.offset) or (hpcurr.paraitem.paraloc[callerside].reference.offset>hp.paraitem.paraloc[callerside].reference.offset)
{$endif x86} {$endif x86}
then then
break; break;
@ -2685,7 +2694,11 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.208 2003-11-23 17:05:15 peter Revision 1.209 2003-11-28 17:24:22 peter
* reversed offset calculation for caller side so it works
correctly for interfaces
Revision 1.208 2003/11/23 17:05:15 peter
* register calling is left-right * register calling is left-right
* parameter ordering * parameter ordering
* left-right calling inserts result parameter last * left-right calling inserts result parameter last

View File

@ -1354,7 +1354,9 @@ implementation
cg.a_op_const_reg(exprasmlist,OP_SUB,locpara.size,ioffset,locpara.register); cg.a_op_const_reg(exprasmlist,OP_SUB,locpara.size,ioffset,locpara.register);
LOC_REFERENCE: LOC_REFERENCE:
begin begin
reference_reset_base(href,locpara.reference.index,locpara.reference.offset); { offset in the wrapper needs to be adjusted for the stored
return address }
reference_reset_base(href,locpara.reference.index,locpara.reference.offset+POINTER_SIZE);
cg.a_op_const_ref(exprasmlist,OP_SUB,locpara.size,ioffset,href); cg.a_op_const_ref(exprasmlist,OP_SUB,locpara.size,ioffset,href);
end end
else else
@ -1368,7 +1370,11 @@ initialization
end. end.
{ {
$Log$ $Log$
Revision 1.55 2003-10-30 16:23:13 peter Revision 1.56 2003-11-28 17:24:22 peter
* reversed offset calculation for caller side so it works
correctly for interfaces
Revision 1.55 2003/10/30 16:23:13 peter
* don't search for overloads in parents for constructors * don't search for overloads in parents for constructors
Revision 1.54 2003/10/29 19:48:50 peter Revision 1.54 2003/10/29 19:48:50 peter