diff --git a/build.zig.zon b/build.zig.zon index 6945fc7d7..efdec55b2 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -12,11 +12,11 @@ .url = "https://github.com/lightpanda-io/tigerbeetle-io/archive/61d9652f1a957b7f4db723ea6aa0ce9635e840ce.tar.gz", .hash = "tigerbeetle_io-0.0.0-ViLgxpyRBAB5BMfIcj3KMXfbJzwARs9uSl8aRy2OXULd", }, - .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/dd087771378ea854452bcb010309fa9ffe5a9cac.tar.gz", - .hash = "v8-0.0.0-xddH66e8AwBL3O_A8yWQYQIyfMbKHFNVQr_NqM6YjU11", - }, - //.v8 = .{ .path = "../zig-v8-fork" }, + //.v8 = .{ + // .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/dd087771378ea854452bcb010309fa9ffe5a9cac.tar.gz", + // .hash = "v8-0.0.0-xddH66e8AwBL3O_A8yWQYQIyfMbKHFNVQr_NqM6YjU11", + //}, + .v8 = .{ .path = "../zig-v8-fork" }, //.tigerbeetle_io = .{ .path = "../tigerbeetle-io" }, }, } diff --git a/src/browser/page.zig b/src/browser/page.zig index fd750b3d9..3d8426b55 100644 --- a/src/browser/page.zig +++ b/src/browser/page.zig @@ -122,6 +122,8 @@ pub const Page = struct { // load polyfills try polyfill.load(self.arena, self.main_context); + _ = session.executor.env.snapshot(self.main_context); + _ = try session.browser.app.loop.timeout(1 * std.time.ns_per_ms, &self.microtask_node); // message loop must run only non-test env if (comptime !builtin.is_test) { diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 80585970b..8bb166922 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -158,7 +158,10 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { platform: ?*const Platform, + snapshot_creator: v8.SnapshotCreator, + // the global isolate + // owned by snapshot_creator. isolate: v8.Isolate, // just kept around because we need to free it on deinit @@ -193,11 +196,12 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { params.array_buffer_allocator = v8.createDefaultArrayBufferAllocator(); errdefer v8.destroyArrayBufferAllocator(params.array_buffer_allocator.?); - var isolate = v8.Isolate.init(params); - errdefer isolate.deinit(); + var snapshot_creator = v8.SnapshotCreator.init(params); + errdefer snapshot_creator.deinit(); + + var isolate = snapshot_creator.getIsolate(); - isolate.enter(); - errdefer isolate.exit(); + // snapshot_creator enters the isolate for us. isolate.setHostInitializeImportMetaObjectCallback(struct { fn callback(c_context: ?*v8.C_Context, c_module: ?*v8.C_Module, c_meta: ?*v8.C_Value) callconv(.C) void { @@ -218,6 +222,7 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { env.* = .{ .platform = platform, + .snapshot_creator = snapshot_creator, .isolate = isolate, .templates = undefined, .allocator = allocator, @@ -258,13 +263,66 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { } pub fn deinit(self: *Self) void { - self.isolate.exit(); - self.isolate.deinit(); + // The snapshot_creator owns the isolate. So it exit and deinit it + // for us. + self.snapshot_creator.deinit(); v8.destroyArrayBufferAllocator(self.isolate_params.array_buffer_allocator.?); self.allocator.destroy(self.isolate_params); self.allocator.destroy(self); } + pub fn snapshot(self: *Self, default_ctx: *const JsContext) v8.StartupData { + self.snapshot_creator.setDefaultContextWithCallbacks( + default_ctx.v8_context, + // SerializeInternalFieldsCallback serializes internal fields + // of V8 objects that contain embedder data + .{ + .callback = struct { + fn callback(holder: ?*v8.C_Object, index: c_int, data: ?*anyopaque) callconv(.C) v8.StartupData { + _ = holder; + _ = index; + _ = data; + // TODO + std.debug.print("SerializeInternalFieldsCallback\n", .{}); + return .{}; + } + }.callback, + .data = null, + }, + // SerializeContextDataCallback serializes context-specific + // state (globals, modules, etc.) + .{ + .callback = struct { + fn callback(context: ?*v8.C_Context, index: c_int, data: ?*anyopaque) callconv(.C) v8.StartupData { + _ = context; + _ = index; + _ = data; + // TODO + std.debug.print("SerializeContextDataCallback\n", .{}); + return .{}; + } + }.callback, + .data = null, + }, + // SerializeAPIWrapperCallback serializes API wrappers that + // bridge V8 and Native objects + .{ + .callback = struct { + fn callback(holder: ?*v8.C_Object, ptr: ?*anyopaque, data: ?*anyopaque) callconv(.C) v8.StartupData { + _ = holder; + _ = ptr; + _ = data; + // TODO + std.debug.print("SerializeAPIWrapperCallback\n", .{}); + return .{}; + } + }.callback, + .data = null, + }, + ); + return self.snapshot_creator.createBlob(); + } + pub fn newInspector(self: *Self, arena: Allocator, ctx: anytype) !Inspector { return Inspector.init(arena, self.isolate, ctx); }