mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-06-11 09:35:59 -04:00
Merge pull request #2105 from lightpanda-io/no-context-handling
Better handle v8 callback with no valid context
This commit is contained in:
@@ -39,9 +39,22 @@ prev_local: ?*const js.Local,
|
||||
prev_context: *Context,
|
||||
|
||||
// Takes the raw v8 isolate and extracts the context from it.
|
||||
pub fn init(self: *Caller, v8_isolate: *v8.Isolate) void {
|
||||
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate });
|
||||
// Returns false if the context has been destroyed (e.g., navigated-away iframe),
|
||||
// in which case a JS exception has been thrown and the caller should return immediately.
|
||||
pub fn init(self: *Caller, v8_isolate: *v8.Isolate) bool {
|
||||
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate }) orelse {
|
||||
throwDetachedError(v8_isolate);
|
||||
return false;
|
||||
};
|
||||
initWithContext(self, ctx, v8_context);
|
||||
return true;
|
||||
}
|
||||
|
||||
fn throwDetachedError(isolate: *v8.Isolate) void {
|
||||
const message = "Cannot execute in detached context (e.g., navigated-away iframe)";
|
||||
const v8_message = v8.v8__String__NewFromUtf8(isolate, message.ptr, v8.kNormal, @intCast(message.len));
|
||||
const js_exception = v8.v8__Exception__Error(v8_message);
|
||||
_ = v8.v8__Isolate__ThrowException(isolate, js_exception);
|
||||
}
|
||||
|
||||
fn initWithContext(self: *Caller, ctx: *Context, v8_context: *const v8.Context) void {
|
||||
@@ -60,9 +73,9 @@ fn initWithContext(self: *Caller, ctx: *Context, v8_context: *const v8.Context)
|
||||
ctx.local = &self.local;
|
||||
}
|
||||
|
||||
pub fn initFromHandle(self: *Caller, handle: ?*const v8.FunctionCallbackInfo) void {
|
||||
pub fn initFromHandle(self: *Caller, handle: ?*const v8.FunctionCallbackInfo) bool {
|
||||
const isolate = v8.v8__FunctionCallbackInfo__GetIsolate(handle).?;
|
||||
self.init(isolate);
|
||||
return self.init(isolate);
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Caller) void {
|
||||
@@ -538,7 +551,10 @@ pub const Function = struct {
|
||||
|
||||
pub fn call(comptime T: type, info_handle: *const v8.FunctionCallbackInfo, func: anytype, comptime opts: Opts) void {
|
||||
const v8_isolate = v8.v8__FunctionCallbackInfo__GetIsolate(info_handle).?;
|
||||
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate });
|
||||
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate }) orelse {
|
||||
throwDetachedError(v8_isolate);
|
||||
return;
|
||||
};
|
||||
const info = FunctionCallbackInfo{ .handle = info_handle };
|
||||
|
||||
var hs: js.HandleScope = undefined;
|
||||
|
||||
@@ -138,7 +138,8 @@ pub fn fromC(c_context: *const v8.Context) ?*Context {
|
||||
/// Returns the Context and v8::Context for the given isolate.
|
||||
/// If the current context is from a destroyed Context (e.g., navigated-away iframe),
|
||||
/// falls back to the incumbent context (the calling context).
|
||||
pub fn fromIsolate(isolate: js.Isolate) struct { *Context, *const v8.Context } {
|
||||
/// Returns null if neither context has a valid Context struct (both were destroyed).
|
||||
pub fn fromIsolate(isolate: js.Isolate) ?struct { *Context, *const v8.Context } {
|
||||
const v8_context = v8.v8__Isolate__GetCurrentContext(isolate.handle).?;
|
||||
if (fromC(v8_context)) |ctx| {
|
||||
return .{ ctx, v8_context };
|
||||
@@ -146,7 +147,8 @@ pub fn fromIsolate(isolate: js.Isolate) struct { *Context, *const v8.Context } {
|
||||
// The current context's Context struct has been freed (e.g., iframe navigated away).
|
||||
// Fall back to the incumbent context (the calling context).
|
||||
const v8_incumbent = v8.v8__Isolate__GetIncumbentContext(isolate.handle).?;
|
||||
return .{ fromC(v8_incumbent).?, v8_incumbent };
|
||||
const ctx = fromC(v8_incumbent) orelse return null;
|
||||
return .{ ctx, v8_incumbent };
|
||||
}
|
||||
|
||||
pub fn deinit(self: *Context) void {
|
||||
@@ -806,7 +808,9 @@ fn resolveDynamicModule(self: *Context, state: *DynamicModuleResolveState, modul
|
||||
const then_callback = newFunctionWithData(local, struct {
|
||||
pub fn callback(callback_handle: ?*const v8.FunctionCallbackInfo) callconv(.c) void {
|
||||
var c: Caller = undefined;
|
||||
c.initFromHandle(callback_handle);
|
||||
if (!c.initFromHandle(callback_handle)) {
|
||||
return;
|
||||
}
|
||||
defer c.deinit();
|
||||
|
||||
const info = Caller.FunctionCallbackInfo{ .handle = callback_handle.? };
|
||||
@@ -830,7 +834,7 @@ fn resolveDynamicModule(self: *Context, state: *DynamicModuleResolveState, modul
|
||||
const catch_callback = newFunctionWithData(local, struct {
|
||||
pub fn callback(callback_handle: ?*const v8.FunctionCallbackInfo) callconv(.c) void {
|
||||
var c: Caller = undefined;
|
||||
c.initFromHandle(callback_handle);
|
||||
if (!c.initFromHandle(callback_handle)) return;
|
||||
defer c.deinit();
|
||||
|
||||
const info = Caller.FunctionCallbackInfo{ .handle = callback_handle.? };
|
||||
|
||||
@@ -519,7 +519,7 @@ fn promiseRejectCallback(message_handle: v8.PromiseRejectMessage) callconv(.c) v
|
||||
const promise_handle = v8.v8__PromiseRejectMessage__GetPromise(&message_handle).?;
|
||||
const v8_isolate = v8.v8__Object__GetIsolate(@ptrCast(promise_handle)).?;
|
||||
const isolate = js.Isolate{ .handle = v8_isolate };
|
||||
const ctx, const v8_context = Context.fromIsolate(isolate);
|
||||
const ctx, const v8_context = Context.fromIsolate(isolate) orelse return;
|
||||
|
||||
const local = js.Local{
|
||||
.ctx = ctx,
|
||||
|
||||
@@ -116,7 +116,9 @@ pub const Constructor = struct {
|
||||
fn wrap(handle: ?*const v8.FunctionCallbackInfo) callconv(.c) void {
|
||||
const v8_isolate = v8.v8__FunctionCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
caller.constructor(T, func, handle.?, .{
|
||||
@@ -216,7 +218,9 @@ pub const Indexed = struct {
|
||||
fn wrap(idx: u32, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
return caller.getIndex(T, getter, idx, handle.?, .{
|
||||
@@ -232,7 +236,9 @@ pub const Indexed = struct {
|
||||
fn wrap(handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
return caller.getEnumerator(T, enumerator, handle.?, .{});
|
||||
}
|
||||
@@ -258,7 +264,9 @@ pub const NamedIndexed = struct {
|
||||
fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
return caller.getNamedIndex(T, getter, c_name.?, handle.?, .{
|
||||
@@ -272,7 +280,9 @@ pub const NamedIndexed = struct {
|
||||
fn wrap(c_name: ?*const v8.Name, c_value: ?*const v8.Value, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
return caller.setNamedIndex(T, setter, c_name.?, c_value.?, handle.?, .{
|
||||
@@ -286,7 +296,9 @@ pub const NamedIndexed = struct {
|
||||
fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
return caller.deleteNamedIndex(T, deleter, c_name.?, handle.?, .{
|
||||
@@ -387,7 +399,9 @@ pub const Property = struct {
|
||||
pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 {
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
const local = &caller.local;
|
||||
@@ -465,7 +479,9 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8
|
||||
const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?;
|
||||
|
||||
var caller: Caller = undefined;
|
||||
caller.init(v8_isolate);
|
||||
if (!caller.init(v8_isolate)) {
|
||||
return 0;
|
||||
}
|
||||
defer caller.deinit();
|
||||
|
||||
const local = &caller.local;
|
||||
|
||||
Reference in New Issue
Block a user