mirror of
https://github.com/lightpanda-io/browser.git
synced 2026-03-22 12:44:43 +00:00
introduce js.createTypedArray
A new way to create typed arrays that allows using the same memory.
This commit is contained in:
@@ -1045,6 +1045,12 @@ pub const FinalizerCallback = struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// Creates a new typed array. Memory is owned by JS context.
|
||||
/// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Typed_arrays
|
||||
pub fn createTypedArray(self: *Context, comptime array_type: js.ArrayType, size: usize) js.ArrayBufferRef(array_type) {
|
||||
return .init(self.isolate, size);
|
||||
}
|
||||
|
||||
// == Profiler ==
|
||||
pub fn startCpuProfiler(self: *Context) void {
|
||||
if (comptime !IS_DEBUG) {
|
||||
|
||||
@@ -306,6 +306,14 @@ pub fn zigValueToJs(self: *const Local, value: anytype, comptime opts: CallOpts)
|
||||
js.Value => return value,
|
||||
js.Exception => return .{ .local = self, .handle = isolate.throwException(value.handle) },
|
||||
|
||||
js.ArrayBufferRef(.Int8), js.ArrayBufferRef(.Uint8), js.ArrayBufferRef(.Uint8Clamped),
|
||||
js.ArrayBufferRef(.Int16), js.ArrayBufferRef(.Uint16),
|
||||
js.ArrayBufferRef(.Int32), js.ArrayBufferRef(.Uint32),
|
||||
js.ArrayBufferRef(.Float16), js.ArrayBufferRef(.Float32), js.ArrayBufferRef(.Float64),
|
||||
=> {
|
||||
return .{ .local = self, .handle = value.internal };
|
||||
},
|
||||
|
||||
inline
|
||||
js.Function,
|
||||
js.Object,
|
||||
|
||||
@@ -77,14 +77,69 @@ pub const ArrayBuffer = struct {
|
||||
}
|
||||
};
|
||||
|
||||
/// `ref` indicates bytes are not copied by `simpleZigValueToJs`;
|
||||
/// instead, `values` references an already allocated memory. Note that
|
||||
/// this variant assumes memory is (de)allocated by an arena allocator.
|
||||
///
|
||||
/// `copy` behaves the same as `TypedArray(T)`.
|
||||
pub fn Uint8ClampedArray(comptime state: enum(u1) { ref, copy }) type {
|
||||
return struct {
|
||||
values: if (state == .ref) []u8 else []const u8,
|
||||
pub const ArrayType = enum(u8) {
|
||||
Int8,
|
||||
Uint8,
|
||||
Uint8Clamped,
|
||||
Int16,
|
||||
Uint16,
|
||||
Int32,
|
||||
Uint32,
|
||||
Float16,
|
||||
Float32,
|
||||
Float64,
|
||||
};
|
||||
|
||||
pub fn ArrayBufferRef(comptime kind: ArrayType) type {
|
||||
return extern struct {
|
||||
const Self = @This();
|
||||
|
||||
const BackingInt = switch (kind) {
|
||||
.Int8 => i8,
|
||||
.Uint8, .Uint8Clamped => u8,
|
||||
.Int16 => i16,
|
||||
.Uint16 => u16,
|
||||
.Int32 => i32,
|
||||
.Uint32 => u32,
|
||||
.Float16 => f16,
|
||||
.Float32 => f32,
|
||||
.Float64 => f64,
|
||||
};
|
||||
|
||||
internal: *const v8.Value,
|
||||
|
||||
pub fn init(isolate: Isolate, size: usize) Self {
|
||||
const bits = switch (@typeInfo(BackingInt)) {
|
||||
.int => |n| n.bits,
|
||||
.float => |f| f.bits,
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
var array_buffer: *const v8.ArrayBuffer = undefined;
|
||||
if (size == 0) {
|
||||
array_buffer = v8.v8__ArrayBuffer__New(isolate.handle, 0).?;
|
||||
} else {
|
||||
const buffer_len = size * bits / 8;
|
||||
const backing_store = v8.v8__ArrayBuffer__NewBackingStore(isolate.handle, buffer_len).?;
|
||||
const backing_store_ptr = v8.v8__BackingStore__TO_SHARED_PTR(backing_store);
|
||||
array_buffer = v8.v8__ArrayBuffer__New2(isolate.handle, &backing_store_ptr).?;
|
||||
}
|
||||
|
||||
const internal: *const v8.Value = switch (comptime kind) {
|
||||
.Int8 => @ptrCast(v8.v8__Int8Array__New(array_buffer, 0, size).?),
|
||||
.Uint8 => @ptrCast(v8.v8__Uint8Array__New(array_buffer, 0, size).?),
|
||||
.Uint8Clamped => @ptrCast(v8.v8__Uint8ClampedArray__New(array_buffer, 0, size).?),
|
||||
.Int16 => @ptrCast(v8.v8__Int16Array__New(array_buffer, 0, size).?),
|
||||
.Uint16 => @ptrCast(v8.v8__Uint16Array__New(array_buffer, 0, size).?),
|
||||
.Int32 => @ptrCast(v8.v8__Int32Array__New(array_buffer, 0, size).?),
|
||||
.Uint32 => @ptrCast(v8.v8__Uint32Array__New(array_buffer, 0, size).?),
|
||||
.Float16 => @ptrCast(v8.v8__Float16Array__New(array_buffer, 0, size).?),
|
||||
.Float32 => @ptrCast(v8.v8__Float32Array__New(array_buffer, 0, size).?),
|
||||
.Float64 => @ptrCast(v8.v8__Float64Array__New(array_buffer, 0, size).?),
|
||||
};
|
||||
|
||||
return .{ .internal = internal };
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -205,40 +260,6 @@ pub fn simpleZigValueToJs(isolate: Isolate, value: anytype, comptime fail: bool,
|
||||
// but this can never be valid.
|
||||
@compileError("Invalid TypeArray type: " ++ @typeName(value_type));
|
||||
},
|
||||
Uint8ClampedArray(.ref) => {
|
||||
const values = value.values;
|
||||
const len = values.len;
|
||||
var array_buffer: *const v8.ArrayBuffer = undefined;
|
||||
if (len == 0) {
|
||||
array_buffer = v8.v8__ArrayBuffer__New(isolate.handle, 0).?;
|
||||
} else {
|
||||
// `deleter` cannot be null.
|
||||
const empty_deleter = struct {
|
||||
fn deleter(_: ?*anyopaque, _: usize, _: ?*anyopaque) callconv(.c) void {}
|
||||
}.deleter;
|
||||
const backing_store = v8.v8__ArrayBuffer__NewBackingStore2(values.ptr, len, empty_deleter, null);
|
||||
const backing_store_ptr = v8.v8__BackingStore__TO_SHARED_PTR(backing_store);
|
||||
// Attach store to array buffer.
|
||||
array_buffer = v8.v8__ArrayBuffer__New2(isolate.handle, &backing_store_ptr).?;
|
||||
}
|
||||
return @ptrCast(v8.v8__Uint8ClampedArray__New(array_buffer, 0, len));
|
||||
},
|
||||
Uint8ClampedArray(.copy) => {
|
||||
const values = value.values;
|
||||
const len = values.len;
|
||||
var array_buffer: *const v8.ArrayBuffer = undefined;
|
||||
if (len == 0) {
|
||||
array_buffer = v8.v8__ArrayBuffer__New(isolate.handle, 0).?;
|
||||
} else {
|
||||
const backing_store = v8.v8__ArrayBuffer__NewBackingStore(isolate.handle, len);
|
||||
const data: [*]u8 = @ptrCast(@alignCast(v8.v8__BackingStore__Data(backing_store)));
|
||||
@memcpy(data[0..len], @as([]const u8, @ptrCast(values))[0..len]);
|
||||
const backing_store_ptr = v8.v8__BackingStore__TO_SHARED_PTR(backing_store);
|
||||
// Attach store to array buffer.
|
||||
array_buffer = v8.v8__ArrayBuffer__New2(isolate.handle, &backing_store_ptr).?;
|
||||
}
|
||||
return @ptrCast(v8.v8__Uint8ClampedArray__New(array_buffer, 0, len));
|
||||
},
|
||||
inline String, BigInt, Integer, Number, Value, Object => return value.handle,
|
||||
else => {},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user