From 1cb431f2048ff3592be9a62d4bce66971d9b60fe Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 29 Sep 2025 20:23:09 +0800 Subject: [PATCH 1/5] Better support for Uint8Array in ReadableStream There's always going to be ambiguity between a string and a Uint8Array. We already had TypedArray(u8) as a discriminator when _returning_ values. But now the type is also used by mapping JS values to Zig. To support this efficiently when probing the union, the typed array mapping logic was extracted into its own function (so that it can be used by the probe). --- src/runtime/js.zig | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/runtime/js.zig b/src/runtime/js.zig index 7d4c79742..6f3cc29b8 100644 --- a/src/runtime/js.zig +++ b/src/runtime/js.zig @@ -1251,23 +1251,31 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { fn jsValueToTypedArray(_: *JsContext, comptime T: type, js_value: v8.Value) !?[]T { var force_u8 = false; var array_buffer: ?v8.ArrayBuffer = null; + var byte_len: usize = undefined; + var byte_offset: usize = undefined; + if (js_value.isTypedArray()) { const buffer_view = js_value.castTo(v8.ArrayBufferView); + byte_len = buffer_view.getByteLength(); + byte_offset = buffer_view.getByteOffset(); array_buffer = buffer_view.getBuffer(); } else if (js_value.isArrayBufferView()) { force_u8 = true; const buffer_view = js_value.castTo(v8.ArrayBufferView); + byte_len = buffer_view.getByteLength(); + byte_offset = buffer_view.getByteOffset(); array_buffer = buffer_view.getBuffer(); } else if (js_value.isArrayBuffer()) { force_u8 = true; array_buffer = js_value.castTo(v8.ArrayBuffer); + byte_len = array_buffer.?.getByteLength(); + byte_offset = 0; } const buffer = array_buffer orelse return null; const backing_store = v8.BackingStore.sharedPtrGet(&buffer.getBackingStore()); const data = backing_store.getData(); - const byte_len = backing_store.getByteLength(); switch (T) { u8 => { @@ -1275,56 +1283,56 @@ pub fn Env(comptime State: type, comptime WebApis: type) type { if (force_u8 or js_value.isUint8Array() or js_value.isUint8ClampedArray()) { if (byte_len == 0) return &[_]u8{}; const arr_ptr = @as([*]u8, @ptrCast(@alignCast(data))); - return arr_ptr[0..byte_len]; + return arr_ptr[byte_offset .. byte_offset + byte_len]; } }, i8 => { if (js_value.isInt8Array()) { if (byte_len == 0) return &[_]i8{}; const arr_ptr = @as([*]i8, @ptrCast(@alignCast(data))); - return arr_ptr[0..byte_len]; + return arr_ptr[byte_offset .. byte_offset + byte_len]; } }, u16 => { if (js_value.isUint16Array()) { if (byte_len == 0) return &[_]u16{}; const arr_ptr = @as([*]u16, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 2]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 2]; } }, i16 => { if (js_value.isInt16Array()) { if (byte_len == 0) return &[_]i16{}; const arr_ptr = @as([*]i16, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 2]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 2]; } }, u32 => { if (js_value.isUint32Array()) { if (byte_len == 0) return &[_]u32{}; const arr_ptr = @as([*]u32, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 4]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 4]; } }, i32 => { if (js_value.isInt32Array()) { if (byte_len == 0) return &[_]i32{}; const arr_ptr = @as([*]i32, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 4]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 4]; } }, u64 => { if (js_value.isBigUint64Array()) { if (byte_len == 0) return &[_]u64{}; const arr_ptr = @as([*]u64, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 8]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 8]; } }, i64 => { if (js_value.isBigInt64Array()) { if (byte_len == 0) return &[_]i64{}; const arr_ptr = @as([*]i64, @ptrCast(@alignCast(data))); - return arr_ptr[0 .. byte_len / 8]; + return arr_ptr[byte_offset .. byte_offset + byte_len / 8]; } }, else => {}, From 298f959e1303f528cf469875edcc0e83c35852b0 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Mon, 29 Sep 2025 20:29:43 +0800 Subject: [PATCH 2/5] Add broken TextDecoder test that should pass --- src/tests/encoding/decoder.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/tests/encoding/decoder.html b/src/tests/encoding/decoder.html index 3ce3f5c10..dfdbd307b 100644 --- a/src/tests/encoding/decoder.html +++ b/src/tests/encoding/decoder.html @@ -45,3 +45,13 @@ testing.expectEqual('', d2.decode(new Uint8Array([226, 153]), { stream: true })); testing.expectEqual('♥', d2.decode(new Uint8Array([165]), { stream: true })); + + From 37fa41b4a284a8774483b63d400d6406ccf0efa2 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 30 Sep 2025 09:14:21 +0800 Subject: [PATCH 3/5] fix buffer ranges --- build.zig.zon | 6 +++--- src/browser/encoding/TextDecoder.zig | 5 +++-- src/tests/encoding/decoder.html | 9 ++++++--- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index f1fbb67c2..9004a506d 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -5,9 +5,9 @@ .fingerprint = 0xda130f3af836cea0, .dependencies = .{ .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/c25223900587005c9cf13f25e56a7e0be26a533c.tar.gz", - .hash = "v8-0.0.0-xddH6x_DAwBh0gSbFFv1fyiExhExXKzZpbmj5sFH4MRY", + .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/b51ed00390101b1fb9dd1ba4650c13f6586d0e24.tar.gz", + .hash = "v8-0.0.0-xddH68vFAwCYTTv4JjcgP7OcXSW7bv3sCKtaJ2SWXjR8", }, - // .v8 = .{ .path = "../zig-v8-fork" } + //.v8 = .{ .path = "../zig-v8-fork" } }, } diff --git a/src/browser/encoding/TextDecoder.zig b/src/browser/encoding/TextDecoder.zig index 8efe4102d..811945b6e 100644 --- a/src/browser/encoding/TextDecoder.zig +++ b/src/browser/encoding/TextDecoder.zig @@ -19,6 +19,7 @@ const std = @import("std"); const log = @import("../../log.zig"); +const Env = @import("../env.zig").Env; const Page = @import("../page.zig").Page; // https://encoding.spec.whatwg.org/#interface-textdecoder @@ -69,8 +70,8 @@ pub fn get_fatal(self: *const TextDecoder) bool { const DecodeOptions = struct { stream: bool = false, }; -pub fn _decode(self: *TextDecoder, input_: ?[]const u8, opts_: ?DecodeOptions, page: *Page) ![]const u8 { - var str = input_ orelse return ""; +pub fn _decode(self: *TextDecoder, str_: ?[]const u8, opts_: ?DecodeOptions, page: *Page) ![]const u8 { + var str = str_ orelse return ""; const opts: DecodeOptions = opts_ orelse .{}; if (self.stream.items.len > 0) { diff --git a/src/tests/encoding/decoder.html b/src/tests/encoding/decoder.html index dfdbd307b..8a93dc46a 100644 --- a/src/tests/encoding/decoder.html +++ b/src/tests/encoding/decoder.html @@ -47,11 +47,14 @@ From 92ca7c5a4bf0e0e7f34c163cfe16d4847beae344 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 30 Sep 2025 19:05:30 +0800 Subject: [PATCH 4/5] update zig-v8-form --- .github/actions/install/action.yml | 2 +- Dockerfile | 2 +- build.zig.zon | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/actions/install/action.yml b/.github/actions/install/action.yml index 291997123..17c027593 100644 --- a/.github/actions/install/action.yml +++ b/.github/actions/install/action.yml @@ -17,7 +17,7 @@ inputs: zig-v8: description: 'zig v8 version to install' required: false - default: 'v0.1.30' + default: 'v0.1.33' v8: description: 'v8 version to install' required: false diff --git a/Dockerfile b/Dockerfile index fc0145af7..bcb613f7f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,7 +4,7 @@ ARG MINISIG=0.12 ARG ZIG=0.15.1 ARG ZIG_MINISIG=RWSGOq2NVecA2UPNdBUZykf1CCb147pkmdtYxgb3Ti+JO/wCYvhbAb/U ARG V8=14.0.365.4 -ARG ZIG_V8=v0.1.30 +ARG ZIG_V8=v0.1.33 ARG TARGETPLATFORM RUN apt-get update -yq && \ diff --git a/build.zig.zon b/build.zig.zon index 9004a506d..4de66da94 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,10 +4,10 @@ .version = "0.0.0", .fingerprint = 0xda130f3af836cea0, .dependencies = .{ - .v8 = .{ - .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/b51ed00390101b1fb9dd1ba4650c13f6586d0e24.tar.gz", - .hash = "v8-0.0.0-xddH68vFAwCYTTv4JjcgP7OcXSW7bv3sCKtaJ2SWXjR8", - }, - //.v8 = .{ .path = "../zig-v8-fork" } + //.v8 = .{ + // .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/b51ed00390101b1fb9dd1ba4650c13f6586d0e24.tar.gz", + // .hash = "v8-0.0.0-xddH68vFAwCYTTv4JjcgP7OcXSW7bv3sCKtaJ2SWXjR8", + //}, + .v8 = .{ .path = "../zig-v8-fork" } }, } From 20ae9c3a53e35abd249dad15417f1ff22cbfba91 Mon Sep 17 00:00:00 2001 From: Karl Seguin Date: Tue, 30 Sep 2025 21:41:08 +0800 Subject: [PATCH 5/5] fix dep link --- build.zig.zon | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/build.zig.zon b/build.zig.zon index 4de66da94..7d24d4118 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,10 +4,10 @@ .version = "0.0.0", .fingerprint = 0xda130f3af836cea0, .dependencies = .{ - //.v8 = .{ - // .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/b51ed00390101b1fb9dd1ba4650c13f6586d0e24.tar.gz", - // .hash = "v8-0.0.0-xddH68vFAwCYTTv4JjcgP7OcXSW7bv3sCKtaJ2SWXjR8", - //}, - .v8 = .{ .path = "../zig-v8-fork" } + .v8 = .{ + .url = "https://github.com/lightpanda-io/zig-v8-fork/archive/7a1beb016efcb2bd66c0b46b5fc6bcd04fa72db8.tar.gz", + .hash = "v8-0.0.0-xddH6_PFAwAqwLMWbF7S0rAZzRbN8zmf2GhLH_ThdMSR", + }, + //.v8 = .{ .path = "../zig-v8-fork" } }, }