mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-08 17:17:10 +01:00
* Fixed parameter generation for dispatch calls: assuming that everything is passed by reference and needs only sizeof(ptruint) bytes is wrong. 64-bit primitive types (Double,Int64) are passed by value and require twice more space on 32-bit platforms.
git-svn-id: trunk@16350 -
This commit is contained in:
parent
6a4ea03acb
commit
2d860e356c
@ -295,7 +295,6 @@ implementation
|
|||||||
assignmenttype,
|
assignmenttype,
|
||||||
vardatadef,
|
vardatadef,
|
||||||
pvardatadef : tdef;
|
pvardatadef : tdef;
|
||||||
dispatchbyref : boolean;
|
|
||||||
useresult: boolean;
|
useresult: boolean;
|
||||||
restype: byte;
|
restype: byte;
|
||||||
|
|
||||||
@ -313,18 +312,23 @@ implementation
|
|||||||
dispintfinvoke,
|
dispintfinvoke,
|
||||||
variantdispatch : boolean;
|
variantdispatch : boolean;
|
||||||
|
|
||||||
procedure increase_paramssize;
|
function is_byref_para(out assign_type: tdef): boolean;
|
||||||
begin
|
begin
|
||||||
{ for now we pass everything by reference
|
// !! This condition is subject to change, see Mantis #17904
|
||||||
case para.left.resultdef.typ of
|
result:=(assigned(para.parasym) and (para.parasym.varspez in [vs_var,vs_out,vs_constref])) or
|
||||||
variantdef:
|
(para.left.resultdef.typ in [variantdef]);
|
||||||
inc(paramssize,para.left.resultdef.size);
|
|
||||||
else
|
if result then
|
||||||
}
|
assign_type:=voidpointertype
|
||||||
inc(paramssize,voidpointertype.size);
|
else
|
||||||
{
|
case para.left.resultdef.size of
|
||||||
end;
|
1..4:
|
||||||
}
|
assign_type:=u32inttype;
|
||||||
|
8:
|
||||||
|
assign_type:=u64inttype;
|
||||||
|
else
|
||||||
|
internalerror(2007042801);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getvardef(sourcedef: TDef): longint;
|
function getvardef(sourcedef: TDef): longint;
|
||||||
@ -412,7 +416,8 @@ implementation
|
|||||||
CGMessagePos1(para.left.fileinfo,type_e_not_automatable,para.left.resultdef.typename);
|
CGMessagePos1(para.left.fileinfo,type_e_not_automatable,para.left.resultdef.typename);
|
||||||
|
|
||||||
{ we've to know the parameter size to allocate the temp. space }
|
{ we've to know the parameter size to allocate the temp. space }
|
||||||
increase_paramssize;
|
is_byref_para(assignmenttype);
|
||||||
|
inc(paramssize, assignmenttype.size);
|
||||||
|
|
||||||
para:=tcallparanode(para.nextpara);
|
para:=tcallparanode(para.nextpara);
|
||||||
end;
|
end;
|
||||||
@ -461,41 +466,29 @@ implementation
|
|||||||
internalerror(200611041);
|
internalerror(200611041);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
dispatchbyref:=(assigned(para.parasym) and (para.parasym.varspez in [vs_var,vs_out,vs_constref])) or
|
calldesc.argtypes[currargpos]:=getvardef(para.left.resultdef);
|
||||||
(para.left.resultdef.typ in [variantdef]);
|
|
||||||
|
|
||||||
{ assign the argument/parameter to the temporary location }
|
{ assign the argument/parameter to the temporary location }
|
||||||
|
|
||||||
if dispatchbyref then
|
if is_byref_para(assignmenttype) then
|
||||||
|
begin
|
||||||
|
addstatement(statements,cassignmentnode.create(
|
||||||
|
ctypeconvnode.create_internal(cderefnode.create(caddnode.create(addn,
|
||||||
|
caddrnode.create(ctemprefnode.create(params)),
|
||||||
|
cordconstnode.create(qword(paramssize),ptruinttype,false)
|
||||||
|
)),voidpointertype),
|
||||||
|
ctypeconvnode.create_internal(caddrnode.create_internal(para.left),voidpointertype)));
|
||||||
|
calldesc.argtypes[currargpos]:=calldesc.argtypes[currargpos] or $80;
|
||||||
|
end
|
||||||
|
else
|
||||||
addstatement(statements,cassignmentnode.create(
|
addstatement(statements,cassignmentnode.create(
|
||||||
ctypeconvnode.create_internal(cderefnode.create(caddnode.create(addn,
|
ctypeconvnode.create_internal(cderefnode.create(caddnode.create(addn,
|
||||||
caddrnode.create(ctemprefnode.create(params)),
|
caddrnode.create(ctemprefnode.create(params)),
|
||||||
cordconstnode.create(qword(paramssize),ptruinttype,false)
|
cordconstnode.create(paramssize,ptruinttype,false)
|
||||||
)),voidpointertype),
|
)),assignmenttype),
|
||||||
ctypeconvnode.create_internal(caddrnode.create_internal(para.left),voidpointertype)))
|
ctypeconvnode.create_internal(para.left,assignmenttype)));
|
||||||
else
|
|
||||||
begin
|
|
||||||
case para.left.resultdef.size of
|
|
||||||
1..4:
|
|
||||||
assignmenttype:=u32inttype;
|
|
||||||
8:
|
|
||||||
assignmenttype:=u64inttype;
|
|
||||||
else
|
|
||||||
internalerror(2007042801);
|
|
||||||
end;
|
|
||||||
addstatement(statements,cassignmentnode.create(
|
|
||||||
ctypeconvnode.create_internal(cderefnode.create(caddnode.create(addn,
|
|
||||||
caddrnode.create(ctemprefnode.create(params)),
|
|
||||||
cordconstnode.create(paramssize,ptruinttype,false)
|
|
||||||
)),assignmenttype),
|
|
||||||
ctypeconvnode.create_internal(para.left,assignmenttype)));
|
|
||||||
end;
|
|
||||||
|
|
||||||
calldesc.argtypes[currargpos]:=getvardef(para.left.resultdef);
|
inc(paramssize,assignmenttype.size);
|
||||||
if dispatchbyref then
|
|
||||||
calldesc.argtypes[currargpos]:=calldesc.argtypes[currargpos] or $80;
|
|
||||||
|
|
||||||
increase_paramssize;
|
|
||||||
|
|
||||||
para.left:=nil;
|
para.left:=nil;
|
||||||
inc(currargpos);
|
inc(currargpos);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user