1
0
mirror of https://github.com/salvadordf/CEF4Delphi.git synced 2025-06-22 22:17:48 +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

@ -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