@@ -927,6 +927,102 @@ procedure SetClearVarToEmptyParam(var V: TVarData);
927
927
{ $IFDEF USESYSTEMDISPINVOKE}
928
928
procedure TPythonVariantType.DispInvoke (Dest: PVarData;
929
929
const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);
930
+ { $IFDEF DELPHIXE2}
931
+ // Modified to correct memory leak QC102387
932
+ procedure PatchedDispInvoke (Dest: PVarData;
933
+ const Source: TVarData; CallDesc: PCallDesc; Params: Pointer);
934
+ type
935
+ PParamRec = ^TParamRec;
936
+ TParamRec = array [0 ..3 ] of LongInt;
937
+ TStringDesc = record
938
+ BStr: WideString;
939
+ PStr: PAnsiString;
940
+ end ;
941
+ const
942
+ CDoMethod = $01 ;
943
+ CPropertyGet = $02 ;
944
+ CPropertySet = $04 ;
945
+ var
946
+ I, LArgCount: Integer;
947
+ LIdent: string;
948
+ LTemp: TVarData;
949
+ VarParams : TVarDataArray;
950
+ Strings: TStringRefList;
951
+ begin
952
+ // Grab the identifier
953
+ LArgCount := CallDesc^.ArgCount;
954
+ LIdent := FixupIdent(AnsiString(PAnsiChar(@CallDesc^.ArgTypes[LArgCount])));
955
+
956
+ FillChar(Strings, SizeOf(Strings), 0 );
957
+ VarParams := GetDispatchInvokeArgs(CallDesc, Params, Strings, true);
958
+
959
+ // What type of invoke is this?
960
+ case CallDesc^.CallType of
961
+ CDoMethod:
962
+ // procedure with N arguments
963
+ if Dest = nil then
964
+ begin
965
+ if not DoProcedure(Source, LIdent, VarParams) then
966
+ begin
967
+
968
+ // ok maybe its a function but first we must make room for a result
969
+ VarDataInit(LTemp);
970
+ try
971
+
972
+ // notate that the destination shouldn't be bothered with
973
+ // functions can still return stuff, we just do this so they
974
+ // can tell that they don't need to if they don't want to
975
+ SetClearVarToEmptyParam(LTemp);
976
+
977
+ // ok lets try for that function
978
+ if not DoFunction(LTemp, Source, LIdent, VarParams) then
979
+ RaiseDispError;
980
+ finally
981
+ VarDataClear(LTemp);
982
+ end ;
983
+ end
984
+ end
985
+
986
+ // property get or function with 0 argument
987
+ else if LArgCount = 0 then
988
+ begin
989
+ if not GetProperty(Dest^, Source, LIdent) and
990
+ not DoFunction(Dest^, Source, LIdent, VarParams) then
991
+ RaiseDispError;
992
+ end
993
+
994
+ // function with N arguments
995
+ else if not DoFunction(Dest^, Source, LIdent, VarParams) then
996
+ RaiseDispError;
997
+
998
+ CPropertyGet:
999
+ if not ((Dest <> nil ) and // there must be a dest
1000
+ (LArgCount = 0 ) and // only no args
1001
+ GetProperty(Dest^, Source, LIdent)) then // get op be valid
1002
+ RaiseDispError;
1003
+
1004
+ CPropertySet:
1005
+ if not ((Dest = nil ) and // there can't be a dest
1006
+ (LArgCount = 1 ) and // can only be one arg
1007
+ SetProperty(Source, LIdent, VarParams[0 ])) then // set op be valid
1008
+ RaiseDispError;
1009
+ else
1010
+ RaiseDispError;
1011
+ end ;
1012
+
1013
+ for I := 0 to Length(Strings) - 1 do
1014
+ begin
1015
+ if Pointer(Strings[I].Wide) = nil then
1016
+ Break;
1017
+ if Strings[I].Ansi <> nil then
1018
+ Strings[I].Ansi^ := AnsiString(Strings[I].Wide)
1019
+ else if Strings[I].Unicode <> nil then
1020
+ Strings[I].Unicode^ := UnicodeString(Strings[I].Wide)
1021
+ end ;
1022
+ for I := Low(VarParams) to High(VarParams) do
1023
+ VarDataClear(VarParams[I]);
1024
+ end ;
1025
+ { $ENDIF DELPHIXE2}
930
1026
931
1027
procedure GetNamedParams ;
932
1028
var
@@ -953,9 +1049,17 @@ procedure TPythonVariantType.DispInvoke(Dest: PVarData;
953
1049
if (CallDesc^.CallType = CPropertyGet) and (CallDesc^.ArgCount = 1 ) then begin
954
1050
NewCallDesc := CallDesc^;
955
1051
NewCallDesc.CallType := CDoMethod;
1052
+ { $IFDEF DELPHIXE2}
1053
+ PatchedDispInvoke(Dest, Source, @NewCallDesc, Params);
1054
+ { $ELSE DELPHIXE2}
956
1055
inherited DispInvoke(Dest, Source, @NewCallDesc, Params);
1056
+ { $ENDIF DELPHIXE2}
957
1057
end else
1058
+ { $IFDEF DELPHIXE2}
1059
+ PatchedDispInvoke(Dest, Source, CallDesc, Params);
1060
+ { $ELSE DELPHIXE2}
958
1061
inherited ;
1062
+ { $ENDIF DELPHIXE2}
959
1063
finally
960
1064
if CallDesc^.NamedArgCount > 0 then SetLength(fNamedParams, 0 );
961
1065
end ;
0 commit comments