Skip to content

Commit 9ac5bfb

Browse files
committed
Fix executor used in resolveNode
1 parent 457eb60 commit 9ac5bfb

File tree

5 files changed

+47
-31
lines changed

5 files changed

+47
-31
lines changed

src/browser/browser.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ pub const Session = struct {
187187
errdefer self.arena.deinit();
188188

189189
self.executor = try browser.env.startExecutor(Window, &self.state, self);
190-
errdefer browser.env.stopExecutor(self.executor);
190+
errdefer browser.env.stopExecutor(self.executor, true);
191191
self.inspector = try Env.Inspector.init(self.arena.allocator(), self.executor, ctx);
192192

193193
self.microtaskLoop();
@@ -202,7 +202,7 @@ pub const Session = struct {
202202
self.arena.deinit();
203203
self.cookie_jar.deinit();
204204
self.storage_shed.deinit();
205-
self.browser.env.stopExecutor(self.executor);
205+
self.browser.env.stopExecutor(self.executor, true);
206206
}
207207

208208
fn microtaskLoop(self: *Session) void {

src/cdp/cdp.zig

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -308,24 +308,6 @@ pub fn BrowserContext(comptime CDP_T: type) type {
308308

309309
isolated_world: ?IsolatedWorld,
310310

311-
pub fn createIsolatedWorld(
312-
self: *Self,
313-
world_name: []const u8,
314-
grant_universal_access: bool,
315-
) !void {
316-
if (self.isolated_world != null) return error.AlreadyExists;
317-
318-
const executor = try self.cdp.browser.env.startExecutor(@import("../browser/html/window.zig").Window, &self.session.state, self.session);
319-
errdefer self.cdp.browser.env.stopExecutor(executor);
320-
executor.context.exit();
321-
322-
self.isolated_world = .{
323-
.name = try self.session.arena.allocator().dupe(u8, world_name), // TODO allocator
324-
.grant_universal_access = grant_universal_access,
325-
.executor = executor,
326-
};
327-
}
328-
329311
const Self = @This();
330312

331313
fn init(self: *Self, id: []const u8, cdp: *CDP_T) !void {
@@ -352,6 +334,11 @@ pub fn BrowserContext(comptime CDP_T: type) type {
352334
}
353335

354336
pub fn deinit(self: *Self) void {
337+
if (self.isolated_world) |isolated_world| {
338+
isolated_world.executor.endScope();
339+
self.cdp.browser.env.stopExecutor(isolated_world.executor, false);
340+
self.isolated_world = null;
341+
}
355342
self.node_registry.deinit();
356343
self.node_search_list.deinit();
357344
}
@@ -361,6 +348,29 @@ pub fn BrowserContext(comptime CDP_T: type) type {
361348
self.node_search_list.reset();
362349
}
363350

351+
pub fn createIsolatedWorld(
352+
self: *Self,
353+
world_name: []const u8,
354+
grant_universal_access: bool,
355+
) !void {
356+
if (self.isolated_world != null) return error.CurrentlyOnly1IsolatedWorldSupported;
357+
358+
const executor = try self.cdp.browser.env.startExecutor(@import("../browser/html/window.zig").Window, &self.session.state, self.session);
359+
errdefer self.cdp.browser.env.stopExecutor(executor, true);
360+
361+
// TBD should we endScope on removePage and re-startScope on createPage?
362+
// Window will be refactored into the executor so we leave it ugly here for now as a reminder.
363+
try executor.startScope(@import("../browser/html/window.zig").Window{});
364+
365+
executor.context.exit(); // The default context should remain open
366+
367+
self.isolated_world = .{
368+
.name = try self.session.arena.allocator().dupe(u8, world_name), // TODO allocator
369+
.grant_universal_access = grant_universal_access,
370+
.executor = executor,
371+
};
372+
}
373+
364374
pub fn nodeWriter(self: *Self, node: *const Node, opts: Node.Writer.Opts) Node.Writer {
365375
return .{
366376
.node = node,

src/cdp/domains/dom.zig

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ fn resolveNode(cmd: anytype) !void {
134134
if (executor.context.debugContextId() != context_id) {
135135
const isolated_world = bc.isolated_world orelse return error.ContextNotFound;
136136
executor = isolated_world.executor;
137+
137138
if (executor.context.debugContextId() != context_id) return error.ContextNotFound;
138139
}
139140
}
@@ -143,7 +144,7 @@ fn resolveNode(cmd: anytype) !void {
143144
// node._node is a *parser.Node we need this to be able to find its most derived type e.g. Node -> Element -> HTMLElement
144145
// So we use the Node.Union when retrieve the value from the environment
145146
const remote_object = try bc.session.inspector.getRemoteObject(
146-
bc.session.executor,
147+
executor,
147148
params.objectGroup orelse "",
148149
try dom_node.Node.toInterface(node._node),
149150
);

src/cdp/domains/page.zig

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ fn setLifecycleEventsEnabled(cmd: anytype) !void {
8484
}
8585

8686
// TODO: hard coded method
87+
// With the command we receive a script we need to store and run for each new document.
88+
// Note that the worldName refers to the name given to the isolated world.
8789
fn addScriptToEvaluateOnNewDocument(cmd: anytype) !void {
8890
// const params = (try cmd.params(struct {
8991
// source: []const u8,
@@ -110,9 +112,10 @@ fn createIsolatedWorld(cmd: anytype) !void {
110112
}
111113
const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded;
112114

113-
try bc.createIsolatedWorld(params.worldName, params.grantUniveralAccess); // orelse return error.IsolatedWorldAlreadyExists;
115+
try bc.createIsolatedWorld(params.worldName, params.grantUniveralAccess);
114116

115-
// Create the auxdata json from
117+
// Create the auxdata json for the contextCreated event
118+
// Calling contextCreated will assign a Id to the context and send the contextCreated event
116119
const aux_json = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":false,\"type\":\"isolated\",\"frameId\":\"{s}\"}}", .{params.frameId});
117120
bc.session.inspector.contextCreated(bc.isolated_world.?.executor, bc.isolated_world.?.name, "", aux_json, false);
118121

@@ -193,18 +196,20 @@ pub fn pageNavigate(bc: anytype, event: *const Notification.PageEvent) !void {
193196
}, .{ .session_id = session_id });
194197
}
195198

196-
// Send Runtime.executionContextsCleared event
197199
// TODO: noop event, we have no env context at this point, is it necesarry?
198-
// When we actually recreated the context we should have the inspector send this event, see: resetContextGroup
200+
// When we actually recreated the context we should have the inspector send this event, see: resetContextGroup
201+
// Sending this event will tell the client that the context ids they had are invalid and the context shouls be dropped
202+
// The client will expect us to send new contextCreated events, such that the client has new id's for the active contexts.
199203
try cdp.sendEvent("Runtime.executionContextsCleared", null, .{ .session_id = session_id });
200204

201205
if (bc.isolated_world != null) {
202206
const aux_json = try std.fmt.allocPrint(
203207
bc.session.arena.allocator(), // TODO change this
204208
"{{\"isDefault\":false,\"type\":\"isolated\",\"frameId\":\"{s}\"}}",
205-
.{bc.target_id.?}, // TODO check this
209+
.{bc.target_id.?},
206210
);
207211

212+
// Calling contextCreated will assign a new Id to the context and send the contextCreated event
208213
bc.session.inspector.contextCreated(
209214
bc.isolated_world.?.executor,
210215
bc.isolated_world.?.name,

src/runtime/js.zig

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
348348
},
349349
};
350350

351-
errdefer self.stopExecutor(executor);
351+
errdefer self.stopExecutor(executor, true); // Note: This likely has issues as context.exit() is errdefered as well
352352

353353
// Custom exception
354354
// NOTE: there is no way in v8 to subclass the Error built-in type
@@ -369,8 +369,8 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
369369
// a Context, it's managed by the garbage collector. So, when the
370370
// `gc_hints` option is enabled, we'll use the `lowMemoryNotification`
371371
// call on the isolate to encourage v8 to free the context.
372-
pub fn stopExecutor(self: *Self, executor: *Executor) void {
373-
executor.deinit();
372+
pub fn stopExecutor(self: *Self, executor: *Executor, exit_context: bool) void {
373+
executor.deinit(exit_context);
374374
self.executor_pool.destroy(executor);
375375
if (self.gc_hints) {
376376
self.isolate.lowMemoryNotification();
@@ -776,11 +776,11 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
776776
// no init, must be initialized via env.startExecutor()
777777

778778
// not public, must be destroyed via env.stopExecutor()
779-
fn deinit(self: *Executor) void {
779+
fn deinit(self: *Executor, exit_context: bool) void {
780780
if (self.scope) |*s| {
781781
s.deinit();
782782
}
783-
self.context.exit();
783+
if (exit_context) self.context.exit();
784784
self.handle_scope.deinit();
785785
self.call_arena.deinit();
786786
self.scope_arena.deinit();

0 commit comments

Comments
 (0)