From d550a893301ef24f5eb74446d4ad440307a7b050 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sun, 28 Jun 2026 08:03:02 +0800 Subject: [PATCH 1/5] v8, dep: Update v8 This update of zig-v8-fork is an update of v8 itself. --- build.zig.zon | 2 +- src/browser/js/Caller.zig | 23 ++++++---------- src/browser/js/Env.zig | 3 +-- src/browser/js/Module.zig | 4 +-- src/browser/js/Snapshot.zig | 1 + src/browser/js/bridge.zig | 54 ++++++++++++++++++------------------- 6 files changed, 38 insertions(+), 49 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index b69d1ef42..e9d41446a 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,7 +5,7 @@ .minimum_zig_version = "0.15.2", .dependencies = .{ .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/v0.4.8.tar.gz", + .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/3a53a258e508ea6a805654a94339b9fd006e7b2d.tar.gz", .hash = "v8-0.0.0-xddH65qdBAA1hmB-gqEmhEzO0-aXKyEsmo1s34mssemb", }, // .v8 = .{ .path = "../zig-v8-fork" }, diff --git a/src/browser/js/Caller.zig b/src/browser/js/Caller.zig index 48d24a780..8b2d782cc 100644 --- a/src/browser/js/Caller.zig +++ b/src/browser/js/Caller.zig @@ -183,8 +183,7 @@ pub fn getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, handle const info = PropertyCallbackInfo{ .handle = handle }; return _getIndex(T, local, func, idx, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - // not intercepted - return 0; + return 1; }; } @@ -210,8 +209,7 @@ pub fn getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *cons const info = PropertyCallbackInfo{ .handle = handle }; return _getNamedIndex(T, local, func, name, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - // not intercepted - return 0; + return 1; }; } @@ -237,8 +235,7 @@ pub fn setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *cons const info = PropertyCallbackInfo{ .handle = handle }; return _setNamedIndex(T, local, func, name, .{ .local = &self.local, .handle = js_value }, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - // not intercepted - return 0; + return 1; }; } @@ -265,7 +262,7 @@ pub fn deleteNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *c const info = PropertyCallbackInfo{ .handle = handle }; return _deleteNamedIndex(T, local, func, name, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 0; + return 1; }; } @@ -291,8 +288,7 @@ pub fn getEnumerator(self: *Caller, comptime T: type, func: anytype, handle: *co const info = PropertyCallbackInfo{ .handle = handle }; return _getEnumerator(T, local, func, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - // not intercepted - return 0; + return 1; }; } @@ -318,13 +314,11 @@ fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: // if error.NotHandled is part of the error set. if (isInErrorSet(error.NotHandled, eu.error_set)) { if (err == error.NotHandled) { - // not intercepted - return 0; + return 1; } } handleError(T, F, local, err, info, opts); - // not intercepted - return 0; + return 1; }; }, else => ret, @@ -333,8 +327,7 @@ fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: if (comptime with_value) { info.getReturnValue().set(try local.zigValueToJs(non_error_ret, opts)); } - // intercepted - return 1; + return 0; } fn isInErrorSet(err: anyerror, comptime T: type) bool { diff --git a/src/browser/js/Env.zig b/src/browser/js/Env.zig index 4ba3d3dd3..3a37e8d4a 100644 --- a/src/browser/js/Env.zig +++ b/src/browser/js/Env.zig @@ -581,8 +581,7 @@ fn promiseRejectCallback(message_handle: v8.PromiseRejectMessage) callconv(.c) v return; } - const promise_handle = v8.v8__PromiseRejectMessage__GetPromise(&message_handle).?; - const v8_isolate = v8.v8__Object__GetIsolate(@ptrCast(promise_handle)).?; + const v8_isolate = v8.v8__Isolate__GetCurrent().?; const isolate = js.Isolate{ .handle = v8_isolate }; const ctx, const v8_context = Context.fromIsolate(isolate) orelse return; diff --git a/src/browser/js/Module.zig b/src/browser/js/Module.zig index 1e290d2d6..2a331ccbf 100644 --- a/src/browser/js/Module.zig +++ b/src/browser/js/Module.zig @@ -46,7 +46,6 @@ pub fn getException(self: Module) js.Value { pub fn getModuleRequests(self: Module) Requests { return .{ - .context_handle = self.local.handle, .handle = v8.v8__Module__GetModuleRequests(self.handle).?, }; } @@ -117,14 +116,13 @@ pub const Global = struct { const Requests = struct { handle: *const v8.FixedArray, - context_handle: *const v8.Context, pub fn len(self: Requests) usize { return @intCast(v8.v8__FixedArray__Length(self.handle)); } pub fn get(self: Requests, idx: usize) Request { - return .{ .handle = v8.v8__FixedArray__Get(self.handle, self.context_handle, @intCast(idx)).? }; + return .{ .handle = v8.v8__FixedArray__Get(self.handle, @intCast(idx)).? }; } }; diff --git a/src/browser/js/Snapshot.zig b/src/browser/js/Snapshot.zig index d0d606bbf..a1cfd9d2e 100644 --- a/src/browser/js/Snapshot.zig +++ b/src/browser/js/Snapshot.zig @@ -798,6 +798,7 @@ fn attachClass(comptime JsApi: type, comptime flatten: bool, isolate: *v8.Isolat .deleter = null, .definer = null, .descriptor = null, + .index_of = null, .data = null, .flags = 0, }; diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig index 0afc1c85e..43db4ff34 100644 --- a/src/browser/js/bridge.zig +++ b/src/browser/js/bridge.zig @@ -275,7 +275,7 @@ pub const Indexed = struct { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); @@ -293,7 +293,7 @@ pub const Indexed = struct { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); return caller.getEnumerator(T, enumerator, handle.?, .{}); @@ -325,7 +325,7 @@ pub const NamedIndexed = struct { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); @@ -341,7 +341,7 @@ pub const NamedIndexed = struct { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); @@ -369,7 +369,7 @@ pub const NamedIndexed = struct { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); @@ -486,8 +486,8 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 // During snapshot creation, there's no Context in embedder data yet. // I hate this check, but there doesn't seem to be a way to add this method // to the global, without triggering it during snapshot creation. - const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate) orelse return 0; - const ctx: *Context = @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(v8_context, 1) orelse return 0)); + const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate) orelse return 1; + const ctx: *Context = @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(v8_context, 1) orelse return 1)); var caller: Caller = undefined; caller.initWithContext(ctx, v8_context); @@ -500,7 +500,7 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 defer hs.deinit(); const property: []const u8 = js.String.toSlice(.{ .local = local, .handle = @ptrCast(c_name.?) }) catch { - return 0; + return 1; }; // Only Page contexts have document.getElementById lookup @@ -508,10 +508,10 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 .frame => |frame| { const document = frame.document; if (document.getElementById(property, frame)) |el| { - const js_val = local.zigValueToJs(el, .{}) catch return 0; + const js_val = local.zigValueToJs(el, .{}) catch return 1; var pc = Caller.PropertyCallbackInfo{ .handle = handle.? }; pc.getReturnValue().set(js_val); - return 1; + return 0; } }, .worker => {}, // no global lookup in a worker @@ -521,7 +521,7 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 if (std.mem.startsWith(u8, property, "__")) { // some frameworks will extend built-in types using a __ prefix // these should always be safe to ignore. - return 0; + return 1; } const ignored = std.StaticStringMap(void).initComptime(.{ @@ -553,13 +553,12 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 }); if (!ignored.has(property)) { var buf: [2048]u8 = undefined; - const key = std.fmt.bufPrint(&buf, "Window:{s}", .{property}) catch return 0; - logUnknownProperty(local, key) catch return 0; + const key = std.fmt.bufPrint(&buf, "Window:{s}", .{property}) catch return 1; + logUnknownProperty(local, key) catch return 1; } } - // not intercepted - return 0; + return 1; } // Only used for debugging @@ -574,7 +573,7 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8 var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 0; + return 1; } defer caller.deinit(); @@ -585,45 +584,44 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8 defer hs.deinit(); const property: []const u8 = js.String.toSlice(.{ .local = local, .handle = @ptrCast(c_name.?) }) catch { - return 0; + return 1; }; if (std.mem.startsWith(u8, property, "__")) { // some frameworks will extend built-in types using a __ prefix // these should always be safe to ignore. - return 0; + return 1; } if (std.mem.startsWith(u8, property, "jQuery")) { - return 0; + return 1; } if (JsApi == @import("../webapi/cdata/Text.zig").JsApi or JsApi == @import("../webapi/cdata/Comment.zig").JsApi) { if (std.mem.eql(u8, property, "tagName")) { // knockout does this, a lot. - return 0; + return 1; } } if (JsApi == @import("../webapi/element/Html.zig").JsApi or JsApi == @import("../webapi/Element.zig").JsApi or JsApi == @import("../webapi/element/html/Custom.zig").JsApi) { // react ? - if (std.mem.eql(u8, property, "props")) return 0; - if (std.mem.eql(u8, property, "hydrated")) return 0; - if (std.mem.eql(u8, property, "isHydrated")) return 0; + if (std.mem.eql(u8, property, "props")) return 1; + if (std.mem.eql(u8, property, "hydrated")) return 1; + if (std.mem.eql(u8, property, "isHydrated")) return 1; } if (JsApi == @import("../webapi/Console.zig").JsApi) { - if (std.mem.eql(u8, property, "firebug")) return 0; + if (std.mem.eql(u8, property, "firebug")) return 1; } const ignored = std.StaticStringMap(void).initComptime(.{}); if (!ignored.has(property)) { var buf: [2048]u8 = undefined; - const key = std.fmt.bufPrint(&buf, "{s}:{s}", .{ if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi), property }) catch return 0; - logUnknownProperty(local, key) catch return 0; + const key = std.fmt.bufPrint(&buf, "{s}:{s}", .{ if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi), property }) catch return 1; + logUnknownProperty(local, key) catch return 1; } - // not intercepted - return 0; + return 1; } }.wrap; } From 8350076972a836a38a0860831e44aab10a248f49 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sun, 28 Jun 2026 14:18:12 +0800 Subject: [PATCH 2/5] update intercepted type from u8 to u32 --- build.zig.zon | 2 +- src/browser/js/Caller.zig | 38 +++++++++---------- src/browser/js/bridge.zig | 78 +++++++++++++++++++-------------------- src/browser/js/js.zig | 5 +++ 4 files changed, 64 insertions(+), 59 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index e9d41446a..90b0a1be6 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,7 +5,7 @@ .minimum_zig_version = "0.15.2", .dependencies = .{ .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/3a53a258e508ea6a805654a94339b9fd006e7b2d.tar.gz", + .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/8bb45873631bf2c419a7eeb452f5f65fcb18c609.tar.gz", .hash = "v8-0.0.0-xddH65qdBAA1hmB-gqEmhEzO0-aXKyEsmo1s34mssemb", }, // .v8 = .{ .path = "../zig-v8-fork" }, diff --git a/src/browser/js/Caller.zig b/src/browser/js/Caller.zig index 8b2d782cc..55daf7c32 100644 --- a/src/browser/js/Caller.zig +++ b/src/browser/js/Caller.zig @@ -173,7 +173,7 @@ fn _constructor(self: *Caller, func: anytype, info: FunctionCallbackInfo, compti info.getReturnValue().set(this.handle); } -pub fn getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 { +pub fn getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u32 { const local = &self.local; var hs: js.HandleScope = undefined; @@ -183,11 +183,11 @@ pub fn getIndex(self: *Caller, comptime T: type, func: anytype, idx: u32, handle const info = PropertyCallbackInfo{ .handle = handle }; return _getIndex(T, local, func, idx, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 1; + return js.Intercepted.no; }; } -fn _getIndex(comptime T: type, local: *const Local, func: anytype, idx: u32, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn _getIndex(comptime T: type, local: *const Local, func: anytype, idx: u32, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { const F = @TypeOf(func); var args: ParameterTypes(F) = undefined; @field(args, "0") = try TaggedOpaque.fromJS(*T, info.getThis()); @@ -199,7 +199,7 @@ fn _getIndex(comptime T: type, local: *const Local, func: anytype, idx: u32, inf return handleIndexedReturn(T, F, true, local, ret, info, opts); } -pub fn getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 { +pub fn getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u32 { const local = &self.local; var hs: js.HandleScope = undefined; @@ -209,11 +209,11 @@ pub fn getNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *cons const info = PropertyCallbackInfo{ .handle = handle }; return _getNamedIndex(T, local, func, name, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 1; + return js.Intercepted.no; }; } -fn _getNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn _getNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { const F = @TypeOf(func); var args: ParameterTypes(F) = undefined; @field(args, "0") = try TaggedOpaque.fromJS(*T, info.getThis()); @@ -225,7 +225,7 @@ fn _getNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *c return handleIndexedReturn(T, F, true, local, ret, info, opts); } -pub fn setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, js_value: *const v8.Value, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 { +pub fn setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, js_value: *const v8.Value, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u32 { const local = &self.local; var hs: js.HandleScope = undefined; @@ -235,11 +235,11 @@ pub fn setNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *cons const info = PropertyCallbackInfo{ .handle = handle }; return _setNamedIndex(T, local, func, name, .{ .local = &self.local, .handle = js_value }, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 1; + return js.Intercepted.no; }; } -fn _setNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, js_value: js.Value, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn _setNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, js_value: js.Value, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { const F = @TypeOf(func); var args: ParameterTypes(F) = undefined; @field(args, "0") = try TaggedOpaque.fromJS(*T, info.getThis()); @@ -252,7 +252,7 @@ fn _setNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *c return handleIndexedReturn(T, F, false, local, ret, info, opts); } -pub fn deleteNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 { +pub fn deleteNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *const v8.Name, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u32 { const local = &self.local; var hs: js.HandleScope = undefined; @@ -262,11 +262,11 @@ pub fn deleteNamedIndex(self: *Caller, comptime T: type, func: anytype, name: *c const info = PropertyCallbackInfo{ .handle = handle }; return _deleteNamedIndex(T, local, func, name, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 1; + return js.Intercepted.no; }; } -fn _deleteNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn _deleteNamedIndex(comptime T: type, local: *const Local, func: anytype, name: *const v8.Name, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { const F = @TypeOf(func); var args: ParameterTypes(F) = undefined; @field(args, "0") = try TaggedOpaque.fromJS(*T, info.getThis()); @@ -278,7 +278,7 @@ fn _deleteNamedIndex(comptime T: type, local: *const Local, func: anytype, name: return handleIndexedReturn(T, F, false, local, ret, info, opts); } -pub fn getEnumerator(self: *Caller, comptime T: type, func: anytype, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u8 { +pub fn getEnumerator(self: *Caller, comptime T: type, func: anytype, handle: *const v8.PropertyCallbackInfo, comptime opts: CallOpts) u32 { const local = &self.local; var hs: js.HandleScope = undefined; @@ -288,11 +288,11 @@ pub fn getEnumerator(self: *Caller, comptime T: type, func: anytype, handle: *co const info = PropertyCallbackInfo{ .handle = handle }; return _getEnumerator(T, local, func, info, opts) catch |err| { handleError(T, @TypeOf(func), local, err, info, opts); - return 1; + return js.Intercepted.no; }; } -fn _getEnumerator(comptime T: type, local: *const Local, func: anytype, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn _getEnumerator(comptime T: type, local: *const Local, func: anytype, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { const F = @TypeOf(func); var args: ParameterTypes(F) = undefined; @field(args, "0") = try TaggedOpaque.fromJS(*T, info.getThis()); @@ -303,7 +303,7 @@ fn _getEnumerator(comptime T: type, local: *const Local, func: anytype, info: Pr return handleIndexedReturn(T, F, true, local, ret, info, opts); } -fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: bool, local: *const Local, ret: anytype, info: PropertyCallbackInfo, comptime opts: CallOpts) !u8 { +fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: bool, local: *const Local, ret: anytype, info: PropertyCallbackInfo, comptime opts: CallOpts) !u32 { // need to unwrap this error immediately for when opts.null_as_undefined == true // and we need to compare it to null; const non_error_ret = switch (@typeInfo(@TypeOf(ret))) { @@ -314,11 +314,11 @@ fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: // if error.NotHandled is part of the error set. if (isInErrorSet(error.NotHandled, eu.error_set)) { if (err == error.NotHandled) { - return 1; + return js.Intercepted.no; } } handleError(T, F, local, err, info, opts); - return 1; + return js.Intercepted.no; }; }, else => ret, @@ -327,7 +327,7 @@ fn handleIndexedReturn(comptime T: type, comptime F: type, comptime with_value: if (comptime with_value) { info.getReturnValue().set(try local.zigValueToJs(non_error_ret, opts)); } - return 0; + return js.Intercepted.yes; } fn isInErrorSet(err: anyerror, comptime T: type) bool { diff --git a/src/browser/js/bridge.zig b/src/browser/js/bridge.zig index 43db4ff34..6131f19b2 100644 --- a/src/browser/js/bridge.zig +++ b/src/browser/js/bridge.zig @@ -259,8 +259,8 @@ pub const Accessor = struct { }; pub const Indexed = struct { - getter: *const fn (idx: u32, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8, - enumerator: ?*const fn (handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8, + getter: *const fn (idx: u32, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32, + enumerator: ?*const fn (handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32, const Opts = struct { as_typed_array: bool = false, @@ -271,11 +271,11 @@ pub const Indexed = struct { var indexed = Indexed{ .enumerator = null, .getter = struct { - fn wrap(idx: u32, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(idx: u32, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); @@ -289,11 +289,11 @@ pub const Indexed = struct { if (@typeInfo(@TypeOf(enumerator)) != .null) { indexed.enumerator = struct { - fn wrap(handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); return caller.getEnumerator(T, enumerator, handle.?, .{}); @@ -306,9 +306,9 @@ pub const Indexed = struct { }; pub const NamedIndexed = struct { - getter: *const fn (c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8, - setter: ?*const fn (c_name: ?*const v8.Name, c_value: ?*const v8.Value, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 = null, - deleter: ?*const fn (c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 = null, + getter: *const fn (c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32, + setter: ?*const fn (c_name: ?*const v8.Name, c_value: ?*const v8.Value, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 = null, + deleter: ?*const fn (c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 = null, const Opts = struct { as_typed_array: bool = false, @@ -321,11 +321,11 @@ pub const NamedIndexed = struct { fn init(comptime T: type, comptime getter: anytype, setter: anytype, deleter: anytype, comptime opts: Opts) NamedIndexed { const getter_fn = struct { - fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); @@ -337,11 +337,11 @@ pub const NamedIndexed = struct { }.wrap; const setter_fn = if (@typeInfo(@TypeOf(setter)) == .null) null else struct { - fn wrap(c_name: ?*const v8.Name, c_value: ?*const v8.Value, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(c_name: ?*const v8.Name, c_value: ?*const v8.Value, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); @@ -365,11 +365,11 @@ pub const NamedIndexed = struct { }.wrap; const deleter_fn = if (@typeInfo(@TypeOf(deleter)) == .null) null else struct { - fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); @@ -480,14 +480,14 @@ pub const Property = struct { } }; -pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { +pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; // During snapshot creation, there's no Context in embedder data yet. // I hate this check, but there doesn't seem to be a way to add this method // to the global, without triggering it during snapshot creation. - const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate) orelse return 1; - const ctx: *Context = @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(v8_context, 1) orelse return 1)); + const v8_context = v8.v8__Isolate__GetCurrentContext(v8_isolate) orelse return js.Intercepted.no; + const ctx: *Context = @ptrCast(@alignCast(v8.v8__Context__GetAlignedPointerFromEmbedderData(v8_context, 1) orelse return js.Intercepted.no)); var caller: Caller = undefined; caller.initWithContext(ctx, v8_context); @@ -500,7 +500,7 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 defer hs.deinit(); const property: []const u8 = js.String.toSlice(.{ .local = local, .handle = @ptrCast(c_name.?) }) catch { - return 1; + return js.Intercepted.no; }; // Only Page contexts have document.getElementById lookup @@ -508,10 +508,10 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 .frame => |frame| { const document = frame.document; if (document.getElementById(property, frame)) |el| { - const js_val = local.zigValueToJs(el, .{}) catch return 1; + const js_val = local.zigValueToJs(el, .{}) catch return js.Intercepted.no; var pc = Caller.PropertyCallbackInfo{ .handle = handle.? }; pc.getReturnValue().set(js_val); - return 0; + return js.Intercepted.yes; } }, .worker => {}, // no global lookup in a worker @@ -521,7 +521,7 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 if (std.mem.startsWith(u8, property, "__")) { // some frameworks will extend built-in types using a __ prefix // these should always be safe to ignore. - return 1; + return js.Intercepted.no; } const ignored = std.StaticStringMap(void).initComptime(.{ @@ -553,27 +553,27 @@ pub fn unknownWindowPropertyCallback(c_name: ?*const v8.Name, handle: ?*const v8 }); if (!ignored.has(property)) { var buf: [2048]u8 = undefined; - const key = std.fmt.bufPrint(&buf, "Window:{s}", .{property}) catch return 1; - logUnknownProperty(local, key) catch return 1; + const key = std.fmt.bufPrint(&buf, "Window:{s}", .{property}) catch return js.Intercepted.no; + logUnknownProperty(local, key) catch return js.Intercepted.no; } } - return 1; + return js.Intercepted.no; } // Only used for debugging -pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8.Name, ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { +pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8.Name, ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { if (comptime !IS_DEBUG) { @compileError("unknownObjectPropertyCallback should only be used in debug builds"); } return struct { - fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u8 { + fn wrap(c_name: ?*const v8.Name, handle: ?*const v8.PropertyCallbackInfo) callconv(.c) u32 { const v8_isolate = v8.v8__PropertyCallbackInfo__GetIsolate(handle).?; var caller: Caller = undefined; if (!caller.init(v8_isolate)) { - return 1; + return js.Intercepted.no; } defer caller.deinit(); @@ -584,44 +584,44 @@ pub fn unknownObjectPropertyCallback(comptime JsApi: type) *const fn (?*const v8 defer hs.deinit(); const property: []const u8 = js.String.toSlice(.{ .local = local, .handle = @ptrCast(c_name.?) }) catch { - return 1; + return js.Intercepted.no; }; if (std.mem.startsWith(u8, property, "__")) { // some frameworks will extend built-in types using a __ prefix // these should always be safe to ignore. - return 1; + return js.Intercepted.no; } if (std.mem.startsWith(u8, property, "jQuery")) { - return 1; + return js.Intercepted.no; } if (JsApi == @import("../webapi/cdata/Text.zig").JsApi or JsApi == @import("../webapi/cdata/Comment.zig").JsApi) { if (std.mem.eql(u8, property, "tagName")) { // knockout does this, a lot. - return 1; + return js.Intercepted.no; } } if (JsApi == @import("../webapi/element/Html.zig").JsApi or JsApi == @import("../webapi/Element.zig").JsApi or JsApi == @import("../webapi/element/html/Custom.zig").JsApi) { // react ? - if (std.mem.eql(u8, property, "props")) return 1; - if (std.mem.eql(u8, property, "hydrated")) return 1; - if (std.mem.eql(u8, property, "isHydrated")) return 1; + if (std.mem.eql(u8, property, "props")) return js.Intercepted.no; + if (std.mem.eql(u8, property, "hydrated")) return js.Intercepted.no; + if (std.mem.eql(u8, property, "isHydrated")) return js.Intercepted.no; } if (JsApi == @import("../webapi/Console.zig").JsApi) { - if (std.mem.eql(u8, property, "firebug")) return 1; + if (std.mem.eql(u8, property, "firebug")) return js.Intercepted.no; } const ignored = std.StaticStringMap(void).initComptime(.{}); if (!ignored.has(property)) { var buf: [2048]u8 = undefined; - const key = std.fmt.bufPrint(&buf, "{s}:{s}", .{ if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi), property }) catch return 1; - logUnknownProperty(local, key) catch return 1; + const key = std.fmt.bufPrint(&buf, "{s}:{s}", .{ if (@hasDecl(JsApi.Meta, "name")) JsApi.Meta.name else @typeName(JsApi), property }) catch return js.Intercepted.no; + logUnknownProperty(local, key) catch return js.Intercepted.no; } - return 1; + return js.Intercepted.no; } }.wrap; } diff --git a/src/browser/js/js.zig b/src/browser/js/js.zig index 3b1fa5950..3095d20b3 100644 --- a/src/browser/js/js.zig +++ b/src/browser/js/js.zig @@ -21,6 +21,11 @@ const lp = @import("lightpanda"); pub const v8 = @import("v8").c; +pub const Intercepted = struct { + pub const yes: u32 = 0; + pub const no: u32 = 1; +}; + const string = @import("../../string.zig"); pub const Env = @import("Env.zig"); From d9c76d0b0e643cc3cca39090d9bd6dba9e181e26 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Sun, 28 Jun 2026 14:25:13 +0800 Subject: [PATCH 3/5] update zig-v8-fork dep hash --- build.zig.zon | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig.zon b/build.zig.zon index 90b0a1be6..1afac904c 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -6,7 +6,7 @@ .dependencies = .{ .v8 = .{ .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/8bb45873631bf2c419a7eeb452f5f65fcb18c609.tar.gz", - .hash = "v8-0.0.0-xddH65qdBAA1hmB-gqEmhEzO0-aXKyEsmo1s34mssemb", + .hash = "v8-0.0.0-xddH63jnAgBlV_WzDYAcATFU7XfA848ysZNHSomz-rXq", }, // .v8 = .{ .path = "../zig-v8-fork" }, .brotli = .{ From 98157e18ab42533e409a83cc91330cd228c26108 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 30 Jun 2026 13:36:02 +0800 Subject: [PATCH 4/5] update zig-v8-fork dep --- .github/actions/install/action.yml | 2 +- .github/actions/v8-snapshot/action.yml | 2 +- Dockerfile | 2 +- build.zig.zon | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml index 97c3349c1..f46ab1596 100644 --- a/.github/actions/install/action.yml +++ b/.github/actions/install/action.yml @@ -13,7 +13,7 @@ inputs: zig-v8: description: 'zig v8 version to install' required: false - default: 'v0.4.8' + default: 'v0.4.9' v8: description: 'v8 version to install' required: false diff --git a/.github/actions/v8-snapshot/action.yml b/.github/actions/v8-snapshot/action.yml index 84a61acaa..7e3365f83 100644 --- a/.github/actions/v8-snapshot/action.yml +++ b/.github/actions/v8-snapshot/action.yml @@ -13,7 +13,7 @@ inputs: zig-v8: description: 'zig-v8 release tag the prebuilt lib came from' required: false - default: 'v0.4.8' + default: 'v0.4.9' runs: using: "composite" diff --git a/Dockerfile b/Dockerfile index 8cecd404b..08535cf7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ FROM debian:stable-slim ARG MINISIG=0.12 ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U ARG V8=14.0.365.4 -ARG ZIG_V8=v0.4.8 +ARG ZIG_V8=v0.4.9 ARG TARGETPLATFORM RUN apt-get update -yq && \ diff --git a/build.zig.zon b/build.zig.zon index 1afac904c..5d549b8fd 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,8 +5,8 @@ .minimum_zig_version = "0.15.2", .dependencies = .{ .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/8bb45873631bf2c419a7eeb452f5f65fcb18c609.tar.gz", - .hash = "v8-0.0.0-xddH63jnAgBlV_WzDYAcATFU7XfA848ysZNHSomz-rXq", + .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/refs/tags/v0.4.9.tar.gz", + .hash = "v8-0.0.0-xddH63jnAgB8guO5jPzJD4pnX-CI5od-g4v-fIIjmQXr", }, // .v8 = .{ .path = "../zig-v8-fork" }, .brotli = .{ From d2f72dfd4b346e266d2cbd465c34c7fd5689a636 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 30 Jun 2026 13:39:13 +0800 Subject: [PATCH 5/5] update v8 version --- .github/actions/install/action.yml | 2 +- Dockerfile | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml index f46ab1596..d752a0b49 100644 --- a/.github/actions/install/action.yml +++ b/.github/actions/install/action.yml @@ -17,7 +17,7 @@ inputs: v8: description: 'v8 version to install' required: false - default: '14.0.365.4' + default: '14.9.207.35' cache-dir: description: 'cache dir to use' required: false diff --git a/Dockerfile b/Dockerfile index 08535cf7c..889c2a78d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,9 @@ + FROM debian:stable-slim ARG MINISIG=0.12 ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U -ARG V8=14.0.365.4 +ARG V8=14.9.207.35 ARG ZIG_V8=v0.4.9 ARG TARGETPLATFORM