mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 06:08:16 +02:00
* fixed big endian bugs in variant dispatching
* fixed size calculation of vardatetime arguments on 32 bit systems with variant dispatching git-svn-id: trunk@29319 -
This commit is contained in:
parent
ee82b6ea0b
commit
476e3fabb7
@ -4004,6 +4004,8 @@ var
|
||||
arg_ptr: pointer;
|
||||
arg_data: PVarData;
|
||||
dummy_data: TVarData;
|
||||
arg_advanced: boolean;
|
||||
|
||||
const
|
||||
argtype_mask = $7F;
|
||||
argref_mask = $80;
|
||||
@ -4032,22 +4034,46 @@ begin
|
||||
Inc(arg_ptr,sizeof(Pointer));
|
||||
end
|
||||
else
|
||||
case arg_type of
|
||||
varError:
|
||||
arg_data^.vError:=VAR_PARAMNOTFOUND;
|
||||
varVariant:
|
||||
begin
|
||||
begin
|
||||
arg_advanced:=false;
|
||||
case arg_type of
|
||||
varError:
|
||||
begin
|
||||
arg_data^.vError:=VAR_PARAMNOTFOUND;
|
||||
arg_advanced := true;
|
||||
end;
|
||||
varVariant:
|
||||
arg_data^ := PVarData(PPointer(arg_ptr)^)^;
|
||||
Inc(arg_ptr,sizeof(Pointer));
|
||||
end;
|
||||
varDouble, varCurrency, varInt64, varQWord:
|
||||
begin
|
||||
arg_data^.vQWord := PQWord(arg_ptr)^; // 64bit on all platforms
|
||||
inc(arg_ptr,sizeof(qword))
|
||||
end
|
||||
else
|
||||
arg_data^.vAny := PPointer(arg_ptr)^; // 32 or 64bit
|
||||
inc(arg_ptr,sizeof(pointer))
|
||||
varDouble, varCurrency, varDate, varInt64, varQWord:
|
||||
begin
|
||||
arg_data^.vQWord := PQWord(arg_ptr)^; // 64bit on all platforms
|
||||
inc(arg_ptr,sizeof(QWord));
|
||||
arg_advanced := true;
|
||||
end;
|
||||
{ values potentially smaller than sizeof(pointer) must be handled
|
||||
explicitly to guarantee endian safety and to prevent copying/
|
||||
skipping data (they are always copied into a 4 byte element
|
||||
by the compiler, although it will still skip sizeof(pointer)
|
||||
bytes afterwards) }
|
||||
varSingle:
|
||||
arg_data^.vSingle := PSingle(arg_ptr)^;
|
||||
varSmallint:
|
||||
arg_data^.vSmallInt := PLongint(arg_ptr)^;
|
||||
varInteger:
|
||||
arg_data^.vInteger := PLongint(arg_ptr)^;
|
||||
varBoolean:
|
||||
arg_data^.vBoolean := WordBool(PLongint(arg_ptr)^);
|
||||
varShortInt:
|
||||
arg_data^.vShortInt := PLongint(arg_ptr)^;
|
||||
varByte:
|
||||
arg_data^.vByte := PLongint(arg_ptr)^;
|
||||
varWord:
|
||||
arg_data^.vWord := PLongint(arg_ptr)^;
|
||||
else
|
||||
arg_data^.vAny := PPointer(arg_ptr)^; // 32 or 64bit
|
||||
end;
|
||||
if not arg_advanced then
|
||||
inc(arg_ptr,sizeof(pointer));
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -49,10 +49,22 @@ function TSampleVariant.GetProperty(var Dest: TVarData; const V: TVarData;
|
||||
const Name: string): Boolean;
|
||||
begin
|
||||
assert(V.VType=varType);
|
||||
if Name='AnyField' then begin
|
||||
variant(Dest) := V.VInt64;
|
||||
result := true;
|
||||
end else
|
||||
if Name='IntField' then
|
||||
begin
|
||||
variant(Dest) := V.VInt64;
|
||||
result := true;
|
||||
end
|
||||
else if Name='FloatField' then
|
||||
begin
|
||||
variant(Dest) := V.VDouble;
|
||||
result := true;
|
||||
end
|
||||
else if Name='BoolField' then
|
||||
begin
|
||||
variant(Dest) := V.VBoolean;
|
||||
result := true;
|
||||
end
|
||||
else
|
||||
result := false;
|
||||
end;
|
||||
|
||||
@ -60,23 +72,90 @@ function TSampleVariant.SetProperty(var V: TVarData; const Name: string;
|
||||
const Value: TVarData): Boolean;
|
||||
begin
|
||||
assert(V.VType=varType);
|
||||
if Name='AnyField' then begin
|
||||
PVarData(@V)^.VInt64 := variant(Value);
|
||||
result := true;
|
||||
end else
|
||||
if Name='IntField' then
|
||||
begin
|
||||
PVarData(@V)^.VInt64 := variant(Value);
|
||||
result := true;
|
||||
end
|
||||
else if Name='FloatField' then
|
||||
begin
|
||||
PVarData(@V)^.VDouble := variant(Value);
|
||||
result := true;
|
||||
end
|
||||
else if Name='BoolField' then
|
||||
begin
|
||||
PVarData(@V)^.VBoolean := variant(Value);
|
||||
result := true;
|
||||
end
|
||||
else
|
||||
result := false;
|
||||
end;
|
||||
|
||||
var
|
||||
SampleVariant: TSampleVariant;
|
||||
v: Variant;
|
||||
|
||||
GB1 : Byte;
|
||||
GS1 : Shortint;
|
||||
GW : Word;
|
||||
GL : longint;
|
||||
gsi : single;
|
||||
gd : double;
|
||||
gi64 : int64;
|
||||
gdate: tdatetime;
|
||||
gb: boolean;
|
||||
begin
|
||||
SampleVariant:=TSampleVariant.Create;
|
||||
v := null;
|
||||
TVarData(v).VType:=SampleVariant.VarType;
|
||||
v.AnyField := 100;
|
||||
if v.AnyField=100 then
|
||||
Halt(0)
|
||||
else
|
||||
v.IntField := 100;
|
||||
if v.IntField<>100 then
|
||||
halt(1);
|
||||
end.
|
||||
|
||||
gb1:=128;
|
||||
gs1:=127;
|
||||
gw:=32768;
|
||||
gl:=longint($b100dbad);
|
||||
gsi:=12345789.5;
|
||||
gd:=999991234889879.5;
|
||||
gi64:=$813245678901234;
|
||||
gdate:=now;
|
||||
gb:=false;
|
||||
|
||||
v.IntField:=gb1;
|
||||
if v.IntField<>gb1 then
|
||||
halt(2);
|
||||
|
||||
v.IntField:=gs1;
|
||||
if v.IntField<>gs1 then
|
||||
halt(3);
|
||||
|
||||
v.IntField:=gw;
|
||||
if v.IntField<>gw then
|
||||
halt(4);
|
||||
|
||||
v.IntField:=gl;
|
||||
if v.IntField<>gl then
|
||||
halt(5);
|
||||
|
||||
v.FloatField:=gsi;
|
||||
if v.FloatField<>gsi then
|
||||
halt(6);
|
||||
|
||||
v.FloatField:=gd;
|
||||
if v.FloatField<>gd then
|
||||
halt(7);
|
||||
|
||||
v.IntField:=gi64;
|
||||
if v.IntField<>gi64 then
|
||||
halt(8);
|
||||
|
||||
v.FloatField:=gdate;
|
||||
if v.FloatField<>gdate then
|
||||
halt(9);
|
||||
|
||||
v.BoolField:=gb;
|
||||
if boolean(v.BoolField)<>gb then
|
||||
halt(10);
|
||||
|
||||
end.
|
||||
|
Loading…
Reference in New Issue
Block a user