1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-06-02 21:57:37 +02:00

Fixed issue #547 : Render process crash in the JSRTTIExtension demo

This commit is contained in:
Salvador Díaz Fau 2025-02-22 15:46:39 +01:00
parent 7deeeac5aa
commit 0ce22061ae
4 changed files with 134 additions and 93 deletions

View File

@ -20,6 +20,7 @@ uses
uCEFTypes, uCEFSchemeRegistrar;
type
ICefBaseRefCounted = interface;
ICefBrowser = interface;
ICefFrame = interface;
ICefFrameHandler = interface;
@ -673,6 +674,7 @@ type
procedure doOnGetLinuxWindowProperties(const window_: ICefWindow; var properties: TLinuxWindowProperties; var aResult: boolean);
end;
{*
*******************************************
************** CEF interfaces *************
@ -712,6 +714,15 @@ type
procedure DestroyOtherRefs;
end;
ICefCustomUserData = interface(ICefBaseRefCounted)
['{BEC09DE3-AB0A-4F5E-8461-5F9F4520FDEF}']
function GetUserDataType : Pointer;
function GetUserData : Pointer;
property UserDataType : Pointer read GetUserDataType;
property UserData : Pointer read GetUserData;
end;
/// <summary>
/// Callback interface for ICefBrowserHost.RunFileDialog. The functions of
/// this interface will be called on the browser process UI thread.
@ -3458,11 +3469,11 @@ type
/// Returns false (0) if this function is called incorrectly. This function
/// can only be called on user created objects.
/// </summary>
function SetUserData(const data: ICefv8Value): Boolean;
function SetUserData(const data: ICefCustomUserData): Boolean;
/// <summary>
/// Returns the user data, if any, assigned to this object.
/// </summary>
function GetUserData: ICefv8Value;
function GetUserData: ICefCustomUserData;
/// <summary>
/// Returns the amount of externally allocated memory registered for the
/// object.

View File

@ -37,6 +37,20 @@ type
constructor Create; virtual;
end;
TCefCustomUserData = class(TCefBaseRefCountedOwn, ICefCustomUserData)
protected
FUserDataType : Pointer;
FUserData : Pointer;
function GetUserDataType : Pointer;
function GetUserData : Pointer;
public
constructor Create(aUserDataType, aUserData : Pointer);
destructor Destroy; override;
class function UnWrap(data: Pointer): ICefCustomUserData;
end;
{$IFDEF DELPHI14_UP}
TCefRTTIExtension = class(TCefv8HandlerOwn)
protected
@ -183,7 +197,62 @@ begin
end;
// TCefCustomUserData
constructor TCefCustomUserData.Create(aUserDataType, aUserData : Pointer);
begin
inherited CreateData(SizeOf(TCefBaseRefCounted));
FUserDataType := aUserDataType;
FUserData := aUserData;
{$IFDEF INTFLOG}
CefDebugLog(ClassName + '.Create');
{$ENDIF}
end;
destructor TCefCustomUserData.Destroy;
begin
{$IFDEF INTFLOG}
CefDebugLog(ClassName + '.Destroy');
{$ENDIF}
inherited Destroy;
end;
class function TCefCustomUserData.UnWrap(data: Pointer): ICefCustomUserData;
var
TempUserData : TCefCustomUserData;
begin
if (data <> nil) then
begin
// Get the original class instance from the data pointer.
TempUserData := TCefCustomUserData(CefGetObject(data));
// TempUserData already has an increased reference count.
// We need to decrease it before querying it with the "as" operator,
// which increases the count.
if not(TempUserData.HasOneRef) and TempUserData.HasAtLeastOneRef then
TempUserData._Release;
Result := TempUserData as ICefCustomUserData;
end
else
Result := nil;
end;
function TCefCustomUserData.GetUserDataType : Pointer;
begin
Result := FUserDataType;
end;
function TCefCustomUserData.GetUserData : Pointer;
begin
Result := FUserData;
end;
{$IFDEF DELPHI14_UP}
// TCefRTTIExtension
constructor TCefRTTIExtension.Create(const value: TValue; SyncMainThread: Boolean);
@ -375,7 +444,7 @@ function TCefRTTIExtension.GetValue(pi: PTypeInfo; const v: ICefv8Value; var ret
function ProcessObject: Boolean;
var
ud: ICefv8Value;
ud: ICefCustomUserData;
i: Pointer;
td: PTypeData;
rt: TRttiType;
@ -384,21 +453,12 @@ function TCefRTTIExtension.GetValue(pi: PTypeInfo; const v: ICefv8Value; var ret
begin
ud := v.GetUserData;
if (ud = nil) then Exit(False);
{$IFDEF TARGET_64BITS}
rt := StrToPtr(ud.GetValueByIndex(0).GetStringValue);
{$ELSE}
rt := TRttiType(ud.GetValueByIndex(0).GetIntValue);
{$ENDIF}
rt := ud.UserDataType;
td := GetTypeData(rt.Handle);
if (rt.TypeKind = tkClass) and td.ClassType.InheritsFrom(GetTypeData(pi).ClassType) then
begin
{$IFDEF TARGET_64BITS}
i := StrToPtr(ud.GetValueByIndex(1).GetStringValue);
{$ELSE}
i := Pointer(ud.GetValueByIndex(1).GetIntValue);
{$ENDIF}
i := ud.UserData;
TValue.Make(@i, pi, ret);
end else
Exit(False);
@ -409,7 +469,7 @@ function TCefRTTIExtension.GetValue(pi: PTypeInfo; const v: ICefv8Value; var ret
function ProcessClass: Boolean;
var
ud: ICefv8Value;
ud: ICefCustomUserData;
i: Pointer;
rt: TRttiType;
begin
@ -417,19 +477,11 @@ function TCefRTTIExtension.GetValue(pi: PTypeInfo; const v: ICefv8Value; var ret
begin
ud := v.GetUserData;
if (ud = nil) then Exit(False);
{$IFDEF TARGET_64BITS}
rt := StrToPtr(ud.GetValueByIndex(0).GetStringValue);
{$ELSE}
rt := TRttiType(ud.GetValueByIndex(0).GetIntValue);
{$ENDIF}
rt := ud.UserDataType;
if (rt.TypeKind = tkClassRef) then
begin
{$IFDEF TARGET_64BITS}
i := StrToPtr(ud.GetValueByIndex(1).GetStringValue);
{$ELSE}
i := Pointer(ud.GetValueByIndex(1).GetIntValue);
{$ENDIF}
i := ud.UserData;
TValue.Make(@i, pi, ret);
end else
Exit(False);
@ -497,19 +549,19 @@ function TCefRTTIExtension.SetValue(const v: TValue; var ret: ICefv8Value): Bool
var
rf: TRttiField;
vl: TValue;
ud, v8: ICefv8Value;
ud: ICefCustomUserData;
v8: ICefv8Value;
rec: Pointer;
rt: TRttiType;
begin
ud := TCefv8ValueRef.NewArray(1);
rt := FCtx.GetType(v.TypeInfo);
{$IFDEF TARGET_64BITS}
ud.SetValueByIndex(0, TCefv8ValueRef.NewString(PtrToStr(rt)));
{$ELSE}
ud.SetValueByIndex(0, TCefv8ValueRef.NewInt(Integer(rt)));
{$ENDIF}
ret := TCefv8ValueRef.NewObject(nil, nil);
ret.SetUserData(ud);
try
ud := TCefCustomUserData.Create(Pointer(rt), nil);
ret := TCefv8ValueRef.NewObject(nil, nil);
ret.SetUserData(ud);
finally
ud := nil;
end;
{$IFDEF DELPHI15_UP}
rec := TValueData(v).FValueData.GetReferenceToRawData;
@ -549,22 +601,19 @@ function TCefRTTIExtension.SetValue(const v: TValue; var ret: ICefv8Value): Bool
p: TRttiProperty;
fl: TRttiField;
f: ICefv8Value;
_r, _g, _s, ud: ICefv8Value;
ud: ICefCustomUserData;
_r, _g, _s: ICefv8Value;
_a: TCefv8ValueArray;
rt: TRttiType;
begin
rt := FCtx.GetType(v.TypeInfo);
ud := TCefv8ValueRef.NewArray(2);
{$IFDEF TARGET_64BITS}
ud.SetValueByIndex(0, TCefv8ValueRef.NewString(PtrToStr(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewString(PtrToStr(v.AsObject)));
{$ELSE}
ud.SetValueByIndex(0, TCefv8ValueRef.NewInt(Integer(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewInt(Integer(v.AsObject)));
{$ENDIF}
ret := TCefv8ValueRef.NewObject(nil, nil); // todo
ret.SetUserData(ud);
try
ud := TCefCustomUserData.Create(Pointer(rt), Pointer(v.AsObject));
ret := TCefv8ValueRef.NewObject(nil, nil); // todo
ret.SetUserData(ud);
finally
ud := nil;
end;
for m in rt.GetMethods do
if m.Visibility > mvProtected then
@ -612,23 +661,20 @@ function TCefRTTIExtension.SetValue(const v: TValue; var ret: ICefv8Value): Bool
function ProcessClass: Boolean;
var
m: TRttiMethod;
f, ud: ICefv8Value;
f: ICefv8Value;
ud: ICefCustomUserData;
c: TClass;
rt: TRttiType;
begin
c := v.AsClass;
rt := FCtx.GetType(c);
ud := TCefv8ValueRef.NewArray(2);
{$IFDEF TARGET_64BITS}
ud.SetValueByIndex(0, TCefv8ValueRef.NewString(PtrToStr(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewString(PtrToStr(c)));
{$ELSE}
ud.SetValueByIndex(0, TCefv8ValueRef.NewInt(Integer(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewInt(Integer(c)));
{$ENDIF}
ret := TCefv8ValueRef.NewObject(nil, nil); // todo
ret.SetUserData(ud);
try
ud := TCefCustomUserData.Create(Pointer(rt), Pointer(c));
ret := TCefv8ValueRef.NewObject(nil, nil); // todo
ret.SetUserData(ud);
finally
ud := nil;
end;
if c <> nil then
begin
@ -674,7 +720,7 @@ function TCefRTTIExtension.SetValue(const v: TValue; var ret: ICefv8Value): Bool
var
m: TRttiMethod;
f: ICefv8Value;
ud: ICefv8Value;
ud: ICefCustomUserData;
rt: TRttiType;
begin
@ -685,18 +731,13 @@ function TCefRTTIExtension.SetValue(const v: TValue; var ret: ICefv8Value): Bool
end else
begin
rt := FCtx.GetType(v.TypeInfo);
ud := TCefv8ValueRef.NewArray(2);
{$IFDEF TARGET_64BITS}
ud.SetValueByIndex(0, TCefv8ValueRef.NewString(PtrToStr(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewString(PtrToStr(Pointer(v.AsInterface))));
{$ELSE}
ud.SetValueByIndex(0, TCefv8ValueRef.NewInt(Integer(rt)));
ud.SetValueByIndex(1, TCefv8ValueRef.NewInt(Integer(v.AsInterface)));
{$ENDIF}
ret := TCefv8ValueRef.NewObject(nil, nil);
ret.SetUserData(ud);
try
ud := TCefCustomUserData.Create(Pointer(rt), Pointer(v.AsInterface));
ret := TCefv8ValueRef.NewObject(nil, nil);
ret.SetUserData(ud);
finally
ud := nil;
end;
for m in rt.GetMethods do
if m.Visibility > mvProtected then
@ -789,7 +830,7 @@ function TCefRTTIExtension.Execute(const name : ustring;
var exception : ustring): Boolean;
var
p: PChar;
ud: ICefv8Value;
ud: ICefCustomUserData;
rt: TRttiType;
val: TObject;
cls: TClass;
@ -812,19 +853,12 @@ begin
ud := object_.GetUserData;
if ud <> nil then
begin
{$IFDEF TARGET_64BITS}
rt := StrToPtr(ud.GetValueByIndex(0).GetStringValue);
{$ELSE}
rt := TRttiType(ud.GetValueByIndex(0).GetIntValue);
{$ENDIF}
rt := TRttiType(ud.UserDataType);
case rt.TypeKind of
tkClass:
begin
{$IFDEF TARGET_64BITS}
val := StrToPtr(ud.GetValueByIndex(1).GetStringValue);
{$ELSE}
val := TObject(ud.GetValueByIndex(1).GetIntValue);
{$ENDIF}
val := TObject(ud.UserData);
cls := GetTypeData(rt.Handle).ClassType;
if p^ = '$' then
@ -904,11 +938,7 @@ begin
tkClassRef:
begin
val := nil;
{$IFDEF TARGET_64BITS}
cls := StrToPtr(ud.GetValueByIndex(1).GetStringValue);
{$ELSE}
cls := TClass(ud.GetValueByIndex(1).GetIntValue);
{$ENDIF}
cls := TClass(ud.UserData);
m := FCtx.GetType(cls).GetMethod(name);
end;
else

View File

@ -59,8 +59,8 @@ type
function SetValueByIndex(index: Integer; const value: ICefv8Value): Boolean;
function SetValueByAccessor(const key: ustring; attribute: TCefV8PropertyAttributes): Boolean;
function GetKeys(const keys: TStrings): Integer;
function SetUserData(const data: ICefv8Value): Boolean;
function GetUserData: ICefv8Value;
function SetUserData(const data: ICefCustomUserData): Boolean;
function GetUserData: ICefCustomUserData;
function GetExternallyAllocatedMemory: Integer;
function AdjustExternallyAllocatedMemory(changeInBytes: Integer): Integer;
function GetArrayLength: Integer;
@ -473,7 +473,7 @@ begin
end;
end;
function TCefv8ValueRef.SetUserData(const data: ICefv8Value): Boolean;
function TCefv8ValueRef.SetUserData(const data: ICefCustomUserData): Boolean;
begin
Result := PCefV8Value(FData)^.set_user_data(PCefV8Value(FData), CefGetData(data)) <> 0;
end;
@ -518,9 +518,9 @@ begin
Result := PCefV8Value(FData)^.set_rethrow_exceptions(PCefV8Value(FData), Ord(rethrow)) <> 0;
end;
function TCefv8ValueRef.GetUserData: ICefv8Value;
function TCefv8ValueRef.GetUserData: ICefCustomUserData;
begin
Result := TCefv8ValueRef.UnWrap(PCefV8Value(FData)^.get_user_data(PCefV8Value(FData)));
Result := TCefCustomUserData.UnWrap(PCefV8Value(FData)^.get_user_data(PCefV8Value(FData)));
end;
function TCefv8ValueRef.GetValueByIndex(index: Integer): ICefv8Value;

View File

@ -2,7 +2,7 @@
"UpdateLazPackages" : [
{
"ForceNotify" : true,
"InternalVersion" : 701,
"InternalVersion" : 702,
"Name" : "cef4delphi_lazarus.lpk",
"Version" : "133.4.6"
}