@@ -927,6 +927,102 @@ procedure SetClearVarToEmptyParam(var V: TVarData);
927927{ $IFDEF USESYSTEMDISPINVOKE}
928928procedure TPythonVariantType.DispInvoke (Dest: PVarData;
929929 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}
9301026
9311027 procedure GetNamedParams ;
9321028 var
@@ -953,9 +1049,17 @@ procedure TPythonVariantType.DispInvoke(Dest: PVarData;
9531049 if (CallDesc^.CallType = CPropertyGet) and (CallDesc^.ArgCount = 1 ) then begin
9541050 NewCallDesc := CallDesc^;
9551051 NewCallDesc.CallType := CDoMethod;
1052+ { $IFDEF DELPHIXE2}
1053+ PatchedDispInvoke(Dest, Source, @NewCallDesc, Params);
1054+ { $ELSE DELPHIXE2}
9561055 inherited DispInvoke(Dest, Source, @NewCallDesc, Params);
1056+ { $ENDIF DELPHIXE2}
9571057 end else
1058+ { $IFDEF DELPHIXE2}
1059+ PatchedDispInvoke(Dest, Source, CallDesc, Params);
1060+ { $ELSE DELPHIXE2}
9581061 inherited ;
1062+ { $ENDIF DELPHIXE2}
9591063 finally
9601064 if CallDesc^.NamedArgCount > 0 then SetLength(fNamedParams, 0 );
9611065 end ;
0 commit comments