mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-29 23:23:28 +00:00
Executor World kind
This commit is contained in:
@@ -192,8 +192,8 @@ pub const Session = struct {
|
|||||||
self.state.cookie_jar = &self.cookie_jar;
|
self.state.cookie_jar = &self.cookie_jar;
|
||||||
errdefer self.arena.deinit();
|
errdefer self.arena.deinit();
|
||||||
|
|
||||||
self.executor = try browser.env.startExecutor(Window, &self.state, self);
|
self.executor = try browser.env.startExecutor(Window, &self.state, self, .main);
|
||||||
errdefer browser.env.stopExecutor(self.executor, true);
|
errdefer browser.env.stopExecutor(self.executor);
|
||||||
self.inspector = try Env.Inspector.init(self.arena.allocator(), self.executor, ctx);
|
self.inspector = try Env.Inspector.init(self.arena.allocator(), self.executor, ctx);
|
||||||
|
|
||||||
self.microtaskLoop();
|
self.microtaskLoop();
|
||||||
@@ -208,7 +208,7 @@ pub const Session = struct {
|
|||||||
self.arena.deinit();
|
self.arena.deinit();
|
||||||
self.cookie_jar.deinit();
|
self.cookie_jar.deinit();
|
||||||
self.storage_shed.deinit();
|
self.storage_shed.deinit();
|
||||||
self.browser.env.stopExecutor(self.executor, true);
|
self.browser.env.stopExecutor(self.executor);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn microtaskLoop(self: *Session) void {
|
fn microtaskLoop(self: *Session) void {
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
pub fn deinit(self: *Self) void {
|
pub fn deinit(self: *Self) void {
|
||||||
if (self.isolated_world) |isolated_world| {
|
if (self.isolated_world) |isolated_world| {
|
||||||
isolated_world.executor.endScope();
|
isolated_world.executor.endScope();
|
||||||
self.cdp.browser.env.stopExecutor(isolated_world.executor, false);
|
self.cdp.browser.env.stopExecutor(isolated_world.executor);
|
||||||
self.isolated_world = null;
|
self.isolated_world = null;
|
||||||
}
|
}
|
||||||
self.node_registry.deinit();
|
self.node_registry.deinit();
|
||||||
@@ -360,15 +360,13 @@ pub fn BrowserContext(comptime CDP_T: type) type {
|
|||||||
) !void {
|
) !void {
|
||||||
if (self.isolated_world != null) return error.CurrentlyOnly1IsolatedWorldSupported;
|
if (self.isolated_world != null) return error.CurrentlyOnly1IsolatedWorldSupported;
|
||||||
|
|
||||||
const executor = try self.cdp.browser.env.startExecutor(@import("../browser/html/window.zig").Window, &self.session.state, self.session);
|
const executor = try self.cdp.browser.env.startExecutor(@import("../browser/html/window.zig").Window, &self.session.state, self.session, .isolated);
|
||||||
errdefer self.cdp.browser.env.stopExecutor(executor, true);
|
errdefer self.cdp.browser.env.stopExecutor(executor);
|
||||||
|
|
||||||
// TBD should we endScope on removePage and re-startScope on createPage?
|
// TBD should we endScope on removePage and re-startScope on createPage?
|
||||||
// Window will be refactored into the executor so we leave it ugly here for now as a reminder.
|
// Window will be refactored into the executor so we leave it ugly here for now as a reminder.
|
||||||
try executor.startScope(@import("../browser/html/window.zig").Window{});
|
try executor.startScope(@import("../browser/html/window.zig").Window{});
|
||||||
|
|
||||||
executor.context.exit(); // The default context should remain open
|
|
||||||
|
|
||||||
self.isolated_world = .{
|
self.isolated_world = .{
|
||||||
.name = try self.arena.dupe(u8, world_name),
|
.name = try self.arena.dupe(u8, world_name),
|
||||||
.grant_universal_access = grant_universal_access,
|
.grant_universal_access = grant_universal_access,
|
||||||
|
|||||||
@@ -265,10 +265,12 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
self.isolate.performMicrotasksCheckpoint();
|
self.isolate.performMicrotasksCheckpoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn startExecutor(self: *Self, comptime Global: type, state: State, module_loader: anytype) !*Executor {
|
pub fn startExecutor(self: *Self, comptime Global: type, state: State, module_loader: anytype, kind: WorldKind) !*Executor {
|
||||||
if (comptime builtin.mode == .Debug) {
|
if (comptime builtin.mode == .Debug) {
|
||||||
std.debug.assert(self.has_executor == false);
|
if (kind == .main) {
|
||||||
self.has_executor = true;
|
std.debug.assert(self.has_executor == false);
|
||||||
|
self.has_executor = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const isolate = self.isolate;
|
const isolate = self.isolate;
|
||||||
const templates = &self.templates;
|
const templates = &self.templates;
|
||||||
@@ -307,8 +309,10 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const context = v8.Context.init(isolate, global_template, null);
|
const context = v8.Context.init(isolate, global_template, null);
|
||||||
context.enter();
|
if (kind == .main) {
|
||||||
errdefer context.exit();
|
context.enter();
|
||||||
|
errdefer context.exit();
|
||||||
|
}
|
||||||
|
|
||||||
// This shouldn't be necessary, but it is:
|
// This shouldn't be necessary, but it is:
|
||||||
// https://groups.google.com/g/v8-users/c/qAQQBmbi--8
|
// https://groups.google.com/g/v8-users/c/qAQQBmbi--8
|
||||||
@@ -344,8 +348,9 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
|
|
||||||
executor.* = .{
|
executor.* = .{
|
||||||
.state = state,
|
.state = state,
|
||||||
.context = context,
|
|
||||||
.isolate = isolate,
|
.isolate = isolate,
|
||||||
|
.kind = kind,
|
||||||
|
.context = context,
|
||||||
.templates = templates,
|
.templates = templates,
|
||||||
.handle_scope = handle_scope,
|
.handle_scope = handle_scope,
|
||||||
.call_arena = undefined,
|
.call_arena = undefined,
|
||||||
@@ -364,7 +369,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
executor.call_arena = executor._call_arena_instance.allocator();
|
executor.call_arena = executor._call_arena_instance.allocator();
|
||||||
executor.scope_arena = executor._scope_arena_instance.allocator();
|
executor.scope_arena = executor._scope_arena_instance.allocator();
|
||||||
|
|
||||||
errdefer self.stopExecutor(executor, false); // Note: This likely has issues as context.exit() is errdefered as well
|
errdefer self.stopExecutor(executor); // Note: This likely has issues as context.exit() is errdefered as well
|
||||||
|
|
||||||
// Custom exception
|
// Custom exception
|
||||||
// NOTE: there is no way in v8 to subclass the Error built-in type
|
// NOTE: there is no way in v8 to subclass the Error built-in type
|
||||||
@@ -385,16 +390,18 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
// a Context, it's managed by the garbage collector. So, when the
|
// a Context, it's managed by the garbage collector. So, when the
|
||||||
// `gc_hints` option is enabled, we'll use the `lowMemoryNotification`
|
// `gc_hints` option is enabled, we'll use the `lowMemoryNotification`
|
||||||
// call on the isolate to encourage v8 to free the context.
|
// call on the isolate to encourage v8 to free the context.
|
||||||
pub fn stopExecutor(self: *Self, executor: *Executor, exit_context: bool) void {
|
pub fn stopExecutor(self: *Self, executor: *Executor) void {
|
||||||
executor.deinit(exit_context);
|
executor.deinit();
|
||||||
self.executor_pool.destroy(executor);
|
self.executor_pool.destroy(executor);
|
||||||
if (self.gc_hints) {
|
if (self.gc_hints) {
|
||||||
self.isolate.lowMemoryNotification();
|
self.isolate.lowMemoryNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (comptime builtin.mode == .Debug) {
|
if (comptime builtin.mode == .Debug) {
|
||||||
std.debug.assert(self.has_executor == true);
|
if (executor.kind == .main) {
|
||||||
self.has_executor = false;
|
std.debug.assert(self.has_executor == true);
|
||||||
|
self.has_executor = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +422,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
// object (i.e. the Window), which gets attached not only to the Window
|
// object (i.e. the Window), which gets attached not only to the Window
|
||||||
// constructor/FunctionTemplate as normal, but also through the default
|
// constructor/FunctionTemplate as normal, but also through the default
|
||||||
// FunctionTemplate of the isolate (in startExecutor)
|
// FunctionTemplate of the isolate (in startExecutor)
|
||||||
fn attachClass(self: *Self, comptime Struct: type, template: v8.FunctionTemplate) void {
|
fn attachClass(self: *const Self, comptime Struct: type, template: v8.FunctionTemplate) void {
|
||||||
const template_proto = template.getPrototypeTemplate();
|
const template_proto = template.getPrototypeTemplate();
|
||||||
inline for (@typeInfo(Struct).@"struct".decls) |declaration| {
|
inline for (@typeInfo(Struct).@"struct".decls) |declaration| {
|
||||||
const name = declaration.name;
|
const name = declaration.name;
|
||||||
@@ -491,7 +498,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generateMethod(self: *Self, comptime Struct: type, comptime name: []const u8, template_proto: v8.ObjectTemplate) void {
|
fn generateMethod(self: *const Self, comptime Struct: type, comptime name: []const u8, template_proto: v8.ObjectTemplate) void {
|
||||||
var js_name: v8.Name = undefined;
|
var js_name: v8.Name = undefined;
|
||||||
if (comptime std.mem.eql(u8, name, "_symbol_iterator")) {
|
if (comptime std.mem.eql(u8, name, "_symbol_iterator")) {
|
||||||
js_name = v8.Symbol.getIterator(self.isolate).toName();
|
js_name = v8.Symbol.getIterator(self.isolate).toName();
|
||||||
@@ -513,7 +520,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
template_proto.set(js_name, function_template, v8.PropertyAttribute.None);
|
template_proto.set(js_name, function_template, v8.PropertyAttribute.None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generateAttribute(self: *Self, comptime Struct: type, comptime name: []const u8, template: v8.FunctionTemplate, template_proto: v8.ObjectTemplate) void {
|
fn generateAttribute(self: *const Self, comptime Struct: type, comptime name: []const u8, template: v8.FunctionTemplate, template_proto: v8.ObjectTemplate) void {
|
||||||
const zig_value = @field(Struct, name);
|
const zig_value = @field(Struct, name);
|
||||||
const js_value = simpleZigValueToJs(self.isolate, zig_value, true);
|
const js_value = simpleZigValueToJs(self.isolate, zig_value, true);
|
||||||
|
|
||||||
@@ -526,7 +533,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
template_proto.set(js_name, js_value, v8.PropertyAttribute.ReadOnly + v8.PropertyAttribute.DontDelete);
|
template_proto.set(js_name, js_value, v8.PropertyAttribute.ReadOnly + v8.PropertyAttribute.DontDelete);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generateProperty(self: *Self, comptime Struct: type, comptime name: []const u8, template_proto: v8.ObjectTemplate) void {
|
fn generateProperty(self: *const Self, comptime Struct: type, comptime name: []const u8, template_proto: v8.ObjectTemplate) void {
|
||||||
const getter = @field(Struct, "get_" ++ name);
|
const getter = @field(Struct, "get_" ++ name);
|
||||||
const param_count = @typeInfo(@TypeOf(getter)).@"fn".params.len;
|
const param_count = @typeInfo(@TypeOf(getter)).@"fn".params.len;
|
||||||
|
|
||||||
@@ -576,7 +583,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
template_proto.setGetterAndSetter(js_name, getter_callback, setter_callback);
|
template_proto.setGetterAndSetter(js_name, getter_callback, setter_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generateIndexer(_: *Self, comptime Struct: type, template_proto: v8.ObjectTemplate) void {
|
fn generateIndexer(_: *const Self, comptime Struct: type, template_proto: v8.ObjectTemplate) void {
|
||||||
if (@hasDecl(Struct, "indexed_get") == false) {
|
if (@hasDecl(Struct, "indexed_get") == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -605,7 +612,7 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
template_proto.setIndexedProperty(configuration, null);
|
template_proto.setIndexedProperty(configuration, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generateNamedIndexer(_: *Self, comptime Struct: type, template_proto: v8.ObjectTemplate) void {
|
fn generateNamedIndexer(_: *const Self, comptime Struct: type, template_proto: v8.ObjectTemplate) void {
|
||||||
if (@hasDecl(Struct, "named_get") == false) {
|
if (@hasDecl(Struct, "named_get") == false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -765,10 +772,17 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
const PersistentObject = v8.Persistent(v8.Object);
|
const PersistentObject = v8.Persistent(v8.Object);
|
||||||
const PersistentFunction = v8.Persistent(v8.Function);
|
const PersistentFunction = v8.Persistent(v8.Function);
|
||||||
|
|
||||||
|
const WorldKind = enum {
|
||||||
|
main,
|
||||||
|
isolated,
|
||||||
|
worker,
|
||||||
|
};
|
||||||
|
|
||||||
// This is capable of executing JavaScript.
|
// This is capable of executing JavaScript.
|
||||||
pub const Executor = struct {
|
pub const Executor = struct {
|
||||||
state: State,
|
state: State,
|
||||||
isolate: v8.Isolate,
|
isolate: v8.Isolate,
|
||||||
|
kind: WorldKind,
|
||||||
|
|
||||||
handle_scope: v8.HandleScope,
|
handle_scope: v8.HandleScope,
|
||||||
|
|
||||||
@@ -819,9 +833,9 @@ pub fn Env(comptime S: type, comptime types: anytype) type {
|
|||||||
|
|
||||||
// not public, must be destroyed via env.stopExecutor()
|
// not public, must be destroyed via env.stopExecutor()
|
||||||
|
|
||||||
fn deinit(self: *Executor, exit_context: bool) void {
|
fn deinit(self: *Executor) void {
|
||||||
if (self.scope != null) self.endScope();
|
if (self.scope != null) self.endScope();
|
||||||
if (exit_context) self.context.exit();
|
if (self.kind == .main) self.context.exit();
|
||||||
self.handle_scope.deinit();
|
self.handle_scope.deinit();
|
||||||
|
|
||||||
self._call_arena_instance.deinit();
|
self._call_arena_instance.deinit();
|
||||||
|
|||||||
@@ -433,7 +433,7 @@ pub const JsRunner = struct {
|
|||||||
.tls_verify_host = false,
|
.tls_verify_host = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
runner.executor = try runner.env.startExecutor(Window, &runner.state, runner);
|
runner.executor = try runner.env.startExecutor(Window, &runner.state, runner, .main);
|
||||||
errdefer runner.env.stopExecutor(runner.executor);
|
errdefer runner.env.stopExecutor(runner.executor);
|
||||||
|
|
||||||
try runner.executor.startScope(&runner.window);
|
try runner.executor.startScope(&runner.window);
|
||||||
|
|||||||
Reference in New Issue
Block a user