mirror of
https://github.com/lightpanda-io/browser.git
synced 2025-10-28 22:53:28 +00:00
Ability to return typed arrays
This commit is contained in:
@@ -13,8 +13,8 @@
|
|||||||
.hash = "tigerbeetle_io-0.0.0-ViLgxpyRBAB5BMfIcj3KMXfbJzwARs9uSl8aRy2OXULd",
|
.hash = "tigerbeetle_io-0.0.0-ViLgxpyRBAB5BMfIcj3KMXfbJzwARs9uSl8aRy2OXULd",
|
||||||
},
|
},
|
||||||
.v8 = .{
|
.v8 = .{
|
||||||
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/f0c7eaaffe39f2f1a224fbe97e550daca0ca1801.tar.gz",
|
.url = "https://github.com/lightpanda-io/zig-v8-fork/archive/fc764e7d29bc1514924e8df09255a057e03d453a.tar.gz",
|
||||||
.hash = "v8-0.0.0-xddH62T4IADchAHFgo4nx79w1VedNDhIVErtSNgup-Tk",
|
.hash = "v8-0.0.0-xddH6zUZIQBJf109L94sC-mWH1NJXWCnOJGJttKtfasI",
|
||||||
},
|
},
|
||||||
//.v8 = .{ .path = "../zig-v8-fork" },
|
//.v8 = .{ .path = "../zig-v8-fork" },
|
||||||
//.tigerbeetle_io = .{ .path = "../tigerbeetle-io" },
|
//.tigerbeetle_io = .{ .path = "../tigerbeetle-io" },
|
||||||
|
|||||||
@@ -1012,6 +1012,22 @@ pub fn Env(comptime State: type, comptime WebApis: type) type {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// If a function returns a []i32, should that map to a plain-old
|
||||||
|
// JavaScript array, or a Int32Array? It's ambiguous. By default, we'll
|
||||||
|
// map arrays/slices to the JavaScript arrays. If you want a TypedArray
|
||||||
|
// wrap it in this.
|
||||||
|
// Also, this type has nothing to do with the Env. But we place it here
|
||||||
|
// for consistency. Want a callback? Env.Callback. Want a JsObject?
|
||||||
|
// Env.JsObject. Want a TypedArray? Env.TypedArray.
|
||||||
|
pub fn TypedArray(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
// See Callback._CALLBACK_ID_KLUDGE
|
||||||
|
const _TYPED_ARRAY_ID_KLUDGE = true;
|
||||||
|
|
||||||
|
values: []const T,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub const Inspector = struct {
|
pub const Inspector = struct {
|
||||||
isolate: v8.Isolate,
|
isolate: v8.Isolate,
|
||||||
inner: *v8.Inspector,
|
inner: *v8.Inspector,
|
||||||
@@ -2632,6 +2648,53 @@ fn simpleZigValueToJs(isolate: v8.Isolate, value: anytype, comptime fail: bool)
|
|||||||
}
|
}
|
||||||
return v8.initNull(isolate).toValue();
|
return v8.initNull(isolate).toValue();
|
||||||
},
|
},
|
||||||
|
.@"struct" => {
|
||||||
|
const T = @TypeOf(value);
|
||||||
|
if (@hasDecl(T, "_TYPED_ARRAY_ID_KLUDGE")) {
|
||||||
|
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)),
|
||||||
|
};
|
||||||
|
|
||||||
|
const buffer_len = len * bits / 8;
|
||||||
|
const backing_store = v8.BackingStore.init(isolate, buffer_len);
|
||||||
|
const data: [*]u8 = @alignCast(@ptrCast(backing_store.getData()));
|
||||||
|
@memcpy(data[0..buffer_len], @as([]const u8, @ptrCast(values))[0..buffer_len]);
|
||||||
|
const 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 => {},
|
||||||
|
}
|
||||||
|
// We normally don't fail in this function unless fail == true
|
||||||
|
// but this can never be valid.
|
||||||
|
@compileError("Invalid TypeArray type: " ++ @typeName(value_type));
|
||||||
|
}
|
||||||
|
},
|
||||||
.@"union" => return simpleZigValueToJs(isolate, std.meta.activeTag(value), fail),
|
.@"union" => return simpleZigValueToJs(isolate, std.meta.activeTag(value), fail),
|
||||||
else => {},
|
else => {},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,10 @@
|
|||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
// TODO: use functions instead of "fake" struct once we handle function API generation
|
// TODO: use functions instead of "fake" struct once we handle function API generation
|
||||||
|
|
||||||
|
const Runner = testing.Runner(void, void, .{Primitives});
|
||||||
|
const Env = Runner.Env;
|
||||||
|
|
||||||
const Primitives = struct {
|
const Primitives = struct {
|
||||||
pub fn constructor() Primitives {
|
pub fn constructor() Primitives {
|
||||||
return .{};
|
return .{};
|
||||||
@@ -114,6 +118,46 @@ const Primitives = struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _returnUint8(_: *const Primitives) Env.TypedArray(u8) {
|
||||||
|
return .{ .values = &.{ 10, 20, 250 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnInt8(_: *const Primitives) Env.TypedArray(i8) {
|
||||||
|
return .{ .values = &.{ 10, -20, -120 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnUint16(_: *const Primitives) Env.TypedArray(u16) {
|
||||||
|
return .{ .values = &.{ 10, 200, 2050 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnInt16(_: *const Primitives) Env.TypedArray(i16) {
|
||||||
|
return .{ .values = &.{ 10, -420, 0 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnUint32(_: *const Primitives) Env.TypedArray(u32) {
|
||||||
|
return .{ .values = &.{ 10, 2444343, 43432432 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnInt32(_: *const Primitives) Env.TypedArray(i32) {
|
||||||
|
return .{ .values = &.{ 10, -20, -495929123 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnUint64(_: *const Primitives) Env.TypedArray(u64) {
|
||||||
|
return .{ .values = &.{ 10, 495812375924, 0 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnInt64(_: *const Primitives) Env.TypedArray(i64) {
|
||||||
|
return .{ .values = &.{ 10, -49283838122, -2 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnFloat32(_: *const Primitives) Env.TypedArray(f32) {
|
||||||
|
return .{ .values = &.{ 1.1, -200.035, 0.0003 } };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn _returnFloat64(_: *const Primitives) Env.TypedArray(f64) {
|
||||||
|
return .{ .values = &.{ 8881.22284, -4928.3838122, -0.00004 } };
|
||||||
|
}
|
||||||
|
|
||||||
pub fn _int16(_: *const Primitives, arr: []i16) void {
|
pub fn _int16(_: *const Primitives, arr: []i16) void {
|
||||||
for (arr) |*a| {
|
for (arr) |*a| {
|
||||||
a.* -= @intCast(arr.len);
|
a.* -= @intCast(arr.len);
|
||||||
@@ -153,7 +197,7 @@ const Primitives = struct {
|
|||||||
|
|
||||||
const testing = @import("testing.zig");
|
const testing = @import("testing.zig");
|
||||||
test "JS: primitive types" {
|
test "JS: primitive types" {
|
||||||
var runner = try testing.Runner(void, void, .{Primitives}).init({}, {});
|
var runner = try Runner.init({}, {});
|
||||||
defer runner.deinit();
|
defer runner.deinit();
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
@@ -280,5 +324,16 @@ test "JS: primitive types" {
|
|||||||
.{ "try { p.int64(arr_u64) } catch(e) { e instanceof TypeError; }", "true" },
|
.{ "try { p.int64(arr_u64) } catch(e) { e instanceof TypeError; }", "true" },
|
||||||
.{ "try { p.intu64(arr_i64) } catch(e) { e instanceof TypeError; }", "true" },
|
.{ "try { p.intu64(arr_i64) } catch(e) { e instanceof TypeError; }", "true" },
|
||||||
.{ "try { p.intu64(arr_u32) } catch(e) { e instanceof TypeError; }", "true" },
|
.{ "try { p.intu64(arr_u32) } catch(e) { e instanceof TypeError; }", "true" },
|
||||||
|
|
||||||
|
.{ "p.returnUint8()", "10,20,250" },
|
||||||
|
.{ "p.returnInt8()", "10,-20,-120" },
|
||||||
|
.{ "p.returnUint16()", "10,200,2050" },
|
||||||
|
.{ "p.returnInt16()", "10,-420,0" },
|
||||||
|
.{ "p.returnUint32()", "10,2444343,43432432" },
|
||||||
|
.{ "p.returnInt32()", "10,-20,-495929123" },
|
||||||
|
.{ "p.returnUint64()", "10,495812375924,0" },
|
||||||
|
.{ "p.returnInt64()", "10,-49283838122,-2" },
|
||||||
|
.{ "p.returnFloat32()", "1.100000023841858,-200.03500366210938,0.0003000000142492354" },
|
||||||
|
.{ "p.returnFloat64()", "8881.22284,-4928.3838122,-0.00004" },
|
||||||
}, .{});
|
}, .{});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,15 +26,16 @@ pub const allocator = std.testing.allocator;
|
|||||||
// browser.Env or the browser.SessionState
|
// browser.Env or the browser.SessionState
|
||||||
pub fn Runner(comptime State: type, comptime Global: type, comptime types: anytype) type {
|
pub fn Runner(comptime State: type, comptime Global: type, comptime types: anytype) type {
|
||||||
const AdjustedTypes = if (Global == void) generate.Tuple(.{ types, DefaultGlobal }) else types;
|
const AdjustedTypes = if (Global == void) generate.Tuple(.{ types, DefaultGlobal }) else types;
|
||||||
const Env = js.Env(State, struct {
|
|
||||||
pub const Interfaces = AdjustedTypes;
|
|
||||||
});
|
|
||||||
|
|
||||||
return struct {
|
return struct {
|
||||||
env: *Env,
|
env: *Env,
|
||||||
scope: *Env.Scope,
|
scope: *Env.Scope,
|
||||||
executor: Env.Executor,
|
executor: Env.Executor,
|
||||||
|
|
||||||
|
pub const Env = js.Env(State, struct {
|
||||||
|
pub const Interfaces = AdjustedTypes;
|
||||||
|
});
|
||||||
|
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
pub fn init(state: State, global: Global) !*Self {
|
pub fn init(state: State, global: Global) !*Self {
|
||||||
|
|||||||
Reference in New Issue
Block a user