diff --git a/src/browser/dom/mutation_observer.zig b/src/browser/dom/mutation_observer.zig index f5394ba8..a6447ade 100644 --- a/src/browser/dom/mutation_observer.zig +++ b/src/browser/dom/mutation_observer.zig @@ -38,7 +38,7 @@ pub const MutationObserver = struct { cbk: Env.Function, arena: Allocator, - // List of records which were observed. When the scopeEnds, we need to + // List of records which were observed. When the call scope ends, we need to // execute our callback with it. observed: std.ArrayListUnmanaged(*MutationRecord), diff --git a/src/browser/page.zig b/src/browser/page.zig index fcfc7748..396022db 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -85,7 +85,7 @@ pub const Page = struct { // Our JavaScript context for this specific page. This is what we use to // execute any JavaScript - scope: *Env.Scope, + main_context: *Env.JsContext, // List of modules currently fetched/loaded. module_map: std.StringHashMapUnmanaged([]const u8), @@ -118,13 +118,13 @@ pub const Page = struct { .request_factory = browser.http_client.requestFactory(.{ .notification = browser.notification, }), - .scope = undefined, + .main_context = undefined, .module_map = .empty, }; - self.scope = try session.executor.startScope(&self.window, self, self, true); + self.main_context = try session.executor.createJsContext(&self.window, self, self, true); // load polyfills - try polyfill.load(self.arena, self.scope); + try polyfill.load(self.arena, self.main_context); _ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.microtask_node); } @@ -166,7 +166,7 @@ pub const Page = struct { pub fn wait(self: *Page) !void { var try_catch: Env.TryCatch = undefined; - try_catch.init(self.scope); + try_catch.init(self.main_context); defer try_catch.deinit(); try self.session.browser.app.loop.run(); @@ -798,7 +798,7 @@ pub const Page = struct { pub fn stackTrace(self: *Page) !?[]const u8 { if (comptime builtin.mode == .Debug) { - return self.scope.stackTrace(); + return self.main_context.stackTrace(); } return null; } @@ -818,7 +818,7 @@ const DelayedNavigation = struct { // // In the first phase, when self.initial == true, we'll shutdown the page // and create a new one. The shutdown is important, because it resets the - // loop ctx_id and closes the scope. Closing the scope calls our XHR + // loop ctx_id and removes the JsContext. Removing the context calls our XHR // destructors which aborts requests. This is necessary to make sure our // [blocking] navigate won't block. // @@ -982,14 +982,14 @@ const Script = struct { fn eval(self: *const Script, page: *Page, body: []const u8) !void { var try_catch: Env.TryCatch = undefined; - try_catch.init(page.scope); + try_catch.init(page.main_context); defer try_catch.deinit(); const src = self.src orelse "inline"; _ = switch (self.kind) { - .javascript => page.scope.exec(body, src), + .javascript => page.main_context.exec(body, src), .module => blk: { - switch (try page.scope.module(body, src)) { + switch (try page.main_context.module(body, src)) { .value => |v| break :blk v, .exception => |e| { log.warn(.user_script, "eval module", .{ @@ -1023,9 +1023,9 @@ const Script = struct { switch (callback) { .string => |str| { var try_catch: Env.TryCatch = undefined; - try_catch.init(page.scope); + try_catch.init(page.main_context); defer try_catch.deinit(); - _ = page.scope.exec(str, typ) catch { + _ = page.main_context.exec(str, typ) catch { if (try try_catch.err(page.arena)) |msg| { log.warn(.user_script, "script callback", .{ .src = self.src, diff --git a/src/browser/polyfill/fetch.zig b/src/browser/polyfill/fetch.zig index d062a2cb..1438022a 100644 --- a/src/browser/polyfill/fetch.zig +++ b/src/browser/polyfill/fetch.zig @@ -16,7 +16,7 @@ test "Browser.fetch" { var runner = try testing.jsRunner(testing.tracking_allocator, .{}); defer runner.deinit(); - try @import("polyfill.zig").load(testing.allocator, runner.page.scope); + try @import("polyfill.zig").load(testing.allocator, runner.page.main_context); try runner.testCases(&.{ .{ diff --git a/src/browser/polyfill/polyfill.zig b/src/browser/polyfill/polyfill.zig index 5fc41c5d..f7baddc9 100644 --- a/src/browser/polyfill/polyfill.zig +++ b/src/browser/polyfill/polyfill.zig @@ -30,13 +30,13 @@ const modules = [_]struct { .{ .name = "polyfill-fetch", .source = @import("fetch.zig").source }, }; -pub fn load(allocator: Allocator, scope: *Env.Scope) !void { +pub fn load(allocator: Allocator, js_context: *Env.JsContext) !void { var try_catch: Env.TryCatch = undefined; - try_catch.init(scope); + try_catch.init(js_context); defer try_catch.deinit(); for (modules) |m| { - _ = scope.exec(m.source, m.name) catch |err| { + _ = js_context.exec(m.source, m.name) catch |err| { if (try try_catch.err(allocator)) |msg| { defer allocator.free(msg); log.fatal(.app, "polyfill error", .{ .name = m.name, .err = msg }); diff --git a/src/browser/session.zig b/src/browser/session.zig index b308ab64..8cedf7d7 100644 --- a/src/browser/session.zig +++ b/src/browser/session.zig @@ -116,11 +116,11 @@ pub const Session = struct { // phase. It's important that we clean these up, as they're holding onto // limited resources (like our fixed-sized http state pool). // - // First thing we do, is endScope() which will execute the destructor + // First thing we do, is removeJsContext() which will execute the destructor // of any type that registered a destructor (e.g. XMLHttpRequest). // This will shutdown any pending sockets, which begins our cleaning // processed - self.executor.endScope(); + self.executor.removeJsContext(); // Second thing we do is reset the loop. This increments the loop ctx_id // so that any "stale" timeouts we process will get ignored. We need to diff --git a/src/cdp/cdp.zig b/src/cdp/cdp.zig index fd8a1da6..3b0005f4 100644 --- a/src/cdp/cdp.zig +++ b/src/cdp/cdp.zig @@ -555,8 +555,8 @@ const IsolatedWorld = struct { self.executor.deinit(); } pub fn removeContext(self: *IsolatedWorld) !void { - if (self.executor.scope == null) return error.NoIsolatedContextToRemove; - self.executor.endScope(); + if (self.executor.js_context == null) return error.NoIsolatedContextToRemove; + self.executor.removeJsContext(); } // The isolate world must share at least some of the state with the related page, specifically the DocumentHTML @@ -565,8 +565,8 @@ const IsolatedWorld = struct { // This also means this pointer becomes invalid after removePage untill a new page is created. // Currently we have only 1 page/frame and thus also only 1 state in the isolate world. pub fn createContext(self: *IsolatedWorld, page: *Page) !void { - if (self.executor.scope != null) return error.Only1IsolatedContextSupported; - _ = try self.executor.startScope(&page.window, page, {}, false); + if (self.executor.js_context != null) return error.Only1IsolatedContextSupported; + _ = try self.executor.createJsContext(&page.window, page, {}, false); } }; diff --git a/src/cdp/domains/dom.zig b/src/cdp/domains/dom.zig index 4e8bd03a..89a077f6 100644 --- a/src/cdp/domains/dom.zig +++ b/src/cdp/domains/dom.zig @@ -259,13 +259,13 @@ fn resolveNode(cmd: anytype) !void { const bc = cmd.browser_context orelse return error.BrowserContextNotLoaded; const page = bc.session.currentPage() orelse return error.PageNotLoaded; - var scope = page.scope; + var js_context = page.main_context; if (params.executionContextId) |context_id| { - if (scope.context.debugContextId() != context_id) { + if (js_context.v8_context.debugContextId() != context_id) { var isolated_world = bc.isolated_world orelse return error.ContextNotFound; - scope = &(isolated_world.executor.scope orelse return error.ContextNotFound); + js_context = &(isolated_world.executor.js_context orelse return error.ContextNotFound); - if (scope.context.debugContextId() != context_id) return error.ContextNotFound; + if (js_context.v8_context.debugContextId() != context_id) return error.ContextNotFound; } } @@ -275,7 +275,7 @@ fn resolveNode(cmd: anytype) !void { // node._node is a *parser.Node we need this to be able to find its most derived type e.g. Node -> Element -> HTMLElement // So we use the Node.Union when retrieve the value from the environment const remote_object = try bc.inspector.getRemoteObject( - scope, + js_context, params.objectGroup orelse "", try dom_node.Node.toInterface(node._node), ); diff --git a/src/cdp/domains/page.zig b/src/cdp/domains/page.zig index 5ed9dd13..36150619 100644 --- a/src/cdp/domains/page.zig +++ b/src/cdp/domains/page.zig @@ -117,14 +117,14 @@ fn createIsolatedWorld(cmd: anytype) !void { const world = try bc.createIsolatedWorld(params.worldName, params.grantUniveralAccess); const page = bc.session.currentPage() orelse return error.PageNotLoaded; try pageCreated(bc, page); - const scope = &world.executor.scope.?; + const js_context = &world.executor.js_context.?; // Create the auxdata json for the contextCreated event // Calling contextCreated will assign a Id to the context and send the contextCreated event const aux_data = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":false,\"type\":\"isolated\",\"frameId\":\"{s}\"}}", .{params.frameId}); - bc.inspector.contextCreated(scope, world.name, "", aux_data, false); + bc.inspector.contextCreated(js_context, world.name, "", aux_data, false); - return cmd.sendResult(.{ .executionContextId = scope.context.debugContextId() }, .{}); + return cmd.sendResult(.{ .executionContextId = js_context.v8_context.debugContextId() }, .{}); } fn navigate(cmd: anytype) !void { @@ -253,7 +253,7 @@ pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.Pa const page = bc.session.currentPage() orelse return error.PageNotLoaded; const aux_data = try std.fmt.allocPrint(arena, "{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}", .{target_id}); bc.inspector.contextCreated( - page.scope, + page.main_context, "", try page.origin(arena), aux_data, @@ -264,7 +264,7 @@ pub fn pageNavigate(arena: Allocator, bc: anytype, event: *const Notification.Pa const aux_json = try std.fmt.allocPrint(arena, "{{\"isDefault\":false,\"type\":\"isolated\",\"frameId\":\"{s}\"}}", .{target_id}); // Calling contextCreated will assign a new Id to the context and send the contextCreated event bc.inspector.contextCreated( - &isolated_world.executor.scope.?, + &isolated_world.executor.js_context.?, isolated_world.name, "://", aux_json, @@ -286,7 +286,7 @@ pub fn pageCreated(bc: anytype, page: *Page) !void { try isolated_world.createContext(page); const polyfill = @import("../../browser/polyfill/polyfill.zig"); - try polyfill.load(bc.arena, &isolated_world.executor.scope.?); + try polyfill.load(bc.arena, &isolated_world.executor.js_context.?); } } diff --git a/src/cdp/domains/target.zig b/src/cdp/domains/target.zig index 3461bd44..c0d76ec0 100644 --- a/src/cdp/domains/target.zig +++ b/src/cdp/domains/target.zig @@ -127,7 +127,7 @@ fn createTarget(cmd: anytype) !void { { const aux_data = try std.fmt.allocPrint(cmd.arena, "{{\"isDefault\":true,\"type\":\"default\",\"frameId\":\"{s}\"}}", .{target_id}); bc.inspector.contextCreated( - page.scope, + page.main_context, "", try page.origin(cmd.arena), aux_data, diff --git a/src/main_wpt.zig b/src/main_wpt.zig index 614b4968..90bcafba 100644 --- a/src/main_wpt.zig +++ b/src/main_wpt.zig @@ -113,7 +113,7 @@ fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *? }); defer runner.deinit(); - try polyfill.load(arena, runner.page.scope); + try polyfill.load(arena, runner.page.main_context); // loop over the scripts. const doc = parser.documentHTMLToDocument(runner.page.window.document); @@ -155,7 +155,7 @@ fn run(arena: Allocator, test_file: []const u8, loader: *FileLoader, err_out: *? { // wait for all async executions var try_catch: Env.TryCatch = undefined; - try_catch.init(runner.page.scope); + try_catch.init(runner.page.main_context); defer try_catch.deinit(); try runner.page.loop.run(); diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 788d9eec..6cea2b21 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -27,7 +27,7 @@ const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; const CALL_ARENA_RETAIN = 1024 * 16; -const SCOPE_ARENA_RETAIN = 1024 * 64; +const CONTEXT_ARENA_RETAIN = 1024 * 64; // Global, should only be initialized once. pub const Platform = struct { @@ -261,9 +261,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub fn newExecutionWorld(self: *Self) !ExecutionWorld { return .{ .env = self, - .scope = null, + .js_context = null, .call_arena = ArenaAllocator.init(self.allocator), - .scope_arena = ArenaAllocator.init(self.allocator), + .context_arena = ArenaAllocator.init(self.allocator), }; } @@ -286,43 +286,43 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // Arena whose lifetime is for a single getter/setter/function/etc. // Largely used to get strings out of V8, like a stack trace from - // a TryCatch. The allocator will be owned by the Scope, but the + // a TryCatch. The allocator will be owned by the JsContext, but the // arena itself is owned by the ExecutionWorld so that we can re-use it - // from scope to scope. + // from context to context. call_arena: ArenaAllocator, - // Arena whose lifetime is for a single page load, aka a Scope. Where - // the call_arena lives for a single function call, the scope_arena + // Arena whose lifetime is for a single page load. Where + // the call_arena lives for a single function call, the context_arena // lives for the lifetime of the entire page. The allocator will be - // owned by the Scope, but the arena itself is owned by the ExecutionWorld - // so that we can re-use it from scope to scope. - scope_arena: ArenaAllocator, + // owned by the JsContext, but the arena itself is owned by the ExecutionWorld + // so that we can re-use it from context to context. + context_arena: ArenaAllocator, - // A Scope maps to a Browser's Page. Here though, it's only a + // Currently a context maps to a Browser's Page. Here though, it's only a // mechanism to organization page-specific memory. The ExecutionWorld // does all the work, but having all page-specific data structures // grouped together helps keep things clean. - scope: ?Scope = null, + js_context: ?JsContext = null, // no init, must be initialized via env.newExecutionWorld() pub fn deinit(self: *ExecutionWorld) void { - if (self.scope != null) { - self.endScope(); + if (self.js_context != null) { + self.removeJsContext(); } self.call_arena.deinit(); - self.scope_arena.deinit(); + self.context_arena.deinit(); } - // Our scope maps to a "browser.Page". + // Only the top JsContext in the Main ExecutionWorld should hold a handle_scope. // A v8.HandleScope is like an arena. Once created, any "Local" that // v8 creates will be released (or at least, releasable by the v8 GC) // when the handle_scope is freed. - // We also maintain our own "scope_arena" which allows us to have + // We also maintain our own "context_arena" which allows us to have // all page related memory easily managed. - pub fn startScope(self: *ExecutionWorld, global: anytype, state: State, module_loader: anytype, enter: bool) !*Scope { - std.debug.assert(self.scope == null); + pub fn createJsContext(self: *ExecutionWorld, global: anytype, state: State, module_loader: anytype, enter: bool) !*JsContext { + std.debug.assert(self.js_context == null); const ModuleLoader = switch (@typeInfo(@TypeOf(module_loader))) { .@"struct" => @TypeOf(module_loader), @@ -338,7 +338,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const isolate = env.isolate; const Global = @TypeOf(global.*); - var context: v8.Context = blk: { + var v8_context: v8.Context = blk: { var temp_scope: v8.HandleScope = undefined; v8.HandleScope.init(&temp_scope, isolate); defer temp_scope.deinit(); @@ -371,10 +371,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } const context_local = v8.Context.init(isolate, global_template, null); - const context = v8.Persistent(v8.Context).init(isolate, context_local).castToContext(); - context.enter(); - errdefer if (enter) context.exit(); - defer if (!enter) context.exit(); + const v8_context = v8.Persistent(v8.Context).init(isolate, context_local).castToContext(); + v8_context.enter(); + errdefer if (enter) v8_context.exit(); + defer if (!enter) v8_context.exit(); // This shouldn't be necessary, but it is: // https://groups.google.com/g/v8-users/c/qAQQBmbi--8 @@ -390,13 +390,13 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } const proto_index = @field(TYPE_LOOKUP, proto_name).index; - const proto_obj = templates[proto_index].getFunction(context).toObject(); + const proto_obj = templates[proto_index].getFunction(v8_context).toObject(); - const self_obj = templates[i].getFunction(context).toObject(); - _ = self_obj.setPrototype(context, proto_obj); + const self_obj = templates[i].getFunction(v8_context).toObject(); + _ = self_obj.setPrototype(v8_context, proto_obj); } } - break :blk context; + break :blk v8_context; }; // For a Page we only create one HandleScope, it is stored in the main World (enter==true). A page can have multple contexts, 1 for each World. @@ -412,34 +412,34 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { { // If we want to overwrite the built-in console, we have to // delete the built-in one. - const js_obj = context.getGlobal(); + const js_obj = v8_context.getGlobal(); const console_key = v8.String.initUtf8(isolate, "console"); - if (js_obj.deleteValue(context, console_key) == false) { + if (js_obj.deleteValue(v8_context, console_key) == false) { return error.ConsoleDeleteError; } } - self.scope = Scope{ + self.js_context = JsContext{ .state = state, .isolate = isolate, - .context = context, + .v8_context = v8_context, .templates = &env.templates, .handle_scope = handle_scope, .call_arena = self.call_arena.allocator(), - .scope_arena = self.scope_arena.allocator(), + .context_arena = self.context_arena.allocator(), .module_loader = .{ .ptr = safe_module_loader, .func = ModuleLoader.fetchModuleSource, }, }; - var scope = &self.scope.?; + var js_context = &self.js_context.?; { // Given a context, we can get our executor. // (we store a pointer to our executor in the context's // embeddeder data) - const data = isolate.initBigIntU64(@intCast(@intFromPtr(scope))); - context.setEmbedderData(1, data); + const data = isolate.initBigIntU64(@intCast(@intFromPtr(js_context))); + v8_context.setEmbedderData(1, data); } { @@ -448,7 +448,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // call_arena field, fill-it in now. const state_type_info = @typeInfo(@TypeOf(state)); if (state_type_info == .pointer and @hasField(state_type_info.pointer.child, "call_arena")) { - scope.state.call_arena = scope.call_arena; + js_context.state.call_arena = js_context.call_arena; } } @@ -459,18 +459,18 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const Struct = s.defaultValue().?; if (@hasDecl(Struct, "ErrorSet")) { const script = comptime classNameForStruct(Struct) ++ ".prototype.__proto__ = Error.prototype"; - _ = try scope.exec(script, "errorSubclass"); + _ = try js_context.exec(script, "errorSubclass"); } } - _ = try scope._mapZigInstanceToJs(context.getGlobal(), global); - return scope; + _ = try js_context._mapZigInstanceToJs(v8_context.getGlobal(), global); + return js_context; } - pub fn endScope(self: *ExecutionWorld) void { - self.scope.?.deinit(); - self.scope = null; - _ = self.scope_arena.reset(.{ .retain_with_limit = SCOPE_ARENA_RETAIN }); + pub fn removeJsContext(self: *ExecutionWorld) void { + self.js_context.?.deinit(); + self.js_context = null; + _ = self.context_arena.reset(.{ .retain_with_limit = CONTEXT_ARENA_RETAIN }); } pub fn terminateExecution(self: *const ExecutionWorld) void { @@ -486,11 +486,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const PersistentFunction = v8.Persistent(v8.Function); // Loosely maps to a Browser Page. - pub const Scope = struct { + pub const JsContext = struct { state: State, isolate: v8.Isolate, // This context is a persistent object. The persistent needs to be recovered and reset. - context: v8.Context, + v8_context: v8.Context, handle_scope: ?v8.HandleScope, // references the Env.template array @@ -500,8 +500,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // call_depth reaches 0. call_arena: Allocator, - // An arena for the lifetime of the scope - scope_arena: Allocator, + // An arena for the lifetime of the context + context_arena: Allocator, // Because calls can be nested (i.e.a function calling a callback), // we can only reset the call_arena when call_depth == 0. If we were @@ -509,12 +509,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // the call which is calling the callback. call_depth: usize = 0, - // Callbacks are PesistendObjects. When the scope ends, we need + // Callbacks are PesistendObjects. When the context ends, we need // to free every callback we created. callbacks: std.ArrayListUnmanaged(v8.Persistent(v8.Function)) = .empty, // Serves two purposes. Like `callbacks` above, this is used to free - // every PeristentObjet we've created during the lifetime of the scope. + // every PeristentObjet we've created during the lifetime of the context. // More importantly, it serves as an identity map - for a given Zig // instance, we map it to the same PersistentObject. // The key is the @intFromPtr of the Zig value @@ -545,9 +545,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { func: *const fn (ptr: *anyopaque, specifier: []const u8) anyerror!?[]const u8, }; - // no init, started with executor.startScope() + // no init, started with executor.createJsContext() - fn deinit(self: *Scope) void { + fn deinit(self: *JsContext) void { { // reverse order, as this has more chance of respecting any // dependencies objects might have with each other. @@ -578,14 +578,14 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } if (self.handle_scope) |*scope| { scope.deinit(); - self.context.exit(); + self.v8_context.exit(); } - var presistent_context = v8.Persistent(v8.Context).recoverCast(self.context); + var presistent_context = v8.Persistent(v8.Context).recoverCast(self.v8_context); presistent_context.deinit(); } - fn trackCallback(self: *Scope, pf: PersistentFunction) !void { - return self.callbacks.append(self.scope_arena, pf); + fn trackCallback(self: *JsContext, pf: PersistentFunction) !void { + return self.callbacks.append(self.context_arena, pf); } // Given an anytype, turns it into a v8.Object. The anytype could be: @@ -593,7 +593,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // 2 - Our JsObject wrapper around a V8.Object // 3 - A zig instance that has previously been given to V8 // (i.e., the value has to be known to the executor) - fn valueToExistingObject(self: *const Scope, value: anytype) !v8.Object { + fn valueToExistingObject(self: *const JsContext, value: anytype) !v8.Object { if (@TypeOf(value) == v8.Object) { return value; } @@ -609,14 +609,14 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return persistent_object.castToObject(); } - pub fn stackTrace(self: *const Scope) !?[]const u8 { + pub fn stackTrace(self: *const JsContext) !?[]const u8 { return stackForLogs(self.call_arena, self.isolate); } // Executes the src - pub fn exec(self: *Scope, src: []const u8, name: ?[]const u8) !Value { + pub fn exec(self: *JsContext, src: []const u8, name: ?[]const u8) !Value { const isolate = self.isolate; - const context = self.context; + const v8_context = self.v8_context; var origin: ?v8.ScriptOrigin = null; if (name) |n| { @@ -624,11 +624,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { origin = v8.ScriptOrigin.initDefault(scr_name.toValue()); } const scr_js = v8.String.initUtf8(isolate, src); - const scr = v8.Script.compile(context, scr_js, origin) catch { + const scr = v8.Script.compile(v8_context, scr_js, origin) catch { return error.CompilationError; }; - const value = scr.run(context) catch { + const value = scr.run(v8_context) catch { return error.ExecutionError; }; @@ -637,13 +637,13 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // compile and eval a JS module // It doesn't wait for callbacks execution - pub fn module(self: *Scope, src: []const u8, name: []const u8) !union(enum) { value: Value, exception: Exception } { - const context = self.context; + pub fn module(self: *JsContext, src: []const u8, name: []const u8) !union(enum) { value: Value, exception: Exception } { + const v8_context = self.v8_context; const m = try compileModule(self.isolate, src, name); // instantiate // resolveModuleCallback loads module's dependencies. - const ok = m.instantiate(context, resolveModuleCallback) catch { + const ok = m.instantiate(v8_context, resolveModuleCallback) catch { return error.ExecutionError; }; @@ -652,40 +652,40 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } // evaluate - const value = m.evaluate(context) catch { + const value = m.evaluate(v8_context) catch { return .{ .exception = self.createException(m.getException()) }; }; return .{ .value = self.createValue(value) }; } // Wrap a v8.Exception - fn createException(self: *const Scope, e: v8.Value) Exception { + fn createException(self: *const JsContext, e: v8.Value) Exception { return .{ .inner = e, - .scope = self, + .js_context = self, }; } // Wrap a v8.Value, largely so that we can provide a convenient // toString function - fn createValue(self: *const Scope, value: v8.Value) Value { + fn createValue(self: *const JsContext, value: v8.Value) Value { return .{ .value = value, - .scope = self, + .js_context = self, }; } - fn zigValueToJs(self: *const Scope, value: anytype) !v8.Value { - return Self.zigValueToJs(self.templates, self.isolate, self.context, value); + fn zigValueToJs(self: *const JsContext, value: anytype) !v8.Value { + return Self.zigValueToJs(self.templates, self.isolate, self.v8_context, value); } // See _mapZigInstanceToJs, this is wrapper that can be called - // without a Scope. This is possible because we store our - // scope in the EmbedderData of the v8.Context. So, as long as - // we have a v8.Context, we can get the scope. - fn mapZigInstanceToJs(context: v8.Context, js_obj_or_template: anytype, value: anytype) !PersistentObject { - const scope: *Scope = @ptrFromInt(context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); - return scope._mapZigInstanceToJs(js_obj_or_template, value); + // without a Context. This is possible because we store our + // js_context in the EmbedderData of the v8.Context. So, as long as + // we have a v8.Context, we can get the js_context. + fn mapZigInstanceToJs(v8_context: v8.Context, js_obj_or_template: anytype, value: anytype) !PersistentObject { + const js_context: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); + return js_context._mapZigInstanceToJs(js_obj_or_template, value); } // To turn a Zig instance into a v8 object, we need to do a number of things. @@ -701,20 +701,20 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // 4 - Store our TaggedAnyOpaque into the persistent object // 5 - Update our identity_map (so that, if we return this same instance again, // we can just grab it from the identity_map) - fn _mapZigInstanceToJs(self: *Scope, js_obj_or_template: anytype, value: anytype) !PersistentObject { - const context = self.context; - const scope_arena = self.scope_arena; + fn _mapZigInstanceToJs(self: *JsContext, js_obj_or_template: anytype, value: anytype) !PersistentObject { + const v8_context = self.v8_context; + const context_arena = self.context_arena; const T = @TypeOf(value); switch (@typeInfo(T)) { .@"struct" => { // Struct, has to be placed on the heap - const heap = try scope_arena.create(T); + const heap = try context_arena.create(T); heap.* = value; return self._mapZigInstanceToJs(js_obj_or_template, heap); }, .pointer => |ptr| { - const gop = try self.identity_map.getOrPut(scope_arena, @intFromPtr(value)); + const gop = try self.identity_map.getOrPut(context_arena, @intFromPtr(value)); if (gop.found_existing) { // we've seen this instance before, return the same // PersistentObject. @@ -722,11 +722,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } if (comptime @hasDecl(ptr.child, "destructor")) { - try self.destructor_callbacks.append(scope_arena, DestructorCallback.init(value)); + try self.destructor_callbacks.append(context_arena, DestructorCallback.init(value)); } if (comptime @hasDecl(ptr.child, "jsCallScopeEnd")) { - try self.call_scope_end_callbacks.append(scope_arena, CallScopeEndCallback.init(value)); + try self.call_scope_end_callbacks.append(context_arena, CallScopeEndCallback.init(value)); } // Sometimes we're creating a new v8.Object, like when @@ -738,7 +738,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // already created the "this" object. const js_obj = switch (@TypeOf(js_obj_or_template)) { v8.Object => js_obj_or_template, - v8.FunctionTemplate => js_obj_or_template.getInstanceTemplate().initInstance(context), + v8.FunctionTemplate => js_obj_or_template.getInstanceTemplate().initInstance(v8_context), else => @compileError("mapZigInstanceToJs requires a v8.Object (constructors) or v8.FunctionTemplate, got: " ++ @typeName(@TypeOf(js_obj_or_template))), }; @@ -748,7 +748,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // The TAO contains the pointer ot our Zig instance as // well as any meta data we'll need to use it later. // See the TaggedAnyOpaque struct for more details. - const tao = try scope_arena.create(TaggedAnyOpaque); + const tao = try context_arena.create(TaggedAnyOpaque); const meta = @field(TYPE_LOOKUP, @typeName(ptr.child)); tao.* = .{ .ptr = value, @@ -774,7 +774,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { gop.value_ptr.* = js_persistent; if (@hasDecl(ptr.child, "postAttach")) { - const obj_wrap = JsThis{ .obj = .{ .js_obj = js_obj, .scope = self } }; + const obj_wrap = JsThis{ .obj = .{ .js_obj = js_obj, .js_context = self } }; switch (@typeInfo(@TypeOf(ptr.child.postAttach)).@"fn".params.len) { 2 => try value.postAttach(obj_wrap), 3 => try value.postAttach(self.state, obj_wrap), @@ -788,7 +788,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } } - fn jsValueToZig(self: *Scope, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !T { + fn jsValueToZig(self: *JsContext, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !T { switch (@typeInfo(T)) { .optional => |o| { if (js_value.isNullOrUndefined()) { @@ -797,11 +797,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return try self.jsValueToZig(named_function, o.child, js_value); }, .float => |f| switch (f.bits) { - 0...32 => return js_value.toF32(self.context), - 33...64 => return js_value.toF64(self.context), + 0...32 => return js_value.toF32(self.v8_context), + 33...64 => return js_value.toF64(self.v8_context), else => {}, }, - .int => return jsIntToZig(T, js_value, self.context), + .int => return jsIntToZig(T, js_value, self.v8_context), .bool => return js_value.toBool(self.isolate), .pointer => |ptr| switch (ptr.size) { .one => { @@ -881,10 +881,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { if (ptr.child == u8) { if (ptr.sentinel()) |s| { if (comptime s == 0) { - return valueToStringZ(self.call_arena, js_value, self.isolate, self.context); + return valueToStringZ(self.call_arena, js_value, self.isolate, self.v8_context); } } else { - return valueToString(self.call_arena, js_value, self.isolate, self.context); + return valueToString(self.call_arena, js_value, self.isolate, self.v8_context); } } @@ -892,7 +892,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return error.InvalidArgument; } - const context = self.context; + const v8_context = self.v8_context; const js_arr = js_value.castTo(v8.Array); const js_obj = js_arr.castTo(v8.Object); @@ -900,7 +900,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // to do this (V8::Array has an iterate method on it) const arr = try self.call_arena.alloc(ptr.child, js_arr.length()); for (arr, 0..) |*a, i| { - a.* = try self.jsValueToZig(named_function, ptr.child, try js_obj.getAtIndex(context, @intCast(i))); + a.* = try self.jsValueToZig(named_function, ptr.child, try js_obj.getAtIndex(v8_context, @intCast(i))); } return arr; }, @@ -952,7 +952,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { }, .@"enum" => |e| { switch (@typeInfo(e.tag_type)) { - .int => return std.meta.intToEnum(T, try jsIntToZig(e.tag_type, js_value, self.context)), + .int => return std.meta.intToEnum(T, try jsIntToZig(e.tag_type, js_value, self.v8_context)), else => @compileError(named_function.full_name ++ " has an unsupported enum parameter type: " ++ @typeName(T)), } }, @@ -964,7 +964,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // Extracted so that it can be used in both jsValueToZig and in // probeJsValueToZig. Avoids having to duplicate this logic when probing. - fn jsValueToStruct(self: *Scope, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !?T { + fn jsValueToStruct(self: *JsContext, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !?T { if (@hasDecl(T, "_FUNCTION_ID_KLUDGE")) { if (!js_value.isFunction()) { return null; @@ -979,7 +979,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // that it needs to pass back into a callback return JsObject{ .js_obj = js_obj, - .scope = self, + .js_context = self, }; } @@ -987,15 +987,15 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return null; } - const context = self.context; + const v8_context = self.v8_context; const isolate = self.isolate; var value: T = undefined; inline for (@typeInfo(T).@"struct".fields) |field| { const name = field.name; const key = v8.String.initUtf8(isolate, name); - if (js_obj.has(context, key.toValue())) { - @field(value, name) = try self.jsValueToZig(named_function, field.type, try js_obj.getValue(context, key)); + if (js_obj.has(v8_context, key.toValue())) { + @field(value, name) = try self.jsValueToZig(named_function, field.type, try js_obj.getValue(v8_context, key)); } else if (@typeInfo(field.type) == .optional) { @field(value, name) = null; } else { @@ -1006,7 +1006,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return value; } - fn createFunction(self: *Scope, js_value: v8.Value) !Function { + fn createFunction(self: *JsContext, js_value: v8.Value) !Function { // caller should have made sure this was a function std.debug.assert(js_value.isFunction()); @@ -1015,7 +1015,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { return .{ .func = func, - .scope = self, + .js_context = self, .id = js_value.castTo(v8.Object).getIdentityHash(), }; } @@ -1056,7 +1056,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { invalid: void, }; } - fn probeJsValueToZig(self: *Scope, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !ProbeResult(T) { + fn probeJsValueToZig(self: *JsContext, comptime named_function: NamedFunction, comptime T: type, js_value: v8.Value) !ProbeResult(T) { switch (@typeInfo(T)) { .optional => |o| { if (js_value.isNullOrUndefined()) { @@ -1171,9 +1171,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // We settle for just probing the first value. Ok, actually // not tricky in this case either. - const context = self.context; + const v8_context = self.v8_context; const js_obj = js_arr.castTo(v8.Object); - switch (try self.probeJsValueToZig(named_function, ptr.child, try js_obj.getAtIndex(context, 0))) { + switch (try self.probeJsValueToZig(named_function, ptr.child, try js_obj.getAtIndex(v8_context, 0))) { .value, .ok => return .{ .ok = {} }, .compatible => return .{ .compatible = {} }, .coerce => return .{ .coerce = {} }, @@ -1208,16 +1208,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { _ = referrer; std.debug.assert(c_context != null); - const context = v8.Context{ .handle = c_context.? }; + const v8_context = v8.Context{ .handle = c_context.? }; - const self: *Scope = @ptrFromInt(context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); + const self: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); // build the specifier value. const specifier = valueToString( self.call_arena, .{ .handle = c_specifier.? }, self.isolate, - context, + v8_context, ) catch |e| { log.err(.js, "resolve module specifier", .{ .err = e }); return null; @@ -1241,7 +1241,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub const Function = struct { id: usize, - scope: *Scope, + js_context: *JsContext, this: ?v8.Object = null, func: PersistentFunction, @@ -1261,13 +1261,13 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const this_obj = if (@TypeOf(value) == JsObject) value.js_obj else - try self.scope.valueToExistingObject(value); + try self.js_context.valueToExistingObject(value); return .{ .id = self.id, .this = this_obj, .func = self.func, - .scope = self.scope, + .js_context = self.js_context, }; } @@ -1281,12 +1281,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub fn tryCallWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype, result: *Result) !T { var try_catch: TryCatch = undefined; - try_catch.init(self.scope); + try_catch.init(self.js_context); defer try_catch.deinit(); return self.callWithThis(T, this, args) catch |err| { if (try_catch.hasCaught()) { - const allocator = self.scope.call_arena; + const allocator = self.js_context.call_arena; result.stack = try_catch.stack(allocator) catch null; result.exception = (try_catch.exception(allocator) catch @errorName(err)) orelse @errorName(err); } else { @@ -1298,42 +1298,42 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } pub fn callWithThis(self: *const Function, comptime T: type, this: anytype, args: anytype) !T { - const scope = self.scope; + const js_context = self.js_context; - const js_this = try scope.valueToExistingObject(this); + const js_this = try js_context.valueToExistingObject(this); const aargs = if (comptime @typeInfo(@TypeOf(args)) == .null) struct {}{} else args; const fields = @typeInfo(@TypeOf(aargs)).@"struct".fields; var js_args: [fields.len]v8.Value = undefined; inline for (fields, 0..) |f, i| { - js_args[i] = try scope.zigValueToJs(@field(aargs, f.name)); + js_args[i] = try js_context.zigValueToJs(@field(aargs, f.name)); } - const result = self.func.castToFunction().call(scope.context, js_this, &js_args); + const result = self.func.castToFunction().call(js_context.v8_context, js_this, &js_args); if (result == null) { return error.JSExecCallback; } if (@typeInfo(T) == .void) return {}; const named_function = comptime NamedFunction.init(T, "callResult"); - return scope.jsValueToZig(named_function, T, result.?); + return js_context.jsValueToZig(named_function, T, result.?); } fn getThis(self: *const Function) v8.Object { - return self.this orelse self.scope.context.getGlobal(); + return self.this orelse self.js_context.v8_context.getGlobal(); } // debug/helper to print the source of the JS callback pub fn printFunc(self: Function) !void { - const scope = self.scope; + const js_context = self.js_context; const value = self.func.castToFunction().toValue(); - const src = try valueToString(scope.call_arena, value, scope.isolate, scope.context); + const src = try valueToString(js_context.call_arena, value, js_context.isolate, js_context.v8_context); std.debug.print("{s}\n", .{src}); } }; pub const JsObject = struct { - scope: *Scope, + js_context: *JsContext, js_obj: v8.Object, // If a Zig struct wants the JsObject parameter, it'll declare a @@ -1357,45 +1357,45 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub fn setIndex(self: JsObject, index: u32, value: anytype, opts: SetOpts) !void { const key = switch (index) { inline 0...1000 => |i| std.fmt.comptimePrint("{d}", .{i}), - else => try std.fmt.allocPrint(self.scope.scope_arena, "{d}", .{index}), + else => try std.fmt.allocPrint(self.js_context.context_arena, "{d}", .{index}), }; return self.set(key, value, opts); } pub fn set(self: JsObject, key: []const u8, value: anytype, opts: SetOpts) !void { - const scope = self.scope; + const js_context = self.js_context; - const js_key = v8.String.initUtf8(scope.isolate, key); - const js_value = try scope.zigValueToJs(value); + const js_key = v8.String.initUtf8(js_context.isolate, key); + const js_value = try js_context.zigValueToJs(value); - const res = self.js_obj.defineOwnProperty(scope.context, js_key.toName(), js_value, @bitCast(opts)) orelse false; + const res = self.js_obj.defineOwnProperty(js_context.v8_context, js_key.toName(), js_value, @bitCast(opts)) orelse false; if (!res) { return error.FailedToSet; } } pub fn get(self: JsObject, key: []const u8) !Value { - const scope = self.scope; - const js_key = v8.String.initUtf8(scope.isolate, key); - const js_val = try self.js_obj.getValue(scope.context, js_key); - return scope.createValue(js_val); + const js_context = self.js_context; + const js_key = v8.String.initUtf8(js_context.isolate, key); + const js_val = try self.js_obj.getValue(js_context.v8_context, js_key); + return js_context.createValue(js_val); } pub fn isTruthy(self: JsObject) bool { const js_value = self.js_obj.toValue(); - return js_value.toBool(self.scope.isolate); + return js_value.toBool(self.js_context.isolate); } pub fn toString(self: JsObject) ![]const u8 { - const scope = self.scope; + const js_context = self.js_context; const js_value = self.js_obj.toValue(); - return valueToString(scope.call_arena, js_value, scope.isolate, scope.context); + return valueToString(js_context.call_arena, js_value, js_context.isolate, js_context.v8_context); } pub fn toDetailString(self: JsObject) ![]const u8 { - const scope = self.scope; + const js_context = self.js_context; const js_value = self.js_obj.toValue(); - return valueToDetailString(scope.call_arena, js_value, scope.isolate, scope.context); + return valueToDetailString(js_context.call_arena, js_value, js_context.isolate, js_context.v8_context); } pub fn format(self: JsObject, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { @@ -1403,17 +1403,17 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } pub fn persist(self: JsObject) !JsObject { - var scope = self.scope; + var js_context = self.js_context; const js_obj = self.js_obj; const handle = js_obj.handle; - const gop = try scope.js_object_map.getOrPut(scope.scope_arena, @intFromPtr(handle)); + const gop = try js_context.js_object_map.getOrPut(js_context.context_arena, @intFromPtr(handle)); if (gop.found_existing == false) { - gop.value_ptr.* = PersistentObject.init(scope.isolate, js_obj); + gop.value_ptr.* = PersistentObject.init(js_context.isolate, js_obj); } return .{ - .scope = scope, + .js_context = js_context, .js_obj = gop.value_ptr.castToObject(), }; } @@ -1422,15 +1422,15 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { if (self.isNullOrUndefined()) { return null; } - const scope = self.scope; + const js_context = self.js_context; - const js_name = v8.String.initUtf8(scope.isolate, name); + const js_name = v8.String.initUtf8(js_context.isolate, name); - const js_value = try self.js_obj.getValue(scope.context, js_name.toName()); + const js_value = try self.js_obj.getValue(js_context.v8_context, js_name.toName()); if (!js_value.isFunction()) { return null; } - return try scope.createFunction(js_value); + return try js_context.createFunction(js_value); } pub fn isNullOrUndefined(self: JsObject) bool { @@ -1438,15 +1438,15 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } pub fn nameIterator(self: JsObject) ValueIterator { - const scope = self.scope; + const js_context = self.js_context; const js_obj = self.js_obj; - const array = js_obj.getPropertyNames(scope.context); + const array = js_obj.getPropertyNames(js_context.v8_context); const count = array.length(); return .{ .count = count, - .scope = scope, + .js_context = js_context, .js_obj = array.castTo(v8.Object), }; } @@ -1476,11 +1476,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub const TryCatch = struct { inner: v8.TryCatch, - scope: *const Scope, + js_context: *const JsContext, - pub fn init(self: *TryCatch, scope: *const Scope) void { - self.scope = scope; - self.inner.init(scope.isolate); + pub fn init(self: *TryCatch, js_context: *const JsContext) void { + self.js_context = js_context; + self.inner.init(js_context.isolate); } pub fn hasCaught(self: TryCatch) bool { @@ -1490,15 +1490,15 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // the caller needs to deinit the string returned pub fn exception(self: TryCatch, allocator: Allocator) !?[]const u8 { const msg = self.inner.getException() orelse return null; - const scope = self.scope; - return try valueToString(allocator, msg, scope.isolate, scope.context); + const js_context = self.js_context; + return try valueToString(allocator, msg, js_context.isolate, js_context.v8_context); } // the caller needs to deinit the string returned pub fn stack(self: TryCatch, allocator: Allocator) !?[]const u8 { - const scope = self.scope; - const s = self.inner.getStackTrace(scope.context) orelse return null; - return try valueToString(allocator, s, scope.isolate, scope.context); + const js_context = self.js_context; + const s = self.inner.getStackTrace(js_context.v8_context) orelse return null; + return try valueToString(allocator, s, js_context.isolate, js_context.v8_context); } // a shorthand method to return either the entire stack message @@ -1570,9 +1570,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } pub fn send(self: *const Inspector, msg: []const u8) void { - // Can't assume there's an existing Scope (with its HandleScope) - // available when doing this. Pages (and thus Scopes) come and - // go, but CDP can keep sending messages. + // Can't assume the main Context exists (with its HandleScope) + // available when doing this. Pages (and thus the HandleScope) + // comes and goes, but CDP can keep sending messages. const isolate = self.isolate; var temp_scope: v8.HandleScope = undefined; v8.HandleScope.init(&temp_scope, isolate); @@ -1591,38 +1591,38 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // - is_default_context: Whether the execution context is default, should match the auxData pub fn contextCreated( self: *const Inspector, - scope: *const Scope, + js_context: *const JsContext, name: []const u8, origin: []const u8, aux_data: ?[]const u8, is_default_context: bool, ) void { - self.inner.contextCreated(scope.context, name, origin, aux_data, is_default_context); + self.inner.contextCreated(js_context.v8_context, name, origin, aux_data, is_default_context); } // Retrieves the RemoteObject for a given value. // The value is loaded through the ExecutionWorld's mapZigInstanceToJs function, // just like a method return value. Therefore, if we've mapped this // value before, we'll get the existing JS PersistedObject and if not - // we'll create it and track it for cleanup when the scope ends. + // we'll create it and track it for cleanup when the context ends. pub fn getRemoteObject( self: *const Inspector, - scope: *const Scope, + js_context: *const JsContext, group: []const u8, value: anytype, ) !RemoteObject { const js_value = try zigValueToJs( - scope.templates, - scope.isolate, - scope.context, + js_context.templates, + js_context.isolate, + js_context.v8_context, value, ); // We do not want to expose this as a parameter for now const generate_preview = false; return self.session.wrapObject( - scope.isolate, - scope.context, + js_context.isolate, + js_context.v8_context, js_value, group, generate_preview, @@ -1643,23 +1643,23 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { pub const Exception = struct { inner: v8.Value, - scope: *const Scope, + js_context: *const JsContext, // the caller needs to deinit the string returned pub fn exception(self: Exception, allocator: Allocator) ![]const u8 { - const scope = self.scope; - return try valueToString(allocator, self.inner, scope.isolate, scope.context); + const js_context = self.js_context; + return try valueToString(allocator, self.inner, js_context.isolate, js_context.v8_context); } }; pub const Value = struct { value: v8.Value, - scope: *const Scope, + js_context: *const JsContext, // the caller needs to deinit the string returned pub fn toString(self: Value, allocator: Allocator) ![]const u8 { - const scope = self.scope; - return valueToString(allocator, self.value, scope.isolate, scope.context); + const js_context = self.js_context; + return valueToString(allocator, self.value, js_context.isolate, js_context.v8_context); } }; @@ -1667,7 +1667,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { count: u32, idx: u32 = 0, js_obj: v8.Object, - scope: *const Scope, + js_context: *const JsContext, pub fn next(self: *ValueIterator) !?Value { const idx = self.idx; @@ -1676,9 +1676,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } self.idx += 1; - const scope = self.scope; - const js_val = try self.js_obj.getAtIndex(scope.context, idx); - return scope.createValue(js_val); + const js_context = self.js_context; + const js_val = try self.js_obj.getAtIndex(js_context.v8_context, idx); + return js_context.createValue(js_val); } }; @@ -1728,7 +1728,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // But it's extracted from generateClass because we also have 1 global // object (i.e. the Window), which gets attached not only to the Window // constructor/FunctionTemplate as normal, but also through the default - // FunctionTemplate of the isolate (in startScope) + // FunctionTemplate of the isolate (in createJsContext) fn attachClass(comptime Struct: type, isolate: v8.Isolate, template: v8.FunctionTemplate) void { const template_proto = template.getPrototypeTemplate(); inline for (@typeInfo(Struct).@"struct".decls) |declaration| { @@ -1983,11 +1983,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { fn callback(c_name: ?*const v8.C_Name, raw_info: ?*const v8.C_PropertyCallbackInfo) callconv(.c) u8 { const info = v8.PropertyCallbackInfo.initFromV8(raw_info); const isolate = info.getIsolate(); - const context = isolate.getCurrentContext(); + const v8_context = isolate.getCurrentContext(); - const scope: *Scope = @ptrFromInt(context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); + const js_context: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); - const property = valueToString(scope.call_arena, .{ .handle = c_name.? }, isolate, context) catch "???"; + const property = valueToString(js_context.call_arena, .{ .handle = c_name.? }, isolate, v8_context) catch "???"; log.debug(.unknown_prop, "unkown property", .{ .@"struct" = @typeName(Struct), .property = property }); return v8.Intercepted.No; } @@ -2032,7 +2032,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { fn zigValueToJs( templates: []v8.FunctionTemplate, isolate: v8.Isolate, - context: v8.Context, + v8_context: v8.Context, value: anytype, ) anyerror!v8.Value { // Check if it's a "simple" type. This is extracted so that it can be @@ -2053,8 +2053,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { var js_arr = v8.Array.init(isolate, value.len); var js_obj = js_arr.castTo(v8.Object); for (value, 0..) |v, i| { - const js_val = try zigValueToJs(templates, isolate, context, v); - if (js_obj.setValueAtIndex(context, @intCast(i), js_val) == false) { + const js_val = try zigValueToJs(templates, isolate, v8_context, v); + if (js_obj.setValueAtIndex(v8_context, @intCast(i), js_val) == false) { return error.FailedToCreateArray; } } @@ -2065,7 +2065,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const type_name = @typeName(ptr.child); if (@hasField(TypeLookup, type_name)) { const template = templates[@field(TYPE_LOOKUP, type_name).index]; - const js_obj = try Scope.mapZigInstanceToJs(context, template, value); + const js_obj = try JsContext.mapZigInstanceToJs(v8_context, template, value); return js_obj.toValue(); } @@ -2088,8 +2088,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { var js_obj = js_arr.castTo(v8.Object); for (value, 0..) |v, i| { - const js_val = try zigValueToJs(templates, isolate, context, v); - if (js_obj.setValueAtIndex(context, @intCast(i), js_val) == false) { + const js_val = try zigValueToJs(templates, isolate, v8_context, v); + if (js_obj.setValueAtIndex(v8_context, @intCast(i), js_val) == false) { return error.FailedToCreateArray; } } @@ -2101,7 +2101,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { const type_name = @typeName(T); if (@hasField(TypeLookup, type_name)) { const template = templates[@field(TYPE_LOOKUP, type_name).index]; - const js_obj = try Scope.mapZigInstanceToJs(context, template, value); + const js_obj = try JsContext.mapZigInstanceToJs(v8_context, template, value); return js_obj.toValue(); } @@ -2120,8 +2120,8 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { var js_arr = v8.Array.init(isolate, @intCast(s.fields.len)); var js_obj = js_arr.castTo(v8.Object); inline for (s.fields, 0..) |f, i| { - const js_val = try zigValueToJs(templates, isolate, context, @field(value, f.name)); - if (js_obj.setValueAtIndex(context, @intCast(i), js_val) == false) { + const js_val = try zigValueToJs(templates, isolate, v8_context, @field(value, f.name)); + if (js_obj.setValueAtIndex(v8_context, @intCast(i), js_val) == false) { return error.FailedToCreateArray; } } @@ -2131,9 +2131,9 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { // return the struct as a JS object const js_obj = v8.Object.init(isolate); inline for (s.fields) |f| { - const js_val = try zigValueToJs(templates, isolate, context, @field(value, f.name)); + const js_val = try zigValueToJs(templates, isolate, v8_context, @field(value, f.name)); const key = v8.String.initUtf8(isolate, f.name); - if (!js_obj.setValue(context, key, js_val)) { + if (!js_obj.setValue(v8_context, key, js_val)) { return error.CreateObjectFailure; } } @@ -2141,12 +2141,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { }, .@"union" => |un| { if (T == std.json.Value) { - return zigJsonToJs(isolate, context, value); + return zigJsonToJs(isolate, v8_context, value); } if (un.tag_type) |UnionTagType| { inline for (un.fields) |field| { if (value == @field(UnionTagType, field.name)) { - return zigValueToJs(templates, isolate, context, @field(value, field.name)); + return zigValueToJs(templates, isolate, v8_context, @field(value, field.name)); } } unreachable; @@ -2155,11 +2155,11 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { }, .optional => { if (value) |v| { - return zigValueToJs(templates, isolate, context, v); + return zigValueToJs(templates, isolate, v8_context, v); } return v8.initNull(isolate).toValue(); }, - .error_union => return zigValueToJs(templates, isolate, context, value catch |err| return err), + .error_union => return zigValueToJs(templates, isolate, v8_context, value catch |err| return err), else => {}, } @@ -2236,7 +2236,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } // An interface for types that want to have their jsDeinit function to be - // called when the call scope ends + // called when the call context ends const DestructorCallback = struct { ptr: *anyopaque, destructorFn: *const fn (ptr: *anyopaque) void, @@ -2264,7 +2264,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { }; // An interface for types that want to have their jsScopeEnd function be - // called when the call scope ends + // called when the call context ends const CallScopeEndCallback = struct { ptr: *anyopaque, callScopeEndFn: *const fn (ptr: *anyopaque) void, @@ -2329,8 +2329,8 @@ fn isEmpty(comptime T: type) bool { // here does feel like it makes it clenaer. fn Caller(comptime E: type, comptime State: type) type { return struct { - scope: *E.Scope, - context: v8.Context, + js_context: *E.JsContext, + v8_context: v8.Context, isolate: v8.Isolate, call_arena: Allocator, @@ -2341,21 +2341,21 @@ fn Caller(comptime E: type, comptime State: type) type { // executor = Isolate -> getCurrentContext -> getEmbedderData() fn init(info: anytype) Self { const isolate = info.getIsolate(); - const context = isolate.getCurrentContext(); - const scope: *E.Scope = @ptrFromInt(context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); + const v8_context = isolate.getCurrentContext(); + const js_context: *E.JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64()); - scope.call_depth += 1; + js_context.call_depth += 1; return .{ - .scope = scope, + .js_context = js_context, .isolate = isolate, - .context = context, - .call_arena = scope.call_arena, + .v8_context = v8_context, + .call_arena = js_context.call_arena, }; } fn deinit(self: *Self) void { - const scope = self.scope; - const call_depth = scope.call_depth - 1; + const js_context = self.js_context; + const call_depth = js_context.call_depth - 1; // Because of callbacks, calls can be nested. Because of this, we // can't clear the call_arena after _every_ call. Imagine we have @@ -2369,18 +2369,18 @@ fn Caller(comptime E: type, comptime State: type) type { // Therefore, we keep a call_depth, and only reset the call_arena // when a top-level (call_depth == 0) function ends. if (call_depth == 0) { - for (scope.call_scope_end_callbacks.items) |cb| { + for (js_context.call_scope_end_callbacks.items) |cb| { cb.callScopeEnd(); } - const arena: *ArenaAllocator = @alignCast(@ptrCast(scope.call_arena.ptr)); + const arena: *ArenaAllocator = @alignCast(@ptrCast(js_context.call_arena.ptr)); _ = arena.reset(.{ .retain_with_limit = CALL_ARENA_RETAIN }); } // Set this _after_ we've executed the above code, so that if the // above code executes any callbacks, they aren't being executed // at scope 0, which would be wrong. - scope.call_depth = call_depth; + js_context.call_depth = call_depth; } fn constructor(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void { @@ -2394,15 +2394,15 @@ fn Caller(comptime E: type, comptime State: type) type { const this = info.getThis(); if (@typeInfo(ReturnType) == .error_union) { const non_error_res = res catch |err| return err; - _ = try E.Scope.mapZigInstanceToJs(self.context, this, non_error_res); + _ = try E.JsContext.mapZigInstanceToJs(self.v8_context, this, non_error_res); } else { - _ = try E.Scope.mapZigInstanceToJs(self.context, this, res); + _ = try E.JsContext.mapZigInstanceToJs(self.v8_context, this, res); } info.getReturnValue().set(this); } fn method(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); comptime assertSelfReceiver(Struct, named_function); @@ -2413,19 +2413,19 @@ fn Caller(comptime E: type, comptime State: type) type { @field(args, "0") = zig_instance; const res = @call(.auto, func, args); - info.getReturnValue().set(try scope.zigValueToJs(res)); + info.getReturnValue().set(try js_context.zigValueToJs(res)); } fn function(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); const args = try self.getArgs(Struct, named_function, 0, info); const res = @call(.auto, func, args); - info.getReturnValue().set(try scope.zigValueToJs(res)); + info.getReturnValue().set(try js_context.zigValueToJs(res)); } fn getter(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, info: v8.FunctionCallbackInfo) !void { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); const Getter = @TypeOf(func); if (@typeInfo(Getter).@"fn".return_type == null) { @@ -2442,17 +2442,17 @@ fn Caller(comptime E: type, comptime State: type) type { @field(args, "0") = zig_instance; if (comptime arg_fields.len == 2) { comptime assertIsStateArg(Struct, named_function, 1); - @field(args, "1") = scope.state; + @field(args, "1") = js_context.state; } }, else => @compileError(named_function.full_name + " has too many parmaters: " ++ @typeName(named_function.func)), } const res = @call(.auto, func, args); - info.getReturnValue().set(try scope.zigValueToJs(res)); + info.getReturnValue().set(try js_context.zigValueToJs(res)); } fn setter(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, js_value: v8.Value, info: v8.FunctionCallbackInfo) !void { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); comptime assertSelfReceiver(Struct, named_function); @@ -2466,10 +2466,10 @@ fn Caller(comptime E: type, comptime State: type) type { 1 => @compileError(named_function.full_name ++ " only has 1 parameter"), 2, 3 => { @field(args, "0") = zig_instance; - @field(args, "1") = try scope.jsValueToZig(named_function, arg_fields[1].type, js_value); + @field(args, "1") = try js_context.jsValueToZig(named_function, arg_fields[1].type, js_value); if (comptime arg_fields.len == 3) { comptime assertIsStateArg(Struct, named_function, 2); - @field(args, "2") = scope.state; + @field(args, "2") = js_context.state; } }, else => @compileError(named_function.full_name ++ " setter with more than 3 parameters, why?"), @@ -2485,7 +2485,7 @@ fn Caller(comptime E: type, comptime State: type) type { } fn getIndex(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, idx: u32, info: v8.PropertyCallbackInfo) !u8 { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); const IndexedGet = @TypeOf(func); if (@typeInfo(IndexedGet).@"fn".return_type == null) { @@ -2506,7 +2506,7 @@ fn Caller(comptime E: type, comptime State: type) type { @field(args, "2") = &has_value; if (comptime arg_fields.len == 4) { comptime assertIsStateArg(Struct, named_function, 3); - @field(args, "3") = scope.state; + @field(args, "3") = js_context.state; } }, else => @compileError(named_function.full_name ++ " has too many parmaters"), @@ -2516,12 +2516,12 @@ fn Caller(comptime E: type, comptime State: type) type { if (has_value == false) { return v8.Intercepted.No; } - info.getReturnValue().set(try scope.zigValueToJs(res)); + info.getReturnValue().set(try js_context.zigValueToJs(res)); return v8.Intercepted.Yes; } fn getNamedIndex(self: *Self, comptime Struct: type, comptime named_function: NamedFunction, name: v8.Name, info: v8.PropertyCallbackInfo) !u8 { - const scope = self.scope; + const js_context = self.js_context; const func = @field(Struct, named_function.name); const NamedGet = @TypeOf(func); if (@typeInfo(NamedGet).@"fn".return_type == null) { @@ -2541,7 +2541,7 @@ fn Caller(comptime E: type, comptime State: type) type { @field(args, "2") = &has_value; if (comptime arg_fields.len == 4) { comptime assertIsStateArg(Struct, named_function, 3); - @field(args, "3") = scope.state; + @field(args, "3") = js_context.state; } }, else => @compileError(named_function.full_name ++ " has too many parmaters"), @@ -2551,12 +2551,12 @@ fn Caller(comptime E: type, comptime State: type) type { if (has_value == false) { return v8.Intercepted.No; } - info.getReturnValue().set(try scope.zigValueToJs(res)); + info.getReturnValue().set(try js_context.zigValueToJs(res)); return v8.Intercepted.Yes; } fn nameToString(self: *Self, name: v8.Name) ![]const u8 { - return valueToString(self.call_arena, .{ .handle = name.handle }, self.isolate, self.context); + return valueToString(self.call_arena, .{ .handle = name.handle }, self.isolate, self.v8_context); } fn assertSelfReceiver(comptime Struct: type, comptime named_function: NamedFunction) void { @@ -2637,7 +2637,7 @@ fn Caller(comptime E: type, comptime State: type) type { } }; // ughh..how to handle an error here? - break :blk self.scope.zigValueToJs(custom_exception) catch createException(isolate, "internal error"); + break :blk self.js_context.zigValueToJs(custom_exception) catch createException(isolate, "internal error"); } // this error isn't part of a custom exception break :blk null; @@ -2696,7 +2696,7 @@ fn Caller(comptime E: type, comptime State: type) type { // the last parameter in Zig is an array, we'll try to slurp the additional // parameters into the array. fn getArgs(self: *const Self, comptime Struct: type, comptime named_function: NamedFunction, comptime offset: usize, info: anytype) !ParamterTypes(@TypeOf(@field(Struct, named_function.name))) { - const scope = self.scope; + const js_context = self.js_context; const F = @TypeOf(@field(Struct, named_function.name)); var args: ParamterTypes(F) = undefined; @@ -2712,7 +2712,7 @@ fn Caller(comptime E: type, comptime State: type) type { // from our params slice, because we don't want to bind it to // a JS argument if (comptime isState(params[params.len - 1].type.?)) { - @field(args, std.fmt.comptimePrint("{d}", .{params.len - 1 + offset})) = self.scope.state; + @field(args, std.fmt.comptimePrint("{d}", .{params.len - 1 + offset})) = self.js_context.state; break :blk params[0 .. params.len - 1]; } @@ -2727,7 +2727,7 @@ fn Caller(comptime E: type, comptime State: type) type { // AND the 2nd last parameter is state if (params.len > 1 and comptime isState(params[params.len - 2].type.?)) { - @field(args, std.fmt.comptimePrint("{d}", .{params.len - 2 + offset})) = self.scope.state; + @field(args, std.fmt.comptimePrint("{d}", .{params.len - 2 + offset})) = self.js_context.state; break :blk params[0 .. params.len - 2]; } @@ -2765,7 +2765,7 @@ fn Caller(comptime E: type, comptime State: type) type { const arr = try self.call_arena.alloc(last_parameter_type_info.pointer.child, js_parameter_count - params_to_map.len + 1); for (arr, last_js_parameter..) |*a, i| { const js_value = info.getArg(@as(u32, @intCast(i))); - a.* = try scope.jsValueToZig(named_function, slice_type, js_value); + a.* = try js_context.jsValueToZig(named_function, slice_type, js_value); } @field(args, tupleFieldName(params_to_map.len + offset - 1)) = arr; } else { @@ -2794,7 +2794,7 @@ fn Caller(comptime E: type, comptime State: type) type { @field(args, tupleFieldName(field_index)) = null; } else { const js_value = info.getArg(@as(u32, @intCast(i))); - @field(args, tupleFieldName(field_index)) = scope.jsValueToZig(named_function, param.type.?, js_value) catch { + @field(args, tupleFieldName(field_index)) = js_context.jsValueToZig(named_function, param.type.?, js_value) catch { return error.InvalidArgument; }; } @@ -2811,7 +2811,7 @@ fn Caller(comptime E: type, comptime State: type) type { fn serializeFunctionArgs(self: *const Self, info: anytype) ![]const u8 { const isolate = self.isolate; - const context = self.context; + const v8_context = self.v8_context; const arena = self.call_arena; const separator = log.separator(); const js_parameter_count = info.length(); @@ -2819,7 +2819,7 @@ fn Caller(comptime E: type, comptime State: type) type { var arr: std.ArrayListUnmanaged(u8) = .{}; for (0..js_parameter_count) |i| { const js_value = info.getArg(@intCast(i)); - const value_string = try valueToDetailString(arena, js_value, isolate, context); + const value_string = try valueToDetailString(arena, js_value, isolate, v8_context); const value_type = try jsStringToZig(arena, try js_value.typeOf(isolate), isolate); try std.fmt.format(arr.writer(arena), "{s}{d}: {s} ({s})", .{ separator, @@ -2841,32 +2841,32 @@ fn isJsThis(comptime T: type) bool { return @typeInfo(T) == .@"struct" and @hasDecl(T, "_JSTHIS_ID_KLUDGE"); } -fn jsIntToZig(comptime T: type, js_value: v8.Value, context: v8.Context) !T { +fn jsIntToZig(comptime T: type, js_value: v8.Value, v8_context: v8.Context) !T { const n = @typeInfo(T).int; switch (n.signedness) { .signed => switch (n.bits) { - 8 => return jsSignedIntToZig(i8, -128, 127, try js_value.toI32(context)), - 16 => return jsSignedIntToZig(i16, -32_768, 32_767, try js_value.toI32(context)), - 32 => return jsSignedIntToZig(i32, -2_147_483_648, 2_147_483_647, try js_value.toI32(context)), + 8 => return jsSignedIntToZig(i8, -128, 127, try js_value.toI32(v8_context)), + 16 => return jsSignedIntToZig(i16, -32_768, 32_767, try js_value.toI32(v8_context)), + 32 => return jsSignedIntToZig(i32, -2_147_483_648, 2_147_483_647, try js_value.toI32(v8_context)), 64 => { if (js_value.isBigInt()) { const v = js_value.castTo(v8.BigInt); return v.getInt64(); } - return jsSignedIntToZig(i64, -2_147_483_648, 2_147_483_647, try js_value.toI32(context)); + return jsSignedIntToZig(i64, -2_147_483_648, 2_147_483_647, try js_value.toI32(v8_context)); }, else => {}, }, .unsigned => switch (n.bits) { - 8 => return jsUnsignedIntToZig(u8, 255, try js_value.toU32(context)), - 16 => return jsUnsignedIntToZig(u16, 65_535, try js_value.toU32(context)), - 32 => return jsUnsignedIntToZig(u32, 4_294_967_295, try js_value.toU32(context)), + 8 => return jsUnsignedIntToZig(u8, 255, try js_value.toU32(v8_context)), + 16 => return jsUnsignedIntToZig(u16, 65_535, try js_value.toU32(v8_context)), + 32 => return jsUnsignedIntToZig(u32, 4_294_967_295, try js_value.toU32(v8_context)), 64 => { if (js_value.isBigInt()) { const v = js_value.castTo(v8.BigInt); return v.getUint64(); } - return jsUnsignedIntToZig(u64, 4_294_967_295, try js_value.toU32(context)); + return jsUnsignedIntToZig(u64, 4_294_967_295, try js_value.toU32(v8_context)); }, else => {}, }, @@ -3007,7 +3007,7 @@ fn simpleZigValueToJs(isolate: v8.Isolate, value: anytype, comptime fail: bool) return null; } -pub fn zigJsonToJs(isolate: v8.Isolate, context: v8.Context, value: std.json.Value) !v8.Value { +pub fn zigJsonToJs(isolate: v8.Isolate, v8_context: v8.Context, value: std.json.Value) !v8.Value { switch (value) { .bool => |v| return simpleZigValueToJs(isolate, v, true), .float => |v| return simpleZigValueToJs(isolate, v, true), @@ -3023,8 +3023,8 @@ pub fn zigJsonToJs(isolate: v8.Isolate, context: v8.Context, value: std.json.Val const a = v8.Array.init(isolate, @intCast(v.items.len)); const obj = a.castTo(v8.Object); for (v.items, 0..) |array_value, i| { - const js_val = try zigJsonToJs(isolate, context, array_value); - if (!obj.setValueAtIndex(context, @intCast(i), js_val)) { + const js_val = try zigJsonToJs(isolate, v8_context, array_value); + if (!obj.setValueAtIndex(v8_context, @intCast(i), js_val)) { return error.JSObjectSetValue; } } @@ -3035,8 +3035,8 @@ pub fn zigJsonToJs(isolate: v8.Isolate, context: v8.Context, value: std.json.Val var it = v.iterator(); while (it.next()) |kv| { const js_key = v8.String.initUtf8(isolate, kv.key_ptr.*); - const js_val = try zigJsonToJs(isolate, context, kv.value_ptr.*); - if (!obj.setValue(context, js_key, js_val)) { + const js_val = try zigJsonToJs(isolate, v8_context, kv.value_ptr.*); + if (!obj.setValue(v8_context, js_key, js_val)) { return error.JSObjectSetValue; } } @@ -3161,10 +3161,10 @@ const TaggedAnyOpaque = struct { subtype: ?SubType, }; -fn valueToDetailString(arena: Allocator, value: v8.Value, isolate: v8.Isolate, context: v8.Context) ![]u8 { +fn valueToDetailString(arena: Allocator, value: v8.Value, isolate: v8.Isolate, v8_context: v8.Context) ![]u8 { var str: ?v8.String = null; if (value.isObject() and !value.isFunction()) { - str = try v8.Json.stringify(context, value, null); + str = try v8.Json.stringify(v8_context, value, null); if (str.?.lenUtf8(isolate) == 2) { // {} isn't useful, null this so that we can get the toDetailString @@ -3174,19 +3174,19 @@ fn valueToDetailString(arena: Allocator, value: v8.Value, isolate: v8.Isolate, c } if (str == null) { - str = try value.toDetailString(context); + str = try value.toDetailString(v8_context); } return jsStringToZig(arena, str.?, isolate); } -fn valueToString(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, context: v8.Context) ![]u8 { - const str = try value.toString(context); +fn valueToString(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, v8_context: v8.Context) ![]u8 { + const str = try value.toString(v8_context); return jsStringToZig(allocator, str, isolate); } -fn valueToStringZ(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, context: v8.Context) ![:0]u8 { - const str = try value.toString(context); +fn valueToStringZ(allocator: Allocator, value: v8.Value, isolate: v8.Isolate, v8_context: v8.Context) ![:0]u8 { + const str = try value.toString(v8_context); const len = str.lenUtf8(isolate); const buf = try allocator.allocSentinel(u8, len, 0); const n = str.writeUtf8(isolate, buf); @@ -3283,10 +3283,10 @@ pub export fn v8_inspector__Client__IMPL__valueSubtype( // put an empty description. pub export fn v8_inspector__Client__IMPL__descriptionForValueSubtype( _: *v8.c.InspectorClientImpl, - context: *const v8.C_Context, + v8_context: *const v8.C_Context, c_value: *const v8.C_Value, ) callconv(.C) [*c]const u8 { - _ = context; + _ = v8_context; // We _must_ include a non-null description in order for the subtype value // to be included. Besides that, I don't know if the value has any meaning diff --git a/src/runtime/testing.zig b/src/runtime/testing.zig index 8cfc5c44..4ecd194f 100644 --- a/src/runtime/testing.zig +++ b/src/runtime/testing.zig @@ -29,7 +29,7 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty return struct { env: *Env, - scope: *Env.Scope, + js_context: *Env.JsContext, executor: Env.ExecutionWorld, pub const Env = js.Env(State, struct { @@ -48,7 +48,7 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty self.executor = try self.env.newExecutionWorld(); errdefer self.executor.deinit(); - self.scope = try self.executor.startScope( + self.js_context = try self.executor.createJsContext( if (Global == void) &default_global else global, state, {}, @@ -68,10 +68,10 @@ pub fn Runner(comptime State: type, comptime Global: type, comptime types: anyty pub fn testCases(self: *Self, cases: []const Case, _: RunOpts) !void { for (cases, 0..) |case, i| { var try_catch: Env.TryCatch = undefined; - try_catch.init(self.scope); + try_catch.init(self.js_context); defer try_catch.deinit(); - const value = self.scope.exec(case.@"0", null) catch |err| { + const value = self.js_context.exec(case.@"0", null) catch |err| { if (try try_catch.err(allocator)) |msg| { defer allocator.free(msg); if (isExpectedTypeError(case.@"1", msg)) { diff --git a/src/testing.zig b/src/testing.zig index faf3455d..75bb3a95 100644 --- a/src/testing.zig +++ b/src/testing.zig @@ -419,17 +419,17 @@ pub const JsRunner = struct { const RunOpts = struct {}; pub const Case = std.meta.Tuple(&.{ []const u8, ?[]const u8 }); pub fn testCases(self: *JsRunner, cases: []const Case, _: RunOpts) !void { - const scope = self.page.scope; + const js_context = self.page.main_context; const arena = self.page.arena; const start = try std.time.Instant.now(); for (cases, 0..) |case, i| { var try_catch: Env.TryCatch = undefined; - try_catch.init(scope); + try_catch.init(js_context); defer try_catch.deinit(); - const value = scope.exec(case.@"0", null) catch |err| { + const value = js_context.exec(case.@"0", null) catch |err| { if (try try_catch.err(arena)) |msg| { std.debug.print("{s}\n\nCase: {d}\n{s}\n", .{ msg, i + 1, case.@"0" }); } @@ -453,14 +453,14 @@ pub const JsRunner = struct { } pub fn eval(self: *JsRunner, src: []const u8, name: ?[]const u8, err_msg: *?[]const u8) !Env.Value { - const scope = self.page.scope; + const js_context = self.page.main_context; const arena = self.page.arena; var try_catch: Env.TryCatch = undefined; - try_catch.init(scope); + try_catch.init(js_context); defer try_catch.deinit(); - return scope.exec(src, name) catch |err| { + return js_context.exec(src, name) catch |err| { if (try try_catch.err(arena)) |msg| { err_msg.* = msg; std.debug.print("Error running script: {s}\n", .{msg});