diff options
author | 2022-08-10 21:26:20 -0700 | |
---|---|---|
committer | 2022-08-10 21:26:20 -0700 | |
commit | d9ae284463c25f6c1e6056c2ee4d5bf81f1d11cb (patch) | |
tree | e4221d5571233981da5b28f17b9076c5d183c550 | |
parent | 00d5f6699b39799b383dc305d4120da7d79c7bce (diff) | |
download | bun-d9ae284463c25f6c1e6056c2ee4d5bf81f1d11cb.tar.gz bun-d9ae284463c25f6c1e6056c2ee4d5bf81f1d11cb.tar.zst bun-d9ae284463c25f6c1e6056c2ee4d5bf81f1d11cb.zip |
Fix console.log with typed arrays
-rw-r--r-- | src/bun.js/api/ffi.zig | 13 | ||||
-rw-r--r-- | src/bun.js/base.zig | 1 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.zig | 76 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 224 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-handwritten.h | 1 | ||||
-rw-r--r-- | src/comptime_string_map.zig | 37 | ||||
-rw-r--r-- | src/string_immutable.zig | 11 | ||||
-rw-r--r-- | test/bun.js/ffi.test.js | 32 | ||||
-rw-r--r-- | test/bun.js/inspect.test.js | 80 |
9 files changed, 371 insertions, 104 deletions
diff --git a/src/bun.js/api/ffi.zig b/src/bun.js/api/ffi.zig index 59d682d3b..52c086d5b 100644 --- a/src/bun.js/api/ffi.zig +++ b/src/bun.js/api/ffi.zig @@ -351,14 +351,15 @@ pub const FFI = struct { return ZigString.init("Failed to compile (nothing happend!)").toErrorInstance(global); }, .compiled => |compiled| { - var cb = JSC.NewFunctionPtr( + const str = ZigString.init(std.mem.span(function_name)); + const cb = JSC.NewFunction( global, - &ZigString.init(std.mem.span(function_name)), + &str, @intCast(u32, function.arg_types.items.len), compiled.ptr, ); - obj.put(global, &ZigString.init(std.mem.span(function_name)), JSC.JSValue.cast(cb)); + obj.put(global, &str, cb); }, } } @@ -443,14 +444,14 @@ pub const FFI = struct { return ZigString.init("Failed to compile (nothing happend!)").toErrorInstance(global); }, .compiled => |compiled| { - var cb = JSC.NewFunctionPtr( + const cb = JSC.NewFunction( global, &ZigString.init(std.mem.span(function_name)), @intCast(u32, function.arg_types.items.len), compiled.ptr, ); - obj.put(global, &ZigString.init(std.mem.span(function_name)), JSC.JSValue.cast(cb)); + obj.put(global, &ZigString.init(std.mem.span(function_name)), cb); }, } } @@ -561,7 +562,7 @@ pub const FFI = struct { var symbols_iter = JSC.JSPropertyIterator(.{ .skip_empty_name = true, - + .include_value = true, }).init(global.ref(), object.asObjectRef()); defer symbols_iter.deinit(); diff --git a/src/bun.js/base.zig b/src/bun.js/base.zig index 2a0e3d037..41454da3c 100644 --- a/src/bun.js/base.zig +++ b/src/bun.js/base.zig @@ -2236,6 +2236,7 @@ pub const ArrayBuffer = extern struct { byte_len: u32, typed_array_type: JSC.JSValue.JSType, value: JSC.JSValue = JSC.JSValue.zero, + shared: bool = false, pub const name = "Bun__ArrayBuffer"; pub const Stream = std.io.FixedBufferStream([]u8); diff --git a/src/bun.js/bindings/bindings.zig b/src/bun.js/bindings/bindings.zig index 9ba5742eb..1c5243336 100644 --- a/src/bun.js/bindings/bindings.zig +++ b/src/bun.js/bindings/bindings.zig @@ -101,12 +101,43 @@ pub const ZigString = extern struct { return this; } + pub fn utf8ByteLength(this: ZigString) usize { + if (this.isUTF8()) { + return this.len; + } + + if (this.is16Bit()) { + return JSC.WebCore.Encoder.byteLengthU16(this.utf16SliceAligned().ptr, this.utf16Slice().len, .utf8); + } + + return JSC.WebCore.Encoder.byteLengthU8(this.slice().ptr, this.slice().len, .utf8); + } + pub fn toOwnedSlice(this: ZigString, allocator: std.mem.Allocator) ![]u8 { - return try std.fmt.allocPrint(allocator, "{any}", .{this}); + if (this.isUTF8()) + return try allocator.dupeZ(u8, this.slice()); + + var list = std.ArrayList(u8).init(allocator); + list = if (this.is16Bit()) + try strings.toUTF8ListWithType(list, []const u16, this.utf16SliceAligned()) + else + try strings.allocateLatin1IntoUTF8WithList(list, 0, []const u8, this.slice()); + + return list.items; } pub fn toOwnedSliceZ(this: ZigString, allocator: std.mem.Allocator) ![:0]u8 { - return try std.fmt.allocPrintZ(allocator, "{any}", .{this}); + if (this.isUTF8()) + return allocator.dupeZ(u8, this.slice()); + + var list = std.ArrayList(u8).init(allocator); + list = if (this.is16Bit()) + try strings.toUTF8ListWithType(list, []const u16, this.utf16SliceAligned()) + else + try strings.allocateLatin1IntoUTF8WithList(list, 0, []const u8, this.slice()); + + try list.append(0); + return list.items[0 .. list.items.len - 1 :0]; } pub fn trunc(this: ZigString, len: usize) ZigString { @@ -341,9 +372,8 @@ pub const ZigString = extern struct { pub fn toSlice(this: ZigString, allocator: std.mem.Allocator) Slice { if (this.len == 0) return Slice{ .ptr = "", .len = 0, .allocator = allocator, .allocated = false }; - if (is16Bit(&this)) { - var buffer = std.fmt.allocPrint(allocator, "{}", .{this}) catch unreachable; + var buffer = this.toOwnedSlice(allocator) catch unreachable; return Slice{ .ptr = buffer.ptr, .len = @truncate(u32, buffer.len), @@ -365,7 +395,7 @@ pub const ZigString = extern struct { return Slice{ .ptr = "", .len = 0, .allocator = allocator, .allocated = false }; if (is16Bit(&this)) { - var buffer = std.fmt.allocPrintZ(allocator, "{}", .{this}) catch unreachable; + var buffer = this.toOwnedSliceZ(allocator) catch unreachable; return Slice{ .ptr = buffer.ptr, .len = @truncate(u32, buffer.len), @@ -2424,7 +2454,7 @@ pub const JSValue = enum(JSValueReprInt) { i64 => jsNumberFromInt64(@intCast(i64, number)), c_uint => jsNumberFromUint64(@intCast(u64, number)), u64 => jsNumberFromUint64(@intCast(u64, number)), - u32 => jsNumberFromInt64(@intCast(i64, number)), + u32 => if (number <= std.math.maxInt(i32)) jsNumberFromInt32(@intCast(i32, number)) else jsNumberFromUint64(@as(u64, number)), u52 => jsNumberFromUint64(@as(u64, number)), usize => jsNumberFromUint64(@as(u64, number)), comptime_int => switch (number) { @@ -2475,6 +2505,12 @@ pub const JSValue = enum(JSValueReprInt) { return cppFn("jsDoubleNumber", .{i}); } + pub fn className(this: JSValue, globalThis: *JSGlobalObject) ZigString { + var str = ZigString.init(""); + this.getClassName(globalThis, &str); + return str; + } + pub fn createStringArray(globalThis: *JSGlobalObject, str: [*c]ZigString, strings_count: usize, clone: bool) JSValue { return cppFn("createStringArray", .{ globalThis, @@ -2516,11 +2552,7 @@ pub const JSValue = enum(JSValueReprInt) { return jsNumberFromInt32(@intCast(i32, i)); } - if (i <= std.math.maxInt(i52)) { - return jsNumberFromDouble(@intToFloat(f64, @intCast(i52, i))); - } - - return cppFn("jsNumberFromInt64", .{i}); + return jsNumberFromDouble(@intToFloat(f64, @truncate(i52, i))); } pub inline fn toJS(this: JSValue, _: *const JSGlobalObject) JSValue { @@ -2528,7 +2560,11 @@ pub const JSValue = enum(JSValueReprInt) { } pub fn jsNumberFromUint64(i: u64) JSValue { - return FFI.UINT64_TO_JSVALUE(JSC.VirtualMachine.vm.global, i).asJSValue; + if (i <= std.math.maxInt(i32)) { + return jsNumberFromInt32(@intCast(i32, i)); + } + + return jsNumberFromDouble(@intToFloat(f64, @intCast(i52, @truncate(u51, i)))); } pub fn toInt64(this: JSValue) i64 { @@ -2631,6 +2667,12 @@ pub const JSValue = enum(JSValueReprInt) { cppFn("getNameProperty", .{ this, global, ret }); } + pub fn getName(this: JSValue, global: *JSGlobalObject) ZigString { + var ret = ZigString.init(""); + getNameProperty(this, global, &ret); + return ret; + } + pub fn getClassName(this: JSValue, global: *JSGlobalObject, ret: *ZigString) void { cppFn("getClassName", .{ this, global, ret }); } @@ -2668,11 +2710,19 @@ pub const JSValue = enum(JSValueReprInt) { } pub fn asArrayBuffer(this: JSValue, global: *JSGlobalObject) ?ArrayBuffer { - var out: ArrayBuffer = undefined; + var out: ArrayBuffer = .{ + .offset = 0, + .len = 0, + .byte_len = 0, + .shared = false, + .typed_array_type = .Uint8Array, + }; + if (this.asArrayBuffer_(global, &out)) { out.value = this; return out; } + return null; } diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index e9447897d..a6439a263 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -297,6 +297,34 @@ pub const JSErrorCode = enum(u8) { _, }; +pub const EventType = enum(u8) { + Event, + MessageEvent, + CloseEvent, + ErrorEvent, + OpenEvent, + unknown = 254, + _, + + pub const map = bun.ComptimeStringMap(EventType, .{ + .{ EventType.Event.label(), EventType.Event }, + .{ EventType.MessageEvent.label(), EventType.MessageEvent }, + .{ EventType.CloseEvent.label(), EventType.CloseEvent }, + .{ EventType.ErrorEvent.label(), EventType.ErrorEvent }, + .{ EventType.OpenEvent.label(), EventType.OpenEvent }, + }); + + pub fn label(this: EventType) string { + return switch (this) { + .Event => "event", + .MessageEvent => "message", + .CloseEvent => "close", + .ErrorEvent => "error", + .OpenEvent => "open", + else => "event", + }; + } +}; pub const JSRuntimeType = enum(u16) { Nothing = 0x0, Function = 0x1, @@ -1326,7 +1354,7 @@ pub const ZigConsoleClient = struct { JSValue.JSType.JSWeakSet, JSValue.JSType.JSSet => .Set, JSValue.JSType.JSDate => .JSON, JSValue.JSType.JSPromise => .Promise, - JSValue.JSType.Object, JSValue.JSType.FinalObject => .Object, + .ArrayBuffer, JSValue.JSType.Object, JSValue.JSType.FinalObject => .Object, JSValue.JSType.Int8Array, JSValue.JSType.Uint8Array, @@ -1875,55 +1903,64 @@ pub const ZigConsoleClient = struct { writer.print("{}", .{str}); }, .Event => { - var className: ZigString = ZigString.init(""); - value.getClassName(this.globalThis, &className); - if (className.eqlComptime("Event")) { + const event_type = EventType.map.getWithEql(value.get(this.globalThis, "type").?.getZigString(this.globalThis), ZigString.eqlComptime) orelse EventType.unknown; + if (event_type != .MessageEvent and event_type != .ErrorEvent) { return this.printAs(.Object, Writer, writer_, value, .Event, enable_ansi_colors); } - writer.print("{any} {{\n", .{className}); + writer.print( + comptime Output.prettyFmt("<r><cyan>{s}<r> {{\n", enable_ansi_colors), + .{ + @tagName(event_type), + }, + ); { this.indent += 1; defer this.indent -|= 1; const old_quote_strings = this.quote_strings; this.quote_strings = true; defer this.quote_strings = old_quote_strings; - if (className.eqlComptime("MessageEvent")) { - this.writeIndent(Writer, writer_) catch unreachable; - writer.print( - comptime Output.prettyFmt("<r><blue>data<d>:<r> ", enable_ansi_colors), - .{}, - ); - const data = value.get(this.globalThis, "data").?; - const tag = Tag.get(data, this.globalThis); - if (tag.cell.isStringLike()) { - this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); - } else { + this.writeIndent(Writer, writer_) catch unreachable; + + writer.print( + comptime Output.prettyFmt("<r>type: <green>\"{s}\"<r><d>,<r>\n", enable_ansi_colors), + .{ + event_type.label(), + }, + ); + this.writeIndent(Writer, writer_) catch unreachable; + + switch (event_type) { + .MessageEvent => { + writer.print( + comptime Output.prettyFmt("<r><blue>data<d>:<r> ", enable_ansi_colors), + .{}, + ); + const data = value.get(this.globalThis, "data").?; + const tag = Tag.get(data, this.globalThis); + if (tag.cell.isStringLike()) { + this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); + } else { + this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); + } + }, + .ErrorEvent => { + writer.print( + comptime Output.prettyFmt("<r><blue>error<d>:<r>\n", enable_ansi_colors), + .{}, + ); + + const data = value.get(this.globalThis, "error").?; + const tag = Tag.get(data, this.globalThis); this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); - } - } else if (className.eqlComptime("CustomEvent")) { - this.writeIndent(Writer, writer_) catch unreachable; - writer.print( - comptime Output.prettyFmt("<r><blue>detail<d>:<r>", enable_ansi_colors), - .{}, - ); - const data = value.get(this.globalThis, "detail").?; - const tag = Tag.get(data, this.globalThis); - this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); - } else if (className.eqlComptime("ErrorEvent")) { - this.writeIndent(Writer, writer_) catch unreachable; - writer.print( - comptime Output.prettyFmt("<r><blue>error<d>:<r>", enable_ansi_colors), - .{}, - ); - const data = value.get(this.globalThis, "error").?; - const tag = Tag.get(data, this.globalThis); - this.format(tag, Writer, writer_, data, this.globalThis, enable_ansi_colors); - } else {} + }, + else => unreachable, + } + writer.writeAll("\n"); } - writer.writeAll("\n"); + this.writeIndent(Writer, writer_) catch unreachable; - writer.print("}}\n", .{}); + writer.writeAll("}"); }, .JSX => { writer.writeAll(comptime Output.prettyFmt("<r>", enable_ansi_colors)); @@ -2238,25 +2275,78 @@ pub const ZigConsoleClient = struct { .TypedArray => { const arrayBuffer = value.asArrayBuffer(this.globalThis).?; + const slice = arrayBuffer.byteSlice(); writer.writeAll(std.mem.span(@tagName(arrayBuffer.typed_array_type))); - const slice = arrayBuffer.slice(); - - writer.print("({d}) [ ", .{slice.len}); + writer.print("({d}) [ ", .{arrayBuffer.len}); if (slice.len > 0) { - writer.print(comptime Output.prettyFmt("<r><yellow>{d}<r>", enable_ansi_colors), .{slice[0]}); - var leftover = slice[1..]; - const max = 512; - leftover = leftover[0..@minimum(leftover.len, max)]; - for (leftover) |el| { - this.printComma(Writer, writer_, enable_ansi_colors) catch unreachable; - writer.writeAll(" "); - - writer.print(comptime Output.prettyFmt("<r><yellow>{d}<r>", enable_ansi_colors), .{el}); - } - - if (slice.len > max + 1) { - writer.print(comptime Output.prettyFmt("<r><d>, ... {d} more<r>", enable_ansi_colors), .{slice.len - max - 1}); + switch (jsType) { + .Int8Array => writeTypedArray( + *@TypeOf(writer), + &writer, + i8, + @alignCast(std.meta.alignment([]i8), std.mem.bytesAsSlice(i8, slice)), + enable_ansi_colors, + ), + .Int16Array => writeTypedArray( + *@TypeOf(writer), + &writer, + i16, + @alignCast(std.meta.alignment([]i16), std.mem.bytesAsSlice(i16, slice)), + enable_ansi_colors, + ), + .Uint16Array => writeTypedArray( + *@TypeOf(writer), + &writer, + u16, + @alignCast(std.meta.alignment([]u16), std.mem.bytesAsSlice(u16, slice)), + enable_ansi_colors, + ), + .Int32Array => writeTypedArray( + *@TypeOf(writer), + &writer, + i32, + @alignCast(std.meta.alignment([]i32), std.mem.bytesAsSlice(i32, slice)), + enable_ansi_colors, + ), + .Uint32Array => writeTypedArray( + *@TypeOf(writer), + &writer, + u32, + @alignCast(std.meta.alignment([]u32), std.mem.bytesAsSlice(u32, slice)), + enable_ansi_colors, + ), + .Float32Array => writeTypedArray( + *@TypeOf(writer), + &writer, + f32, + @alignCast(std.meta.alignment([]f32), std.mem.bytesAsSlice(f32, slice)), + enable_ansi_colors, + ), + .Float64Array => writeTypedArray( + *@TypeOf(writer), + &writer, + f64, + @alignCast(std.meta.alignment([]f64), std.mem.bytesAsSlice(f64, slice)), + enable_ansi_colors, + ), + .BigInt64Array => writeTypedArray( + *@TypeOf(writer), + &writer, + i64, + @alignCast(std.meta.alignment([]i64), std.mem.bytesAsSlice(i64, slice)), + enable_ansi_colors, + ), + .BigUint64Array => writeTypedArray( + *@TypeOf(writer), + &writer, + u64, + @alignCast(std.meta.alignment([]u64), std.mem.bytesAsSlice(u64, slice)), + enable_ansi_colors, + ), + + // Uint8Array, Uint8ClampedArray, DataView + else => writeTypedArray(*@TypeOf(writer), &writer, u8, slice, enable_ansi_colors), } } @@ -2266,6 +2356,32 @@ pub const ZigConsoleClient = struct { } } + fn writeTypedArray(comptime Writer: type, writer: Writer, comptime Number: type, slice: []const Number, comptime enable_ansi_colors: bool) void { + const fmt_ = if (Number == i64 or Number == u64) + "<r><yellow>{d}n<r>" + else + "<r><yellow>{d}<r>"; + const more = if (Number == i64 or Number == u64) + "<r><d>n, ... {d} more<r>" + else + "<r><d>, ... {d} more<r>"; + + writer.print(comptime Output.prettyFmt(fmt_, enable_ansi_colors), .{slice[0]}); + var leftover = slice[1..]; + const max = 512; + leftover = leftover[0..@minimum(leftover.len, max)]; + for (leftover) |el| { + printComma(undefined, @TypeOf(&writer.ctx), &writer.ctx, enable_ansi_colors) catch unreachable; + writer.writeAll(" "); + + writer.print(comptime Output.prettyFmt(fmt_, enable_ansi_colors), .{el}); + } + + if (slice.len > max + 1) { + writer.print(comptime Output.prettyFmt(more, enable_ansi_colors), .{slice.len - max - 1}); + } + } + pub fn format(this: *ZigConsoleClient.Formatter, result: Tag.Result, comptime Writer: type, writer: Writer, value: JSValue, globalThis: *JSGlobalObject, comptime enable_ansi_colors: bool) void { if (comptime is_bindgen) { return; diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index b0b6dd738..3d5523a64 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -171,6 +171,7 @@ typedef struct { uint32_t byte_len; uint8_t cell_type; uint64_t _value; + bool shared; } Bun__ArrayBuffer; extern "C" ZigErrorCode Zig_ErrorCodeParserError; diff --git a/src/comptime_string_map.zig b/src/comptime_string_map.zig index 546f928c9..18b06d9de 100644 --- a/src/comptime_string_map.zig +++ b/src/comptime_string_map.zig @@ -96,6 +96,29 @@ pub fn ComptimeStringMapWithKeyType(comptime KeyType: type, comptime V: type, co return null; } + pub fn getWithLengthAndEql(str: anytype, comptime len: usize, comptime eqls: anytype) ?V { + const end = comptime brk: { + var i = len_indexes[len]; + @setEvalBranchQuota(99999); + + while (i < kvs.len and kvs[i].key.len == len) : (i += 1) {} + + break :brk i; + }; + + comptime var i = len_indexes[len]; + + // This benchmarked faster for both small and large lists of strings than using a big switch statement + // But only so long as the keys are a sorted list. + inline while (i < end) : (i += 1) { + if (eqls(str, kvs[i].key)) { + return kvs[i].value; + } + } + + return null; + } + pub fn get(str: []const KeyType) ?V { if (str.len < precomputed.min_len or str.len > precomputed.max_len) return null; @@ -109,6 +132,20 @@ pub fn ComptimeStringMapWithKeyType(comptime KeyType: type, comptime V: type, co return null; } + + pub fn getWithEql(input: anytype, comptime eql: anytype) ?V { + if (input.len < precomputed.min_len or input.len > precomputed.max_len) + return null; + + comptime var i: usize = precomputed.min_len; + inline while (i <= precomputed.max_len) : (i += 1) { + if (input.len == i) { + return getWithLengthAndEql(input, i, eql); + } + } + + return null; + } }; } diff --git a/src/string_immutable.zig b/src/string_immutable.zig index 540572b6f..aaee55319 100644 --- a/src/string_immutable.zig +++ b/src/string_immutable.zig @@ -1014,7 +1014,13 @@ pub fn utf16Codepoint(comptime Type: type, input: Type) UTF16Replacement { } pub fn toUTF8AllocWithType(allocator: std.mem.Allocator, comptime Type: type, utf16: Type) ![]u8 { - var list = std.ArrayList(u8).initCapacity(allocator, utf16.len) catch unreachable; + var list = try std.ArrayList(u8).initCapacity(allocator, utf16.len); + list = try toUTF8ListWithType(list, Type, utf16); + return list.items; +} + +pub fn toUTF8ListWithType(list_: std.ArrayList(u8), comptime Type: type, utf16: Type) !std.ArrayList(u8) { + var list = list_; var utf16_remaining = utf16; while (firstNonASCII16(Type, utf16_remaining)) |i| { @@ -1048,8 +1054,7 @@ pub fn toUTF8AllocWithType(allocator: std.mem.Allocator, comptime Type: type, ut list.items.len += utf16_remaining.len; copyU16IntoU8(list.items[old_len..], Type, utf16_remaining); - // don't call toOwnedSlice() because our - return list.items; + return list; } pub const EncodeIntoResult = struct { diff --git a/test/bun.js/ffi.test.js b/test/bun.js/ffi.test.js index e24aaaf66..873a7f7aa 100644 --- a/test/bun.js/ffi.test.js +++ b/test/bun.js/ffi.test.js @@ -359,9 +359,9 @@ function ffiRunner(types) { }, close, } = dlopen("/tmp/bun-ffi-test.dylib", types); - + Bun.gc(true); expect(returns_true()).toBe(true); - + Bun.gc(true); expect(returns_false()).toBe(false); expect(returns_42_char()).toBe(42); @@ -371,7 +371,7 @@ function ffiRunner(types) { // returns_42_uint64_t().valueOf() === returns_42_uint64_t() // ); // expect(returns_42_uint64_t().valueOf()).toBe(42); - + Bun.gc(true); expect(Math.fround(returns_42_float())).toBe(Math.fround(42.41999804973602)); expect(returns_42_double()).toBe(42.42); expect(returns_42_uint8_t()).toBe(42); @@ -382,6 +382,7 @@ function ffiRunner(types) { expect(returns_neg_42_int16_t()).toBe(-42); expect(returns_neg_42_int32_t()).toBe(-42); expect(identity_int32_t(10)).toBe(10); + Bun.gc(true); // expect(returns_neg_42_int64_t()).toBe(-42); expect(identity_char(10)).toBe(10); @@ -399,8 +400,8 @@ function ffiRunner(types) { expect(identity_uint8_t(10)).toBe(10); expect(identity_uint16_t(10)).toBe(10); expect(identity_uint32_t(10)).toBe(10); - // expect(identity_uint64_t(10)).toBe(10); - + // expect(identity_uint64_t(10)).toBe(10); + Bun.gc(true); var bigArray = new BigUint64Array(8); new Uint8Array(bigArray.buffer).fill(255); var bigIntArray = new BigInt64Array(bigArray.buffer); @@ -420,8 +421,9 @@ function ffiRunner(types) { // expect(identity_int64_t(bigIntArray[0] - BigInt(1))).toBe( // bigIntArray[0] - BigInt(1) // ); + Bun.gc(true); + expect(add_char.native(1, 1)).toBe(2); - expect(add_char(1, 1)).toBe(2); expect(add_float(2.4, 2.8)).toBe(Math.fround(5.2)); expect(add_double(4.2, 0.1)).toBe(4.3); expect(add_int8_t(1, 1)).toBe(2); @@ -431,7 +433,7 @@ function ffiRunner(types) { expect(add_uint8_t(1, 1)).toBe(2); expect(add_uint16_t(1, 1)).toBe(2); expect(add_uint32_t(1, 1)).toBe(2); - + Bun.gc(true); const cptr = ptr_should_point_to_42_as_int32_t(); expect(cptr != 0).toBe(true); expect(typeof cptr === "number").toBe(true); @@ -463,20 +465,18 @@ function ffiRunner(types) { // callback, no userData constructor(bufferPtr, 0, 128, getDeallocatorCallback()); - // callback, userData + // callback, userData; constructor(bufferPtr, 0, 128, bufferPtr, getDeallocatorCallback()); } Bun.gc(true); expect(getDeallocatorCalledCount() >= 190).toBe(true); + Bun.gc(true); } - // close the library - close(); - - /* - --- - This style of callback is not implemented yet + /* + --- + This style of callback is not implemented yet */ // function identityBool() { // return true; @@ -574,9 +574,9 @@ function ffiRunner(types) { } it("run ffi fast", () => { - return ffiRunner(getTypes(true)); + ffiRunner(getTypes(true)); }); it("run ffi", () => { - return ffiRunner(getTypes(false)); + ffiRunner(getTypes(false)); }); diff --git a/test/bun.js/inspect.test.js b/test/bun.js/inspect.test.js index f7b364953..7428933c9 100644 --- a/test/bun.js/inspect.test.js +++ b/test/bun.js/inspect.test.js @@ -57,23 +57,79 @@ Request (0 KB) { ); }); +it("MessageEvent", () => { + expect(Bun.inspect(new MessageEvent("message", { data: 123 }))).toBe( + `MessageEvent { + type: "message", + data: 123 +}` + ); +}); + // https://github.com/oven-sh/bun/issues/561 it("TypedArray prints", () => { - // TODO: add tests for all variants of typed arrays - // even if the code is the same for each implementation, we should test it - const buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + for (let TypedArray of [ + Uint8Array, + Uint16Array, + Uint32Array, + Uint8ClampedArray, + Int8Array, + Int16Array, + Int32Array, + Float32Array, + Float64Array, + ]) { + const buffer = new TypedArray([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + const input = Bun.inspect(buffer); + + expect(input).toBe( + `${TypedArray.name}(${buffer.length}) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]` + ); + for (let i = 1; i < buffer.length + 1; i++) { + expect(Bun.inspect(buffer.subarray(i))).toBe( + `${TypedArray.name}(${buffer.length - i}) [ ` + + [...buffer.subarray(i)].join(", ") + + " ]" + ); + } + } +}); - const input = Bun.inspect(buffer); +it("BigIntArray", () => { + for (let TypedArray of [BigInt64Array, BigUint64Array]) { + const buffer = new TypedArray([1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 10n]); + const input = Bun.inspect(buffer); - expect(input).toBe( - `Uint8Array(${buffer.length}) [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]` - ); - for (let i = 1; i < buffer.length + 1; i++) { - expect(Bun.inspect(buffer.subarray(i))).toBe( - `Uint8Array(${buffer.length - i}) [ ` + - [...buffer.subarray(i)].join(", ") + - " ]" + expect(input).toBe( + `${TypedArray.name}(${buffer.length}) [ 1n, 2n, 3n, 4n, 5n, 6n, 7n, 8n, 9n, 10n ]` + ); + for (let i = 1; i < buffer.length + 1; i++) { + expect(Bun.inspect(buffer.subarray(i))).toBe( + `${TypedArray.name}(${buffer.length - i}) [ ` + + [...buffer.subarray(i)].map((a) => a.toString(10) + "n").join(", ") + + " ]" + ); + } + } +}); + +it("FloatArray", () => { + for (let TypedArray of [Float32Array, Float64Array]) { + const buffer = new TypedArray([Math.fround(42.68)]); + const input = Bun.inspect(buffer); + + expect(input).toBe( + `${TypedArray.name}(${buffer.length}) [ ${[Math.fround(42.68)].join( + ", " + )} ]` ); + for (let i = 1; i < buffer.length + 1; i++) { + expect(Bun.inspect(buffer.subarray(i))).toBe( + `${TypedArray.name}(${buffer.length - i}) [ ` + + [...buffer.subarray(i)].join(", ") + + " ]" + ); + } } }); |