mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 04:34:44 +00:00
Merge pull request #1885 from lightpanda-io/danling_context_fallback
Fallback to the Incumbent Context when the Current Context is dangling
This commit is contained in:
@@ -40,8 +40,8 @@ prev_context: *Context,
|
|||||||
|
|
||||||
// Takes the raw v8 isolate and extracts the context from it.
|
// Takes the raw v8 isolate and extracts the context from it.
|
||||||
pub fn init(self: *Caller, v8_isolate: *v8.Isolate) void {
|
pub fn init(self: *Caller, v8_isolate: *v8.Isolate) void {
|
||||||
const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate).?;
|
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate });
|
||||||
initWithContext(self, Context.fromC(v8_context), v8_context);
|
initWithContext(self, ctx, v8_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initWithContext(self: *Caller, ctx: *Context, v8_context: *const v8.Context) void {
|
fn initWithContext(self: *Caller, ctx: *Context, v8_context: *const v8.Context) void {
|
||||||
@@ -537,9 +537,7 @@ pub const Function = struct {
|
|||||||
|
|
||||||
pub fn call(comptime T: type, info_handle: *const v8.FunctionCallbackInfo, func: anytype, comptime opts: Opts) void {
|
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 v8_isolate = v8.v8__FunctionCallbackInfo__GetIsolate(info_handle).?;
|
||||||
const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate).?;
|
const ctx, const v8_context = Context.fromIsolate(.{ .handle = v8_isolate });
|
||||||
|
|
||||||
const ctx = Context.fromC(v8_context);
|
|
||||||
const info = FunctionCallbackInfo{ .handle = info_handle };
|
const info = FunctionCallbackInfo{ .handle = info_handle };
|
||||||
|
|
||||||
var hs: js.HandleScope = undefined;
|
var hs: js.HandleScope = undefined;
|
||||||
|
|||||||
@@ -119,12 +119,22 @@ const ModuleEntry = struct {
|
|||||||
resolver_promise: ?js.Promise.Global = null,
|
resolver_promise: ?js.Promise.Global = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn fromC(c_context: *const v8.Context) *Context {
|
pub fn fromC(c_context: *const v8.Context) ?*Context {
|
||||||
return @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(c_context, 1)));
|
return @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(c_context, 1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fromIsolate(isolate: js.Isolate) *Context {
|
/// Returns the Context and v8::Context for the given isolate.
|
||||||
return fromC(v8.v8__Isolate__GetCurrentContext(isolate.handle).?);
|
/// 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 } {
|
||||||
|
const v8_context = v8.v8__Isolate__GetCurrentContext(isolate.handle).?;
|
||||||
|
if (fromC(v8_context)) |ctx| {
|
||||||
|
return .{ ctx, 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 };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *Context) void {
|
pub fn deinit(self: *Context) void {
|
||||||
@@ -155,6 +165,11 @@ pub fn deinit(self: *Context) void {
|
|||||||
|
|
||||||
self.session.releaseOrigin(self.origin);
|
self.session.releaseOrigin(self.origin);
|
||||||
|
|
||||||
|
// Clear the embedder data so that if V8 keeps this context alive
|
||||||
|
// (because objects created in it are still referenced), we don't
|
||||||
|
// have a dangling pointer to our freed Context struct.
|
||||||
|
v8.v8__Context__SetAlignedPointerInEmbedderData(entered.handle, 1, null);
|
||||||
|
|
||||||
v8.v8__Global__Reset(&self.handle);
|
v8.v8__Global__Reset(&self.handle);
|
||||||
env.isolate.notifyContextDisposed();
|
env.isolate.notifyContextDisposed();
|
||||||
// There can be other tasks associated with this context that we need to
|
// There can be other tasks associated with this context that we need to
|
||||||
@@ -255,7 +270,7 @@ pub fn toLocal(self: *Context, global: anytype) js.Local.ToLocalReturnType(@Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn getIncumbent(self: *Context) *Page {
|
pub fn getIncumbent(self: *Context) *Page {
|
||||||
return fromC(v8.v8__Isolate__GetIncumbentContext(self.env.isolate.handle).?).page;
|
return fromC(v8.v8__Isolate__GetIncumbentContext(self.env.isolate.handle).?).?.page;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn stringToPersistedFunction(
|
pub fn stringToPersistedFunction(
|
||||||
@@ -479,7 +494,7 @@ fn resolveModuleCallback(
|
|||||||
) callconv(.c) ?*const v8.Module {
|
) callconv(.c) ?*const v8.Module {
|
||||||
_ = import_attributes;
|
_ = import_attributes;
|
||||||
|
|
||||||
const self = fromC(c_context.?);
|
const self = fromC(c_context.?).?;
|
||||||
const local = js.Local{
|
const local = js.Local{
|
||||||
.ctx = self,
|
.ctx = self,
|
||||||
.handle = c_context.?,
|
.handle = c_context.?,
|
||||||
@@ -512,7 +527,7 @@ pub fn dynamicModuleCallback(
|
|||||||
_ = host_defined_options;
|
_ = host_defined_options;
|
||||||
_ = import_attrs;
|
_ = import_attrs;
|
||||||
|
|
||||||
const self = fromC(c_context.?);
|
const self = fromC(c_context.?).?;
|
||||||
const local = js.Local{
|
const local = js.Local{
|
||||||
.ctx = self,
|
.ctx = self,
|
||||||
.handle = c_context.?,
|
.handle = c_context.?,
|
||||||
@@ -559,7 +574,7 @@ pub fn dynamicModuleCallback(
|
|||||||
|
|
||||||
pub fn metaObjectCallback(c_context: ?*v8.Context, c_module: ?*v8.Module, c_meta: ?*v8.Value) callconv(.c) void {
|
pub fn metaObjectCallback(c_context: ?*v8.Context, c_module: ?*v8.Module, c_meta: ?*v8.Value) callconv(.c) void {
|
||||||
// @HandleScope implement this without a fat context/local..
|
// @HandleScope implement this without a fat context/local..
|
||||||
const self = fromC(c_context.?);
|
const self = fromC(c_context.?).?;
|
||||||
var local = js.Local{
|
var local = js.Local{
|
||||||
.ctx = self,
|
.ctx = self,
|
||||||
.handle = c_context.?,
|
.handle = c_context.?,
|
||||||
|
|||||||
@@ -497,13 +497,13 @@ pub fn terminate(self: *const Env) void {
|
|||||||
fn promiseRejectCallback(message_handle: v8.PromiseRejectMessage) callconv(.c) void {
|
fn promiseRejectCallback(message_handle: v8.PromiseRejectMessage) callconv(.c) void {
|
||||||
const promise_handle = v8.v8__PromiseRejectMessage__GetPromise(&message_handle).?;
|
const promise_handle = v8.v8__PromiseRejectMessage__GetPromise(&message_handle).?;
|
||||||
const v8_isolate = v8.v8__Object__GetIsolate(@ptrCast(promise_handle)).?;
|
const v8_isolate = v8.v8__Object__GetIsolate(@ptrCast(promise_handle)).?;
|
||||||
const js_isolate = js.Isolate{ .handle = v8_isolate };
|
const isolate = js.Isolate{ .handle = v8_isolate };
|
||||||
const ctx = Context.fromIsolate(js_isolate);
|
const ctx, const v8_context = Context.fromIsolate(isolate);
|
||||||
|
|
||||||
const local = js.Local{
|
const local = js.Local{
|
||||||
.ctx = ctx,
|
.ctx = ctx,
|
||||||
.isolate = js_isolate,
|
.isolate = isolate,
|
||||||
.handle = v8.v8__Isolate__GetCurrentContext(v8_isolate).?,
|
.handle = v8_context,
|
||||||
.call_arena = ctx.call_arena,
|
.call_arena = ctx.call_arena,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user