diff --git a/bench/snippets/require-builtins.mjs b/bench/snippets/require-builtins.mjs index 34c008a892..4d59f13532 100644 --- a/bench/snippets/require-builtins.mjs +++ b/bench/snippets/require-builtins.mjs @@ -8,9 +8,9 @@ for (let builtin of builtinModules) { path, ` const builtin = ${JSON.stringify(builtin)}; -const now = require("perf_hooks").performance.now(); +const now = performance.now(); require(builtin); -const end = require("perf_hooks").performance.now(); +const end = performance.now(); process.stdout.write(JSON.stringify({builtin, time: end - now}) + "\\n"); `, ); diff --git a/scripts/runner.node.mjs b/scripts/runner.node.mjs index 1adcea3616..70c7cd5def 100755 --- a/scripts/runner.node.mjs +++ b/scripts/runner.node.mjs @@ -132,7 +132,7 @@ const { values: options, positionals: filters } = parseArgs({ }, ["retries"]: { type: "string", - default: isCI ? "4" : "0", // N retries = N+1 attempts + default: isCI ? "3" : "0", // N retries = N+1 attempts }, ["junit"]: { type: "boolean", diff --git a/src/bake/production.zig b/src/bake/production.zig index c38b661562..9828812d1f 100644 --- a/src/bake/production.zig +++ b/src/bake/production.zig @@ -525,7 +525,7 @@ pub fn buildWithVm(ctx: bun.CLI.Command.Context, cwd: []const u8, vm: *VirtualMa if (params_buf.items.len > 0) { const param_info_array = JSValue.createEmptyArray(global, params_buf.items.len); for (params_buf.items, 0..) |param, i| { - param_info_array.putIndex(global, @intCast(params_buf.items.len - i - 1), JSValue.toJSString(global, param)); + param_info_array.putIndex(global, @intCast(params_buf.items.len - i - 1), bun.String.createUTF8ForJS(global, param)); } route_param_info.putIndex(global, @intCast(nav_index), param_info_array); } else { diff --git a/src/bun.js/api.zig b/src/bun.js/api.zig index fc932fd3ab..fadc6f249e 100644 --- a/src/bun.js/api.zig +++ b/src/bun.js/api.zig @@ -40,6 +40,7 @@ pub const Shell = @import("../shell/shell.zig"); pub const SocketAddress = @import("api/bun/socket.zig").SocketAddress; pub const TCPSocket = @import("api/bun/socket.zig").TCPSocket; pub const TLSSocket = @import("api/bun/socket.zig").TLSSocket; +pub const SocketHandlers = @import("api/bun/socket.zig").Handlers; pub const UDPSocket = @import("api/bun/udp_socket.zig").UDPSocket; pub const Valkey = @import("../valkey/js_valkey.zig").JSValkeyClient; pub const BlockList = @import("./node/net/BlockList.zig"); diff --git a/src/bun.js/api/bun/dns_resolver.zig b/src/bun.js/api/bun/dns_resolver.zig index 37ef9691f5..aff0499e01 100644 --- a/src/bun.js/api/bun/dns_resolver.zig +++ b/src/bun.js/api/bun/dns_resolver.zig @@ -2527,10 +2527,7 @@ pub const DNSResolver = struct { break :brk RecordType.default; } - const record_type_str = record_type_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const record_type_str = try record_type_value.toJSString(globalThis); if (record_type_str.length() == 0) { break :brk RecordType.default; } @@ -2546,10 +2543,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolve", "name", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolve", "name", "non-empty string"); } @@ -2610,9 +2604,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("reverse", "ip", "string"); } - const ip_str = ip_value.toStringOrNull(globalThis) orelse { - return .zero; - }; + const ip_str = try ip_value.toJSString(globalThis); if (ip_str.length() == 0) { return globalThis.throwInvalidArgumentType("reverse", "ip", "non-empty string"); } @@ -2670,10 +2662,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("lookup", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("lookup", "hostname", "non-empty string"); } @@ -2754,10 +2743,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveSrv", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveSrv", "hostname", "non-empty string"); } @@ -2784,10 +2770,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveSoa", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); const name = try name_str.toSliceClone(globalThis, bun.default_allocator); return this.doResolveCAres(c_ares.struct_ares_soa_reply, "soa", name.slice(), globalThis); } @@ -2810,10 +2793,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveCaa", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveCaa", "hostname", "non-empty string"); } @@ -2840,9 +2820,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveNs", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; + const name_str = try name_value.toJSString(globalThis); const name = try name_str.toSliceClone(globalThis, bun.default_allocator); return this.doResolveCAres(c_ares.struct_hostent, "ns", name.slice(), globalThis); @@ -2866,10 +2844,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolvePtr", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolvePtr", "hostname", "non-empty string"); } @@ -2896,10 +2871,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveCname", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveCname", "hostname", "non-empty string"); } @@ -2926,10 +2898,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveMx", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveMx", "hostname", "non-empty string"); } @@ -2956,10 +2925,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveNaptr", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveNaptr", "hostname", "non-empty string"); } @@ -2986,10 +2952,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveTxt", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveTxt", "hostname", "non-empty string"); } @@ -3016,10 +2979,7 @@ pub const DNSResolver = struct { return globalThis.throwInvalidArgumentType("resolveAny", "hostname", "string"); } - const name_str = name_value.toStringOrNull(globalThis) orelse { - return .zero; - }; - + const name_str = try name_value.toJSString(globalThis); if (name_str.length() == 0) { return globalThis.throwInvalidArgumentType("resolveAny", "hostname", "non-empty string"); } @@ -3375,9 +3335,8 @@ pub const DNSResolver = struct { if (addr_value.isEmptyOrUndefinedOrNull() or !addr_value.isString()) { return globalThis.throwInvalidArgumentType("lookupService", "address", "string"); } - const addr_str = addr_value.toStringOrNull(globalThis) orelse { - return .zero; - }; + + const addr_str = try addr_value.toJSString(globalThis); if (addr_str.length() == 0) { return globalThis.throwInvalidArgumentType("lookupService", "address", "non-empty string"); } diff --git a/src/bun.js/api/bun/h2_frame_parser.zig b/src/bun.js/api/bun/h2_frame_parser.zig index 104192cd37..37ee14b190 100644 --- a/src/bun.js/api/bun/h2_frame_parser.zig +++ b/src/bun.js/api/bun/h2_frame_parser.zig @@ -3321,7 +3321,8 @@ pub const H2FrameParser = struct { return globalObject.throwValue(exception); } - const value_str = item.toStringOrNull(globalObject) orelse { + const value_str = item.toJSString(globalObject) catch { + globalObject.clearException(); const exception = globalObject.toTypeError(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{validated_name}); return globalObject.throwValue(exception); }; @@ -3351,7 +3352,8 @@ pub const H2FrameParser = struct { } single_value_headers[idx] = true; } - const value_str = js_value.toStringOrNull(globalObject) orelse { + const value_str = js_value.toJSString(globalObject) catch { + globalObject.clearException(); const exception = globalObject.toTypeError(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{validated_name}); return globalObject.throwValue(exception); }; @@ -3729,11 +3731,9 @@ pub const H2FrameParser = struct { return .zero; } - const value_str = item.toStringOrNull(globalObject) orelse { - if (!globalObject.hasException()) { - return globalObject.ERR(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{validated_name}).throw(); - } - return .zero; + const value_str = item.toJSString(globalObject) catch { + globalObject.clearException(); + return globalObject.ERR(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{validated_name}).throw(); }; const never_index = (try sensitive_arg.getTruthy(globalObject, validated_name) orelse try sensitive_arg.getTruthy(globalObject, name)) != null; @@ -3765,11 +3765,9 @@ pub const H2FrameParser = struct { } single_value_headers[idx] = true; } - const value_str = js_value.toStringOrNull(globalObject) orelse { - if (!globalObject.hasException()) { - return globalObject.ERR(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}).throw(); - } - return .zero; + const value_str = js_value.toJSString(globalObject) catch { + globalObject.clearException(); + return globalObject.ERR(.HTTP2_INVALID_HEADER_VALUE, "Invalid value for header \"{s}\"", .{name}).throw(); }; const never_index = (try sensitive_arg.getTruthy(globalObject, validated_name) orelse try sensitive_arg.getTruthy(globalObject, name)) != null; diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index 8c24b2b28a..920a019ff8 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -114,7 +114,7 @@ const WrappedType = enum { tcp, }; -const Handlers = struct { +pub const Handlers = struct { onOpen: JSC.JSValue = .zero, onClose: JSC.JSValue = .zero, onData: JSC.JSValue = .zero, @@ -130,7 +130,7 @@ const Handlers = struct { vm: *JSC.VirtualMachine, globalObject: *JSC.JSGlobalObject, active_connections: u32 = 0, - is_server: bool = false, + is_server: bool, promise: JSC.Strong.Optional = .empty, protection_count: bun.DebugOnly(u32) = if (Environment.isDebug) 0, @@ -202,7 +202,7 @@ const Handlers = struct { } } - pub fn callErrorHandler(this: *Handlers, thisValue: JSValue, err: []const JSValue) bool { + pub fn callErrorHandler(this: *Handlers, thisValue: JSValue, args: *const [2]JSValue) bool { const vm = this.vm; if (vm.isShuttingDown()) { return false; @@ -212,22 +212,20 @@ const Handlers = struct { const onError = this.onError; if (onError == .zero) { - if (err.len > 0) - _ = vm.uncaughtException(globalObject, err[0], false); - + _ = vm.uncaughtException(globalObject, args[1], false); return false; } - _ = onError.call(globalObject, thisValue, err) catch |e| - globalObject.reportActiveExceptionAsUnhandled(e); + _ = onError.call(globalObject, thisValue, args) catch |e| globalObject.reportActiveExceptionAsUnhandled(e); return true; } - pub fn fromJS(globalObject: *JSC.JSGlobalObject, opts: JSC.JSValue) bun.JSError!Handlers { + pub fn fromJS(globalObject: *JSC.JSGlobalObject, opts: JSC.JSValue, is_server: bool) bun.JSError!Handlers { var handlers = Handlers{ .vm = globalObject.bunVM(), .globalObject = globalObject, + .is_server = is_server, }; if (opts.isEmptyOrUndefinedOrNull() or opts.isBoolean() or !opts.isObject()) { @@ -338,7 +336,7 @@ pub const SocketConfig = struct { return flags; } - pub fn fromJS(vm: *JSC.VirtualMachine, opts: JSC.JSValue, globalObject: *JSC.JSGlobalObject) bun.JSError!SocketConfig { + pub fn fromJS(vm: *JSC.VirtualMachine, opts: JSC.JSValue, globalObject: *JSC.JSGlobalObject, is_server: bool) bun.JSError!SocketConfig { var hostname_or_unix: JSC.ZigString.Slice = JSC.ZigString.Slice.empty; errdefer hostname_or_unix.deinit(); var port: ?u16 = null; @@ -460,7 +458,7 @@ pub const SocketConfig = struct { return globalObject.throwInvalidArguments("Expected either \"hostname\" or \"unix\"", .{}); } - var handlers = try Handlers.fromJS(globalObject, try opts.get(globalObject, "socket") orelse JSValue.zero); + var handlers = try Handlers.fromJS(globalObject, try opts.get(globalObject, "socket") orelse JSValue.zero, is_server); if (opts.fastGet(globalObject, .data)) |default_data_value| { default_data = default_data_value; @@ -608,7 +606,7 @@ pub const Listener = struct { return globalObject.throw("Expected \"socket\" object", .{}); }; - const handlers = try Handlers.fromJS(globalObject, socket_obj); + const handlers = try Handlers.fromJS(globalObject, socket_obj, this.handlers.is_server); var prev_handlers = &this.handlers; prev_handlers.unprotect(); @@ -626,14 +624,13 @@ pub const Listener = struct { const vm = JSC.VirtualMachine.get(); - var socket_config = try SocketConfig.fromJS(vm, opts, globalObject); + var socket_config = try SocketConfig.fromJS(vm, opts, globalObject, true); var hostname_or_unix = socket_config.hostname_or_unix; const port = socket_config.port; var ssl = socket_config.ssl; var handlers = socket_config.handlers; var protos: ?[]const u8 = null; - handlers.is_server = true; const ssl_enabled = ssl != null; @@ -1074,7 +1071,7 @@ pub const Listener = struct { } const vm = globalObject.bunVM(); - const socket_config = try SocketConfig.fromJS(vm, opts, globalObject); + const socket_config = try SocketConfig.fromJS(vm, opts, globalObject, false); var hostname_or_unix = socket_config.hostname_or_unix; const port = socket_config.port; @@ -1552,12 +1549,13 @@ fn NewSocket(comptime ssl: bool) type { defer vm.eventLoop().exit(); const globalObject = handlers.globalObject; const this_value = this.getThisValue(globalObject); - _ = handlers.callErrorHandler(this_value, &[_]JSC.JSValue{ this_value, err_value }); + _ = handlers.callErrorHandler(this_value, &.{ this_value, err_value }); } pub fn onWritable(this: *This, _: Socket) void { JSC.markBinding(@src()); - log("onWritable detached={s}, native_callback_writable={s} sanity={s}", .{ + log("onWritable {s} detached={s}, native_callback_writable={s} sanity={s}", .{ + if (this.handlers.is_server) "S" else "C", if (this.socket.isDetached()) "true" else "false", if (this.native_callback.onWritable()) "true" else "false", if (this.handlers.onWritable == .zero) "true" else "false", @@ -1591,7 +1589,7 @@ fn NewSocket(comptime ssl: bool) type { pub fn onTimeout(this: *This, _: Socket) void { JSC.markBinding(@src()); - log("onTimeout", .{}); + log("onTimeout {s}", .{if (this.handlers.is_server) "S" else "C"}); if (this.socket.isDetached()) return; const handlers = this.handlers; @@ -1614,7 +1612,7 @@ fn NewSocket(comptime ssl: bool) type { } fn handleConnectError(this: *This, errno: c_int) void { - log("onConnectError({d}, {})", .{ errno, this.ref_count }); + log("onConnectError {s} ({d}, {})", .{ if (this.handlers.is_server) "S" else "C", errno, this.ref_count }); // Ensure the socket is still alive for any defer's we have this.ref(); defer this.deref(); @@ -1677,7 +1675,7 @@ fn NewSocket(comptime ssl: bool) type { if (result.toError()) |err_val| { if (handlers.rejectPromise(err_val)) return; - _ = handlers.callErrorHandler(this_value, &[_]JSC.JSValue{ this_value, err_val }); + _ = handlers.callErrorHandler(this_value, &.{ this_value, err_val }); } else if (handlers.promise.trySwap()) |val| { // They've defined a `connectError` callback // The error is effectively handled, but we should still reject the promise. @@ -1734,12 +1732,12 @@ fn NewSocket(comptime ssl: bool) type { this.ref(); defer this.deref(); - log("onOpen {} {}", .{ this.socket.isDetached(), this.ref_count }); + log("onOpen {s} {} {}", .{ if (this.handlers.is_server) "S" else "C", this.socket.isDetached(), this.ref_count }); // update the internal socket instance to the one that was just connected // This socket must be replaced because the previous one is a connecting socket not a uSockets socket this.socket = socket; JSC.markBinding(@src()); - log("onOpen ssl: {}", .{comptime ssl}); + log("onOpen {s} ssl: {}", .{ if (this.handlers.is_server) "S" else "C", ssl }); // Add SNI support for TLS (mongodb and others requires this) if (comptime ssl) { @@ -1830,7 +1828,7 @@ fn NewSocket(comptime ssl: bool) type { pub fn onEnd(this: *This, _: Socket) void { JSC.markBinding(@src()); - log("onEnd", .{}); + log("onEnd {s}", .{if (this.handlers.is_server) "S" else "C"}); if (this.socket.isDetached()) return; // Ensure the socket remains alive until this is finished this.ref(); @@ -1860,7 +1858,7 @@ fn NewSocket(comptime ssl: bool) type { } pub fn onHandshake(this: *This, _: Socket, success: i32, ssl_error: uws.us_bun_verify_error_t) void { - log("onHandshake({d})", .{success}); + log("onHandshake {s} ({d})", .{ if (this.handlers.is_server) "S" else "C", success }); JSC.markBinding(@src()); this.flags.handshake_complete = true; if (this.socket.isDetached()) return; @@ -1922,13 +1920,13 @@ fn NewSocket(comptime ssl: bool) type { } if (result.toError()) |err_value| { - _ = handlers.callErrorHandler(this_value, &[_]JSC.JSValue{ this_value, err_value }); + _ = handlers.callErrorHandler(this_value, &.{ this_value, err_value }); } } pub fn onClose(this: *This, _: Socket, err: c_int, _: ?*anyopaque) void { JSC.markBinding(@src()); - log("onClose", .{}); + log("onClose {s}", .{if (this.handlers.is_server) "S" else "C"}); this.detachNativeCallback(); this.socket.detach(); defer this.deref(); @@ -1974,7 +1972,7 @@ fn NewSocket(comptime ssl: bool) type { pub fn onData(this: *This, _: Socket, data: []const u8) void { JSC.markBinding(@src()); - log("onData({d})", .{data.len}); + log("onData {s} ({d})", .{ if (this.handlers.is_server) "S" else "C", data.len }); if (this.socket.isDetached()) return; if (this.native_callback.onData(data)) return; @@ -2660,7 +2658,7 @@ fn NewSocket(comptime ssl: bool) type { return globalObject.throw("Expected \"socket\" option", .{}); }; - const handlers = try Handlers.fromJS(globalObject, socket_obj); + const handlers = try Handlers.fromJS(globalObject, socket_obj, this.handlers.is_server); var prev_handlers = this.handlers; prev_handlers.unprotect(); @@ -3349,7 +3347,7 @@ fn NewSocket(comptime ssl: bool) type { return .zero; } - const handlers = try Handlers.fromJS(globalObject, socket_obj); + const handlers = try Handlers.fromJS(globalObject, socket_obj, false); if (globalObject.hasException()) { return .zero; @@ -3403,11 +3401,8 @@ fn NewSocket(comptime ssl: bool) type { const ext_size = @sizeOf(WrappedSocket); - const is_server = this.handlers.is_server; - var handlers_ptr = bun.default_allocator.create(Handlers) catch bun.outOfMemory(); handlers_ptr.* = handlers; - handlers_ptr.is_server = is_server; handlers_ptr.protect(); var tls = bun.new(TLSSocket, .{ .ref_count = .init(), @@ -3429,19 +3424,9 @@ fn NewSocket(comptime ssl: bool) type { // reconfigure context to use the new wrapper handlers Socket.unsafeConfigure(this.socket.context().?, true, true, WrappedSocket, TCPHandler); const TLSHandler = NewWrappedHandler(true); - const new_socket = this.socket.wrapTLS( - options, - ext_size, - true, - WrappedSocket, - TLSHandler, - ) orelse { + const new_socket = this.socket.wrapTLS(options, ext_size, true, WrappedSocket, TLSHandler) orelse { const err = BoringSSL.ERR_get_error(); - defer { - if (err != 0) { - BoringSSL.ERR_clear_error(); - } - } + defer if (err != 0) BoringSSL.ERR_clear_error(); tls.wrapped = .none; // Reset config to TCP @@ -3504,7 +3489,7 @@ fn NewSocket(comptime ssl: bool) type { .onError = this.handlers.onError, .onHandshake = this.handlers.onHandshake, .binary_type = this.handlers.binary_type, - .is_server = is_server, + .is_server = this.handlers.is_server, }; raw_handlers_ptr.protect(); @@ -3562,7 +3547,7 @@ fn NewSocket(comptime ssl: bool) type { this.socket.detach(); // start TLS handshake after we set extension on the socket - new_socket.startTLS(!is_server); + new_socket.startTLS(!handlers_ptr.is_server); success = true; return array; @@ -4223,7 +4208,7 @@ pub fn jsUpgradeDuplexToTLS(globalObject: *JSC.JSGlobalObject, callframe: *JSC.C return globalObject.throw("Expected \"socket\" option", .{}); }; - var handlers = try Handlers.fromJS(globalObject, socket_obj); + var handlers = try Handlers.fromJS(globalObject, socket_obj, false); var ssl_opts: ?JSC.API.ServerConfig.SSLConfig = null; if (try opts.getTruthy(globalObject, "tls")) |tls| { diff --git a/src/bun.js/bindings/JSValue.zig b/src/bun.js/bindings/JSValue.zig index ea24587481..08f3f532eb 100644 --- a/src/bun.js/bindings/JSValue.zig +++ b/src/bun.js/bindings/JSValue.zig @@ -1446,10 +1446,6 @@ pub const JSValue = enum(i64) { }; } - pub fn toJSString(globalObject: *JSC.JSGlobalObject, slice_: []const u8) JSC.JSValue { - return JSC.ZigString.init(slice_).withEncoding().toJS(globalObject); - } - extern fn JSC__JSValue__asCell(this: JSValue) *JSCell; pub fn asCell(this: JSValue) *JSCell { // NOTE: asCell already asserts this, but since we're crossing an FFI @@ -1574,8 +1570,8 @@ pub const JSValue = enum(i64) { return getZigString(this, global).toSliceZ(allocator); } - // On exception, this returns the empty string. extern fn JSC__JSValue__toString(this: JSValue, globalThis: *JSGlobalObject) *JSString; + /// On exception, this returns the empty string. pub fn toString(this: JSValue, globalThis: *JSGlobalObject) *JSString { return JSC__JSValue__toString(this, globalThis); } @@ -1584,10 +1580,11 @@ pub const JSValue = enum(i64) { pub fn jsonStringify(this: JSValue, globalThis: *JSGlobalObject, indent: u32, out: *bun.String) void { return JSC__JSValue__jsonStringify(this, globalThis, indent, out); } + extern fn JSC__JSValue__toStringOrNull(this: JSValue, globalThis: *JSGlobalObject) ?*JSString; - /// On exception, this returns null, to make exception checks clearer. - pub fn toStringOrNull(this: JSValue, globalThis: *JSGlobalObject) ?*JSString { - return JSC__JSValue__toStringOrNull(this, globalThis); + // Calls JSValue::toStringOrNull. Returns error on exception. + pub fn toJSString(this: JSValue, globalThis: *JSGlobalObject) bun.JSError!*JSString { + return JSC__JSValue__toStringOrNull(this, globalThis) orelse return error.JSError; } /// Call `toString()` on the JSValue and clone the result. @@ -1627,7 +1624,7 @@ pub const JSValue = enum(i64) { globalThis: *JSGlobalObject, allocator: std.mem.Allocator, ) ?ZigString.Slice { - var str = this.toStringOrNull(globalThis) orelse return null; + var str = this.toJSString(globalThis) catch return null; return str.toSlice(globalThis, allocator).cloneIfNeeded(allocator) catch { globalThis.throwOutOfMemory() catch {}; // TODO: properly propagate exception upwards return null; diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 18303141aa..03d5cc459a 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -2083,8 +2083,7 @@ JSC::EncodedJSValue JSGlobalObject__createOutOfMemoryError(JSC::JSGlobalObject* return JSValue::encode(exception); } -JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, - JSC::JSGlobalObject* globalObject) +JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::JSGlobalObject* globalObject) { ASSERT_NO_PENDING_EXCEPTION(globalObject); SystemError err = *arg0; @@ -2122,24 +2121,20 @@ JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, if (err.fd >= 0) { JSC::JSValue fd = JSC::JSValue(jsNumber(err.fd)); - result->putDirect(vm, names.fdPublicName(), fd, - JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, names.fdPublicName(), fd, JSC::PropertyAttribute::DontDelete | 0); } if (err.syscall.tag != BunStringTag::Empty) { JSC::JSValue syscall = Bun::toJS(globalObject, err.syscall); - result->putDirect(vm, names.syscallPublicName(), syscall, - JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, names.syscallPublicName(), syscall, JSC::PropertyAttribute::DontDelete | 0); } if (err.hostname.tag != BunStringTag::Empty) { JSC::JSValue hostname = Bun::toJS(globalObject, err.hostname); - result->putDirect(vm, names.hostnamePublicName(), hostname, - JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, names.hostnamePublicName(), hostname, JSC::PropertyAttribute::DontDelete | 0); } - result->putDirect(vm, names.errnoPublicName(), JSC::JSValue(err.errno_), - JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, names.errnoPublicName(), JSC::JSValue(err.errno_), JSC::PropertyAttribute::DontDelete | 0); RETURN_IF_EXCEPTION(scope, {}); scope.release(); @@ -2147,8 +2142,7 @@ JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, return JSC::JSValue::encode(JSC::JSValue(result)); } -JSC::EncodedJSValue SystemError__toErrorInstanceWithInfoObject(const SystemError* arg0, - JSC::JSGlobalObject* globalObject) +JSC::EncodedJSValue SystemError__toErrorInstanceWithInfoObject(const SystemError* arg0, JSC::JSGlobalObject* globalObject) { ASSERT_NO_PENDING_EXCEPTION(globalObject); SystemError err = *arg0; @@ -2169,34 +2163,22 @@ JSC::EncodedJSValue SystemError__toErrorInstanceWithInfoObject(const SystemError auto clientData = WebCore::clientData(vm); - result->putDirect( - vm, vm.propertyNames->name, - JSC::JSValue(jsString(vm, String("SystemError"_s))), - JSC::PropertyAttribute::DontEnum | 0); - result->putDirect( - vm, clientData->builtinNames().codePublicName(), - JSC::JSValue(jsString(vm, String("ERR_SYSTEM_ERROR"_s))), - JSC::PropertyAttribute::DontEnum | 0); + result->putDirect(vm, vm.propertyNames->name, JSC::JSValue(jsString(vm, String("SystemError"_s))), JSC::PropertyAttribute::DontEnum | 0); + result->putDirect(vm, clientData->builtinNames().codePublicName(), JSC::JSValue(jsString(vm, String("ERR_SYSTEM_ERROR"_s))), JSC::PropertyAttribute::DontEnum | 0); info->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, codeString), JSC::PropertyAttribute::DontDelete | 0); result->putDirect(vm, JSC::Identifier::fromString(vm, "info"_s), info, JSC::PropertyAttribute::DontDelete | 0); auto syscallJsString = jsString(vm, syscallString); - result->putDirect(vm, clientData->builtinNames().syscallPublicName(), syscallJsString, - JSC::PropertyAttribute::DontDelete | 0); - info->putDirect(vm, clientData->builtinNames().syscallPublicName(), syscallJsString, - JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, clientData->builtinNames().syscallPublicName(), syscallJsString, JSC::PropertyAttribute::DontDelete | 0); + info->putDirect(vm, clientData->builtinNames().syscallPublicName(), syscallJsString, JSC::PropertyAttribute::DontDelete | 0); - info->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, codeString), - JSC::PropertyAttribute::DontDelete | 0); - info->putDirect(vm, vm.propertyNames->message, jsString(vm, messageString), - JSC::PropertyAttribute::DontDelete | 0); + info->putDirect(vm, clientData->builtinNames().codePublicName(), jsString(vm, codeString), JSC::PropertyAttribute::DontDelete | 0); + info->putDirect(vm, vm.propertyNames->message, jsString(vm, messageString), JSC::PropertyAttribute::DontDelete | 0); - info->putDirect(vm, clientData->builtinNames().errnoPublicName(), jsNumber(err.errno_), - JSC::PropertyAttribute::DontDelete | 0); - result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(err.errno_), - JSC::PropertyAttribute::DontDelete | 0); + info->putDirect(vm, clientData->builtinNames().errnoPublicName(), jsNumber(err.errno_), JSC::PropertyAttribute::DontDelete | 0); + result->putDirect(vm, clientData->builtinNames().errnoPublicName(), JSC::JSValue(err.errno_), JSC::PropertyAttribute::DontDelete | 0); RELEASE_AND_RETURN(scope, JSC::JSValue::encode(JSC::JSValue(result))); } @@ -5999,37 +5981,30 @@ extern "C" JSC::EncodedJSValue WebCore__AbortSignal__abortReason(WebCore::AbortS return JSC::JSValue::encode(abortSignal->reason().getValue(jsNull())); } -extern "C" WebCore::AbortSignal* WebCore__AbortSignal__ref(WebCore::AbortSignal* arg0) +extern "C" WebCore::AbortSignal* WebCore__AbortSignal__ref(WebCore::AbortSignal* abortSignal) { - WebCore::AbortSignal* abortSignal = reinterpret_cast(arg0); abortSignal->ref(); - return arg0; + return abortSignal; } -extern "C" void WebCore__AbortSignal__unref(WebCore::AbortSignal* arg0) +extern "C" void WebCore__AbortSignal__unref(WebCore::AbortSignal* abortSignal) { - WebCore::AbortSignal* abortSignal = reinterpret_cast(arg0); abortSignal->deref(); } -extern "C" void WebCore__AbortSignal__cleanNativeBindings(WebCore::AbortSignal* arg0, void* arg1) +extern "C" void WebCore__AbortSignal__cleanNativeBindings(WebCore::AbortSignal* abortSignal, void* arg1) { - WebCore::AbortSignal* abortSignal = reinterpret_cast(arg0); abortSignal->cleanNativeBindings(arg1); } -extern "C" WebCore::AbortSignal* WebCore__AbortSignal__addListener(WebCore::AbortSignal* arg0, void* ctx, void (*callback)(void* ctx, JSC::EncodedJSValue reason)) +extern "C" WebCore::AbortSignal* WebCore__AbortSignal__addListener(WebCore::AbortSignal* abortSignal, void* ctx, void (*callback)(void* ctx, JSC::EncodedJSValue reason)) { - WebCore::AbortSignal* abortSignal = reinterpret_cast(arg0); - if (abortSignal->aborted()) { callback(ctx, JSC::JSValue::encode(abortSignal->reason().getValue(jsNull()))); - return arg0; + return abortSignal; } - abortSignal->addNativeCallback(std::make_tuple(ctx, callback)); - - return arg0; + return abortSignal; } extern "C" WebCore::AbortSignal* WebCore__AbortSignal__fromJS(JSC::EncodedJSValue value) { diff --git a/src/bun.js/node/path.zig b/src/bun.js/node/path.zig index 1e51374c49..808a83ece0 100644 --- a/src/bun.js/node/path.zig +++ b/src/bun.js/node/path.zig @@ -74,8 +74,6 @@ const CHAR_STR_DOT = "."; const StringBuilder = bun.StringBuilder; -const toJSString = JSC.JSValue.toJSString; - /// Based on Node v21.6.1 path.parse: /// https://github.com/nodejs/node/blob/6ae20aa63de78294b18d5015481485b7cd8fbb60/lib/path.js#L919 /// The structs returned by parse methods. @@ -86,13 +84,14 @@ fn PathParsed(comptime T: type) type { base: []const T = "", ext: []const T = "", name: []const T = "", + pub fn toJSObject(this: @This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue { var jsObject = JSC.JSValue.createEmptyObject(globalObject, 5); - jsObject.put(globalObject, JSC.ZigString.static("root"), toJSString(globalObject, this.root)); - jsObject.put(globalObject, JSC.ZigString.static("dir"), toJSString(globalObject, this.dir)); - jsObject.put(globalObject, JSC.ZigString.static("base"), toJSString(globalObject, this.base)); - jsObject.put(globalObject, JSC.ZigString.static("ext"), toJSString(globalObject, this.ext)); - jsObject.put(globalObject, JSC.ZigString.static("name"), toJSString(globalObject, this.name)); + jsObject.put(globalObject, JSC.ZigString.static("root"), bun.String.createUTF8ForJS(globalObject, this.root)); + jsObject.put(globalObject, JSC.ZigString.static("dir"), bun.String.createUTF8ForJS(globalObject, this.dir)); + jsObject.put(globalObject, JSC.ZigString.static("base"), bun.String.createUTF8ForJS(globalObject, this.base)); + jsObject.put(globalObject, JSC.ZigString.static("ext"), bun.String.createUTF8ForJS(globalObject, this.ext)); + jsObject.put(globalObject, JSC.ZigString.static("name"), bun.String.createUTF8ForJS(globalObject, this.name)); return jsObject; } }; @@ -421,11 +420,11 @@ pub fn basenameWindowsT(comptime T: type, path: []const T, suffix: ?[]const T) [ } pub inline fn basenamePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, suffix: ?[]const T) JSC.JSValue { - return toJSString(globalObject, basenamePosixT(T, path, suffix)); + return bun.String.createUTF8ForJS(globalObject, basenamePosixT(T, path, suffix)); } pub inline fn basenameWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, suffix: ?[]const T) JSC.JSValue { - return toJSString(globalObject, basenameWindowsT(T, path, suffix)); + return bun.String.createUTF8ForJS(globalObject, basenameWindowsT(T, path, suffix)); } pub inline fn basenameJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, isWindows: bool, path: []const T, suffix: ?[]const T) JSC.JSValue { @@ -622,11 +621,11 @@ pub fn dirnameWindowsT(comptime T: type, path: []const T) []const T { } pub inline fn dirnamePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T) JSC.JSValue { - return toJSString(globalObject, dirnamePosixT(T, path)); + return bun.String.createUTF8ForJS(globalObject, dirnamePosixT(T, path)); } pub inline fn dirnameWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T) JSC.JSValue { - return toJSString(globalObject, dirnameWindowsT(T, path)); + return bun.String.createUTF8ForJS(globalObject, dirnameWindowsT(T, path)); } pub inline fn dirnameJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, isWindows: bool, path: []const T) JSC.JSValue { @@ -645,7 +644,7 @@ pub fn dirname(globalObject: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [*] }; const pathZStr = path_ptr.getZigString(globalObject) catch return .zero; - if (pathZStr.len == 0) return toJSString(globalObject, CHAR_STR_DOT); + if (pathZStr.len == 0) return bun.String.createUTF8ForJS(globalObject, CHAR_STR_DOT); var stack_fallback = std.heap.stackFallback(stack_fallback_size_small, bun.default_allocator); const allocator = stack_fallback.get(); @@ -821,11 +820,11 @@ pub fn extnameWindowsT(comptime T: type, path: []const T) []const T { } pub inline fn extnamePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T) JSC.JSValue { - return toJSString(globalObject, extnamePosixT(T, path)); + return bun.String.createUTF8ForJS(globalObject, extnamePosixT(T, path)); } pub inline fn extnameWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T) JSC.JSValue { - return toJSString(globalObject, extnameWindowsT(T, path)); + return bun.String.createUTF8ForJS(globalObject, extnameWindowsT(T, path)); } pub inline fn extnameJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, isWindows: bool, path: []const T) JSC.JSValue { @@ -930,11 +929,11 @@ fn _formatT(comptime T: type, pathObject: PathParsed(T), sep: T, buf: []T) []con } pub inline fn formatPosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, pathObject: PathParsed(T), buf: []T) JSC.JSValue { - return toJSString(globalObject, _formatT(T, pathObject, CHAR_FORWARD_SLASH, buf)); + return bun.String.createUTF8ForJS(globalObject, _formatT(T, pathObject, CHAR_FORWARD_SLASH, buf)); } pub inline fn formatWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, pathObject: PathParsed(T), buf: []T) JSC.JSValue { - return toJSString(globalObject, _formatT(T, pathObject, CHAR_BACKWARD_SLASH, buf)); + return bun.String.createUTF8ForJS(globalObject, _formatT(T, pathObject, CHAR_BACKWARD_SLASH, buf)); } pub fn formatJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, allocator: std.mem.Allocator, isWindows: bool, pathObject: PathParsed(T)) JSC.JSValue { @@ -1237,11 +1236,11 @@ pub fn joinWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf2: } pub inline fn joinPosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, paths: []const []const T, buf: []T, buf2: []T) JSC.JSValue { - return toJSString(globalObject, joinPosixT(T, paths, buf, buf2)); + return bun.String.createUTF8ForJS(globalObject, joinPosixT(T, paths, buf, buf2)); } pub inline fn joinWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, paths: []const []const T, buf: []T, buf2: []T) JSC.JSValue { - return toJSString(globalObject, joinWindowsT(T, paths, buf, buf2)); + return bun.String.createUTF8ForJS(globalObject, joinWindowsT(T, paths, buf, buf2)); } pub fn joinJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, allocator: std.mem.Allocator, isWindows: bool, paths: []const []const T) JSC.JSValue { @@ -1257,7 +1256,7 @@ pub fn joinJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, allocator: } pub fn join(globalObject: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [*]JSC.JSValue, args_len: u16) callconv(JSC.conv) JSC.JSValue { - if (args_len == 0) return toJSString(globalObject, CHAR_STR_DOT); + if (args_len == 0) return bun.String.createUTF8ForJS(globalObject, CHAR_STR_DOT); var arena = bun.ArenaAllocator.init(bun.default_allocator); defer arena.deinit(); @@ -1652,11 +1651,11 @@ pub fn normalizeT(comptime T: type, path: []const T, buf: []T) []const T { } pub inline fn normalizePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, buf: []T) JSC.JSValue { - return toJSString(globalObject, normalizePosixT(T, path, buf)); + return bun.String.createUTF8ForJS(globalObject, normalizePosixT(T, path, buf)); } pub inline fn normalizeWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, buf: []T) JSC.JSValue { - return toJSString(globalObject, normalizeWindowsT(T, path, buf)); + return bun.String.createUTF8ForJS(globalObject, normalizeWindowsT(T, path, buf)); } pub fn normalizeJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, allocator: std.mem.Allocator, isWindows: bool, path: []const T) JSC.JSValue { @@ -1675,7 +1674,7 @@ pub fn normalize(globalObject: *JSC.JSGlobalObject, isWindows: bool, args_ptr: [ }; const pathZStr = path_ptr.getZigString(globalObject) catch return .zero; const len = pathZStr.len; - if (len == 0) return toJSString(globalObject, CHAR_STR_DOT); + if (len == 0) return bun.String.createUTF8ForJS(globalObject, CHAR_STR_DOT); var stack_fallback = std.heap.stackFallback(stack_fallback_size_small, bun.default_allocator); const allocator = stack_fallback.get(); @@ -2327,14 +2326,14 @@ pub fn relativeWindowsT(comptime T: type, from: []const T, to: []const T, buf: [ pub inline fn relativePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, from: []const T, to: []const T, buf: []T, buf2: []T, buf3: []T) JSC.JSValue { return switch (relativePosixT(T, from, to, buf, buf2, buf3)) { - .result => |r| toJSString(globalObject, r), + .result => |r| bun.String.createUTF8ForJS(globalObject, r), .err => |e| e.toJSC(globalObject), }; } pub inline fn relativeWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, from: []const T, to: []const T, buf: []T, buf2: []T, buf3: []T) JSC.JSValue { return switch (relativeWindowsT(T, from, to, buf, buf2, buf3)) { - .result => |r| toJSString(globalObject, r), + .result => |r| bun.String.createUTF8ForJS(globalObject, r), .err => |e| e.toJSC(globalObject), }; } @@ -2781,14 +2780,14 @@ pub fn resolveWindowsT(comptime T: type, paths: []const []const T, buf: []T, buf pub inline fn resolvePosixJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, paths: []const []const T, buf: []T, buf2: []T) JSC.JSValue { return switch (resolvePosixT(T, paths, buf, buf2)) { - .result => |r| toJSString(globalObject, r), + .result => |r| bun.String.createUTF8ForJS(globalObject, r), .err => |e| e.toJSC(globalObject), }; } pub inline fn resolveWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, paths: []const []const T, buf: []T, buf2: []T) JSC.JSValue { return switch (resolveWindowsT(T, paths, buf, buf2)) { - .result => |r| toJSString(globalObject, r), + .result => |r| bun.String.createUTF8ForJS(globalObject, r), .err => |e| e.toJSC(globalObject), }; } @@ -2927,13 +2926,13 @@ pub fn toNamespacedPathWindowsT(comptime T: type, path: []const T, buf: []T, buf pub inline fn toNamespacedPathWindowsJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, path: []const T, buf: []T, buf2: []T) JSC.JSValue { return switch (toNamespacedPathWindowsT(T, path, buf, buf2)) { - .result => |r| toJSString(globalObject, r), + .result => |r| bun.String.createUTF8ForJS(globalObject, r), .err => |e| e.toJSC(globalObject), }; } pub fn toNamespacedPathJS_T(comptime T: type, globalObject: *JSC.JSGlobalObject, allocator: std.mem.Allocator, isWindows: bool, path: []const T) JSC.JSValue { - if (!isWindows or path.len == 0) return toJSString(globalObject, path); + if (!isWindows or path.len == 0) return bun.String.createUTF8ForJS(globalObject, path); const bufLen = @max(path.len, PATH_SIZE(T)); const buf = allocator.alloc(T, bufLen) catch bun.outOfMemory(); defer allocator.free(buf); diff --git a/src/bun.js/test/expect.zig b/src/bun.js/test/expect.zig index a7239aefcc..f2fba97e13 100644 --- a/src/bun.js/test/expect.zig +++ b/src/bun.js/test/expect.zig @@ -2249,10 +2249,8 @@ pub const Expect = struct { if (expected_value.isString()) { const received_message: JSValue = (if (result.isObject()) result.fastGet(globalThis, .message) - else if (result.toStringOrNull(globalThis)) |js_str| - JSValue.fromCell(js_str) else - .undefined) orelse .undefined; + JSValue.fromCell(try result.toJSString(globalThis))) orelse .jsUndefined(); if (globalThis.hasException()) return .zero; // TODO: remove this allocation @@ -2274,10 +2272,8 @@ pub const Expect = struct { if (expected_value.isRegExp()) { const received_message: JSValue = (if (result.isObject()) result.fastGet(globalThis, .message) - else if (result.toStringOrNull(globalThis)) |js_str| - JSValue.fromCell(js_str) else - .undefined) orelse .undefined; + JSValue.fromCell(try result.toJSString(globalThis))) orelse .jsUndefined(); if (globalThis.hasException()) return .zero; // TODO: REMOVE THIS GETTER! Expose a binding to call .test on the RegExp object directly. @@ -2295,10 +2291,8 @@ pub const Expect = struct { if (expected_value.fastGet(globalThis, .message)) |expected_message| { const received_message: JSValue = (if (result.isObject()) result.fastGet(globalThis, .message) - else if (result.toStringOrNull(globalThis)) |js_str| - JSValue.fromCell(js_str) else - .undefined) orelse .undefined; + JSValue.fromCell(try result.toJSString(globalThis))) orelse .jsUndefined(); if (globalThis.hasException()) return .zero; // no partial match for this case @@ -2325,10 +2319,8 @@ pub const Expect = struct { const _received_message: ?JSValue = if (result.isObject()) result.fastGet(globalThis, .message) - else if (result.toStringOrNull(globalThis)) |js_str| - JSValue.fromCell(js_str) else - null; + JSValue.fromCell(try result.toJSString(globalThis)); if (expected_value.isString()) { if (_received_message) |received_message| { @@ -5676,13 +5668,13 @@ pub const ExpectMatcherUtils = struct { is_not = val.coerce(bool, globalThis); } if (try options.get(globalThis, "comment")) |val| { - comment = val.toStringOrNull(globalThis); + comment = try val.toJSString(globalThis); } if (try options.get(globalThis, "promise")) |val| { - promise = val.toStringOrNull(globalThis); + promise = try val.toJSString(globalThis); } if (try options.get(globalThis, "secondArgument")) |val| { - second_argument = val.toStringOrNull(globalThis); + second_argument = try val.toJSString(globalThis); } } diff --git a/src/deps/libuv.zig b/src/deps/libuv.zig index 3ab0540dbc..234583e9b7 100644 --- a/src/deps/libuv.zig +++ b/src/deps/libuv.zig @@ -2826,7 +2826,7 @@ pub const ReturnCode = enum(c_int) { return null; } - pub inline fn errno(this: ReturnCode) ?@TypeOf(@intFromEnum(bun.sys.E.ACCES)) { + pub inline fn errno(this: ReturnCode) ?u16 { return if (this.int() < 0) switch (this.int()) { UV_EPERM => @intFromEnum(bun.sys.E.PERM), diff --git a/src/deps/uws.zig b/src/deps/uws.zig index 40dccf2121..97751a9e45 100644 --- a/src/deps/uws.zig +++ b/src/deps/uws.zig @@ -1241,30 +1241,41 @@ pub const InternalSocket = union(enum) { pub fn NewSocketHandler(comptime is_ssl: bool) type { return struct { const ssl_int: i32 = @intFromBool(is_ssl); + socket: InternalSocket, + const ThisSocket = @This(); + pub const detached: NewSocketHandler(is_ssl) = NewSocketHandler(is_ssl){ .socket = .{ .detached = {} } }; + pub fn setNoDelay(this: ThisSocket, enabled: bool) bool { return this.socket.setNoDelay(enabled); } + pub fn setKeepAlive(this: ThisSocket, enabled: bool, delay: u32) bool { return this.socket.setKeepAlive(enabled, delay); } + pub fn pauseStream(this: ThisSocket) bool { return this.socket.pauseResume(is_ssl, true); } + pub fn resumeStream(this: ThisSocket) bool { return this.socket.pauseResume(is_ssl, false); } + pub fn detach(this: *ThisSocket) void { this.socket.detach(); } + pub fn isDetached(this: ThisSocket) bool { return this.socket.isDetached(); } + pub fn isNamedPipe(this: ThisSocket) bool { return this.socket.isNamedPipe(); } + pub fn verifyError(this: ThisSocket) us_bun_verify_error_t { switch (this.socket) { .connected => |socket| return uws.us_socket_verify_error(comptime ssl_int, socket), @@ -1562,6 +1573,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { .connecting, .detached => 0, }; } + pub fn rawWrite(this: ThisSocket, data: []const u8, msg_more: bool) i32 { return switch (this.socket) { .connected => |socket| socket.rawWrite(is_ssl, data, msg_more), @@ -1570,6 +1582,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { .pipe => |pipe| if (comptime Environment.isWindows) pipe.rawWrite(data, msg_more) else 0, }; } + pub fn shutdown(this: ThisSocket) void { switch (this.socket) { .connected => |socket| socket.shutdown(is_ssl), @@ -1659,6 +1672,7 @@ pub fn NewSocketHandler(comptime is_ssl: bool) type { pub fn close(this: ThisSocket, code: Socket.CloseCode) void { return this.socket.close(comptime is_ssl, code); } + pub fn localPort(this: ThisSocket) i32 { return switch (this.socket) { .connected => |socket| socket.localPort(is_ssl), diff --git a/src/errno/darwin_errno.zig b/src/errno/darwin_errno.zig index 9b59aaf251..b254f4a542 100644 --- a/src/errno/darwin_errno.zig +++ b/src/errno/darwin_errno.zig @@ -2,7 +2,7 @@ pub const Mode = std.posix.mode_t; pub const E = std.posix.E; pub const S = std.posix.S; -pub const SystemErrno = enum(u8) { +pub const SystemErrno = enum(u16) { SUCCESS = 0, EPERM = 1, ENOENT = 2, diff --git a/src/errno/linux_errno.zig b/src/errno/linux_errno.zig index e1bdccdd4b..22ab85ce21 100644 --- a/src/errno/linux_errno.zig +++ b/src/errno/linux_errno.zig @@ -1,7 +1,7 @@ pub const Mode = std.posix.mode_t; pub const E = std.posix.E; pub const S = std.posix.S; -pub const SystemErrno = enum(u8) { +pub const SystemErrno = enum(u16) { SUCCESS = 0, EPERM = 1, ENOENT = 2, diff --git a/src/js/internal/streams/state.ts b/src/js/internal/streams/state.ts index 061db9ec40..7bdb008096 100644 --- a/src/js/internal/streams/state.ts +++ b/src/js/internal/streams/state.ts @@ -18,7 +18,7 @@ function highWaterMarkFrom( return options.highWaterMark != null ? options.highWaterMark : isDuplex ? options[duplexKey] : null; } -function getDefaultHighWaterMark(objectMode: boolean): number { +function getDefaultHighWaterMark(objectMode?: boolean): number { return objectMode ? defaultHighWaterMarkObjectMode : defaultHighWaterMarkBytes; } diff --git a/src/js/internal/streams/utils.ts b/src/js/internal/streams/utils.ts index 12f0e9ff3d..3e11425e08 100644 --- a/src/js/internal/streams/utils.ts +++ b/src/js/internal/streams/utils.ts @@ -158,7 +158,7 @@ function isWritable(stream) { return isWritableNodeStream(stream) && stream.writable && !isWritableEnded(stream); } -function isFinished(stream, opts) { +function isFinished(stream, opts?) { if (!isNodeStream(stream)) { return null; } diff --git a/src/js/node/child_process.ts b/src/js/node/child_process.ts index a66a7f0fee..a0692919c5 100644 --- a/src/js/node/child_process.ts +++ b/src/js/node/child_process.ts @@ -1172,7 +1172,7 @@ class ChildProcess extends EventEmitter { if (!NetModule) NetModule = require("node:net"); const fd = handle && handle.stdio[i]; if (!fd) return null; - return new NetModule.connect({ fd }); + return NetModule.connect({ fd }); } return null; } diff --git a/src/js/node/dns.ts b/src/js/node/dns.ts index c6e6ca7704..42b747c690 100644 --- a/src/js/node/dns.ts +++ b/src/js/node/dns.ts @@ -645,9 +645,7 @@ var InternalResolver = class Resolver { function Resolver(options) { return new InternalResolver(options); } -Resolver.prototype = {}; -Object.setPrototypeOf(Resolver.prototype, InternalResolver.prototype); -Object.setPrototypeOf(Resolver, InternalResolver); +$toClass(Resolver, "Resolver", InternalResolver); var { resolve, diff --git a/src/semver/SemverObject.zig b/src/semver/SemverObject.zig index b341b0d2b4..c17598d8e0 100644 --- a/src/semver/SemverObject.zig +++ b/src/semver/SemverObject.zig @@ -45,8 +45,8 @@ pub fn order( const left_arg = arguments[0]; const right_arg = arguments[1]; - const left_string = left_arg.toStringOrNull(globalThis) orelse return JSC.jsNumber(0); - const right_string = right_arg.toStringOrNull(globalThis) orelse return JSC.jsNumber(0); + const left_string = try left_arg.toJSString(globalThis); + const right_string = try right_arg.toJSString(globalThis); const left = left_string.toSlice(globalThis, allocator); defer left.deinit(); @@ -91,8 +91,8 @@ pub fn satisfies(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame) bun const left_arg = arguments[0]; const right_arg = arguments[1]; - const left_string = left_arg.toStringOrNull(globalThis) orelse return .zero; - const right_string = right_arg.toStringOrNull(globalThis) orelse return .zero; + const left_string = try left_arg.toJSString(globalThis); + const right_string = try right_arg.toJSString(globalThis); const left = left_string.toSlice(globalThis, allocator); defer left.deinit(); diff --git a/src/sys.zig b/src/sys.zig index 5f142004c7..0666a5e5d2 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -331,7 +331,7 @@ pub const Error = struct { const todo_errno = std.math.maxInt(Int) - 1; - pub const Int = if (Environment.isWindows) u16 else u8; // @TypeOf(@intFromEnum(E.BADF)); + pub const Int = u16; /// TODO: convert to function pub const oom = fromCode(E.NOMEM, .read);