diff --git a/Source/uPSRuntime.pas b/Source/uPSRuntime.pas index d22c6182..0212cdb3 100644 --- a/Source/uPSRuntime.pas +++ b/Source/uPSRuntime.pas @@ -9159,7 +9159,8 @@ function TPSExec.RunScript: Boolean; bts64: dec(tbts64(vd.P^)); btU64: dec(tbtu64(vd.P^)); {$ENDIF} - btVariant: dec(Variant(vd.P^)); + // Inc/Dec on a Variant is Delphi-only; +/- 1 works on FPC too + btVariant: Variant(vd.P^) := Variant(vd.P^) - 1; else begin CMD_Err(ErTypeMismatch); @@ -9192,7 +9193,8 @@ function TPSExec.RunScript: Boolean; bts64: Inc(tbts64(vd.P^)); btU64: Inc(tbtu64(vd.P^)); {$ENDIF} - btVariant: Inc(Variant(vd.P^)); + // Inc/Dec on a Variant is Delphi-only; +/- 1 works on FPC too + btVariant: Variant(vd.P^) := Variant(vd.P^) + 1; else begin CMD_Err(ErTypeMismatch); @@ -12473,6 +12475,55 @@ function ParamAsVariable(const Modifier: tbtchar; aType: TPSTypeRec): Boolean; Result := (Modifier = '%') or (Modifier = '!') or AlwaysAsVariable(aType); end; +{ implementation must stay outside the empty_methods_handler region below: + the interface declares it unconditionally } +function ResultAsRegister(b: TPSTypeRec): Boolean; +begin + case b.BaseType of + btSingle, + btDouble, + btExtended, + btCurrency, + btU8, + bts8, + bts16, + btu16, + bts32, + btu32, +{$IFDEF PS_FPCSTRINGWORKAROUND} + btString, +{$ENDIF} +{$IFNDEF PS_NOINT64} + bts64, + btU64, +{$ENDIF} + btPChar, +{$IFNDEF PS_NOWIDESTRING} + btWideChar, +{$ENDIF} + btChar, + btclass, + btEnum: Result := true; +{$IFDEF DELPHI} + { The Delphi x64 ABI returns a record of 1, 2, or 4 bytes in RAX, and + the x86 ABI a record of 1 or 2 bytes in AL/AX (see System.Rtti's + UseResultPointer). Records of these sizes never contain a managed + field, so no managed check is needed. A record of pointer size is + also returned in RAX/EAX, but only when it contains no managed + field. Static arrays follow the same rule: UseResultPointer treats + tkArray like tkRecord. } + btRecord, btStaticArray: Result := (b.RealSize in [1, 2{$IFDEF CPU64}, 4{$ENDIF}]) or + ((b.RealSize = PointerSize) and not IsManagedType(b)); +{$ENDIF} + btSet: Result := b.RealSize <= PointerSize; +{$IFNDEF DELPHI} + btStaticArray: Result := b.RealSize <= PointerSize; +{$ENDIF} + else + Result := false; + end; +end; + {$ifdef fpc} {$if defined(cpupowerpc) or defined(cpuarm) or defined(cpu64)} {$define empty_methods_handler} @@ -12617,53 +12668,6 @@ procedure MyAllMethodsHandler; {$ENDIF} {$endif CPU64} -function ResultAsRegister(b: TPSTypeRec): Boolean; -begin - case b.BaseType of - btSingle, - btDouble, - btExtended, - btCurrency, - btU8, - bts8, - bts16, - btu16, - bts32, - btu32, -{$IFDEF PS_FPCSTRINGWORKAROUND} - btString, -{$ENDIF} -{$IFNDEF PS_NOINT64} - bts64, - btU64, -{$ENDIF} - btPChar, -{$IFNDEF PS_NOWIDESTRING} - btWideChar, -{$ENDIF} - btChar, - btclass, - btEnum: Result := true; -{$IFDEF DELPHI} - { The Delphi x64 ABI returns a record of 1, 2, or 4 bytes in RAX, and - the x86 ABI a record of 1 or 2 bytes in AL/AX (see System.Rtti's - UseResultPointer). Records of these sizes never contain a managed - field, so no managed check is needed. A record of pointer size is - also returned in RAX/EAX, but only when it contains no managed - field. Static arrays follow the same rule: UseResultPointer treats - tkArray like tkRecord. } - btRecord, btStaticArray: Result := (b.RealSize in [1, 2{$IFDEF CPU64}, 4{$ENDIF}]) or - ((b.RealSize = PointerSize) and not IsManagedType(b)); -{$ENDIF} - btSet: Result := b.RealSize <= PointerSize; -{$IFNDEF DELPHI} - btStaticArray: Result := b.RealSize <= PointerSize; -{$ENDIF} - else - Result := false; - end; -end; - function SupportsRegister(b: TPSTypeRec): Boolean; begin case b.BaseType of