Skip to content

Commit 340b8a2

Browse files
authored
Merge pull request #1019 from lightpanda-io/jsValueToZig-for-fixed-sized-arrays
jsValueToZig for fixed sized arrays
2 parents 429dc4d + 6631292 commit 340b8a2

File tree

2 files changed

+44
-11
lines changed

2 files changed

+44
-11
lines changed

src/browser/fetch/Headers.zig

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ headers: HeaderHashMap = .empty,
6262
// 3. Another Headers object.
6363
pub const HeadersInit = union(enum) {
6464
// List of Pairs of []const u8
65-
strings: []const []const []const u8,
65+
strings: []const [2][]const u8,
6666
headers: *Headers,
6767
};
6868

@@ -74,11 +74,6 @@ pub fn constructor(_init: ?HeadersInit, page: *Page) !Headers {
7474
switch (init) {
7575
.strings => |kvs| {
7676
for (kvs) |pair| {
77-
// Can only have two string elements if in a pair.
78-
if (pair.len != 2) {
79-
return error.TypeError;
80-
}
81-
8277
const key = try arena.dupe(u8, pair[0]);
8378
const value = try arena.dupe(u8, pair[1]);
8479

src/runtime/js.zig

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,18 +331,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
331331

332332
fn promiseRejectCallback(v8_msg: v8.C_PromiseRejectMessage) callconv(.c) void {
333333
const msg = v8.PromiseRejectMessage.initFromC(v8_msg);
334-
const isolate = msg.getPromise().toObject().getIsolate();
334+
const isolate = msg.getPromise().toObject().getIsolate();
335335
const v8_context = isolate.getCurrentContext();
336336
const context: *JsContext = @ptrFromInt(v8_context.getEmbedderData(1).castTo(v8.BigInt).getUint64());
337337

338338
const value =
339-
if (msg.getValue()) |v8_value| valueToString(context.call_arena, v8_value, isolate, v8_context) catch |err| @errorName(err)
340-
else "no value";
339+
if (msg.getValue()) |v8_value| valueToString(context.call_arena, v8_value, isolate, v8_context) catch |err| @errorName(err) else "no value";
341340

342-
log.debug(.js, "unhandled rejection", .{.value =value});
341+
log.debug(.js, "unhandled rejection", .{ .value = value });
343342
}
344343

345-
346344
// ExecutionWorld closely models a JS World.
347345
// https://chromium.googlesource.com/chromium/src/+/master/third_party/blink/renderer/bindings/core/v8/V8BindingDesign.md#World
348346
// https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/ExecutionWorld
@@ -1110,6 +1108,16 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
11101108
},
11111109
else => {},
11121110
},
1111+
.array => |arr| {
1112+
// Retrieve fixed-size array as slice
1113+
const slice_type = []arr.child;
1114+
const slice_value = try self.jsValueToZig(named_function, slice_type, js_value);
1115+
if (slice_value.len != arr.len) {
1116+
// Exact length match, we could allow smaller arrays, but we would not be able to communicate how many were written
1117+
return error.InvalidArgument;
1118+
}
1119+
return @as(*T, @ptrCast(slice_value.ptr)).*;
1120+
},
11131121
.@"struct" => {
11141122
return try (self.jsValueToStruct(named_function, T, js_value)) orelse {
11151123
return error.InvalidArgument;
@@ -1393,6 +1401,36 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
13931401
},
13941402
else => {},
13951403
},
1404+
.array => |arr| {
1405+
// Retrieve fixed-size array as slice then probe
1406+
const slice_type = []arr.child;
1407+
switch (try self.probeJsValueToZig(named_function, slice_type, js_value)) {
1408+
.value => |slice_value| {
1409+
if (slice_value.len == arr.len) {
1410+
return .{ .value = @as(*T, @ptrCast(slice_value.ptr)).* };
1411+
}
1412+
return .{ .invalid = {} };
1413+
},
1414+
.ok => {
1415+
// Exact length match, we could allow smaller arrays as .compatible, but we would not be able to communicate how many were written
1416+
if (js_value.isArray()) {
1417+
const js_arr = js_value.castTo(v8.Array);
1418+
if (js_arr.length() == arr.len) {
1419+
return .{ .ok = {} };
1420+
}
1421+
} else if (js_value.isString() and arr.child == u8) {
1422+
const str = try js_value.toString(self.v8_context);
1423+
if (str.lenUtf8(self.isolate) == arr.len) {
1424+
return .{ .ok = {} };
1425+
}
1426+
}
1427+
return .{ .invalid = {} };
1428+
},
1429+
.compatible => return .{ .compatible = {} },
1430+
.coerce => return .{ .coerce = {} },
1431+
.invalid => return .{ .invalid = {} },
1432+
}
1433+
},
13961434
.@"struct" => {
13971435
// We don't want to duplicate the code for this, so we call
13981436
// the actual conversion function.

0 commit comments

Comments
 (0)