mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-28 21:00:28 +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_ptr: pointer;
|
||||||
arg_data: PVarData;
|
arg_data: PVarData;
|
||||||
dummy_data: TVarData;
|
dummy_data: TVarData;
|
||||||
|
arg_advanced: boolean;
|
||||||
|
|
||||||
const
|
const
|
||||||
argtype_mask = $7F;
|
argtype_mask = $7F;
|
||||||
argref_mask = $80;
|
argref_mask = $80;
|
||||||
@ -4032,22 +4034,46 @@ begin
|
|||||||
Inc(arg_ptr,sizeof(Pointer));
|
Inc(arg_ptr,sizeof(Pointer));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
case arg_type of
|
begin
|
||||||
varError:
|
arg_advanced:=false;
|
||||||
arg_data^.vError:=VAR_PARAMNOTFOUND;
|
case arg_type of
|
||||||
varVariant:
|
varError:
|
||||||
begin
|
begin
|
||||||
|
arg_data^.vError:=VAR_PARAMNOTFOUND;
|
||||||
|
arg_advanced := true;
|
||||||
|
end;
|
||||||
|
varVariant:
|
||||||
arg_data^ := PVarData(PPointer(arg_ptr)^)^;
|
arg_data^ := PVarData(PPointer(arg_ptr)^)^;
|
||||||
Inc(arg_ptr,sizeof(Pointer));
|
varDouble, varCurrency, varDate, varInt64, varQWord:
|
||||||
end;
|
begin
|
||||||
varDouble, varCurrency, varInt64, varQWord:
|
arg_data^.vQWord := PQWord(arg_ptr)^; // 64bit on all platforms
|
||||||
begin
|
inc(arg_ptr,sizeof(QWord));
|
||||||
arg_data^.vQWord := PQWord(arg_ptr)^; // 64bit on all platforms
|
arg_advanced := true;
|
||||||
inc(arg_ptr,sizeof(qword))
|
end;
|
||||||
end
|
{ values potentially smaller than sizeof(pointer) must be handled
|
||||||
else
|
explicitly to guarantee endian safety and to prevent copying/
|
||||||
arg_data^.vAny := PPointer(arg_ptr)^; // 32 or 64bit
|
skipping data (they are always copied into a 4 byte element
|
||||||
inc(arg_ptr,sizeof(pointer))
|
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;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -49,10 +49,22 @@ function TSampleVariant.GetProperty(var Dest: TVarData; const V: TVarData;
|
|||||||
const Name: string): Boolean;
|
const Name: string): Boolean;
|
||||||
begin
|
begin
|
||||||
assert(V.VType=varType);
|
assert(V.VType=varType);
|
||||||
if Name='AnyField' then begin
|
if Name='IntField' then
|
||||||
variant(Dest) := V.VInt64;
|
begin
|
||||||
result := true;
|
variant(Dest) := V.VInt64;
|
||||||
end else
|
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;
|
result := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -60,23 +72,90 @@ function TSampleVariant.SetProperty(var V: TVarData; const Name: string;
|
|||||||
const Value: TVarData): Boolean;
|
const Value: TVarData): Boolean;
|
||||||
begin
|
begin
|
||||||
assert(V.VType=varType);
|
assert(V.VType=varType);
|
||||||
if Name='AnyField' then begin
|
if Name='IntField' then
|
||||||
PVarData(@V)^.VInt64 := variant(Value);
|
begin
|
||||||
result := true;
|
PVarData(@V)^.VInt64 := variant(Value);
|
||||||
end else
|
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;
|
result := false;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
SampleVariant: TSampleVariant;
|
SampleVariant: TSampleVariant;
|
||||||
v: Variant;
|
v: Variant;
|
||||||
|
|
||||||
|
GB1 : Byte;
|
||||||
|
GS1 : Shortint;
|
||||||
|
GW : Word;
|
||||||
|
GL : longint;
|
||||||
|
gsi : single;
|
||||||
|
gd : double;
|
||||||
|
gi64 : int64;
|
||||||
|
gdate: tdatetime;
|
||||||
|
gb: boolean;
|
||||||
begin
|
begin
|
||||||
SampleVariant:=TSampleVariant.Create;
|
SampleVariant:=TSampleVariant.Create;
|
||||||
v := null;
|
v := null;
|
||||||
TVarData(v).VType:=SampleVariant.VarType;
|
TVarData(v).VType:=SampleVariant.VarType;
|
||||||
v.AnyField := 100;
|
v.IntField := 100;
|
||||||
if v.AnyField=100 then
|
if v.IntField<>100 then
|
||||||
Halt(0)
|
|
||||||
else
|
|
||||||
halt(1);
|
halt(1);
|
||||||
|
|
||||||
|
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.
|
end.
|
Loading…
Reference in New Issue
Block a user