mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-12-14 15:28:57 +00:00
Merge pull request #1269 from lightpanda-io/nikneym/zigdom-fix-kludge-hack
backport: Remove `_TYPED_ARRAY_ID_KLUDGE` hack
This commit is contained in:
@@ -821,64 +821,62 @@ pub fn jsValueToZig(self: *Context, comptime T: type, js_value: v8.Value) !T {
|
|||||||
// Extracted so that it can be used in both jsValueToZig and in
|
// Extracted so that it can be used in both jsValueToZig and in
|
||||||
// probeJsValueToZig. Avoids having to duplicate this logic when probing.
|
// probeJsValueToZig. Avoids having to duplicate this logic when probing.
|
||||||
fn jsValueToStruct(self: *Context, comptime T: type, js_value: v8.Value) !?T {
|
fn jsValueToStruct(self: *Context, comptime T: type, js_value: v8.Value) !?T {
|
||||||
if (T == js.Function) {
|
return switch (T) {
|
||||||
if (!js_value.isFunction()) {
|
js.Function => {
|
||||||
return null;
|
if (!js_value.isFunction()) {
|
||||||
}
|
return null;
|
||||||
return try self.createFunction(js_value);
|
}
|
||||||
}
|
return try self.createFunction(js_value);
|
||||||
|
},
|
||||||
if (@hasDecl(T, "_TYPED_ARRAY_ID_KLUDGE")) {
|
// zig fmt: off
|
||||||
const VT = @typeInfo(std.meta.fieldInfo(T, .values).type).pointer.child;
|
js.TypedArray(u8), js.TypedArray(u16), js.TypedArray(u32), js.TypedArray(u64),
|
||||||
const arr = (try self.jsValueToTypedArray(VT, js_value)) orelse return null;
|
js.TypedArray(i8), js.TypedArray(i16), js.TypedArray(i32), js.TypedArray(i64),
|
||||||
return .{ .values = arr };
|
js.TypedArray(f32), js.TypedArray(f64),
|
||||||
}
|
// zig fmt: on
|
||||||
|
=> {
|
||||||
if (T == js.String) {
|
const ValueType = @typeInfo(std.meta.fieldInfo(T, .values).type).pointer.child;
|
||||||
return .{ .string = try self.valueToString(js_value, .{ .allocator = self.arena }) };
|
const arr = (try self.jsValueToTypedArray(ValueType, js_value)) orelse return null;
|
||||||
}
|
return .{ .values = arr };
|
||||||
|
},
|
||||||
if (comptime T == js.Value) {
|
js.String => .{ .string = try self.valueToString(js_value, .{ .allocator = self.arena }) },
|
||||||
// Caller wants an opaque js.Object. Probably a parameter
|
// Caller wants an opaque js.Object. Probably a parameter
|
||||||
// that it needs to pass back into a callback
|
// that it needs to pass back into a callback.
|
||||||
return js.Value{
|
js.Value => js.Value{
|
||||||
.context = self,
|
|
||||||
.js_val = js_value,
|
.js_val = js_value,
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const js_obj = js_value.castTo(v8.Object);
|
|
||||||
|
|
||||||
if (comptime T == js.Object) {
|
|
||||||
// Caller wants an opaque js.Object. Probably a parameter
|
|
||||||
// that it needs to pass back into a callback
|
|
||||||
return js.Object{
|
|
||||||
.js_obj = js_obj,
|
|
||||||
.context = self,
|
.context = self,
|
||||||
};
|
},
|
||||||
}
|
// Caller wants an opaque js.Object. Probably a parameter
|
||||||
|
// that it needs to pass back into a callback.
|
||||||
|
js.Object => js.Object{
|
||||||
|
.js_obj = js_value.castTo(v8.Object),
|
||||||
|
.context = self,
|
||||||
|
},
|
||||||
|
else => {
|
||||||
|
if (!js_value.isObject()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (!js_value.isObject()) {
|
const js_obj = js_value.castTo(v8.Object);
|
||||||
return null;
|
const v8_context = self.v8_context;
|
||||||
}
|
const isolate = self.isolate;
|
||||||
|
|
||||||
const v8_context = self.v8_context;
|
var value: T = undefined;
|
||||||
const isolate = self.isolate;
|
inline for (@typeInfo(T).@"struct".fields) |field| {
|
||||||
|
const name = field.name;
|
||||||
|
const key = v8.String.initUtf8(isolate, name);
|
||||||
|
if (js_obj.has(v8_context, key.toValue())) {
|
||||||
|
@field(value, name) = try self.jsValueToZig(field.type, try js_obj.getValue(v8_context, key));
|
||||||
|
} else if (@typeInfo(field.type) == .optional) {
|
||||||
|
@field(value, name) = null;
|
||||||
|
} else {
|
||||||
|
const dflt = field.defaultValue() orelse return null;
|
||||||
|
@field(value, name) = dflt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var value: T = undefined;
|
return value;
|
||||||
inline for (@typeInfo(T).@"struct".fields) |field| {
|
},
|
||||||
const name = field.name;
|
};
|
||||||
const key = v8.String.initUtf8(isolate, name);
|
|
||||||
if (js_obj.has(v8_context, key.toValue())) {
|
|
||||||
@field(value, name) = try self.jsValueToZig(field.type, try js_obj.getValue(v8_context, key));
|
|
||||||
} else if (@typeInfo(field.type) == .optional) {
|
|
||||||
@field(value, name) = null;
|
|
||||||
} else {
|
|
||||||
const dflt = field.defaultValue() orelse return null;
|
|
||||||
@field(value, name) = dflt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn jsValueToTypedArray(_: *Context, comptime T: type, js_value: v8.Value) !?[]T {
|
fn jsValueToTypedArray(_: *Context, comptime T: type, js_value: v8.Value) !?[]T {
|
||||||
|
|||||||
@@ -53,8 +53,6 @@ pub fn Bridge(comptime T: type) type {
|
|||||||
// Env.JsObject. Want a TypedArray? Env.TypedArray.
|
// Env.JsObject. Want a TypedArray? Env.TypedArray.
|
||||||
pub fn TypedArray(comptime T: type) type {
|
pub fn TypedArray(comptime T: type) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub const _TYPED_ARRAY_ID_KLUDGE = true;
|
|
||||||
|
|
||||||
values: []const T,
|
values: []const T,
|
||||||
|
|
||||||
pub fn dupe(self: TypedArray(T), allocator: Allocator) !TypedArray(T) {
|
pub fn dupe(self: TypedArray(T), allocator: Allocator) !TypedArray(T) {
|
||||||
@@ -63,6 +61,14 @@ pub fn TypedArray(comptime T: type) type {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const ArrayBuffer = struct {
|
||||||
|
values: []const u8,
|
||||||
|
|
||||||
|
pub fn dupe(self: ArrayBuffer, allocator: Allocator) !ArrayBuffer {
|
||||||
|
return .{ .values = try allocator.dupe(u8, self.values) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
pub const PromiseResolver = struct {
|
pub const PromiseResolver = struct {
|
||||||
context: *Context,
|
context: *Context,
|
||||||
resolver: v8.PromiseResolver,
|
resolver: v8.PromiseResolver,
|
||||||
@@ -317,55 +323,73 @@ pub fn simpleZigValueToJs(isolate: v8.Isolate, value: anytype, comptime fail: bo
|
|||||||
return v8.initNull(isolate).toValue();
|
return v8.initNull(isolate).toValue();
|
||||||
},
|
},
|
||||||
.@"struct" => {
|
.@"struct" => {
|
||||||
const T = @TypeOf(value);
|
switch (@TypeOf(value)) {
|
||||||
if (@hasDecl(T, "_TYPED_ARRAY_ID_KLUDGE")) {
|
ArrayBuffer => {
|
||||||
const values = value.values;
|
const values = value.values;
|
||||||
const value_type = @typeInfo(@TypeOf(values)).pointer.child;
|
const len = values.len;
|
||||||
const len = values.len;
|
var array_buffer: v8.ArrayBuffer = undefined;
|
||||||
const bits = switch (@typeInfo(value_type)) {
|
const backing_store = v8.BackingStore.init(isolate, len);
|
||||||
.int => |n| n.bits,
|
|
||||||
.float => |f| f.bits,
|
|
||||||
else => @compileError("Invalid TypeArray type: " ++ @typeName(value_type)),
|
|
||||||
};
|
|
||||||
|
|
||||||
var array_buffer: v8.ArrayBuffer = undefined;
|
|
||||||
if (len == 0) {
|
|
||||||
array_buffer = v8.ArrayBuffer.init(isolate, 0);
|
|
||||||
} else {
|
|
||||||
const buffer_len = len * bits / 8;
|
|
||||||
const backing_store = v8.BackingStore.init(isolate, buffer_len);
|
|
||||||
const data: [*]u8 = @ptrCast(@alignCast(backing_store.getData()));
|
const data: [*]u8 = @ptrCast(@alignCast(backing_store.getData()));
|
||||||
@memcpy(data[0..buffer_len], @as([]const u8, @ptrCast(values))[0..buffer_len]);
|
@memcpy(data[0..len], @as([]const u8, @ptrCast(values))[0..len]);
|
||||||
array_buffer = v8.ArrayBuffer.initWithBackingStore(isolate, &backing_store.toSharedPtr());
|
array_buffer = v8.ArrayBuffer.initWithBackingStore(isolate, &backing_store.toSharedPtr());
|
||||||
}
|
|
||||||
|
|
||||||
switch (@typeInfo(value_type)) {
|
return .{ .handle = array_buffer.handle };
|
||||||
.int => |n| switch (n.signedness) {
|
},
|
||||||
.unsigned => switch (n.bits) {
|
// zig fmt: off
|
||||||
8 => return v8.Uint8Array.init(array_buffer, 0, len).toValue(),
|
TypedArray(u8), TypedArray(u16), TypedArray(u32), TypedArray(u64),
|
||||||
16 => return v8.Uint16Array.init(array_buffer, 0, len).toValue(),
|
TypedArray(i8), TypedArray(i16), TypedArray(i32), TypedArray(i64),
|
||||||
32 => return v8.Uint32Array.init(array_buffer, 0, len).toValue(),
|
TypedArray(f32), TypedArray(f64),
|
||||||
64 => return v8.BigUint64Array.init(array_buffer, 0, len).toValue(),
|
// zig fmt: on
|
||||||
|
=> {
|
||||||
|
const values = value.values;
|
||||||
|
const value_type = @typeInfo(@TypeOf(values)).pointer.child;
|
||||||
|
const len = values.len;
|
||||||
|
const bits = switch (@typeInfo(value_type)) {
|
||||||
|
.int => |n| n.bits,
|
||||||
|
.float => |f| f.bits,
|
||||||
|
else => @compileError("Invalid TypeArray type: " ++ @typeName(value_type)),
|
||||||
|
};
|
||||||
|
|
||||||
|
var array_buffer: v8.ArrayBuffer = undefined;
|
||||||
|
if (len == 0) {
|
||||||
|
array_buffer = v8.ArrayBuffer.init(isolate, 0);
|
||||||
|
} else {
|
||||||
|
const buffer_len = len * bits / 8;
|
||||||
|
const backing_store = v8.BackingStore.init(isolate, buffer_len);
|
||||||
|
const data: [*]u8 = @ptrCast(@alignCast(backing_store.getData()));
|
||||||
|
@memcpy(data[0..buffer_len], @as([]const u8, @ptrCast(values))[0..buffer_len]);
|
||||||
|
array_buffer = v8.ArrayBuffer.initWithBackingStore(isolate, &backing_store.toSharedPtr());
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (@typeInfo(value_type)) {
|
||||||
|
.int => |n| switch (n.signedness) {
|
||||||
|
.unsigned => switch (n.bits) {
|
||||||
|
8 => return v8.Uint8Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
16 => return v8.Uint16Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
32 => return v8.Uint32Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
64 => return v8.BigUint64Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
else => {},
|
||||||
|
},
|
||||||
|
.signed => switch (n.bits) {
|
||||||
|
8 => return v8.Int8Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
16 => return v8.Int16Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
32 => return v8.Int32Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
64 => return v8.BigInt64Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
else => {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.float => |f| switch (f.bits) {
|
||||||
|
32 => return v8.Float32Array.init(array_buffer, 0, len).toValue(),
|
||||||
|
64 => return v8.Float64Array.init(array_buffer, 0, len).toValue(),
|
||||||
else => {},
|
else => {},
|
||||||
},
|
},
|
||||||
.signed => switch (n.bits) {
|
|
||||||
8 => return v8.Int8Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
16 => return v8.Int16Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
32 => return v8.Int32Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
64 => return v8.BigInt64Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
else => {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.float => |f| switch (f.bits) {
|
|
||||||
32 => return v8.Float32Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
64 => return v8.Float64Array.init(array_buffer, 0, len).toValue(),
|
|
||||||
else => {},
|
else => {},
|
||||||
},
|
}
|
||||||
else => {},
|
// We normally don't fail in this function unless fail == true
|
||||||
}
|
// but this can never be valid.
|
||||||
// We normally don't fail in this function unless fail == true
|
@compileError("Invalid TypeArray type: " ++ @typeName(value_type));
|
||||||
// but this can never be valid.
|
},
|
||||||
@compileError("Invalid TypeArray type: " ++ @typeName(value_type));
|
else => {},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
.@"union" => return simpleZigValueToJs(isolate, std.meta.activeTag(value), fail, null_as_undefined),
|
.@"union" => return simpleZigValueToJs(isolate, std.meta.activeTag(value), fail, null_as_undefined),
|
||||||
|
|||||||
Reference in New Issue
Block a user