mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-18 05:00:07 +02:00
* correctly handle non-static functions where the result is passed as a parameter (the order is "Self/VMT, Result, other Args" there)
git-svn-id: trunk@37387 -
This commit is contained in:
parent
98bb449945
commit
5edbdd5a00
@ -315,12 +315,15 @@ var
|
||||
argindirect: array of Pointer;
|
||||
rtype: pffi_type;
|
||||
rvalue: ffi_arg;
|
||||
i, arglen, argoffset: LongInt;
|
||||
i, arglen, argoffset, retidx, argstart: LongInt;
|
||||
cif: ffi_cif;
|
||||
retparam: Boolean;
|
||||
begin
|
||||
aResultValue := TValue.Empty;
|
||||
|
||||
if not (fcfStatic in aFlags) and (Length(aArgs) = 0) then
|
||||
raise EInvocationError.Create(SErrMissingSelfParam);
|
||||
|
||||
case aCallConv of
|
||||
{$if defined(CPUI386)}
|
||||
ccReg:
|
||||
@ -358,22 +361,36 @@ begin
|
||||
if retparam then begin
|
||||
Inc(arglen);
|
||||
argoffset := 1;
|
||||
end else
|
||||
retidx := 0;
|
||||
end else begin
|
||||
argoffset := 0;
|
||||
retidx := -1;
|
||||
end;
|
||||
|
||||
SetLength(argtypes, arglen);
|
||||
SetLength(argvalues, arglen);
|
||||
SetLength(argindirect, arglen);
|
||||
|
||||
for i := Low(aArgs) to High(aArgs) do begin
|
||||
{ the order is Self/Vmt (if any), Result param (if any), other params }
|
||||
|
||||
if not (fcfStatic in aFlags) and retparam then begin
|
||||
argtypes[0] := TypeInfoToFFIType(aArgs[0].Value.TypeInfo);
|
||||
argvalues[0] := ValueToFFIValue(aArgs[0].Value, argindirect[0], False);
|
||||
if retparam then
|
||||
Inc(retidx);
|
||||
argstart := 1;
|
||||
end else
|
||||
argstart := 0;
|
||||
|
||||
for i := Low(aArgs) + argstart to High(aArgs) do begin
|
||||
argtypes[i - Low(aArgs) + Low(argtypes) + argoffset] := TypeInfoToFFIType(aArgs[i].Value.TypeInfo);
|
||||
argvalues[i - Low(aArgs) + Low(argtypes) + argoffset] := ValueToFFIValue(aArgs[i].Value, argindirect[i + argoffset], False);
|
||||
end;
|
||||
|
||||
if retparam then begin
|
||||
argtypes[0] := TypeInfoToFFIType(aResultType);
|
||||
argtypes[retidx] := TypeInfoToFFIType(aResultType);
|
||||
TValue.Make(Nil, aResultType, aResultValue);
|
||||
argvalues[0] := ValueToFFIValue(aResultValue, argindirect[0], True);
|
||||
argvalues[retidx] := ValueToFFIValue(aResultValue, argindirect[retidx], True);
|
||||
rtype := @ffi_type_void;
|
||||
end else begin
|
||||
rtype := TypeInfoToFFIType(aResultType);
|
||||
|
Loading…
Reference in New Issue
Block a user