diff --git a/src/browser/js/Context.zig b/src/browser/js/Context.zig index 787527b6..5c58c5cb 100644 --- a/src/browser/js/Context.zig +++ b/src/browser/js/Context.zig @@ -171,6 +171,7 @@ pub fn setOrigin(self: *Context, key: ?[]const u8) !void { errdefer self.session.releaseOrigin(origin); try self.origin.transferTo(origin); + lp.assert(self.origin.rc == 1, "Ref opaque origin", .{ .rc = self.origin.rc }); self.origin.deinit(env.app); self.origin = origin; diff --git a/src/browser/js/Env.zig b/src/browser/js/Env.zig index e8488541..ba2e3e5a 100644 --- a/src/browser/js/Env.zig +++ b/src/browser/js/Env.zig @@ -326,7 +326,7 @@ pub fn createContext(self: *Env, page: *Page) !*Context { .script_manager = &page._script_manager, .scheduler = .init(context_arena), }; - try context.origin.identity_map.putNoClobber(context_arena, @intFromPtr(page.window), global_global); + try context.origin.identity_map.putNoClobber(origin.arena, @intFromPtr(page.window), global_global); // Store a pointer to our context inside the v8 context so that, given // a v8 context, we can get our context out diff --git a/src/browser/js/Local.zig b/src/browser/js/Local.zig index ee2ca5cd..a45b35df 100644 --- a/src/browser/js/Local.zig +++ b/src/browser/js/Local.zig @@ -202,20 +202,20 @@ pub fn compileAndRun(self: *const Local, src: []const u8, name: ?[]const u8) !js // we can just grab it from the identity_map) pub fn mapZigInstanceToJs(self: *const Local, js_obj_handle: ?*const v8.Object, value: anytype) !js.Object { const ctx = self.ctx; - const arena = ctx.arena; + const origin_arena = ctx.origin.arena; const T = @TypeOf(value); switch (@typeInfo(T)) { .@"struct" => { // Struct, has to be placed on the heap - const heap = try arena.create(T); + const heap = try origin_arena.create(T); heap.* = value; return self.mapZigInstanceToJs(js_obj_handle, heap); }, .pointer => |ptr| { const resolved = resolveValue(value); - const gop = try ctx.origin.identity_map.getOrPut(arena, @intFromPtr(resolved.ptr)); + const gop = try ctx.origin.addIdentity(@intFromPtr(resolved.ptr)); if (gop.found_existing) { // we've seen this instance before, return the same object return (js.Object.Global{ .handle = gop.value_ptr.* }).local(self); @@ -244,7 +244,7 @@ pub fn mapZigInstanceToJs(self: *const Local, js_obj_handle: ?*const v8.Object, // The TAO contains the pointer to our Zig instance as // well as any meta data we'll need to use it later. // See the TaggedOpaque struct for more details. - const tao = try arena.create(TaggedOpaque); + const tao = try origin_arena.create(TaggedOpaque); tao.* = .{ .value = resolved.ptr, .prototype_chain = resolved.prototype_chain.ptr, diff --git a/src/browser/js/Origin.zig b/src/browser/js/Origin.zig index 486888f1..d7e74e4f 100644 --- a/src/browser/js/Origin.zig +++ b/src/browser/js/Origin.zig @@ -129,6 +129,19 @@ pub fn trackGlobal(self: *Origin, global: v8.Global) !void { return self.globals.append(self.arena, global); } +pub const IdentityResult = struct { + value_ptr: *v8.Global, + found_existing: bool, +}; + +pub fn addIdentity(self: *Origin, ptr: usize) !IdentityResult { + const gop = try self.identity_map.getOrPut(self.arena, ptr); + return .{ + .value_ptr = gop.value_ptr, + .found_existing = gop.found_existing, + }; +} + pub fn trackTemp(self: *Origin, global: v8.Global) !void { return self.temps.put(self.arena, global.data_ptr, global); } diff --git a/src/browser/js/String.zig b/src/browser/js/String.zig index 04eda642..47be227a 100644 --- a/src/browser/js/String.zig +++ b/src/browser/js/String.zig @@ -56,7 +56,7 @@ fn _toSlice(self: String, comptime null_terminate: bool, allocator: Allocator) ! pub fn toSSO(self: String, comptime global: bool) !(if (global) SSO.Global else SSO) { if (comptime global) { - return .{ .str = try self.toSSOWithAlloc(self.local.ctx.arena) }; + return .{ .str = try self.toSSOWithAlloc(self.local.ctx.origin.arena) }; } return self.toSSOWithAlloc(self.local.call_arena); }