mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-29 16:10:04 +00:00
Take 2.
History: We started with 1 context and thus only had 1 identity map. Frames were added, and we tried to stick with 1 identity map per context. That didn't work - it breaks cross-frame scripting. We introduced "Origin" so that all frames on the same origin share the same objects. That almost worked, by the v8::Inspector isn't bound by a Context's SecurityToken. So we tried 1 global identity map. But that doesn't work. CDP IsolateWorlds do, in fact, need some isolation. They need new v8::Objects created in their context, even if the object already exists in the main context. In the end, you end up with something like this: A page (and all its frames) needs 1 view of the data. And each IsolateWorld needs it own view. This commit introduces a js.Identity which is referenced by the context. The Session has a js.Identity (used by all pages), and each IsolateWorld has its own js.Identity. As a bonus, the arena pool memory-leak detection has been moved out of the session and into the ArenaPool. This means _all_ arena pool access is audited (in debug mode). This seems superfluous, but it's actually necessary since IsolateWorlds (which now own their own identity) can outlive the Page so there's no clear place to "check" for leaks - except on ArenaPool deinit.
This commit is contained in:
@@ -489,7 +489,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
||||
|
||||
pub fn createIsolatedWorld(self: *Self, world_name: []const u8, grant_universal_access: bool) !*IsolatedWorld {
|
||||
const browser = &self.cdp.browser;
|
||||
const arena = try browser.arena_pool.acquire();
|
||||
const arena = try browser.arena_pool.acquire(.{ .debug = "IsolatedWorld" });
|
||||
errdefer browser.arena_pool.release(arena);
|
||||
|
||||
const world = try arena.create(IsolatedWorld);
|
||||
@@ -750,8 +750,13 @@ const IsolatedWorld = struct {
|
||||
context: ?*js.Context = null,
|
||||
grant_universal_access: bool,
|
||||
|
||||
// Identity tracking for this isolated world (separate from main world).
|
||||
// This ensures CDP inspector contexts don't share v8::Globals with main world.
|
||||
identity: js.Identity = .{},
|
||||
|
||||
pub fn deinit(self: *IsolatedWorld) void {
|
||||
self.removeContext() catch {};
|
||||
self.identity.deinit();
|
||||
self.browser.arena_pool.release(self.arena);
|
||||
}
|
||||
|
||||
@@ -768,7 +773,12 @@ const IsolatedWorld = struct {
|
||||
// Currently we have only 1 page/frame and thus also only 1 state in the isolate world.
|
||||
pub fn createContext(self: *IsolatedWorld, page: *Page) !*js.Context {
|
||||
if (self.context == null) {
|
||||
self.context = try self.browser.env.createContext(page);
|
||||
const ctx = try self.browser.env.createContext(page, .{
|
||||
.identity = &self.identity,
|
||||
.identity_arena = self.arena,
|
||||
.debug_name = "IsolatedContext",
|
||||
});
|
||||
self.context = ctx;
|
||||
} else {
|
||||
log.warn(.cdp, "not implemented", .{
|
||||
.feature = "createContext: Not implemented second isolated context creation",
|
||||
|
||||
Reference in New Issue
Block a user