diff --git a/scripts/runner.node.mjs b/scripts/runner.node.mjs index 2aaaa179d6..bd24218397 100755 --- a/scripts/runner.node.mjs +++ b/scripts/runner.node.mjs @@ -245,7 +245,7 @@ const shouldValidateExceptions = (() => { } skipArray = readFileSync(path, "utf-8") .split("\n") - .filter(line => !line.startsWith("#")); + .filter(line => !line.startsWith("#") && line.length > 0); } return !(skipArray.includes(test) || skipArray.includes("test/" + test)); }; diff --git a/src/bun.js/ConsoleObject.zig b/src/bun.js/ConsoleObject.zig index 90891e020b..5ec6dbcf6d 100644 --- a/src/bun.js/ConsoleObject.zig +++ b/src/bun.js/ConsoleObject.zig @@ -767,7 +767,7 @@ pub const FormatOptions = struct { } formatOptions.max_depth = @as(u16, @truncate(@as(u32, @intCast(@min(arg, std.math.maxInt(u16)))))); } else if (opt.isNumber()) { - const v = opt.coerce(f64, globalThis); + const v = try opt.coerce(f64, globalThis); if (std.math.isInf(v)) { formatOptions.max_depth = std.math.maxInt(u16); } else { @@ -795,7 +795,7 @@ pub const FormatOptions = struct { } formatOptions.max_depth = @as(u16, @truncate(@as(u32, @intCast(@min(arg, std.math.maxInt(u16)))))); } else if (depthArg.isNumber()) { - const v = depthArg.coerce(f64, globalThis); + const v = try depthArg.coerce(f64, globalThis); if (std.math.isInf(v)) { formatOptions.max_depth = std.math.maxInt(u16); } else { @@ -803,10 +803,7 @@ pub const FormatOptions = struct { } } if (arguments.len > 1 and !arguments[1].isEmptyOrUndefinedOrNull()) { - formatOptions.enable_colors = arguments[1].coerce(bool, globalThis); - if (globalThis.hasException()) { - return error.JSError; - } + formatOptions.enable_colors = arguments[1].toBoolean(); } } } @@ -2044,7 +2041,6 @@ pub const Formatter = struct { depth: u32, max_depth: u32, colors: bool, - is_exception: *bool, ) JSValue; pub fn printAs( @@ -2176,7 +2172,7 @@ pub const Formatter = struct { } }, .Integer => { - const int = value.coerce(i64, this.globalThis); + const int = try value.coerce(i64, this.globalThis); if (int < std.math.maxInt(u32)) { var i = int; const is_negative = i < 0; @@ -2251,21 +2247,16 @@ pub const Formatter = struct { writer.print(comptime Output.prettyFmt("null", enable_ansi_colors), .{}); }, .CustomFormattedObject => { - var is_exception = false; // Call custom inspect function. Will return the error if there is one // we'll need to pass the callback through to the "this" value in here - const result = JSC__JSValue__callCustomInspectFunction( + const result = try bun.jsc.fromJSHostCall(this.globalThis, @src(), JSC__JSValue__callCustomInspectFunction, .{ this.globalThis, this.custom_formatted_object.function, this.custom_formatted_object.this, this.max_depth -| this.depth, this.max_depth, enable_ansi_colors, - &is_exception, - ); - if (is_exception) { - return error.JSError; - } + }); // Strings are printed directly, otherwise we recurse. It is possible to end up in an infinite loop. if (result.isString()) { writer.print("{}", .{result.fmtString(this.globalThis)}); diff --git a/src/bun.js/ModuleLoader.zig b/src/bun.js/ModuleLoader.zig index 5154d9c3e5..2a9af6ece3 100644 --- a/src/bun.js/ModuleLoader.zig +++ b/src/bun.js/ModuleLoader.zig @@ -1358,7 +1358,7 @@ pub fn transpileSourceCode( globalValue.put( globalThis, ZigString.static("wasmSourceBytes"), - JSC.ArrayBuffer.create(globalThis, source.contents, .Uint8Array), + try JSC.ArrayBuffer.create(globalThis, source.contents, .Uint8Array), ); } } diff --git a/src/bun.js/VirtualMachine.zig b/src/bun.js/VirtualMachine.zig index ac4a53f840..09de65cc5b 100644 --- a/src/bun.js/VirtualMachine.zig +++ b/src/bun.js/VirtualMachine.zig @@ -3602,7 +3602,7 @@ pub const ExitHandler = struct { pub fn dispatchOnBeforeExit(this: *ExitHandler) void { JSC.markBinding(@src()); const vm: *VirtualMachine = @alignCast(@fieldParentPtr("exit_handler", this)); - Process__dispatchOnBeforeExit(vm.global, this.exit_code); + bun.jsc.fromJSHostCallVoid(vm.global, @src(), Process__dispatchOnBeforeExit, .{ vm.global, this.exit_code }) catch return; } }; diff --git a/src/bun.js/api/BunObject.zig b/src/bun.js/api/BunObject.zig index 7263c2ccec..c4f3b4e255 100644 --- a/src/bun.js/api/BunObject.zig +++ b/src/bun.js/api/BunObject.zig @@ -762,7 +762,7 @@ pub fn sleepSync(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b } //NOTE: if argument is > max(i32) then it will be truncated - const milliseconds = arg.coerce(i32, globalObject); + const milliseconds = try arg.coerce(i32, globalObject); if (milliseconds < 0) { return globalObject.throwInvalidArguments("argument to sleepSync must not be negative, got {d}", .{milliseconds}); } @@ -1184,7 +1184,6 @@ pub fn allocUnsafe(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b if (!size.isUInt32AsAnyInt()) { return globalThis.throwInvalidArguments("Expected a positive number", .{}); } - return JSC.JSValue.createUninitializedUint8Array(globalThis, size.toUInt64NoTruncate()); } @@ -1249,7 +1248,7 @@ pub fn mmapFile(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun. .result => |map| map, .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, }; @@ -1507,21 +1506,21 @@ pub const JSZlib = struct { var library: Library = .zlib; if (options_val_) |options_val| { if (try options_val.get(globalThis, "windowBits")) |window| { - opts.windowBits = window.coerce(i32, globalThis); + opts.windowBits = try window.coerce(i32, globalThis); library = .zlib; } if (try options_val.get(globalThis, "level")) |level| { - opts.level = level.coerce(i32, globalThis); + opts.level = try level.coerce(i32, globalThis); } if (try options_val.get(globalThis, "memLevel")) |memLevel| { - opts.memLevel = memLevel.coerce(i32, globalThis); + opts.memLevel = try memLevel.coerce(i32, globalThis); library = .zlib; } if (try options_val.get(globalThis, "strategy")) |strategy| { - opts.strategy = strategy.coerce(i32, globalThis); + opts.strategy = try strategy.coerce(i32, globalThis); library = .zlib; } @@ -1633,7 +1632,7 @@ pub const JSZlib = struct { if (options_val_) |options_val| { if (try options_val.get(globalThis, "windowBits")) |window| { - windowBits = window.coerce(i32, globalThis); + windowBits = try window.coerce(i32, globalThis); library = .zlib; } @@ -1648,7 +1647,7 @@ pub const JSZlib = struct { } if (try options_val.get(globalThis, "level")) |level_value| { - level = level_value.coerce(i32, globalThis); + level = try level_value.coerce(i32, globalThis); if (globalThis.hasException()) return .zero; } } @@ -1749,7 +1748,7 @@ pub const JSZstd = struct { fn getLevel(globalThis: *JSGlobalObject, options_val: ?JSValue) bun.JSError!i32 { if (options_val) |option_obj| { if (try option_obj.get(globalThis, "level")) |level_val| { - const value = level_val.coerce(i32, globalThis); + const value = try level_val.coerce(i32, globalThis); if (globalThis.hasException()) return error.JSError; if (value < 1 or value > 22) { @@ -1948,15 +1947,6 @@ pub const JSZstd = struct { const output_slice = this.output; const buffer_value = JSC.JSValue.createBuffer(globalThis, output_slice, bun.default_allocator); - if (globalThis.hasException()) { - promise.reject(globalThis, error.JSError); - return; - } - if (buffer_value == .zero) { - promise.reject(globalThis, ZigString.init("Failed to create buffer").toErrorInstance(globalThis)); - return; - } - this.output = &[_]u8{}; promise.resolve(globalThis, buffer_value); } diff --git a/src/bun.js/api/FFIObject.zig b/src/bun.js/api/FFIObject.zig index dcd733ac58..0f32dab42b 100644 --- a/src/bun.js/api/FFIObject.zig +++ b/src/bun.js/api/FFIObject.zig @@ -546,7 +546,7 @@ pub fn toBuffer( valueLength: ?JSValue, finalizationCtxOrPtr: ?JSValue, finalizationCallback: ?JSValue, -) JSC.JSValue { +) bun.JSError!JSC.JSValue { switch (getPtrSlice(globalThis, value, byteOffset, valueLength)) { .err => |err| { return err; diff --git a/src/bun.js/api/JSTranspiler.zig b/src/bun.js/api/JSTranspiler.zig index b9a7dbdcd0..88486f25a9 100644 --- a/src/bun.js/api/JSTranspiler.zig +++ b/src/bun.js/api/JSTranspiler.zig @@ -486,7 +486,7 @@ fn transformOptionsFromJSC(globalObject: *JSC.JSGlobalObject, temp_allocator: st if (try object.getTruthy(globalThis, "minify")) |minify| { if (minify.isBoolean()) { - transpiler.minify_whitespace = minify.coerce(bool, globalThis); + transpiler.minify_whitespace = minify.toBoolean(); transpiler.minify_syntax = transpiler.minify_whitespace; transpiler.minify_identifiers = transpiler.minify_syntax; } else if (minify.isObject()) { diff --git a/src/bun.js/api/UnsafeObject.zig b/src/bun.js/api/UnsafeObject.zig index a9f66fb954..a7568d8766 100644 --- a/src/bun.js/api/UnsafeObject.zig +++ b/src/bun.js/api/UnsafeObject.zig @@ -23,7 +23,7 @@ pub fn gcAggressionLevel( const value = callframe.arguments_old(1).ptr[0]; if (!value.isEmptyOrUndefinedOrNull()) { - switch (value.coerce(i32, globalThis)) { + switch (try value.coerce(i32, globalThis)) { 1 => globalThis.bunVM().aggressive_garbage_collection = .mild, 2 => globalThis.bunVM().aggressive_garbage_collection = .aggressive, 0 => globalThis.bunVM().aggressive_garbage_collection = .none, diff --git a/src/bun.js/api/bun/h2_frame_parser.zig b/src/bun.js/api/bun/h2_frame_parser.zig index 14352b7246..44eb029494 100644 --- a/src/bun.js/api/bun/h2_frame_parser.zig +++ b/src/bun.js/api/bun/h2_frame_parser.zig @@ -1384,7 +1384,10 @@ pub const H2FrameParser = struct { if (debug_data.len > 0) { _ = this.write(debug_data); } - const chunk = this.handlers.binary_type.toJS(debug_data, this.handlers.globalObject); + const chunk = this.handlers.binary_type.toJS(debug_data, this.handlers.globalObject) catch |err| { + this.dispatch(.onError, this.globalThis.takeException(err)); + return; + }; if (emitError) { if (rstCode != .NO_ERROR) { @@ -1688,7 +1691,7 @@ pub const H2FrameParser = struct { this.writeBuffer.clearRetainingCapacity(); } } - const output_value = this.handlers.binary_type.toJS(bytes, this.handlers.globalObject); + const output_value = this.handlers.binary_type.toJS(bytes, this.handlers.globalObject) catch .zero; // TODO: properly propagate exception upwards const result = this.call(.onWrite, output_value); if (result.isBoolean() and !result.toBoolean()) { this.has_nonnative_backpressure = true; @@ -1721,7 +1724,7 @@ pub const H2FrameParser = struct { return false; } // fallback to onWrite non-native callback - const output_value = this.handlers.binary_type.toJS(bytes, this.handlers.globalObject); + const output_value = this.handlers.binary_type.toJS(bytes, this.handlers.globalObject) catch .zero; // TODO: properly propagate exception upwards const result = this.call(.onWrite, output_value); const code = if (result.isNumber()) result.to(i32) else -1; switch (code) { @@ -2000,7 +2003,7 @@ pub const H2FrameParser = struct { data_needed -= padding; log("data received {} {}", .{ padding, payload.len }); payload = payload[0..@min(@as(usize, @intCast(data_needed)), payload.len)]; - const chunk = this.handlers.binary_type.toJS(payload, this.handlers.globalObject); + const chunk = this.handlers.binary_type.toJS(payload, this.handlers.globalObject) catch .zero; // TODO: properly propagate exception upwards // its fine to truncate because is not possible to receive more data than u32 here, usize is only because of slices in size this.ajustWindowSize(stream, @truncate(payload.len)); this.dispatchWithExtra(.onStreamData, stream.getIdentifier(), chunk); @@ -2048,7 +2051,7 @@ pub const H2FrameParser = struct { if (handleIncommingPayload(this, data, frame.streamIdentifier)) |content| { const payload = content.data; const error_code = u32FromBytes(payload[4..8]); - const chunk = this.handlers.binary_type.toJS(payload[8..], this.handlers.globalObject); + const chunk = this.handlers.binary_type.toJS(payload[8..], this.handlers.globalObject) catch .zero; // TODO: properly propagate exception upwards this.readBuffer.reset(); this.dispatchWith2Extra(.onGoAway, JSC.JSValue.jsNumber(error_code), JSC.JSValue.jsNumber(this.lastStreamID), chunk); return content.end; @@ -2207,7 +2210,7 @@ pub const H2FrameParser = struct { } else { this.outStandingPings -|= 1; } - const buffer = this.handlers.binary_type.toJS(payload, this.handlers.globalObject); + const buffer = this.handlers.binary_type.toJS(payload, this.handlers.globalObject) catch .zero; // TODO: properly propagate exception upwards this.dispatchWithExtra(.onPing, buffer, JSC.JSValue.jsBoolean(!isNotACK)); return content.end; } @@ -4109,7 +4112,7 @@ pub const H2FrameParser = struct { this.rejectedStreams += 1; this.dispatchWithExtra(.onStreamError, stream.getIdentifier(), JSC.JSValue.jsNumber(stream.rstCode)); if (this.rejectedStreams >= this.maxRejectedStreams) { - const chunk = this.handlers.binary_type.toJS("ENHANCE_YOUR_CALM", this.handlers.globalObject); + const chunk = try this.handlers.binary_type.toJS("ENHANCE_YOUR_CALM", this.handlers.globalObject); this.dispatchWith2Extra(.onError, JSC.JSValue.jsNumber(@intFromEnum(ErrorCode.ENHANCE_YOUR_CALM)), JSC.JSValue.jsNumber(this.lastStreamID), chunk); } return JSC.JSValue.jsNumber(stream_id); diff --git a/src/bun.js/api/bun/socket.zig b/src/bun.js/api/bun/socket.zig index cfb171112d..d885173533 100644 --- a/src/bun.js/api/bun/socket.zig +++ b/src/bun.js/api/bun/socket.zig @@ -190,7 +190,7 @@ pub fn NewSocket(comptime ssl: bool) type { const enabled: bool = brk: { if (args.len >= 1) { - break :brk args.ptr[0].coerce(bool, globalThis); + break :brk args.ptr[0].toBoolean(); } break :brk false; }; @@ -208,11 +208,12 @@ pub fn NewSocket(comptime ssl: bool) type { pub fn setNoDelay(this: *This, globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSValue { JSC.markBinding(@src()); + _ = globalThis; const args = callframe.arguments_old(1); const enabled: bool = brk: { if (args.len >= 1) { - break :brk args.ptr[0].coerce(bool, globalThis); + break :brk args.ptr[0].toBoolean(); } break :brk true; }; @@ -639,7 +640,7 @@ pub fn NewSocket(comptime ssl: bool) type { var js_error: JSValue = .js_undefined; if (err != 0) { // errors here are always a read error - js_error = bun.sys.Error.fromCodeInt(err, .read).toJSC(globalObject); + js_error = bun.sys.Error.fromCodeInt(err, .read).toJS(globalObject); } _ = callback.call(globalObject, this_value, &[_]JSValue{ @@ -665,7 +666,10 @@ pub fn NewSocket(comptime ssl: bool) type { const globalObject = handlers.globalObject; const this_value = this.getThisValue(globalObject); - const output_value = handlers.binary_type.toJS(data, globalObject); + const output_value = handlers.binary_type.toJS(data, globalObject) catch |err| { + this.handleError(globalObject.takeException(err)); + return; + }; // the handlers must be kept alive for the duration of the function call // that way if we need to call the error handler, we can @@ -726,7 +730,7 @@ pub fn NewSocket(comptime ssl: bool) type { if (args.len == 0) { return globalObject.throw("Expected 1 argument, got 0", .{}); } - const t = args.ptr[0].coerce(i32, globalObject); + const t = try args.ptr[0].coerce(i32, globalObject); if (t < 0) { return globalObject.throw("Timeout must be a positive integer", .{}); } @@ -2070,7 +2074,7 @@ pub fn jsCreateSocketPair(global: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JS const rc = std.c.socketpair(std.posix.AF.UNIX, std.posix.SOCK.STREAM, 0, &fds_); if (rc != 0) { const err = bun.sys.Error.fromCode(bun.sys.getErrno(rc), .socketpair); - return global.throwValue(err.toJSC(global)); + return global.throwValue(err.toJS(global)); } _ = bun.FD.fromNative(fds_[0]).updateNonblocking(true); @@ -2102,12 +2106,12 @@ pub fn jsSetSocketOptions(global: *JSC.JSGlobalObject, callframe: *JSC.CallFrame if (is_for_send_buffer) { const result = bun.sys.setsockopt(file_descriptor, std.posix.SOL.SOCKET, std.posix.SO.SNDBUF, buffer_size); if (result.asErr()) |err| { - return global.throwValue(err.toJSC(global)); + return global.throwValue(err.toJS(global)); } } else if (is_for_recv_buffer) { const result = bun.sys.setsockopt(file_descriptor, std.posix.SOL.SOCKET, std.posix.SO.RCVBUF, buffer_size); if (result.asErr()) |err| { - return global.throwValue(err.toJSC(global)); + return global.throwValue(err.toJS(global)); } } } diff --git a/src/bun.js/api/bun/socket/WindowsNamedPipeContext.zig b/src/bun.js/api/bun/socket/WindowsNamedPipeContext.zig index d7ce4c6cf7..94d8db186f 100644 --- a/src/bun.js/api/bun/socket/WindowsNamedPipeContext.zig +++ b/src/bun.js/api/bun/socket/WindowsNamedPipeContext.zig @@ -99,10 +99,10 @@ fn onError(this: *WindowsNamedPipeContext, err: bun.sys.Error) void { if (this.is_open) { switch (this.socket) { .tls => |tls| { - tls.handleError(err.toJSC(this.globalThis)); + tls.handleError(err.toJS(this.globalThis)); }, .tcp => |tcp| { - tcp.handleError(err.toJSC(this.globalThis)); + tcp.handleError(err.toJS(this.globalThis)); }, else => {}, } diff --git a/src/bun.js/api/bun/subprocess.zig b/src/bun.js/api/bun/subprocess.zig index 428ac48320..3cfd6ca3c9 100644 --- a/src/bun.js/api/bun/subprocess.zig +++ b/src/bun.js/api/bun/subprocess.zig @@ -608,7 +608,7 @@ pub fn asyncDispose( .result => {}, .err => |err| { // Signal 9 should always be fine, but just in case that somehow fails. - return global.throwValue(err.toJSC(global)); + return global.throwValue(err.toJS(global)); }, } @@ -695,7 +695,7 @@ pub fn kill( .result => {}, .err => |err| { // EINVAL or ENOSYS means the signal is not supported in the current platform (most likely unsupported on windows) - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, } @@ -1602,7 +1602,7 @@ pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Sta switch (status) { .exited => |exited| promise.asAnyPromise().?.resolve(globalThis, JSValue.jsNumber(exited.code)), - .err => |err| promise.asAnyPromise().?.reject(globalThis, err.toJSC(globalThis)), + .err => |err| promise.asAnyPromise().?.reject(globalThis, err.toJS(globalThis)), .signaled => promise.asAnyPromise().?.resolve(globalThis, JSValue.jsNumber(128 +% @intFromEnum(status.signaled))), else => { // crash in debug mode @@ -1615,7 +1615,7 @@ pub fn onProcessExit(this: *Subprocess, process: *Process, status: bun.spawn.Sta if (consumeOnExitCallback(this_jsvalue, globalThis)) |callback| { const waitpid_value: JSValue = if (status == .err) - status.err.toJSC(globalThis) + status.err.toJS(globalThis) else .js_undefined; @@ -1757,7 +1757,7 @@ pub fn getExited( return JSC.JSPromise.resolvedPromiseValue(globalThis, JSValue.jsNumber(signal.toExitCode() orelse 254)); }, .err => |err| { - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); }, else => { const promise = JSC.JSPromise.create(globalThis).toJS(); @@ -2139,7 +2139,7 @@ pub fn spawnMaybeSync( if (try args.get(globalThis, "maxBuffer")) |val| { if (val.isNumber() and val.isFinite()) { // 'Infinity' does not set maxBuffer - const value = val.coerce(i64, globalThis); + const value = try val.coerce(i64, globalThis); if (value > 0) { maxBuffer = value; } @@ -2322,7 +2322,7 @@ pub fn spawnMaybeSync( else => {}, } - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, .result => |result| result, }; @@ -2434,7 +2434,7 @@ pub fn spawnMaybeSync( subprocess.stdio_pipes.items[@intCast(ipc_channel)].buffer, ).asErr()) |err| { subprocess.deref(); - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); } subprocess.stdio_pipes.items[@intCast(ipc_channel)] = .unavailable; } diff --git a/src/bun.js/api/bun/udp_socket.zig b/src/bun.js/api/bun/udp_socket.zig index d6ae1e3765..80294f58de 100644 --- a/src/bun.js/api/bun/udp_socket.zig +++ b/src/bun.js/api/bun/udp_socket.zig @@ -106,7 +106,7 @@ fn onData(socket: *uws.udp.Socket, buf: *uws.udp.PacketBuffer, packets: c_int) c _ = callback.call(globalThis, udpSocket.thisValue, &.{ udpSocket.thisValue, - udpSocket.config.binary_type.toJS(slice, globalThis), + udpSocket.config.binary_type.toJS(slice, globalThis) catch return, // TODO: properly propagate exception upwards JSC.jsNumber(port), hostname_string.transferToJS(globalThis), }) catch |err| { @@ -354,11 +354,11 @@ pub const UDPSocket = struct { const ret = this.socket.connect(connect.address, connect.port); if (ret != 0) { if (JSC.Maybe(void).errnoSys(ret, .connect)) |sys_err| { - return globalThis.throwValue(sys_err.toJS(globalThis)); + return globalThis.throwValue(try sys_err.toJS(globalThis)); } if (bun.c_ares.Error.initEAI(ret)) |eai_err| { - return globalThis.throwValue(eai_err.toJS(globalThis)); + return globalThis.throwValue(eai_err.toJSWithSyscallAndHostname(globalThis, "connect", connect.address)); } } this.connect_info = .{ .port = connect.port }; @@ -393,7 +393,7 @@ pub const UDPSocket = struct { pub fn setBroadcast(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -405,7 +405,7 @@ pub const UDPSocket = struct { const res = this.socket.setBroadcast(enabled); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return arguments[0]; @@ -413,7 +413,7 @@ pub const UDPSocket = struct { pub fn setMulticastLoopback(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -425,7 +425,7 @@ pub const UDPSocket = struct { const res = this.socket.setMulticastLoopback(enabled); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return arguments[0]; @@ -433,7 +433,7 @@ pub const UDPSocket = struct { fn setMembership(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame, drop: bool) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -443,7 +443,7 @@ pub const UDPSocket = struct { var addr = std.mem.zeroes(std.posix.sockaddr.storage); if (!parseAddr(this, globalThis, JSC.jsNumber(0), arguments[0], &addr)) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); } var interface = std.mem.zeroes(std.posix.sockaddr.storage); @@ -456,7 +456,7 @@ pub const UDPSocket = struct { } else this.socket.setMembership(&addr, null, drop); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return .true; @@ -472,7 +472,7 @@ pub const UDPSocket = struct { fn setSourceSpecificMembership(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame, drop: bool) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -482,12 +482,12 @@ pub const UDPSocket = struct { var source_addr: std.posix.sockaddr.storage = undefined; if (!parseAddr(this, globalThis, JSC.jsNumber(0), arguments[0], &source_addr)) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); } var group_addr: std.posix.sockaddr.storage = undefined; if (!parseAddr(this, globalThis, JSC.jsNumber(0), arguments[1], &group_addr)) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.INVAL))), .setsockopt).?.toJS(globalThis)); } if (source_addr.family != group_addr.family) { @@ -504,7 +504,7 @@ pub const UDPSocket = struct { } else this.socket.setSourceSpecificMembership(&source_addr, &group_addr, null, drop); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return .true; @@ -520,7 +520,7 @@ pub const UDPSocket = struct { pub fn setMulticastInterface(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -537,7 +537,7 @@ pub const UDPSocket = struct { const res = this.socket.setMulticastInterface(&addr); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return .true; @@ -576,7 +576,7 @@ pub const UDPSocket = struct { fn setAnyTTL(this: *This, globalThis: *JSGlobalObject, callframe: *CallFrame, comptime function: fn (*uws.udp.Socket, i32) c_int) bun.JSError!JSValue { if (this.closed) { - return globalThis.throwValue(bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); + return globalThis.throwValue(try bun.JSC.Maybe(void).errnoSys(@as(i32, @intCast(@intFromEnum(std.posix.E.BADF))), .setsockopt).?.toJS(globalThis)); } const arguments = callframe.arguments(); @@ -588,7 +588,7 @@ pub const UDPSocket = struct { const res = function(this.socket, ttl); if (getUSError(res, .setsockopt, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return JSValue.jsNumber(ttl); @@ -666,7 +666,7 @@ pub const UDPSocket = struct { } const res = this.socket.send(payloads, lens, addr_ptrs); if (getUSError(res, .send, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return JSValue.jsNumber(res); } @@ -724,7 +724,7 @@ pub const UDPSocket = struct { const res = this.socket.send(&.{payload.ptr}, &.{payload.len}, &.{addr_ptr}); if (getUSError(res, .send, true)) |err| { - return globalThis.throwValue(err.toJS(globalThis)); + return globalThis.throwValue(try err.toJS(globalThis)); } return JSValue.jsBoolean(res > 0); } diff --git a/src/bun.js/api/crypto/CryptoHasher.zig b/src/bun.js/api/crypto/CryptoHasher.zig index f7bd57e3ee..3f4e97e898 100644 --- a/src/bun.js/api/crypto/CryptoHasher.zig +++ b/src/bun.js/api/crypto/CryptoHasher.zig @@ -839,7 +839,7 @@ fn StaticCryptoHasher(comptime Hasher: type, comptime name: [:0]const u8) type { } } - fn digestToEncoding(this: *@This(), globalThis: *JSGlobalObject, encoding: JSC.Node.Encoding) JSC.JSValue { + fn digestToEncoding(this: *@This(), globalThis: *JSGlobalObject, encoding: JSC.Node.Encoding) bun.JSError!JSC.JSValue { var output_digest_buf: Hasher.Digest = comptime brk: { var bytes: Hasher.Digest = undefined; var i: usize = 0; diff --git a/src/bun.js/api/crypto/PBKDF2.zig b/src/bun.js/api/crypto/PBKDF2.zig index 101fa7a512..e4764d2aba 100644 --- a/src/bun.js/api/crypto/PBKDF2.zig +++ b/src/bun.js/api/crypto/PBKDF2.zig @@ -76,11 +76,6 @@ pub const Job = struct { const output_slice = this.output; assert(output_slice.len == @as(usize, @intCast(this.pbkdf2.length))); const buffer_value = JSC.JSValue.createBuffer(globalThis, output_slice, bun.default_allocator); - if (buffer_value == .zero) { - promise.reject(globalThis, ZigString.init("Failed to create buffer").toErrorInstance(globalThis)); - return; - } - this.output = &[_]u8{}; promise.resolve(globalThis, buffer_value); } @@ -149,7 +144,7 @@ pub fn fromJS(globalThis: *JSC.JSGlobalObject, callFrame: *JSC.CallFrame, is_asy return globalThis.throwInvalidArgumentTypeValue("iterations", "number", arg2); } - const iteration_count = arg2.coerce(i64, globalThis); + const iteration_count = try arg2.coerce(i64, globalThis); if (!globalThis.hasException() and (iteration_count < 1 or iteration_count > std.math.maxInt(i32))) { return globalThis.throwRangeError(iteration_count, .{ .field_name = "iterations", .min = 1, .max = std.math.maxInt(i32) + 1 }); diff --git a/src/bun.js/api/crypto/PasswordObject.zig b/src/bun.js/api/crypto/PasswordObject.zig index 559a4e3011..273f768be9 100644 --- a/src/bun.js/api/crypto/PasswordObject.zig +++ b/src/bun.js/api/crypto/PasswordObject.zig @@ -41,7 +41,7 @@ pub const PasswordObject = struct { return globalObject.throwInvalidArgumentType("hash", "cost", "number"); } - const rounds = rounds_value.coerce(i32, globalObject); + const rounds = try rounds_value.coerce(i32, globalObject); if (rounds < 4 or rounds > 31) { return globalObject.throwInvalidArguments("Rounds must be between 4 and 31", .{}); @@ -60,7 +60,7 @@ pub const PasswordObject = struct { return globalObject.throwInvalidArgumentType("hash", "timeCost", "number"); } - const time_cost = time_value.coerce(i32, globalObject); + const time_cost = try time_value.coerce(i32, globalObject); if (time_cost < 1) { return globalObject.throwInvalidArguments("Time cost must be greater than 0", .{}); @@ -74,7 +74,7 @@ pub const PasswordObject = struct { return globalObject.throwInvalidArgumentType("hash", "memoryCost", "number"); } - const memory_cost = memory_value.coerce(i32, globalObject); + const memory_cost = try memory_value.coerce(i32, globalObject); if (memory_cost < 1) { return globalObject.throwInvalidArguments("Memory cost must be greater than 0", .{}); diff --git a/src/bun.js/api/glob.zig b/src/bun.js/api/glob.zig index 8d49134623..1a6f223b81 100644 --- a/src/bun.js/api/glob.zig +++ b/src/bun.js/api/glob.zig @@ -58,7 +58,7 @@ const ScanOpts = struct { const cwd = switch (bun.sys.getcwd((&path_buf))) { .result => |cwd| cwd, .err => |err| { - const errJs = err.toJSC(globalThis); + const errJs = err.toJS(globalThis); return globalThis.throwValue(errJs); }, }; @@ -150,9 +150,9 @@ pub const WalkTask = struct { syscall: Syscall.Error, unknown: anyerror, - pub fn toJSC(this: Err, globalThis: *JSGlobalObject) JSValue { + pub fn toJS(this: Err, globalThis: *JSGlobalObject) JSValue { return switch (this) { - .syscall => |err| err.toJSC(globalThis), + .syscall => |err| err.toJS(globalThis), .unknown => |err| ZigString.fromBytes(@errorName(err)).toJS(globalThis), }; } @@ -194,7 +194,7 @@ pub const WalkTask = struct { defer this.deinit(); if (this.err) |err| { - const errJs = err.toJSC(this.global); + const errJs = err.toJS(this.global); promise.reject(this.global, errJs); return; } @@ -252,7 +252,7 @@ fn makeGlobWalker( only_files, )) { .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => {}, } @@ -269,7 +269,7 @@ fn makeGlobWalker( only_files, )) { .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => {}, } @@ -360,7 +360,7 @@ pub fn __scanSync(this: *Glob, globalThis: *JSGlobalObject, callframe: *JSC.Call switch (try globWalker.walk()) { .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, .result => {}, } diff --git a/src/bun.js/api/server.zig b/src/bun.js/api/server.zig index 1d755a01b0..cc140d473a 100644 --- a/src/bun.js/api/server.zig +++ b/src/bun.js/api/server.zig @@ -1815,7 +1815,7 @@ pub fn NewServer(protocol_enum: enum { http, https }, development_kind: enum { d else => |e| { var sys_err = bun.sys.Error.fromCode(e, .listen); sys_err.path = unix; - error_instance = sys_err.toJSC(globalThis); + error_instance = sys_err.toJS(globalThis); }, } }, @@ -1922,7 +1922,7 @@ pub fn NewServer(protocol_enum: enum { http, https }, development_kind: enum { d } } - const result: JSValue = onNodeHTTPRequestFn( + const result: JSValue = bun.jsc.fromJSHostCall(globalThis, @src(), onNodeHTTPRequestFn, .{ @intFromPtr(AnyServer.from(this).ptr.ptr()), globalThis, thisObject, @@ -1935,7 +1935,7 @@ pub fn NewServer(protocol_enum: enum { http, https }, development_kind: enum { d resp, upgrade_ctx, &node_http_response, - ); + }) catch globalThis.takeException(error.JSError); const HTTPResult = union(enum) { rejection: JSC.JSValue, @@ -2911,7 +2911,7 @@ pub fn NewServer(protocol_enum: enum { http, https }, development_kind: enum { d } const error_code_value = JSValue.jsNumber(error_code); - const raw_packet_value = JSC.ArrayBuffer.createBuffer(this.globalThis, raw_packet); + const raw_packet_value = JSC.ArrayBuffer.createBuffer(this.globalThis, raw_packet) catch return; // TODO: properly propagate exception upwards const loop = this.globalThis.bunVM().eventLoop(); loop.enter(); defer loop.exit(); diff --git a/src/bun.js/api/server/NodeHTTPResponse.zig b/src/bun.js/api/server/NodeHTTPResponse.zig index 50dffeb601..d19c4e7dd5 100644 --- a/src/bun.js/api/server/NodeHTTPResponse.zig +++ b/src/bun.js/api/server/NodeHTTPResponse.zig @@ -587,7 +587,7 @@ fn drainBufferedRequestBodyFromPause(this: *NodeHTTPResponse, globalObject: *JSC return null; } -pub fn doResume(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) bun.JSError!JSC.JSValue { +pub fn doResume(this: *NodeHTTPResponse, globalObject: *JSC.JSGlobalObject, _: *JSC.CallFrame) JSC.JSValue { log("doResume", .{}); if (this.flags.request_has_completed or this.flags.socket_closed or this.flags.ended) { return .false; @@ -744,7 +744,7 @@ fn onDataOrAborted(this: *NodeHTTPResponse, chunk: []const u8, last: bool, event } if (chunk.len > 0) { - break :brk JSC.ArrayBuffer.createBuffer(globalThis, chunk); + break :brk JSC.ArrayBuffer.createBuffer(globalThis, chunk) catch return; // TODO: properly propagate exception upwards } break :brk .js_undefined; }; diff --git a/src/bun.js/api/server/RequestContext.zig b/src/bun.js/api/server/RequestContext.zig index da894d68eb..c3506bfc5a 100644 --- a/src/bun.js/api/server/RequestContext.zig +++ b/src/bun.js/api/server/RequestContext.zig @@ -856,14 +856,14 @@ pub fn NewRequestContext(comptime ssl_enabled: bool, comptime debug_mode: bool, file.pathlike.fd else switch (bun.sys.open(file.pathlike.path.sliceZ(&file_buf), bun.O.RDONLY | bun.O.NONBLOCK | bun.O.CLOEXEC, 0)) { .result => |_fd| _fd, - .err => |err| return this.runErrorHandler(err.withPath(file.pathlike.path.slice()).toJSC(globalThis)), + .err => |err| return this.runErrorHandler(err.withPath(file.pathlike.path.slice()).toJS(globalThis)), }; // stat only blocks if the target is a file descriptor const stat: bun.Stat = switch (bun.sys.fstat(fd)) { .result => |result| result, .err => |err| { - this.runErrorHandler(err.withPathLike(file.pathlike).toJSC(globalThis)); + this.runErrorHandler(err.withPathLike(file.pathlike).toJS(globalThis)); if (auto_close) { fd.close(); } diff --git a/src/bun.js/api/server/SSLConfig.zig b/src/bun.js/api/server/SSLConfig.zig index bbe7cd5b29..2e40b5a348 100644 --- a/src/bun.js/api/server/SSLConfig.zig +++ b/src/bun.js/api/server/SSLConfig.zig @@ -41,7 +41,7 @@ const BlobFileContentResult = struct { const read = fs.readFileWithOptions(.{ .path = body.Blob.store.?.data.file.pathlike }, .sync, .null_terminated); switch (read) { .err => { - return global.throwValue(read.err.toJSC(global)); + return global.throwValue(read.err.toJS(global)); }, else => { const str = read.result.null_terminated; diff --git a/src/bun.js/api/server/ServerConfig.zig b/src/bun.js/api/server/ServerConfig.zig index a46bead0b1..1449dbe2fc 100644 --- a/src/bun.js/api/server/ServerConfig.zig +++ b/src/bun.js/api/server/ServerConfig.zig @@ -752,7 +752,7 @@ pub fn fromJS( args.address.tcp.port = @as( u16, @intCast(@min( - @max(0, port_.coerce(i32, global)), + @max(0, try port_.coerce(i32, global)), std.math.maxInt(u16), )), ); @@ -836,17 +836,17 @@ pub fn fromJS( } if (try arg.get(global, "reusePort")) |dev| { - args.reuse_port = dev.coerce(bool, global); + args.reuse_port = dev.toBoolean(); } if (global.hasException()) return error.JSError; if (try arg.get(global, "ipv6Only")) |dev| { - args.ipv6_only = dev.coerce(bool, global); + args.ipv6_only = dev.toBoolean(); } if (global.hasException()) return error.JSError; if (try arg.get(global, "inspector")) |inspector| { - args.inspector = inspector.coerce(bool, global); + args.inspector = inspector.toBoolean(); if (args.inspector and args.development == .production) { return global.throwInvalidArguments("Cannot enable inspector in production. Please set development: true in Bun.serve()", .{}); diff --git a/src/bun.js/api/server/ServerWebSocket.zig b/src/bun.js/api/server/ServerWebSocket.zig index ab6bc051c6..c956735fa1 100644 --- a/src/bun.js/api/server/ServerWebSocket.zig +++ b/src/bun.js/api/server/ServerWebSocket.zig @@ -143,7 +143,7 @@ pub fn onMessage( this.getThisValue(), switch (opcode) { .text => bun.String.createUTF8ForJS(globalObject, message), - .binary => this.binaryToJS(globalObject, message), + .binary => this.binaryToJS(globalObject, message) catch .zero, // TODO: properly propagate exception upwards else => unreachable, }, }; @@ -208,7 +208,7 @@ pub fn onDrain(this: *ServerWebSocket, _: uws.AnyWebSocket) void { } } -fn binaryToJS(this: *const ServerWebSocket, globalThis: *JSC.JSGlobalObject, data: []const u8) JSC.JSValue { +fn binaryToJS(this: *const ServerWebSocket, globalThis: *JSC.JSGlobalObject, data: []const u8) bun.JSError!JSC.JSValue { return switch (this.flags.binary_type) { .Buffer => JSC.ArrayBuffer.createBuffer( globalThis, @@ -244,7 +244,7 @@ pub fn onPing(this: *ServerWebSocket, _: uws.AnyWebSocket, data: []const u8) voi _ = cb.call( globalThis, .js_undefined, - &[_]JSC.JSValue{ this.getThisValue(), this.binaryToJS(globalThis, data) }, + &[_]JSC.JSValue{ this.getThisValue(), this.binaryToJS(globalThis, data) catch .zero }, // TODO: properly propagate exception upwards ) catch |e| { const err = globalThis.takeException(e); log("onPing error", .{}); @@ -272,7 +272,7 @@ pub fn onPong(this: *ServerWebSocket, _: uws.AnyWebSocket, data: []const u8) voi _ = cb.call( globalThis, .js_undefined, - &[_]JSC.JSValue{ this.getThisValue(), this.binaryToJS(globalThis, data) }, + &[_]JSC.JSValue{ this.getThisValue(), this.binaryToJS(globalThis, data) catch .zero }, // TODO: properly propagate exception upwards ) catch |e| { const err = globalThis.takeException(e); log("onPong error", .{}); @@ -1077,7 +1077,7 @@ pub fn close( return globalThis.throwInvalidArguments("close requires a numeric code or undefined", .{}); } - break :brk args.ptr[0].coerce(i32, globalThis); + break :brk try args.ptr[0].coerce(i32, globalThis); }; var message_value: ZigString.Slice = brk: { diff --git a/src/bun.js/bindings/BunObject.cpp b/src/bun.js/bindings/BunObject.cpp index 9c52c9537b..25e207d27a 100644 --- a/src/bun.js/bindings/BunObject.cpp +++ b/src/bun.js/bindings/BunObject.cpp @@ -111,15 +111,12 @@ static inline JSC::EncodedJSValue flattenArrayOfBuffersIntoArrayBufferOrUint8Arr size_t arrayLength = array->length(); const auto returnEmptyArrayBufferView = [&]() -> EncodedJSValue { if (asUint8Array) { - return JSValue::encode( - JSC::JSUint8Array::create( - lexicalGlobalObject, - lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), - 0)); + RELEASE_AND_RETURN(throwScope, JSValue::encode(JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), 0))); } RELEASE_AND_RETURN(throwScope, JSValue::encode(JSC::JSArrayBuffer::create(vm, lexicalGlobalObject->arrayBufferStructure(), JSC::ArrayBuffer::create(static_cast(0), 1)))); }; + RETURN_IF_EXCEPTION(throwScope, {}); if (arrayLength < 1) { return returnEmptyArrayBufferView(); @@ -228,6 +225,7 @@ static inline JSC::EncodedJSValue flattenArrayOfBuffersIntoArrayBufferOrUint8Arr if (asUint8Array) { auto uint8array = JSC::JSUint8Array::create(lexicalGlobalObject, lexicalGlobalObject->m_typedArrayUint8.get(lexicalGlobalObject), WTFMove(buffer), 0, byteLength); + RETURN_IF_EXCEPTION(throwScope, {}); return JSValue::encode(uint8array); } @@ -265,7 +263,7 @@ JSC_DEFINE_HOST_FUNCTION(functionConcatTypedArrays, (JSGlobalObject * globalObje asUint8Array = arg2.toBoolean(globalObject); } - return flattenArrayOfBuffersIntoArrayBufferOrUint8Array(globalObject, arrayValue, maxLength, asUint8Array); + RELEASE_AND_RETURN(throwScope, flattenArrayOfBuffersIntoArrayBufferOrUint8Array(globalObject, arrayValue, maxLength, asUint8Array)); } JSC_DECLARE_HOST_FUNCTION(functionConcatTypedArrays); diff --git a/src/bun.js/bindings/BunPlugin.cpp b/src/bun.js/bindings/BunPlugin.cpp index 34fdbdad12..03de1b1d17 100644 --- a/src/bun.js/bindings/BunPlugin.cpp +++ b/src/bun.js/bindings/BunPlugin.cpp @@ -60,12 +60,12 @@ static JSC::EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject* auto* filterObject = callframe->uncheckedArgument(0).toObject(globalObject); RETURN_IF_EXCEPTION(scope, {}); JSC::RegExpObject* filter = nullptr; - if (JSValue filterValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "filter"_s))) { - RETURN_IF_EXCEPTION(scope, {}); + auto filterValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "filter"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (filterValue) { if (filterValue.isCell() && filterValue.asCell()->inherits()) filter = jsCast(filterValue); } - RETURN_IF_EXCEPTION(scope, {}); if (!filter) { throwException(globalObject, scope, createError(globalObject, "onLoad() expects first argument to be an object with a filter RegExp"_s)); @@ -73,7 +73,9 @@ static JSC::EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject* } String namespaceString = String(); - if (JSValue namespaceValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "namespace"_s))) { + auto namespaceValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "namespace"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (namespaceValue) { if (namespaceValue.isString()) { namespaceString = namespaceValue.toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, {}); @@ -83,7 +85,6 @@ static JSC::EncodedJSValue jsFunctionAppendOnLoadPluginBody(JSC::JSGlobalObject* } } } - RETURN_IF_EXCEPTION(scope, {}); auto func = callframe->uncheckedArgument(1); RETURN_IF_EXCEPTION(scope, {}); @@ -151,6 +152,7 @@ static EncodedJSValue jsFunctionAppendVirtualModulePluginBody(JSC::JSGlobalObjec global->requireMap()->remove(globalObject, moduleIdValue); global->esmRegistryMap()->remove(globalObject, moduleIdValue); + RETURN_IF_EXCEPTION(scope, {}); return JSValue::encode(callframe->thisValue()); } @@ -168,12 +170,13 @@ static JSC::EncodedJSValue jsFunctionAppendOnResolvePluginBody(JSC::JSGlobalObje auto* filterObject = callframe->uncheckedArgument(0).toObject(globalObject); RETURN_IF_EXCEPTION(scope, {}); JSC::RegExpObject* filter = nullptr; - if (JSValue filterValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "filter"_s))) { + auto filterValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "filter"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (filterValue) { RETURN_IF_EXCEPTION(scope, {}); if (filterValue.isCell() && filterValue.asCell()->inherits()) filter = jsCast(filterValue); } - RETURN_IF_EXCEPTION(scope, {}); if (!filter) { throwException(globalObject, scope, createError(globalObject, "onResolve() expects first argument to be an object with a filter RegExp"_s)); @@ -181,7 +184,9 @@ static JSC::EncodedJSValue jsFunctionAppendOnResolvePluginBody(JSC::JSGlobalObje } String namespaceString = String(); - if (JSValue namespaceValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "namespace"_s))) { + auto namespaceValue = filterObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "namespace"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (namespaceValue) { if (namespaceValue.isString()) { namespaceString = namespaceValue.toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, {}); @@ -190,7 +195,6 @@ static JSC::EncodedJSValue jsFunctionAppendOnResolvePluginBody(JSC::JSGlobalObje return {}; } } - RETURN_IF_EXCEPTION(scope, {}); } @@ -286,7 +290,9 @@ static inline JSC::EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObje return {}; } - if (JSValue targetValue = obj->getIfPropertyExists(globalObject, Identifier::fromString(vm, "target"_s))) { + auto targetValue = obj->getIfPropertyExists(globalObject, Identifier::fromString(vm, "target"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (targetValue) { if (auto* targetJSString = targetValue.toStringOrNull(globalObject)) { String targetString = targetJSString->value(globalObject); if (!(targetString == "node"_s || targetString == "bun"_s || targetString == "browser"_s)) { @@ -294,7 +300,6 @@ static inline JSC::EncodedJSValue setupBunPlugin(JSC::JSGlobalObject* globalObje } } } - RETURN_IF_EXCEPTION(throwScope, {}); JSObject* builderObject = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 4); @@ -573,6 +578,7 @@ extern "C" JSC_DEFINE_HOST_FUNCTION(JSMock__jsModuleMock, (JSC::JSGlobalObject * JSModuleMock* mock = JSModuleMock::create(vm, globalObject->mockModule.mockModuleStructure.getInitializedOnMainThread(globalObject), callback); auto* esm = globalObject->esmRegistryMap(); + RETURN_IF_EXCEPTION(scope, {}); auto getJSValue = [&]() -> JSValue { auto scope = DECLARE_THROW_SCOPE(vm); @@ -610,8 +616,9 @@ extern "C" JSC_DEFINE_HOST_FUNCTION(JSMock__jsModuleMock, (JSC::JSGlobalObject * removeFromESM = true; JSObject* entry = entryValue ? entryValue.getObject() : nullptr; if (entry) { - if (JSValue moduleValue = entry->getIfPropertyExists(globalObject, Identifier::fromString(vm, String("module"_s)))) { - RETURN_IF_EXCEPTION(scope, {}); + auto moduleValue = entry->getIfPropertyExists(globalObject, Identifier::fromString(vm, String("module"_s))); + RETURN_IF_EXCEPTION(scope, {}); + if (moduleValue) { if (auto* mod = jsDynamicCast(moduleValue)) { JSC::JSModuleNamespaceObject* moduleNamespaceObject = mod->getModuleNamespace(globalObject); RETURN_IF_EXCEPTION(scope, {}); @@ -630,7 +637,7 @@ extern "C" JSC_DEFINE_HOST_FUNCTION(JSMock__jsModuleMock, (JSC::JSGlobalObject * // consistent with regular esm handling code auto catchScope = DECLARE_CATCH_SCOPE(vm); JSValue value = object->get(globalObject, name); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); value = jsUndefined(); } diff --git a/src/bun.js/bindings/BunProcess.cpp b/src/bun.js/bindings/BunProcess.cpp index 2d815ac1a3..cc511af28d 100644 --- a/src/bun.js/bindings/BunProcess.cpp +++ b/src/bun.js/bindings/BunProcess.cpp @@ -1147,19 +1147,23 @@ extern "C" void Bun__promises__emitUnhandledRejectionWarning(JSC::JSGlobalObject JSValue reasonStack {}; if (Bun__promises__isErrorLike(globalObject, JSValue::decode(reason))) { reasonStack = JSValue::decode(reason).get(globalObject, vm.propertyNames->stack); - if (scope.exception()) scope.clearException(); + if (scope.exception()) [[unlikely]] + scope.clearException(); warning->putDirect(vm, vm.propertyNames->stack, reasonStack); } if (!reasonStack) { reasonStack = JSValue::decode(Bun__noSideEffectsToString(vm, globalObject, reason)); - if (scope.exception()) scope.clearException(); + if (scope.exception()) [[unlikely]] + scope.clearException(); } if (!reasonStack) reasonStack = jsUndefined(); Process::emitWarning(globalObject, reasonStack, jsString(globalObject->vm(), "UnhandledPromiseRejectionWarning"_str), jsUndefined(), jsUndefined()); - if (scope.exception()) scope.clearException(); + if (scope.exception()) [[unlikely]] + scope.clearException(); Process::emitWarningErrorInstance(globalObject, warning); - if (scope.exception()) scope.clearException(); + if (scope.exception()) [[unlikely]] + scope.clearException(); } extern "C" int Bun__handleUnhandledRejection(JSC::JSGlobalObject* lexicalGlobalObject, JSC::JSValue reason, JSC::JSValue promise) @@ -1495,6 +1499,7 @@ JSValue Process::emitWarningErrorInstance(JSC::JSGlobalObject* lexicalGlobalObje // }); auto func = JSFunction::create(vm, globalObject, 1, ""_s, jsFunction_throwValue, JSC::ImplementationVisibility::Private); process->queueNextTick(globalObject, func, errorInstance); + RETURN_IF_EXCEPTION(scope, {}); return jsUndefined(); } } @@ -1502,6 +1507,7 @@ JSValue Process::emitWarningErrorInstance(JSC::JSGlobalObject* lexicalGlobalObje // process.nextTick(doEmitWarning, warning); auto func = JSFunction::create(vm, globalObject, 1, ""_s, jsFunction_emitWarning, JSC::ImplementationVisibility::Private); process->queueNextTick(globalObject, func, errorInstance); + RETURN_IF_EXCEPTION(scope, {}); return jsUndefined(); } JSValue Process::emitWarning(JSC::JSGlobalObject* lexicalGlobalObject, JSValue warning, JSValue type, JSValue code, JSValue ctor) @@ -3160,9 +3166,9 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionOpenStdin, (JSGlobalObject * globalObje Zig::GlobalObject* global = defaultGlobalObject(globalObject); auto throwScope = DECLARE_THROW_SCOPE(vm); - if (JSValue stdinValue = global->processObject()->getIfPropertyExists(globalObject, Identifier::fromString(vm, "stdin"_s))) { - RETURN_IF_EXCEPTION(throwScope, {}); - + auto stdinValue = global->processObject()->getIfPropertyExists(globalObject, Identifier::fromString(vm, "stdin"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (stdinValue) { if (!stdinValue.isObject()) { throwTypeError(globalObject, throwScope, "stdin is not an object"_s); return {}; @@ -3170,7 +3176,7 @@ JSC_DEFINE_HOST_FUNCTION(Process_functionOpenStdin, (JSGlobalObject * globalObje JSValue resumeValue = stdinValue.getObject()->getIfPropertyExists(globalObject, Identifier::fromString(vm, "resume"_s)); RETURN_IF_EXCEPTION(throwScope, {}); - if (!resumeValue.isUndefinedOrNull()) { + if (resumeValue && !resumeValue.isUndefinedOrNull()) { auto resumeFunction = jsDynamicCast(resumeValue); if (!resumeFunction) [[unlikely]] { throwTypeError(globalObject, throwScope, "stdin.resume is not a function"_s); diff --git a/src/bun.js/bindings/BunString.cpp b/src/bun.js/bindings/BunString.cpp index 52b912c6bc..68cf63cbbb 100644 --- a/src/bun.js/bindings/BunString.cpp +++ b/src/bun.js/bindings/BunString.cpp @@ -106,7 +106,6 @@ extern "C" JSC::EncodedJSValue BunString__createUTF8ForJS(JSC::JSGlobalObject* g extern "C" JSC::EncodedJSValue BunString__transferToJS(BunString* bunString, JSC::JSGlobalObject* globalObject) { auto& vm = JSC::getVM(globalObject); - auto scope = DECLARE_THROW_SCOPE(vm); if (bunString->tag == BunStringTag::Empty || bunString->tag == BunStringTag::Dead) [[unlikely]] { return JSValue::encode(JSC::jsEmptyString(vm)); diff --git a/src/bun.js/bindings/CallSitePrototype.cpp b/src/bun.js/bindings/CallSitePrototype.cpp index a12be1bcae..35340632a0 100644 --- a/src/bun.js/bindings/CallSitePrototype.cpp +++ b/src/bun.js/bindings/CallSitePrototype.cpp @@ -55,11 +55,9 @@ ALWAYS_INLINE static CallSite* getCallSite(JSGlobalObject* globalObject, JSC::JS #define ENTER_PROTO_FUNC() \ auto& vm = JSC::getVM(globalObject); \ auto scope = DECLARE_THROW_SCOPE(vm); \ - \ CallSite* callSite = getCallSite(globalObject, callFrame->thisValue()); \ - if (!callSite) { \ - return JSC::JSValue::encode(JSC::jsUndefined()); \ - } + RETURN_IF_EXCEPTION(scope, {}); \ + (void)callSite; static const HashTableValue CallSitePrototypeTableValues[] = { diff --git a/src/bun.js/bindings/ErrorCode.cpp b/src/bun.js/bindings/ErrorCode.cpp index 423929922a..59731af820 100644 --- a/src/bun.js/bindings/ErrorCode.cpp +++ b/src/bun.js/bindings/ErrorCode.cpp @@ -263,7 +263,10 @@ void JSValueToStringSafe(JSC::JSGlobalObject* globalObject, WTF::StringBuilder& switch (cell->type()) { case JSC::JSType::StringType: { JSString* jsString = jsDynamicCast(cell); + auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); auto str = jsString->view(globalObject); + RETURN_IF_EXCEPTION(scope, ); if (quotesLikeInspect) { if (str->contains('\'')) { builder.append('"'); @@ -364,8 +367,9 @@ void determineSpecificType(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WTF:: } if (value.isBigInt()) { auto str = value.toStringOrNull(globalObject); - if (!str) return void(); + RETURN_IF_EXCEPTION(scope, void()); auto view = str->view(globalObject); + RETURN_IF_EXCEPTION(scope, ); builder.append("type bigint ("_s); builder.append(view); builder.append("n)"_s); @@ -399,6 +403,7 @@ void determineSpecificType(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WTF:: if (cell->isString()) { auto* jsString = jsCast(cell); auto str = jsString->view(globalObject); + RETURN_IF_EXCEPTION(scope, ); StringView view = str; @@ -458,6 +463,7 @@ void determineSpecificType(JSC::VM& vm, JSC::JSGlobalObject* globalObject, WTF:: RETURN_IF_EXCEPTION(scope, void()); builder.append("an instance of "_s); auto view = str->view(globalObject); + RETURN_IF_EXCEPTION(scope, ); builder.append(view); return; } @@ -548,26 +554,31 @@ WTF::String ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalObject* gl auto* str = expected_types.at(0).toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); result.append(str->view(globalObject)); + RETURN_IF_EXCEPTION(scope, {}); } else if (length == 2) { auto* str1 = expected_types.at(0).toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); result.append(str1->view(globalObject)); + RETURN_IF_EXCEPTION(scope, {}); result.append(" or "_s); auto* str2 = expected_types.at(1).toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); result.append(str2->view(globalObject)); + RETURN_IF_EXCEPTION(scope, {}); } else { for (unsigned i = 0, end = length - 1; i < end; i++) { JSValue expected_type = expected_types.at(i); auto* str = expected_type.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); result.append(str->view(globalObject)); + RETURN_IF_EXCEPTION(scope, {}); result.append(", "_s); } result.append("or "_s); auto* str = expected_types.at(length - 1).toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); result.append(str->view(globalObject)); + RETURN_IF_EXCEPTION(scope, {}); } result.append(". Received "_s); @@ -634,26 +645,29 @@ namespace ERR { EncodedJSValue INVALID_ARG_TYPE(ThrowScope& scope, JSGlobalObject* globalObject, ASCIILiteral message) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message)); + scope.release(); return {}; } JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value) { auto message = Message::ERR_INVALID_ARG_TYPE(throwScope, globalObject, arg_name, expected_type, val_actual_value); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue INVALID_ARG_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue val_arg_name, const WTF::String& expected_type, JSC::JSValue val_actual_value) { auto* jsString = val_arg_name.toString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto arg_name = jsString->view(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto message = Message::ERR_INVALID_ARG_TYPE(throwScope, globalObject, arg_name, expected_type, val_actual_value); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, message)); + throwScope.release(); return {}; } @@ -669,9 +683,10 @@ JSC::EncodedJSValue INVALID_ARG_TYPE_INSTANCE(JSC::ThrowScope& throwScope, JSC:: builder.append(expected_instance_types); builder.append(". Received "_s); determineSpecificType(vm, globalObject, builder, val_actual_value); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, builder.toString())); + throwScope.release(); return {}; } @@ -685,9 +700,10 @@ JSC::EncodedJSValue INVALID_ARG_TYPE_INSTANCE(JSC::ThrowScope& throwScope, JSC:: builder.append(expected_instance_types); builder.append(". Received "_s); determineSpecificType(vm, globalObject, builder, val_actual_value); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, builder.toString())); + throwScope.release(); return {}; } @@ -705,9 +721,10 @@ JSC::EncodedJSValue INVALID_ARG_INSTANCE(JSC::ThrowScope& throwScope, JSC::JSGlo builder.append(expected_type); builder.append(". Received "_s); determineSpecificType(vm, globalObject, builder, val_actual_value); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, builder.toString())); + throwScope.release(); return {}; } @@ -722,18 +739,19 @@ JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObjec builder.append(upper); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, actual); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name_val, double lower, double upper, JSC::JSValue actual) { auto* jsString = arg_name_val.toString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto arg_name = jsString->view(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); WTF::StringBuilder builder; builder.append("The value of \""_s); @@ -744,18 +762,19 @@ JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObjec builder.append(upper); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, actual); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name_val, double bound_num, Bound bound, JSC::JSValue actual) { auto* jsString = arg_name_val.toString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto arg_name = jsString->view(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); WTF::StringBuilder builder; builder.append("The value of \""_s); @@ -765,18 +784,19 @@ JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObjec builder.append(bound_num); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, actual); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue arg_name_val, const WTF::String& msg, JSC::JSValue actual) { auto* jsString = arg_name_val.toString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto arg_name = jsString->view(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); WTF::StringBuilder builder; builder.append("The value of \""_s); @@ -785,9 +805,10 @@ JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObjec builder.append(msg); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, actual); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, builder.toString())); + throwScope.release(); return {}; } @@ -800,15 +821,17 @@ JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& throwScope, JSC::JSGlobalObjec builder.append(msg); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, actual); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue OUT_OF_RANGE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, ASCIILiteral message) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OUT_OF_RANGE, message)); + scope.release(); return {}; } @@ -825,9 +848,10 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal builder.append(reason); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, value, true); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue INVALID_ARG_VALUE_RangeError(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral name, JSC::JSValue value, const WTF::String& reason) @@ -844,11 +868,12 @@ JSC::EncodedJSValue INVALID_ARG_VALUE_RangeError(JSC::ThrowScope& throwScope, JS builder.append(reason); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, value, true); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto* structure = createErrorStructure(vm, globalObject, ErrorType::RangeError, "RangeError"_s, "ERR_INVALID_ARG_VALUE"_s); auto error = JSC::ErrorInstance::create(vm, structure, builder.toString(), jsUndefined(), nullptr, JSC::RuntimeType::TypeNothing, ErrorType::RangeError, true); throwScope.throwException(globalObject, error); + throwScope.release(); return {}; } JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue name, JSC::JSValue value, const WTF::String& reason) @@ -857,15 +882,16 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal builder.append("The argument '"_s); auto& vm = JSC::getVM(globalObject); determineSpecificType(vm, globalObject, builder, name); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append("' "_s); builder.append(reason); builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, value, true); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } @@ -875,23 +901,24 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal WTF::StringBuilder builder; builder.append("The argument '"_s); JSValueToStringSafe(globalObject, builder, name); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append("' "_s); builder.append(reason); unsigned length = oneOf->length(); for (size_t i = 0; i < length; i++) { JSValue index = oneOf->getIndex(globalObject, i); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); if (index.isString()) { JSString* str = index.toString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append('\''); builder.append(str->view(globalObject)); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append('\''); } else { JSValueToStringSafe(globalObject, builder, index); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); } if (i < length - 1) { @@ -900,9 +927,10 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal } builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, value, true); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } @@ -931,6 +959,7 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal } throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } @@ -957,6 +986,7 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal } throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } @@ -976,9 +1006,10 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal builder.append(". Received "_s); JSValueToStringSafe(globalObject, builder, value, true); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE, builder.toString())); + throwScope.release(); return {}; } @@ -986,18 +1017,21 @@ JSC::EncodedJSValue INVALID_URL_SCHEME(JSC::ThrowScope& throwScope, JSC::JSGloba { auto message = makeString("The URL must be of scheme "_s, expectedScheme); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_URL_SCHEME, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue INVALID_FILE_URL_HOST(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& platform) { auto message = makeString("File URL host must be \"localhost\" or empty on "_s, platform); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_FILE_URL_HOST, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue INVALID_FILE_URL_HOST(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const ASCIILiteral platform) { auto message = makeString("File URL host must be \"localhost\" or empty on "_s, platform); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_FILE_URL_HOST, message)); + throwScope.release(); return {}; } /// `File URL path {suffix}` @@ -1005,6 +1039,7 @@ JSC::EncodedJSValue INVALID_FILE_URL_PATH(JSC::ThrowScope& throwScope, JSC::JSGl { auto message = makeString("File URL path "_s, suffix); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_FILE_URL_PATH, message)); + throwScope.release(); return {}; } @@ -1012,18 +1047,20 @@ JSC::EncodedJSValue UNKNOWN_ENCODING(JSC::ThrowScope& throwScope, JSC::JSGlobalO { auto message = makeString("Unknown encoding: "_s, encoding); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_UNKNOWN_ENCODING, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue UNKNOWN_ENCODING(JSC::ThrowScope& scope, JSGlobalObject* globalObject, JSValue encodingValue) { WTF::String encodingString = encodingValue.toWTFString(globalObject); - RETURN_IF_EXCEPTION(scope, {}); + RELEASE_RETURN_IF_EXCEPTION(scope, {}); WTF::StringBuilder builder; builder.append("Unknown encoding: "_s); builder.append(encodingString); scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_UNKNOWN_ENCODING, builder.toString())); + scope.release(); return {}; } @@ -1031,6 +1068,7 @@ JSC::EncodedJSValue INVALID_STATE(JSC::ThrowScope& throwScope, JSC::JSGlobalObje { auto message = makeString("Invalid state: "_s, statemsg); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_STATE, message)); + throwScope.release(); return {}; } @@ -1038,6 +1076,7 @@ JSC::EncodedJSValue STRING_TOO_LONG(JSC::ThrowScope& throwScope, JSC::JSGlobalOb { auto message = makeString("Cannot create a string longer than "_s, WTF::String ::MaxLength, " characters"_s); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_STRING_TOO_LONG, message)); + throwScope.release(); return {}; } @@ -1045,9 +1084,11 @@ JSC::EncodedJSValue BUFFER_OUT_OF_BOUNDS(JSC::ThrowScope& throwScope, JSC::JSGlo { if (!name.isEmpty()) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, makeString("\""_s, name, "\" is outside of buffer bounds"_s))); + throwScope.release(); return {}; } throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_BUFFER_OUT_OF_BOUNDS, "Attempt to access memory outside buffer bounds"_s)); + throwScope.release(); return {}; } @@ -1056,11 +1097,12 @@ JSC::EncodedJSValue UNKNOWN_SIGNAL(JSC::ThrowScope& throwScope, JSC::JSGlobalObj WTF::StringBuilder builder; builder.append("Unknown signal: "_s); JSValueToStringSafe(globalObject, builder, signal); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); if (triedUppercase) { builder.append(" (signals must use all capital letters)"_s); } throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_UNKNOWN_SIGNAL, builder.toString())); + throwScope.release(); return {}; } @@ -1069,14 +1111,15 @@ JSC::EncodedJSValue SOCKET_BAD_PORT(JSC::ThrowScope& throwScope, JSC::JSGlobalOb ASCIILiteral op = allowZero ? ">="_s : ">"_s; WTF::StringBuilder builder; JSValueToStringSafe(globalObject, builder, name); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append(" should be "_s); builder.append(op); builder.append(" 0 and < 65536. Received "_s); JSValueToStringSafe(globalObject, builder, port); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_SOCKET_BAD_PORT, builder.toString())); + throwScope.release(); return {}; } @@ -1084,21 +1127,24 @@ JSC::EncodedJSValue UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET(JSC::ThrowScope& thro { auto message = "`process.setupUncaughtExceptionCapture()` was called while a capture callback was already active"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_UNCAUGHT_EXCEPTION_CAPTURE_ALREADY_SET, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue ASSERTION(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, JSC::JSValue msg) { auto msg_string = msg.toWTFString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); auto message = msg_string; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_ASSERTION, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue ASSERTION(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ASCIILiteral msg) { auto message = msg; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_ASSERTION, message)); + throwScope.release(); return {}; } @@ -1106,12 +1152,14 @@ JSC::EncodedJSValue CRYPTO_INVALID_CURVE(JSC::ThrowScope& throwScope, JSC::JSGlo { auto message = "Invalid EC curve name"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_CURVE, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEYTYPE, message)); + throwScope.release(); return {}; } @@ -1119,6 +1167,7 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEYTYPE(JSC::ThrowScope& throwScope, JSC::JSG { auto message = "Invalid key type"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEYTYPE, message)); + throwScope.release(); return {}; } @@ -1128,60 +1177,70 @@ JSC::EncodedJSValue CRYPTO_UNKNOWN_CIPHER(JSC::ThrowScope& throwScope, JSC::JSGl builder.append("Unknown cipher: "_s); builder.append(cipherName); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_UNKNOWN_CIPHER, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_AUTH_TAG(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, const WTF::String& message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_AUTH_TAG, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_IV(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_IV, "Invalid initialization vector"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_UNSUPPORTED_OPERATION(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_UNSUPPORTED_OPERATION, message)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_UNSUPPORTED_OPERATION(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_UNSUPPORTED_OPERATION, "Unsupported crypto operation"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_KEYLEN(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEYLEN, "Invalid key length"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_STATE(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_STATE, message)); + scope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_MESSAGELEN(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_MESSAGELEN, "Invalid message length"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue MISSING_ARGS(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_MISSING_ARGS, message)); + scope.release(); return {}; } JSC::EncodedJSValue CRYPTO_OPERATION_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ASCIILiteral message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_OPERATION_FAILED, message)); + throwScope.release(); return {}; } @@ -1189,6 +1248,7 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEYPAIR(JSC::ThrowScope& throwScope, JSC::JSG { auto message = "Invalid key pair"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEYPAIR, message)); + throwScope.release(); return {}; } @@ -1196,6 +1256,7 @@ JSC::EncodedJSValue CRYPTO_ECDH_INVALID_PUBLIC_KEY(JSC::ThrowScope& throwScope, { auto message = "Public key is not valid for specified curve"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_ECDH_INVALID_PUBLIC_KEY, message)); + throwScope.release(); return {}; } @@ -1215,6 +1276,7 @@ JSC::EncodedJSValue CRYPTO_JWK_UNSUPPORTED_CURVE(JSC::ThrowScope& throwScope, JS builder.append(curve); builder.append('.'); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_JWK_UNSUPPORTED_CURVE, builder.toString())); + throwScope.release(); return {}; } @@ -1227,24 +1289,28 @@ JSC::EncodedJSValue CRYPTO_JWK_UNSUPPORTED_CURVE(JSC::ThrowScope& throwScope, JS } builder.append('.'); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_JWK_UNSUPPORTED_CURVE, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_JWK_UNSUPPORTED_KEY_TYPE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_JWK_UNSUPPORTED_KEY_TYPE, "Unsupported JWK Key Type."_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_JWK(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_JWK, "Invalid JWK data"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_INVALID_JWK(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, ASCIILiteral message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_JWK, message)); + throwScope.release(); return {}; } @@ -1252,6 +1318,7 @@ JSC::EncodedJSValue CRYPTO_SIGN_KEY_REQUIRED(JSC::ThrowScope& throwScope, JSC::J { auto message = "No key provided to sign"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_SIGN_KEY_REQUIRED, message)); + throwScope.release(); return {}; } @@ -1260,11 +1327,12 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, WTF::StringBuilder builder; builder.append("Invalid key object type "_s); JSValueToStringSafe(globalObject, builder, received); - RETURN_IF_EXCEPTION(throwScope, {}); + RELEASE_RETURN_IF_EXCEPTION(throwScope, {}); builder.append(". Expected "_s); builder.append(expected); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, builder.toString())); + throwScope.release(); return {}; } @@ -1287,6 +1355,7 @@ JSC::EncodedJSValue CRYPTO_INVALID_KEY_OBJECT_TYPE(JSC::ThrowScope& throwScope, builder.append(expected); builder.append('.'); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_KEY_OBJECT_TYPE, builder.toString())); + throwScope.release(); return {}; } @@ -1299,6 +1368,7 @@ JSC::EncodedJSValue CRYPTO_INCOMPATIBLE_KEY_OPTIONS(JSC::ThrowScope& throwScope, builder.append(expectedOperation); builder.append('.'); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INCOMPATIBLE_KEY_OPTIONS, builder.toString())); + throwScope.release(); return {}; } @@ -1308,6 +1378,7 @@ JSC::EncodedJSValue CRYPTO_INVALID_DIGEST(JSC::ThrowScope& throwScope, JSC::JSGl builder.append("Invalid digest: "_s); builder.append(digest); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_DIGEST, builder.toString())); + throwScope.release(); return {}; } @@ -1317,18 +1388,21 @@ JSC::EncodedJSValue CRYPTO_INVALID_DIGEST(JSC::ThrowScope& throwScope, JSC::JSGl builder.append(message); builder.append(digest); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_INVALID_DIGEST, builder.toString())); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_HASH_FINALIZED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_HASH_FINALIZED, "Digest already called"_s)); + throwScope.release(); return {}; } JSC::EncodedJSValue CRYPTO_HASH_UPDATE_FAILED(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_HASH_UPDATE_FAILED, "Hash update failed"_s)); + throwScope.release(); return {}; } @@ -1336,6 +1410,7 @@ JSC::EncodedJSValue CRYPTO_TIMING_SAFE_EQUAL_LENGTH(JSC::ThrowScope& scope, JSC: { auto message = "Input buffers must have the same byte length"_s; scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH, message)); + scope.release(); return {}; } @@ -1343,18 +1418,21 @@ JSC::EncodedJSValue CRYPTO_UNKNOWN_DH_GROUP(JSC::ThrowScope& scope, JSGlobalObje { auto message = "Unknown DH group"_s; scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CRYPTO_UNKNOWN_DH_GROUP, message)); + scope.release(); return {}; } JSC::EncodedJSValue OSSL_EVP_INVALID_DIGEST(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_OSSL_EVP_INVALID_DIGEST, "Invalid digest used"_s)); + scope.release(); return {}; } JSC::EncodedJSValue MISSING_PASSPHRASE(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral message) { throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_MISSING_PASSPHRASE, message)); + throwScope.release(); return {}; } @@ -1362,6 +1440,7 @@ JSC::EncodedJSValue KEY_GENERATION_JOB_FAILED(JSC::ThrowScope& throwScope, JSC:: { auto message = "Key generation job failed"_s; throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_KEY_GENERATION_JOB_FAILED, message)); + throwScope.release(); return {}; } @@ -1375,6 +1454,7 @@ JSC::EncodedJSValue INCOMPATIBLE_OPTION_PAIR(JSC::ThrowScope& throwScope, JSC::J builder.append("\""_s); throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INCOMPATIBLE_OPTION_PAIR, builder.toString())); + throwScope.release(); return {}; } @@ -1384,6 +1464,7 @@ JSC::EncodedJSValue MISSING_OPTION(JSC::ThrowScope& scope, JSC::JSGlobalObject* builder.append(message); builder.append(" is required"_s); scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_MISSING_OPTION, builder.toString())); + scope.release(); return {}; } @@ -1402,12 +1483,14 @@ JSC::EncodedJSValue INVALID_MIME_SYNTAX(JSC::ThrowScope& scope, JSC::JSGlobalObj } scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_MIME_SYNTAX, builder.toString())); + scope.release(); return {}; } EncodedJSValue CLOSED_MESSAGE_PORT(ThrowScope& scope, JSGlobalObject* globalObject) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_CLOSED_MESSAGE_PORT, "Cannot send data on closed MessagePort"_s)); + scope.release(); return {}; } @@ -1417,12 +1500,14 @@ JSC::EncodedJSValue INVALID_THIS(JSC::ThrowScope& scope, JSC::JSGlobalObject* gl builder.append("Value of \"this\" must be of type "_s); builder.append(expectedType); scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_THIS, builder.toString())); + scope.release(); return {}; } JSC::EncodedJSValue DLOPEN_DISABLED(JSC::ThrowScope& scope, JSC::JSGlobalObject* globalObject, ASCIILiteral message) { scope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_DLOPEN_DISABLED, message)); + scope.release(); return {}; } @@ -1441,10 +1526,12 @@ static JSC::JSValue ERR_INVALID_ARG_TYPE(JSC::ThrowScope& scope, JSC::JSGlobalOb } const auto msg = Bun::Message::ERR_INVALID_ARG_TYPE(scope, globalObject, argName, expected_types, arg2); + RETURN_IF_EXCEPTION(scope, {}); return createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, msg); } const auto msg = Bun::Message::ERR_INVALID_ARG_TYPE(scope, globalObject, arg0, arg1, arg2); + RETURN_IF_EXCEPTION(scope, {}); return createError(globalObject, ErrorCode::ERR_INVALID_ARG_TYPE, msg); } @@ -1612,7 +1699,7 @@ JSC_DEFINE_HOST_FUNCTION(Bun::jsFunctionMakeErrorWithCode, (JSC::JSGlobalObject #if ASSERT_ENABLED if (!codeValue.isNumber()) { JSC::throwTypeError(globalObject, scope, "First argument to $ERR_ must be a number"_s); - return {}; + RELEASE_AND_RETURN(scope, {}); } #endif @@ -1621,7 +1708,7 @@ JSC_DEFINE_HOST_FUNCTION(Bun::jsFunctionMakeErrorWithCode, (JSC::JSGlobalObject #if ASSERT_ENABLED if (code > Bun::NODE_ERROR_COUNT - 1 || code < 0) { JSC::throwTypeError(globalObject, scope, "Invalid error code. Use $ERR_* constants"_s); - return {}; + RELEASE_AND_RETURN(scope, {}); } #endif @@ -1826,11 +1913,13 @@ JSC_DEFINE_HOST_FUNCTION(Bun::jsFunctionMakeErrorWithCode, (JSC::JSGlobalObject auto str0 = arg0.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto view0 = str0->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); auto arg1 = callFrame->argument(2); auto str1 = arg1.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto view1 = str1->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); auto arg2 = callFrame->argument(3); diff --git a/src/bun.js/bindings/ErrorCode.h b/src/bun.js/bindings/ErrorCode.h index 92f626ad23..7385242bf7 100644 --- a/src/bun.js/bindings/ErrorCode.h +++ b/src/bun.js/bindings/ErrorCode.h @@ -9,6 +9,18 @@ #include "ErrorCode+List.h" #include "CryptoKeyType.h" +#define RELEASE_RETURN_IF_EXCEPTION(scope__, value__) \ + do { \ + SUPPRESS_UNCOUNTED_LOCAL JSC::VM& vm = (scope__).vm(); \ + EXCEPTION_ASSERT(!!(scope__).exception() == vm.traps().needHandling(JSC::VMTraps::NeedExceptionHandling)); \ + if (vm.traps().maybeNeedHandling()) [[unlikely]] { \ + if (vm.hasExceptionsAfterHandlingTraps()) { \ + scope__.release(); \ + return value__; \ + } \ + } \ + } while (false) + namespace Bun { class ErrorCodeCache : public JSC::JSInternalFieldObjectImpl { diff --git a/src/bun.js/bindings/ImportMetaObject.cpp b/src/bun.js/bindings/ImportMetaObject.cpp index f670fc76f1..c7b76015a1 100644 --- a/src/bun.js/bindings/ImportMetaObject.cpp +++ b/src/bun.js/bindings/ImportMetaObject.cpp @@ -107,7 +107,9 @@ static JSC::EncodedJSValue functionRequireResolve(JSC::JSGlobalObject* globalObj // require.resolve also supports a paths array // we only support a single path if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) { - if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName())) { + auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName()); + RETURN_IF_EXCEPTION(scope, {}); + if (pathsObject) { if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) { auto pathsArray = JSC::jsCast(pathsObject); if (pathsArray->length() > 0) { @@ -213,7 +215,9 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) { - if (auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName())) { + auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName()); + RETURN_IF_EXCEPTION(scope, {}); + if (pathsObject) { if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) { auto pathsArray = JSC::jsCast(pathsObject); if (pathsArray->length() > 0) { @@ -246,6 +250,7 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSync(JSC::JSGlobalObje auto clientData = WebCore::clientData(vm); JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName()); + RETURN_IF_EXCEPTION(scope, {}); if (pathProperty && pathProperty.isString()) from = JSC::JSValue::encode(pathProperty); @@ -354,12 +359,14 @@ extern "C" JSC::EncodedJSValue functionImportMeta__resolveSyncPrivate(JSC::JSGlo for (size_t i = 0; i < userPathListArray->length(); ++i) { JSValue path = userPathListArray->getIndex(globalObject, i); WTF::String pathStr = path.toWTFString(globalObject); - if (scope.exception()) goto cleanup; + if (scope.exception()) [[unlikely]] + goto cleanup; paths.append(Bun::toStringRef(pathStr)); } result = Bun__resolveSyncWithPaths(lexicalGlobalObject, JSC::JSValue::encode(moduleName), JSValue::encode(from), isESM, isRequireDotResolve, paths.begin(), paths.size()); - if (scope.exception()) goto cleanup; + if (scope.exception()) [[unlikely]] + goto cleanup; if (!JSC::JSValue::decode(result).isString()) { JSC::throwException(lexicalGlobalObject, scope, JSC::JSValue::decode(result)); @@ -418,7 +425,9 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve, JSValue fromValue = callFrame->uncheckedArgument(1); if (!fromValue.isUndefinedOrNull() && fromValue.isObject()) { - if (JSValue pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName())) { + auto pathsObject = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).pathsPublicName()); + RETURN_IF_EXCEPTION(scope, {}); + if (pathsObject) { if (pathsObject.isCell() && pathsObject.asCell()->type() == JSC::JSType::ArrayType) { auto* pathsArray = JSC::jsCast(pathsObject); if (pathsArray->length() > 0) { @@ -444,6 +453,7 @@ JSC_DEFINE_HOST_FUNCTION(functionImportMeta__resolve, auto clientData = WebCore::clientData(vm); JSValue pathProperty = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().pathPublicName()); + RETURN_IF_EXCEPTION(scope, {}); if (pathProperty && pathProperty.isString()) [[likely]] { from = pathProperty; diff --git a/src/bun.js/bindings/InspectorLifecycleAgent.cpp b/src/bun.js/bindings/InspectorLifecycleAgent.cpp index a5eadfc1f0..6dae95566d 100644 --- a/src/bun.js/bindings/InspectorLifecycleAgent.cpp +++ b/src/bun.js/bindings/InspectorLifecycleAgent.cpp @@ -146,12 +146,9 @@ Protocol::ErrorStringOr InspectorLifecycleAgent::getModuleGraph() auto* global = defaultGlobalObject(&m_globalObject); auto* esmMap = global->esmRegistryMap(); + if (!esmMap) return makeUnexpected(ErrorString("Module graph not available"_s)); auto* cjsMap = global->requireMap(); - if (!esmMap || !cjsMap) { - return makeUnexpected(ErrorString("Module graph not available"_s)); - } - Ref> esm = JSON::ArrayOf::create(); { auto iter1 = JSC::JSMapIterator::create(global, global->mapIteratorStructure(), esmMap, JSC::IterationKind::Keys); diff --git a/src/bun.js/bindings/JSBigInt.zig b/src/bun.js/bindings/JSBigInt.zig index 6aa0ca06fb..8e6249aba7 100644 --- a/src/bun.js/bindings/JSBigInt.zig +++ b/src/bun.js/bindings/JSBigInt.zig @@ -37,10 +37,11 @@ pub const JSBigInt = opaque { extern fn JSC__JSBigInt__toString(*JSBigInt, *JSGlobalObject) bun.String; pub fn toString(this: *JSBigInt, global: *JSGlobalObject) JSError!bun.String { + var scope: jsc.CatchScope = undefined; + scope.init(global, @src(), .enabled); + defer scope.deinit(); const str = JSC__JSBigInt__toString(this, global); - if (global.hasException()) { - return error.JSError; - } + try scope.returnIfException(); return str; } }; diff --git a/src/bun.js/bindings/JSBuffer.cpp b/src/bun.js/bindings/JSBuffer.cpp index 4d0fd7e6b1..9bd68b9d5c 100644 --- a/src/bun.js/bindings/JSBuffer.cpp +++ b/src/bun.js/bindings/JSBuffer.cpp @@ -345,6 +345,7 @@ JSC::EncodedJSValue JSBuffer__bufferFromPointerAndLengthAndDeinit(JSC::JSGlobalO auto* globalObject = defaultGlobalObject(lexicalGlobalObject); auto* subclassStructure = globalObject->JSBufferSubclassStructure(); + auto scope = DECLARE_CATCH_SCOPE(lexicalGlobalObject->vm()); if (length > 0) [[likely]] { auto buffer = ArrayBuffer::createFromBytes({ reinterpret_cast(ptr), length }, createSharedTask([ctx, bytesDeallocator](void* p) { @@ -357,6 +358,10 @@ JSC::EncodedJSValue JSBuffer__bufferFromPointerAndLengthAndDeinit(JSC::JSGlobalO uint8Array = JSC::JSUint8Array::create(lexicalGlobalObject, subclassStructure, 0); } + // only JSC::JSUint8Array::create can throw and we control the ArrayBuffer passed in. + scope.assertNoException(); + ASSERT(uint8Array); + return JSC::JSValue::encode(uint8Array); } @@ -753,7 +758,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_byteLengthBody(JSC::JSGlo } if (arg0.value().isString()) [[likely]] - return jsBufferByteLengthFromStringAndEncoding(lexicalGlobalObject, asString(arg0.value()), encoding); + RELEASE_AND_RETURN(scope, jsBufferByteLengthFromStringAndEncoding(lexicalGlobalObject, asString(arg0.value()), encoding)); if (auto* arrayBufferView = jsDynamicCast(arg0.value())) { return JSValue::encode(jsNumber(arrayBufferView->byteLength())); @@ -890,11 +895,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_concatBody(JSC::JSGlobalO // there will be some data that needs to be zeroed out // let's let the operating system do that for us allocBuffer(lexicalGlobalObject, byteLength); - - if (!outBuffer) { - ASSERT(throwScope.exception()); - return {}; - } + RETURN_IF_EXCEPTION(throwScope, {}); size_t remain = byteLength; auto* head = outBuffer->typedVector(); @@ -935,7 +936,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_copyBytesFromBody(JSC::JS auto viewLength = view->length(); if (viewLength == 0) { - return JSValue::encode(createEmptyBuffer(lexicalGlobalObject)); + RELEASE_AND_RETURN(throwScope, JSValue::encode(createEmptyBuffer(lexicalGlobalObject))); } size_t offset; @@ -945,7 +946,7 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_copyBytesFromBody(JSC::JS if (!offsetValue.isUndefined()) { Bun::V::validateInteger(throwScope, lexicalGlobalObject, offsetValue, "offset"_s, jsNumber(0), jsUndefined(), &offset); RETURN_IF_EXCEPTION(throwScope, {}); - if (offset >= viewLength) return JSValue::encode(createEmptyBuffer(lexicalGlobalObject)); + if (offset >= viewLength) RELEASE_AND_RETURN(throwScope, JSValue::encode(createEmptyBuffer(lexicalGlobalObject))); } else { offset = 0; } @@ -964,13 +965,13 @@ static JSC::EncodedJSValue jsBufferConstructorFunction_copyBytesFromBody(JSC::JS auto offset_r = offset * elemSize; auto end_r = end * elemSize; auto span = view->span().subspan(offset_r, end_r - offset_r); - return JSValue::encode(createBuffer(lexicalGlobalObject, span.data(), span.size())); + RELEASE_AND_RETURN(throwScope, JSValue::encode(createBuffer(lexicalGlobalObject, span.data(), span.size()))); } auto boffset = view->byteOffset(); auto blength = view->byteLength(); auto span = view->span().subspan(boffset, blength - boffset); - return JSValue::encode(createBuffer(lexicalGlobalObject, span.data(), span.size())); + RELEASE_AND_RETURN(throwScope, JSValue::encode(createBuffer(lexicalGlobalObject, span.data(), span.size()))); } static JSC::EncodedJSValue jsBufferConstructorFunction_isEncodingBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame) @@ -1546,6 +1547,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_indexOfBody(JSC::JSGlobalOb auto& vm = JSC::getVM(lexicalGlobalObject); auto scope = DECLARE_THROW_SCOPE(vm); auto index = indexOf(lexicalGlobalObject, scope, callFrame, castedThis, false); + RETURN_IF_EXCEPTION(scope, {}); return JSC::JSValue::encode(jsNumber(index)); } @@ -1626,6 +1628,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_lastIndexOfBody(JSC::JSGlob auto& vm = JSC::getVM(lexicalGlobalObject); auto scope = DECLARE_THROW_SCOPE(vm); auto index = indexOf(lexicalGlobalObject, scope, callFrame, castedThis, true); + RETURN_IF_EXCEPTION(scope, {}); return JSC::JSValue::encode(jsNumber(index)); } @@ -2009,12 +2012,10 @@ static JSC::EncodedJSValue jsBufferPrototypeFunction_writeEncodingBody(JSC::VM& } if (offset < 0 || offset > byteLength) { - Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "offset"); - RETURN_IF_EXCEPTION(scope, {}); + return Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "offset"); } if (length < 0 || length > byteLength - offset) { - Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "length"); - RETURN_IF_EXCEPTION(scope, {}); + return Bun::ERR::BUFFER_OUT_OF_BOUNDS(scope, lexicalGlobalObject, "length"); } RELEASE_AND_RETURN(scope, writeToBuffer(lexicalGlobalObject, castedThis, str, offset, length, encoding)); @@ -2045,7 +2046,7 @@ static JSC::EncodedJSValue jsBufferPrototypeFunctionWriteWithEncoding(JSC::JSGlo return {}; } - return jsBufferPrototypeFunction_writeEncodingBody(vm, lexicalGlobalObject, castedThis, text, offsetValue, lengthValue); + RELEASE_AND_RETURN(scope, jsBufferPrototypeFunction_writeEncodingBody(vm, lexicalGlobalObject, castedThis, text, offsetValue, lengthValue)); } static JSC::EncodedJSValue jsBufferPrototypeFunction_writeBody(JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame, typename IDLOperation::ClassParameter castedThis) @@ -2448,6 +2449,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64LE, (JSGlobalObj if (bigint->length() > 1) [[unlikely]] return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); auto limb = valueVal.toBigUInt64(lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); if (!bigint->sign() && limb > 0x7fffffffffffffff) return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); if (bigint->sign() && limb - 0x8000000000000000 > 0x7fffffffffffffff) return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); int64_t value = static_cast(limb); @@ -2487,6 +2489,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigInt64BE, (JSGlobalObj if (bigint->length() > 1) [[unlikely]] return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); auto limb = valueVal.toBigUInt64(lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); if (!bigint->sign() && limb > 0x7fffffffffffffff) return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); if (bigint->sign() && limb - 0x8000000000000000 > 0x7fffffffffffffff) return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= -(2n ** 63n) and < 2n ** 63n"_s, valueVal); int64_t value = static_cast(limb); @@ -2528,6 +2531,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64LE, (JSGlobalOb if (bigint->length() > 1) [[unlikely]] return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= 0n and < 2n ** 64n"_s, valueVal); uint64_t value = valueVal.toBigUInt64(lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); if (offsetVal.isUndefined()) offsetVal = jsNumber(0); if (!offsetVal.isNumber()) [[unlikely]] @@ -2566,6 +2570,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBufferPrototypeFunction_writeBigUInt64BE, (JSGlobalOb if (bigint->length() > 1) [[unlikely]] return Bun::ERR::OUT_OF_RANGE(scope, lexicalGlobalObject, "value"_s, ">= 0n and < 2n ** 64n"_s, valueVal); uint64_t value = valueVal.toBigUInt64(lexicalGlobalObject); + RETURN_IF_EXCEPTION(scope, {}); if (offsetVal.isUndefined()) offsetVal = jsNumber(0); if (!offsetVal.isNumber()) [[unlikely]] @@ -2862,15 +2867,16 @@ static JSC::EncodedJSValue createJSBufferFromJS(JSC::JSGlobalObject* lexicalGlob } auto anyint = distinguishingArg.asAnyInt(); if (anyint < 0 or anyint > Bun::Buffer::kMaxLength) return Bun::ERR::OUT_OF_RANGE(throwScope, lexicalGlobalObject, "size"_s, 0, Bun::Buffer::kMaxLength, distinguishingArg); - return JSValue::encode(allocBuffer(lexicalGlobalObject, anyint)); + RELEASE_AND_RETURN(throwScope, JSValue::encode(allocBuffer(lexicalGlobalObject, anyint))); } else if (distinguishingArg.isNumber()) { JSValue lengthValue = distinguishingArg; Bun::V::validateNumber(throwScope, lexicalGlobalObject, lengthValue, "size"_s, jsNumber(0), jsNumber(Bun::Buffer::kMaxLength)); RETURN_IF_EXCEPTION(throwScope, {}); size_t length = lengthValue.toLength(lexicalGlobalObject); - return JSValue::encode(allocBuffer(lexicalGlobalObject, length)); + RELEASE_AND_RETURN(throwScope, JSValue::encode(allocBuffer(lexicalGlobalObject, length))); } else if (distinguishingArg.isUndefinedOrNull() || distinguishingArg.isBoolean()) { auto arg_string = distinguishingArg.toWTFString(globalObject); + RETURN_IF_EXCEPTION(throwScope, {}); auto message = makeString("The first argument must be of type string or an instance of Buffer, ArrayBuffer, Array or an Array-like object. Received "_s, arg_string); return throwVMTypeError(globalObject, throwScope, message); } else if (distinguishingArg.isCell()) { @@ -2901,10 +2907,7 @@ static JSC::EncodedJSValue createJSBufferFromJS(JSC::JSGlobalObject* lexicalGlob return {}; } auto* uint8Array = createUninitializedBuffer(lexicalGlobalObject, byteLength); - if (!uint8Array) [[unlikely]] { - ASSERT(throwScope.exception()); - return {}; - } + RETURN_IF_EXCEPTION(throwScope, {}); if (byteLength) { uint8Array->setFromTypedArray(lexicalGlobalObject, 0, view, 0, byteLength, CopyType::LeftToRight); } diff --git a/src/bun.js/bindings/JSBunRequest.cpp b/src/bun.js/bindings/JSBunRequest.cpp index 2cefe94f33..d93c7480c8 100644 --- a/src/bun.js/bindings/JSBunRequest.cpp +++ b/src/bun.js/bindings/JSBunRequest.cpp @@ -229,7 +229,7 @@ JSC_DEFINE_CUSTOM_GETTER(jsJSBunRequestGetCookies, (JSC::JSGlobalObject * global RETURN_IF_EXCEPTION(throwScope, encodedJSValue()); if (cookieMapResult.hasException()) { WebCore::propagateException(*globalObject, throwScope, cookieMapResult.releaseException()); - return JSValue::encode(jsUndefined()); + RELEASE_AND_RETURN(throwScope, {}); } auto cookieMap = cookieMapResult.releaseReturnValue(); diff --git a/src/bun.js/bindings/JSBundlerPlugin.cpp b/src/bun.js/bindings/JSBundlerPlugin.cpp index 397ee5d4fd..799f731ec6 100644 --- a/src/bun.js/bindings/JSBundlerPlugin.cpp +++ b/src/bun.js/bindings/JSBundlerPlugin.cpp @@ -505,7 +505,7 @@ extern "C" void JSBundlerPlugin__matchOnLoad(Bun::JSBundlerPlugin* plugin, const call(globalObject, function, callData, plugin, arguments); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto exception = scope.exception(); scope.clearException(); if (!plugin->plugin.tombstoned) { diff --git a/src/bun.js/bindings/JSCommonJSModule.cpp b/src/bun.js/bindings/JSCommonJSModule.cpp index 4c4a0468ae..36d0e03cb6 100644 --- a/src/bun.js/bindings/JSCommonJSModule.cpp +++ b/src/bun.js/bindings/JSCommonJSModule.cpp @@ -450,6 +450,9 @@ JSC_DEFINE_CUSTOM_GETTER(getterPath, (JSC::JSGlobalObject * globalObject, JSC::E JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC::EncodedJSValue thisValue, JSC::PropertyName)) { + auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + JSCommonJSModule* thisObject = jsDynamicCast(JSValue::decode(thisValue)); if (!thisObject) [[unlikely]] { return JSValue::encode(jsUndefined()); @@ -469,6 +472,7 @@ JSC_DEFINE_CUSTOM_GETTER(getterParent, (JSC::JSGlobalObject * globalObject, JSC: auto idValue = thisObject->m_id.get(); if (idValue) { auto id = idValue->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); if (id == "."_s) { thisObject->m_overriddenParent.set(globalObject->vm(), thisObject, jsNull()); return JSValue::encode(jsNull()); @@ -1268,14 +1272,15 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionRequireCommonJS, (JSGlobalObject * lexicalGlo if (options.isObject()) { JSObject* obj = options.getObject(); // This getter is expensive and rare. - if (auto typeValue = obj->getIfPropertyExists(globalObject, vm.propertyNames->type)) { + auto typeValue = obj->getIfPropertyExists(globalObject, vm.propertyNames->type); + REQUIRE_CJS_RETURN_IF_EXCEPTION; + if (typeValue) { if (typeValue.isString()) { typeAttribute = typeValue.toWTFString(globalObject); - RETURN_IF_EXCEPTION(throwScope, {}); + REQUIRE_CJS_RETURN_IF_EXCEPTION; typeAttributeStr = Bun::toString(typeAttribute); } } - REQUIRE_CJS_RETURN_IF_EXCEPTION; } } diff --git a/src/bun.js/bindings/JSPromise.zig b/src/bun.js/bindings/JSPromise.zig index 631e29e6bc..a67fb9c87d 100644 --- a/src/bun.js/bindings/JSPromise.zig +++ b/src/bun.js/bindings/JSPromise.zig @@ -262,9 +262,6 @@ pub const JSPromise = opaque { /// The value can be another Promise /// If you want to create a new Promise that is already resolved, see JSPromise.resolvedPromiseValue pub fn resolve(this: *JSPromise, globalThis: *JSGlobalObject, value: JSValue) void { - var scope: JSC.CatchScope = undefined; - scope.init(globalThis, @src(), .enabled); - defer scope.deinit(); if (comptime bun.Environment.isDebug) { const loop = JSC.VirtualMachine.get().eventLoop(); loop.debug.js_call_count_outside_tick_queue += @as(usize, @intFromBool(!loop.debug.is_inside_tick_queue)); @@ -273,8 +270,7 @@ pub const JSPromise = opaque { } } - JSC__JSPromise__resolve(this, globalThis, value); - bun.debugAssert(!scope.hasException()); // TODO: properly propagate exception upwards + return bun.jsc.fromJSHostCallVoid(globalThis, @src(), JSC__JSPromise__resolve, .{ this, globalThis, value }) catch return bun.debugAssert(false); // TODO: properly propagate exception upwards } pub fn reject(this: *JSPromise, globalThis: *JSGlobalObject, value: JSError!JSValue) void { @@ -288,7 +284,7 @@ pub const JSPromise = opaque { const err = value catch |err| globalThis.takeException(err); - JSC__JSPromise__reject(this, globalThis, err); + return bun.jsc.fromJSHostCallVoid(globalThis, @src(), JSC__JSPromise__reject, .{ this, globalThis, err }) catch return bun.debugAssert(false); // TODO: properly propagate exception upwards } pub fn rejectAsHandled(this: *JSPromise, globalThis: *JSGlobalObject, value: JSValue) void { diff --git a/src/bun.js/bindings/JSPropertyIterator.cpp b/src/bun.js/bindings/JSPropertyIterator.cpp index b7891e8383..d9bd3ed52f 100644 --- a/src/bun.js/bindings/JSPropertyIterator.cpp +++ b/src/bun.js/bindings/JSPropertyIterator.cpp @@ -162,11 +162,11 @@ extern "C" EncodedJSValue Bun__JSPropertyIterator__getNameAndValueNonObservable( auto scope = DECLARE_THROW_SCOPE(vm); PropertySlot slot(object, PropertySlot::InternalMethodType::VMInquiry, vm.ptr()); - if (!object->getNonIndexPropertySlot(globalObject, prop, slot)) { + auto has = object->getNonIndexPropertySlot(globalObject, prop, slot); + RETURN_IF_EXCEPTION(scope, {}); + if (!has) { return {}; } - RETURN_IF_EXCEPTION(scope, {}); - if (slot.isAccessor() || slot.isCustom()) { return {}; } diff --git a/src/bun.js/bindings/JSPropertyIterator.zig b/src/bun.js/bindings/JSPropertyIterator.zig index 401d47d0df..55bae0558e 100644 --- a/src/bun.js/bindings/JSPropertyIterator.zig +++ b/src/bun.js/bindings/JSPropertyIterator.zig @@ -81,13 +81,8 @@ pub fn JSPropertyIterator(comptime options: JSPropertyIteratorOptions) type { var name = bun.String.dead; if (comptime options.include_value) { const FnToUse = if (options.observable) JSPropertyIteratorImpl.getNameAndValue else JSPropertyIteratorImpl.getNameAndValueNonObservable; - const current = FnToUse(this.impl.?, this.globalObject, this.object, &name, i); - if (current == .zero) { - if (this.globalObject.hasException()) { - return error.JSError; - } - continue; - } + const current: JSC.JSValue = try FnToUse(this.impl.?, this.globalObject, this.object, &name, i); + if (current == .zero) continue; current.ensureStillAlive(); this.value = current; } else { @@ -130,9 +125,27 @@ const JSPropertyIteratorImpl = opaque { } pub const deinit = Bun__JSPropertyIterator__deinit; - pub const getNameAndValue = Bun__JSPropertyIterator__getNameAndValue; - pub const getNameAndValueNonObservable = Bun__JSPropertyIterator__getNameAndValueNonObservable; + + pub fn getNameAndValue(iter: *JSPropertyIteratorImpl, globalObject: *JSC.JSGlobalObject, object: *JSC.JSObject, propertyName: *bun.String, i: usize) bun.JSError!JSC.JSValue { + var scope: bun.jsc.CatchScope = undefined; + scope.init(globalObject, @src(), .enabled); + defer scope.deinit(); + const value = Bun__JSPropertyIterator__getNameAndValue(iter, globalObject, object, propertyName, i); + try scope.returnIfException(); + return value; + } + + pub fn getNameAndValueNonObservable(iter: *JSPropertyIteratorImpl, globalObject: *JSC.JSGlobalObject, object: *JSC.JSObject, propertyName: *bun.String, i: usize) bun.JSError!JSC.JSValue { + var scope: bun.jsc.CatchScope = undefined; + scope.init(globalObject, @src(), .enabled); + defer scope.deinit(); + const value = Bun__JSPropertyIterator__getNameAndValueNonObservable(iter, globalObject, object, propertyName, i); + try scope.returnIfException(); + return value; + } + pub const getName = Bun__JSPropertyIterator__getName; + pub const getLongestPropertyName = Bun__JSPropertyIterator__getLongestPropertyName; /// may return null without an exception diff --git a/src/bun.js/bindings/JSStringDecoder.cpp b/src/bun.js/bindings/JSStringDecoder.cpp index 0212dd4a32..4795880fdf 100644 --- a/src/bun.js/bindings/JSStringDecoder.cpp +++ b/src/bun.js/bindings/JSStringDecoder.cpp @@ -81,6 +81,7 @@ static inline JSStringDecoder* jsStringDecoderCast(JSGlobalObject* globalObject, if (JSC::JSObject* thisObject = stringDecoderValue.getObject()) { auto clientData = WebCore::clientData(vm); JSValue existingDecoderValue = thisObject->getIfPropertyExists(globalObject, clientData->builtinNames().decodePrivateName()); + RETURN_IF_EXCEPTION(throwScope, {}); if (existingDecoderValue) [[likely]] { if (auto cast = jsDynamicCast(existingDecoderValue); cast) [[likely]] { return cast; @@ -458,7 +459,7 @@ JSC_DEFINE_HOST_FUNCTION(jsStringDecoderPrototypeFunction_write, auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSStringDecoder* castedThis = jsStringDecoderCast(globalObject, callFrame->thisValue(), "write"_s); RETURN_IF_EXCEPTION(scope, {}); - return jsStringDecoderPrototypeFunction_writeBody(globalObject, callFrame, castedThis); + RELEASE_AND_RETURN(scope, jsStringDecoderPrototypeFunction_writeBody(globalObject, callFrame, castedThis)); } JSC_DEFINE_HOST_FUNCTION(jsStringDecoderPrototypeFunction_end, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) @@ -466,7 +467,7 @@ JSC_DEFINE_HOST_FUNCTION(jsStringDecoderPrototypeFunction_end, auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSStringDecoder* castedThis = jsStringDecoderCast(globalObject, callFrame->thisValue(), "end"_s); RETURN_IF_EXCEPTION(scope, {}); - return jsStringDecoderPrototypeFunction_endBody(globalObject, callFrame, castedThis); + RELEASE_AND_RETURN(scope, jsStringDecoderPrototypeFunction_endBody(globalObject, callFrame, castedThis)); } JSC_DEFINE_HOST_FUNCTION(jsStringDecoderPrototypeFunction_text, (JSC::JSGlobalObject * globalObject, JSC::CallFrame* callFrame)) @@ -474,7 +475,7 @@ JSC_DEFINE_HOST_FUNCTION(jsStringDecoderPrototypeFunction_text, auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSStringDecoder* castedThis = jsStringDecoderCast(globalObject, callFrame->thisValue(), "text"_s); RETURN_IF_EXCEPTION(scope, {}); - return jsStringDecoderPrototypeFunction_textBody(globalObject, callFrame, castedThis); + RELEASE_AND_RETURN(scope, jsStringDecoderPrototypeFunction_textBody(globalObject, callFrame, castedThis)); } static JSC_DEFINE_CUSTOM_GETTER(jsStringDecoder_lastChar, (JSGlobalObject * lexicalGlobalObject, JSC::EncodedJSValue thisValue, PropertyName attributeName)) diff --git a/src/bun.js/bindings/JSValue.zig b/src/bun.js/bindings/JSValue.zig index b4e9519be8..853ba1b3f0 100644 --- a/src/bun.js/bindings/JSValue.zig +++ b/src/bun.js/bindings/JSValue.zig @@ -125,26 +125,17 @@ pub const JSValue = enum(i64) { try scope.returnIfException(); } - extern fn JSC__JSValue__coerceToDouble(this: JSValue, globalObject: *JSC.JSGlobalObject) f64; - /// Prefer toNumber over this function to - /// - Match the underlying JSC api name - /// - Match the underlying specification - /// - Catch exceptions - pub fn coerceToDouble(this: JSValue, globalObject: *JSC.JSGlobalObject) f64 { - return JSC__JSValue__coerceToDouble(this, globalObject); - } - - extern fn Bun__JSValue__toNumber(value: JSValue, global: *JSGlobalObject, had_error: *bool) f64; + extern fn Bun__JSValue__toNumber(value: JSValue, global: *JSGlobalObject) f64; /// Perform the ToNumber abstract operation, coercing a value to a number. /// Equivalent to `+value` /// https://tc39.es/ecma262/#sec-tonumber pub fn toNumber(this: JSValue, global: *JSGlobalObject) bun.JSError!f64 { - var had_error: bool = false; - const result = Bun__JSValue__toNumber(this, global, &had_error); - if (had_error) { - return error.JSError; - } + var scope: bun.jsc.CatchScope = undefined; + scope.init(global, @src(), .enabled); + defer scope.deinit(); + const result = Bun__JSValue__toNumber(this, global); + try scope.returnIfException(); return result; } @@ -176,14 +167,13 @@ pub const JSValue = enum(i64) { return @trunc(d) == d and @abs(d) <= JSC.MAX_SAFE_INTEGER; } - pub fn coerce(this: JSValue, comptime T: type, globalThis: *JSC.JSGlobalObject) T { + pub fn coerce(this: JSValue, comptime T: type, globalThis: *JSC.JSGlobalObject) bun.JSError!T { return switch (T) { - bool => this.toBoolean(), f64 => { if (this.isDouble()) { return this.asDouble(); } - return this.coerceToDouble(globalThis); + return this.toNumber(globalThis); }, i64 => { return this.coerceToInt64(globalThis); @@ -620,9 +610,9 @@ pub const JSValue = enum(i64) { } extern fn JSC__JSValue__createUninitializedUint8Array(globalObject: *JSGlobalObject, len: usize) JSValue; - pub fn createUninitializedUint8Array(globalObject: *JSGlobalObject, len: usize) JSValue { + pub fn createUninitializedUint8Array(globalObject: *JSGlobalObject, len: usize) bun.JSError!JSValue { JSC.markBinding(@src()); - return JSC__JSValue__createUninitializedUint8Array(globalObject, len); + return bun.jsc.fromJSHostCall(globalObject, @src(), JSC__JSValue__createUninitializedUint8Array, .{ globalObject, len }); } pub fn createBufferWithCtx(globalObject: *JSGlobalObject, slice: []u8, ptr: ?*anyopaque, func: JSC.C.JSTypedArrayBytesDeallocator) JSValue { @@ -1157,16 +1147,12 @@ pub const JSValue = enum(i64) { extern fn JSC__JSValue__toZigException(this: JSValue, global: *JSGlobalObject, exception: *ZigException) void; pub fn toZigException(this: JSValue, global: *JSGlobalObject, exception: *ZigException) void { - return JSC__JSValue__toZigException(this, global, exception); + return bun.jsc.fromJSHostCallVoid(global, @src(), JSC__JSValue__toZigException, .{ this, global, exception }) catch return; // TODO: properly propagate termination } extern fn JSC__JSValue__toZigString(this: JSValue, out: *ZigString, global: *JSGlobalObject) void; pub fn toZigString(this: JSValue, out: *ZigString, global: *JSGlobalObject) JSError!void { - var scope: CatchScope = undefined; - scope.init(global, @src(), .enabled); - defer scope.deinit(); - JSC__JSValue__toZigString(this, out, global); - try scope.returnIfException(); + return bun.jsc.fromJSHostCallVoid(global, @src(), JSC__JSValue__toZigString, .{ this, out, global }); } /// Increments the reference count, you must call `.deref()` or it will leak memory. diff --git a/src/bun.js/bindings/JSX509Certificate.cpp b/src/bun.js/bindings/JSX509Certificate.cpp index 86afb980f0..0bf271ba65 100644 --- a/src/bun.js/bindings/JSX509Certificate.cpp +++ b/src/bun.js/bindings/JSX509Certificate.cpp @@ -391,7 +391,6 @@ static JSObject* GetX509NameObject(JSGlobalObject* globalObject, const X509* cer // Check if this key already exists JSValue existing = result->getIfPropertyExists(globalObject, Identifier::fromString(vm, key)); - RETURN_IF_EXCEPTION(scope, nullptr); if (existing) { JSArray* array = jsDynamicCast(existing); diff --git a/src/bun.js/bindings/JSX509CertificatePrototype.cpp b/src/bun.js/bindings/JSX509CertificatePrototype.cpp index 198960046e..2883aabe9e 100644 --- a/src/bun.js/bindings/JSX509CertificatePrototype.cpp +++ b/src/bun.js/bindings/JSX509CertificatePrototype.cpp @@ -264,6 +264,7 @@ JSC_DEFINE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckEmail, (JSGlobalObject * auto emailString = arg0.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto view = emailString->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); uint32_t flags = getFlags(vm, globalObject, scope, callFrame->argument(1)); RETURN_IF_EXCEPTION(scope, {}); @@ -300,6 +301,7 @@ JSC_DEFINE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckHost, (JSGlobalObject * auto hostString = arg0.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto view = hostString->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); Bun::UTF8View hostView(view); @@ -330,6 +332,7 @@ JSC_DEFINE_HOST_FUNCTION(jsX509CertificateProtoFuncCheckIP, (JSGlobalObject * gl auto ipString = arg0.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto view = ipString->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); WTF::CString ip = view->utf8(); // ignore flags diff --git a/src/bun.js/bindings/ModuleLoader.cpp b/src/bun.js/bindings/ModuleLoader.cpp index e383c4327b..03284445d4 100644 --- a/src/bun.js/bindings/ModuleLoader.cpp +++ b/src/bun.js/bindings/ModuleLoader.cpp @@ -134,20 +134,25 @@ static OnLoadResult handleOnLoadObjectResult(Zig::GlobalObject* globalObject, JS OnLoadResult result {}; result.type = OnLoadResultTypeObject; auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); auto& builtinNames = WebCore::builtinNames(vm); - if (JSC::JSValue exportsValue = object->getIfPropertyExists(globalObject, builtinNames.exportsPublicName())) { + auto exportsValue = object->getIfPropertyExists(globalObject, builtinNames.exportsPublicName()); + if (scope.exception()) [[unlikely]] { + result.value.error = scope.exception(); + scope.clearException(); + return result; + } + if (exportsValue) { if (exportsValue.isObject()) { result.value.object = exportsValue; return result; } } - auto scope = DECLARE_THROW_SCOPE(vm); scope.throwException(globalObject, createTypeError(globalObject, "\"object\" loader must return an \"exports\" object"_s)); result.type = OnLoadResultTypeError; result.value.error = scope.exception(); scope.clearException(); - scope.release(); return result; } @@ -225,11 +230,18 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC:: scope.throwException(globalObject, JSC::createError(globalObject, "Expected module mock to return an object"_s)); result.value.error = scope.exception(); + scope.clearException(); result.type = OnLoadResultTypeError; return result; } - if (JSC::JSValue loaderValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "loader"_s))) { + auto loaderValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "loader"_s)); + if (scope.exception()) [[unlikely]] { + result.value.error = scope.exception(); + scope.clearException(); + return result; + } + if (loaderValue) { if (!loaderValue.isUndefinedOrNull()) { // If a loader is passed, we must validate it loader = BunLoaderTypeNone; @@ -258,6 +270,7 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC:: if (loader == BunLoaderTypeNone) [[unlikely]] { throwException(globalObject, scope, createError(globalObject, "Expected loader to be one of \"js\", \"jsx\", \"object\", \"ts\", \"tsx\", \"toml\", or \"json\""_s)); result.value.error = scope.exception(); + scope.clearException(); return result; } @@ -265,7 +278,13 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC:: result.value.sourceText.value = JSValue {}; result.value.sourceText.string = {}; - if (JSC::JSValue contentsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "contents"_s))) { + auto contentsValue = object->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "contents"_s)); + if (scope.exception()) [[unlikely]] { + result.value.error = scope.exception(); + scope.clearException(); + return result; + } + if (contentsValue) { if (contentsValue.isString()) { if (JSC::JSString* contentsJSString = contentsValue.toStringOrNull(globalObject)) { result.value.sourceText.string = Zig::toZigString(contentsJSString, globalObject); @@ -280,6 +299,7 @@ OnLoadResult handleOnLoadResultNotPromise(Zig::GlobalObject* globalObject, JSC:: if (result.value.sourceText.value.isEmpty()) [[unlikely]] { throwException(globalObject, scope, createError(globalObject, "Expected \"contents\" to be a string or an ArrayBufferView"_s)); result.value.error = scope.exception(); + scope.clearException(); return result; } @@ -372,11 +392,15 @@ static JSValue handleVirtualModuleResult( JSC::JSObject* object = onLoadResult.value.object.getObject(); if (commonJSModule) { const auto& __esModuleIdentifier = vm.propertyNames->__esModule; - JSValue esModuleValue = object->getIfPropertyExists(globalObject, __esModuleIdentifier); - RETURN_IF_EXCEPTION(scope, {}); + auto esModuleValue = object->getIfPropertyExists(globalObject, __esModuleIdentifier); + if (scope.exception()) [[unlikely]] { + return reject(scope.exception()); + } if (esModuleValue && esModuleValue.toBoolean(globalObject)) { - JSValue defaultValue = object->getIfPropertyExists(globalObject, vm.propertyNames->defaultKeyword); - RETURN_IF_EXCEPTION(scope, {}); + auto defaultValue = object->getIfPropertyExists(globalObject, vm.propertyNames->defaultKeyword); + if (scope.exception()) [[unlikely]] { + return reject(scope.exception()); + } if (defaultValue && !defaultValue.isUndefined()) { commonJSModule->setExportsObject(defaultValue); commonJSModule->hasEvaluated = true; @@ -715,6 +739,7 @@ JSValue fetchCommonJSModule( } JSMap* registry = globalObject->esmRegistryMap(); + RETURN_IF_EXCEPTION(scope, {}); bool hasAlreadyLoadedESMVersionSoWeShouldntTranspileItTwice = [&]() -> bool { JSValue entry = registry->get(globalObject, specifierValue); @@ -921,6 +946,7 @@ static JSValue fetchESMSourceCode( scope.clearException(); return rejectedInternalPromise(globalObject, exception); } else { + scope.release(); return {}; } } @@ -984,6 +1010,7 @@ static JSValue fetchESMSourceCode( scope.clearException(); return rejectedInternalPromise(globalObject, exception); } else { + scope.release(); return {}; } } @@ -1009,7 +1036,7 @@ static JSValue fetchESMSourceCode( if (res->result.value.tag == SyntheticModuleType::JSONForObjectLoader) { WTF::String jsonSource = res->result.value.source_code.toWTFString(BunString::NonNull); JSC::JSValue value = JSC::JSONParseWithException(globalObject, jsonSource); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto* exception = scope.exception(); scope.clearException(); return reject(exception); @@ -1109,7 +1136,7 @@ BUN_DEFINE_HOST_FUNCTION(jsFunctionOnLoadObjectResultResolve, (JSC::JSGlobalObje JSC::JSValue result = handleVirtualModuleResult(reinterpret_cast(globalObject), objectResult, &res, &specifier, &referrer, wasModuleMock); if (res.success) { - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto retValue = JSValue::encode(promise->rejectWithCaughtException(globalObject, scope)); pendingModule->internalField(2).set(vm, pendingModule, JSC::jsUndefined()); return retValue; diff --git a/src/bun.js/bindings/NodeDirent.cpp b/src/bun.js/bindings/NodeDirent.cpp index de4385bac7..04a339cc14 100644 --- a/src/bun.js/bindings/NodeDirent.cpp +++ b/src/bun.js/bindings/NodeDirent.cpp @@ -339,6 +339,7 @@ extern "C" JSC::EncodedJSValue Bun__Dirent__toJS(Zig::GlobalObject* globalObject JSString* pathValue = nullptr; if (path && path->tag == BunStringTag::WTFStringImpl && previousPath && *previousPath && (*previousPath)->length() == path->impl.wtf->length()) { auto view = (*previousPath)->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); if (view == path->impl.wtf) { pathValue = *previousPath; diff --git a/src/bun.js/bindings/NodeFSStatBinding.cpp b/src/bun.js/bindings/NodeFSStatBinding.cpp index d818b610e6..382bdefc42 100644 --- a/src/bun.js/bindings/NodeFSStatBinding.cpp +++ b/src/bun.js/bindings/NodeFSStatBinding.cpp @@ -143,6 +143,7 @@ static JSValue modeStatFunction(JSC::JSGlobalObject* globalObject, CallFrame* ca if constexpr (isBigInt) { int64_t mode_value = modeValue.toBigInt64(globalObject); + RETURN_IF_EXCEPTION(scope, {}); return jsBoolean(isModeFn(statFunction, mode_value)); } @@ -602,7 +603,6 @@ extern "C" JSC::EncodedJSValue Bun__createJSStatsObject(Zig::GlobalObject* globa int64_t uid, int64_t gid, int64_t rdev, int64_t size, int64_t blksize, int64_t blocks, double atimeMs, double mtimeMs, double ctimeMs, double birthtimeMs) { auto& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); JSC::JSValue js_dev = JSC::jsDoubleNumber(dev); JSC::JSValue js_ino = JSC::jsDoubleNumber(ino); @@ -637,7 +637,7 @@ extern "C" JSC::EncodedJSValue Bun__createJSStatsObject(Zig::GlobalObject* globa object->putDirectOffset(vm, 12, js_ctimeMs); object->putDirectOffset(vm, 13, js_birthtimeMs); - RELEASE_AND_RETURN(scope, JSC::JSValue::encode(object)); + return JSC::JSValue::encode(object); } extern "C" JSC::EncodedJSValue Bun__createJSBigIntStatsObject(Zig::GlobalObject* globalObject, @@ -665,23 +665,42 @@ extern "C" JSC::EncodedJSValue Bun__createJSBigIntStatsObject(Zig::GlobalObject* auto* structure = getStructure(globalObject); JSC::JSValue js_dev = JSC::JSBigInt::createFrom(globalObject, dev); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_ino = JSC::JSBigInt::createFrom(globalObject, ino); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_mode = JSC::JSBigInt::createFrom(globalObject, mode); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_nlink = JSC::JSBigInt::createFrom(globalObject, nlink); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_uid = JSC::JSBigInt::createFrom(globalObject, uid); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_gid = JSC::JSBigInt::createFrom(globalObject, gid); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_rdev = JSC::JSBigInt::createFrom(globalObject, rdev); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_size = JSC::JSBigInt::createFrom(globalObject, size); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_blksize = JSC::JSBigInt::createFrom(globalObject, blksize); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_blocks = JSC::JSBigInt::createFrom(globalObject, blocks); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_atimeMs = JSC::JSBigInt::createFrom(globalObject, atimeMs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_mtimeMs = JSC::JSBigInt::createFrom(globalObject, mtimeMs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_ctimeMs = JSC::JSBigInt::createFrom(globalObject, ctimeMs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_birthtimeMs = JSC::JSBigInt::createFrom(globalObject, birthtimeMs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_atimeNs = JSC::JSBigInt::createFrom(globalObject, atimeNs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_mtimeNs = JSC::JSBigInt::createFrom(globalObject, mtimeNs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_ctimeNs = JSC::JSBigInt::createFrom(globalObject, ctimeNs); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_birthtimeNs = JSC::JSBigInt::createFrom(globalObject, birthtimeNs); + RETURN_IF_EXCEPTION(scope, {}); + auto* object = JSC::JSFinalObject::create(vm, structure); object->putDirectOffset(vm, 0, js_dev); diff --git a/src/bun.js/bindings/NodeFSStatFSBinding.cpp b/src/bun.js/bindings/NodeFSStatFSBinding.cpp index e4256e613d..d768ed9596 100644 --- a/src/bun.js/bindings/NodeFSStatFSBinding.cpp +++ b/src/bun.js/bindings/NodeFSStatFSBinding.cpp @@ -259,7 +259,6 @@ extern "C" JSC::EncodedJSValue Bun__createJSStatFSObject(Zig::GlobalObject* glob int64_t ffree) { auto& vm = globalObject->vm(); - auto scope = DECLARE_THROW_SCOPE(vm); JSC::JSValue js_fstype = JSC::jsNumber(fstype); JSC::JSValue js_bsize = JSC::jsNumber(bsize); @@ -280,7 +279,7 @@ extern "C" JSC::EncodedJSValue Bun__createJSStatFSObject(Zig::GlobalObject* glob object->putDirectOffset(vm, 5, js_files); object->putDirectOffset(vm, 6, js_ffree); - RELEASE_AND_RETURN(scope, JSC::JSValue::encode(object)); + return JSC::JSValue::encode(object); } extern "C" JSC::EncodedJSValue Bun__createJSBigIntStatFSObject(Zig::GlobalObject* globalObject, @@ -297,12 +296,19 @@ extern "C" JSC::EncodedJSValue Bun__createJSBigIntStatFSObject(Zig::GlobalObject auto* structure = getStatFSStructure(globalObject); JSC::JSValue js_fstype = JSC::JSBigInt::createFrom(globalObject, fstype); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_bsize = JSC::JSBigInt::createFrom(globalObject, bsize); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_blocks = JSC::JSBigInt::createFrom(globalObject, blocks); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_bfree = JSC::JSBigInt::createFrom(globalObject, bfree); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_bavail = JSC::JSBigInt::createFrom(globalObject, bavail); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_files = JSC::JSBigInt::createFrom(globalObject, files); + RETURN_IF_EXCEPTION(scope, {}); JSC::JSValue js_ffree = JSC::JSBigInt::createFrom(globalObject, ffree); + RETURN_IF_EXCEPTION(scope, {}); auto* object = JSC::JSFinalObject::create(vm, structure); diff --git a/src/bun.js/bindings/NodeHTTP.cpp b/src/bun.js/bindings/NodeHTTP.cpp index d2a57e19cf..b0ce4653ee 100644 --- a/src/bun.js/bindings/NodeHTTP.cpp +++ b/src/bun.js/bindings/NodeHTTP.cpp @@ -922,12 +922,7 @@ static EncodedJSValue NodeHTTPServer__onRequest( args.append(thisValue); assignHeadersFromUWebSocketsForCall(request, methodString, args, globalObject, vm); - if (scope.exception()) { - auto* exception = scope.exception(); - response->endWithoutBody(); - scope.clearException(); - return JSValue::encode(exception); - } + RETURN_IF_EXCEPTION(scope, {}); bool hasBody = false; WebCore::JSNodeHTTPResponse* nodeHTTPResponseObject = jsCast(JSValue::decode(NodeHTTPResponse__createForJS(any_server, globalObject, &hasBody, request, isSSL, response, upgrade_ctx, nodeHttpResponsePtr))); @@ -948,11 +943,7 @@ static EncodedJSValue NodeHTTPServer__onRequest( args.append(jsUndefined()); } } else { - JSNodeHTTPServerSocket* socket = JSNodeHTTPServerSocket::create( - vm, - globalObject->m_JSNodeHTTPServerSocketStructure.getInitializedOnMainThread(globalObject), - (us_socket_t*)response, - isSSL, nodeHTTPResponseObject); + JSNodeHTTPServerSocket* socket = JSNodeHTTPServerSocket::create(vm, globalObject->m_JSNodeHTTPServerSocketStructure.getInitializedOnMainThread(globalObject), (us_socket_t*)response, isSSL, nodeHTTPResponseObject); socket->strongThis.set(vm, socket); @@ -964,13 +955,8 @@ static EncodedJSValue NodeHTTPServer__onRequest( } args.append(jsBoolean(request->isAncient())); - WTF::NakedPtr exception; - JSValue returnValue = AsyncContextFrame::call(globalObject, callbackObject, jsUndefined(), args, exception); - if (exception) { - auto* ptr = exception.get(); - exception.clear(); - return JSValue::encode(ptr); - } + JSValue returnValue = AsyncContextFrame::profiledCall(globalObject, callbackObject, jsUndefined(), args); + RETURN_IF_EXCEPTION(scope, {}); return JSValue::encode(returnValue); } @@ -1102,7 +1088,7 @@ static void NodeHTTPServer__writeHead( String key = entry.key(); String value = headerValue.toWTFString(globalObject); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { return false; } @@ -1117,6 +1103,7 @@ static void NodeHTTPServer__writeHead( for (unsigned i = 0; i < propertyNames.size(); ++i) { JSValue headerValue = headersObject->getIfPropertyExists(globalObject, propertyNames[i]); + RETURN_IF_EXCEPTION(scope, ); if (!headerValue.isString()) { continue; } @@ -1257,7 +1244,7 @@ JSC_DEFINE_HOST_FUNCTION(jsHTTPAssignHeaders, (JSGlobalObject * globalObject, Ca RETURN_IF_EXCEPTION(scope, {}); } - return assignHeadersFromFetchHeaders(impl, globalObject->objectPrototype(), objectValue, tuple, globalObject, vm); + RELEASE_AND_RETURN(scope, assignHeadersFromFetchHeaders(impl, globalObject->objectPrototype(), objectValue, tuple, globalObject, vm)); } } } @@ -1369,7 +1356,7 @@ JSC_DEFINE_HOST_FUNCTION(jsHTTPGetHeader, (JSGlobalObject * globalObject, CallFr WebCore::ExceptionOr res = impl->get(name); if (res.hasException()) { WebCore::propagateException(globalObject, scope, res.releaseException()); - return JSValue::encode(jsUndefined()); + RELEASE_AND_RETURN(scope, {}); } String value = res.returnValue(); diff --git a/src/bun.js/bindings/NodeVM.cpp b/src/bun.js/bindings/NodeVM.cpp index 94b8b0b253..c0aef23763 100644 --- a/src/bun.js/bindings/NodeVM.cpp +++ b/src/bun.js/bindings/NodeVM.cpp @@ -423,23 +423,26 @@ std::optional getNodeVMContextOptions(JSGlobalObject* globa JSObject* options = asObject(optionsArg); // Check name property - if (JSValue nameValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "name"_s))) { - RETURN_IF_EXCEPTION(scope, {}); + auto nameValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "name"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (nameValue) { if (!nameValue.isUndefined() && !nameValue.isString()) { return ERR::INVALID_ARG_TYPE(scope, globalObject, "options.name"_s, "string"_s, nameValue); } } // Check origin property - if (JSValue originValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "origin"_s))) { - RETURN_IF_EXCEPTION(scope, {}); + auto originValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "origin"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (originValue) { if (!originValue.isUndefined() && !originValue.isString()) { return ERR::INVALID_ARG_TYPE(scope, globalObject, "options.origin"_s, "string"_s, originValue); } } - if (JSValue codeGenerationValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, codeGenerationKey))) { - RETURN_IF_EXCEPTION(scope, {}); + auto codeGenerationValue = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, codeGenerationKey)); + RETURN_IF_EXCEPTION(scope, {}); + if (codeGenerationValue) { if (codeGenerationValue.isUndefined()) { return std::nullopt; @@ -451,8 +454,9 @@ std::optional getNodeVMContextOptions(JSGlobalObject* globa JSObject* codeGenerationObject = asObject(codeGenerationValue); - if (JSValue allowStringsValue = codeGenerationObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "strings"_s))) { - RETURN_IF_EXCEPTION(scope, {}); + auto allowStringsValue = codeGenerationObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "strings"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (allowStringsValue) { if (!allowStringsValue.isBoolean()) { return ERR::INVALID_ARG_TYPE(scope, globalObject, WTF::makeString("options."_s, codeGenerationKey, ".strings"_s), "boolean"_s, allowStringsValue); } @@ -460,8 +464,9 @@ std::optional getNodeVMContextOptions(JSGlobalObject* globa outOptions.allowStrings = allowStringsValue.toBoolean(globalObject); } - if (JSValue allowWasmValue = codeGenerationObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "wasm"_s))) { - RETURN_IF_EXCEPTION(scope, {}); + auto allowWasmValue = codeGenerationObject->getIfPropertyExists(globalObject, Identifier::fromString(vm, "wasm"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (allowWasmValue) { if (!allowWasmValue.isBoolean()) { return ERR::INVALID_ARG_TYPE(scope, globalObject, WTF::makeString("options."_s, codeGenerationKey, ".wasm"_s), "boolean"_s, allowWasmValue); } @@ -1260,7 +1265,9 @@ bool BaseVMOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC:: return false; } - if (JSValue filenameOpt = options->getIfPropertyExists(globalObject, builtinNames(vm).filenamePublicName())) { + auto filenameOpt = options->getIfPropertyExists(globalObject, builtinNames(vm).filenamePublicName()); + RETURN_IF_EXCEPTION(scope, false); + if (filenameOpt) { if (filenameOpt.isString()) { this->filename = filenameOpt.toWTFString(globalObject); RETURN_IF_EXCEPTION(scope, false); @@ -1273,7 +1280,9 @@ bool BaseVMOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC:: this->filename = "evalmachine."_s; } - if (JSValue lineOffsetOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "lineOffset"_s))) { + auto lineOffsetOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "lineOffset"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (lineOffsetOpt) { if (lineOffsetOpt.isAnyInt()) { if (!lineOffsetOpt.isInt32()) { ERR::OUT_OF_RANGE(scope, globalObject, "options.lineOffset"_s, std::numeric_limits().min(), std::numeric_limits().max(), lineOffsetOpt); @@ -1290,7 +1299,9 @@ bool BaseVMOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC:: } } - if (JSValue columnOffsetOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "columnOffset"_s))) { + auto columnOffsetOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "columnOffset"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (columnOffsetOpt) { if (columnOffsetOpt.isAnyInt()) { if (!columnOffsetOpt.isInt32()) { ERR::OUT_OF_RANGE(scope, globalObject, "options.columnOffset"_s, std::numeric_limits().min(), std::numeric_limits().max(), columnOffsetOpt); @@ -1316,8 +1327,8 @@ bool BaseVMOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC:: bool BaseVMOptions::validateProduceCachedData(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC::ThrowScope& scope, JSObject* options, bool& outProduceCachedData) { JSValue produceCachedDataOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "produceCachedData"_s)); + RETURN_IF_EXCEPTION(scope, false); if (produceCachedDataOpt && !produceCachedDataOpt.isUndefined()) { - RETURN_IF_EXCEPTION(scope, {}); if (!produceCachedDataOpt.isBoolean()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.produceCachedData"_s, "boolean"_s, produceCachedDataOpt); return false; @@ -1348,6 +1359,7 @@ bool BaseVMOptions::validateCachedData(JSC::JSGlobalObject* globalObject, JSC::V bool BaseVMOptions::validateTimeout(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC::ThrowScope& scope, JSObject* options, std::optional& outTimeout) { JSValue timeoutOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "timeout"_s)); + RETURN_IF_EXCEPTION(scope, false); if (timeoutOpt && !timeoutOpt.isUndefined()) { if (!timeoutOpt.isNumber()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.timeout"_s, "number"_s, timeoutOpt); diff --git a/src/bun.js/bindings/NodeVMModule.cpp b/src/bun.js/bindings/NodeVMModule.cpp index 6cfc93a5a1..4b6ce40cb2 100644 --- a/src/bun.js/bindings/NodeVMModule.cpp +++ b/src/bun.js/bindings/NodeVMModule.cpp @@ -86,7 +86,7 @@ JSValue NodeVMModule::evaluate(JSGlobalObject* globalObject, uint32_t timeout, b } else if (syntheticThis) { syntheticThis->evaluate(globalObject); } - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { return; } result = record->evaluate(globalObject, jsUndefined(), jsNumber(static_cast(JSGenerator::ResumeMode::NormalMode))); diff --git a/src/bun.js/bindings/NodeVMScript.cpp b/src/bun.js/bindings/NodeVMScript.cpp index 2a31141151..42726c8275 100644 --- a/src/bun.js/bindings/NodeVMScript.cpp +++ b/src/bun.js/bindings/NodeVMScript.cpp @@ -25,23 +25,25 @@ bool ScriptOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm, JSC:: JSObject* options = asObject(optionsArg); // Validate contextName and contextOrigin are strings - if (JSValue contextNameOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "contextName"_s))) { + auto contextNameOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "contextName"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (contextNameOpt) { if (!contextNameOpt.isUndefined() && !contextNameOpt.isString()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.contextName"_s, "string"_s, contextNameOpt); return false; } any = true; } - RETURN_IF_EXCEPTION(scope, false); - if (JSValue contextOriginOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "contextOrigin"_s))) { + auto contextOriginOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "contextOrigin"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (contextOriginOpt) { if (!contextOriginOpt.isUndefined() && !contextOriginOpt.isString()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.contextOrigin"_s, "string"_s, contextOriginOpt); return false; } any = true; } - RETURN_IF_EXCEPTION(scope, false); if (validateTimeout(globalObject, vm, scope, options, this->timeout)) { RETURN_IF_EXCEPTION(scope, false); @@ -553,7 +555,7 @@ JSC_DEFINE_HOST_FUNCTION(scriptRunInNewContext, (JSGlobalObject * globalObject, zigGlobal->NodeVMGlobalObjectStructure(), {}); - return runInContext(targetContext, script, context, callFrame->argument(1)); + RELEASE_AND_RETURN(scope, runInContext(targetContext, script, context, callFrame->argument(1))); } class NodeVMScriptPrototype final : public JSC::JSNonFinalObject { @@ -624,8 +626,9 @@ bool RunningScriptOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm if (!optionsArg.isUndefined() && !optionsArg.isString()) { JSObject* options = asObject(optionsArg); - if (JSValue displayErrorsOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "displayErrors"_s))) { - RETURN_IF_EXCEPTION(scope, false); + auto displayErrorsOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "displayErrors"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (displayErrorsOpt) { if (!displayErrorsOpt.isUndefined()) { if (!displayErrorsOpt.isBoolean()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.displayErrors"_s, "boolean"_s, displayErrorsOpt); @@ -637,12 +640,13 @@ bool RunningScriptOptions::fromJS(JSC::JSGlobalObject* globalObject, JSC::VM& vm } if (validateTimeout(globalObject, vm, scope, options, this->timeout)) { - RETURN_IF_EXCEPTION(scope, false); any = true; } + RETURN_IF_EXCEPTION(scope, {}); - if (JSValue breakOnSigintOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "breakOnSigint"_s))) { - RETURN_IF_EXCEPTION(scope, false); + auto breakOnSigintOpt = options->getIfPropertyExists(globalObject, Identifier::fromString(vm, "breakOnSigint"_s)); + RETURN_IF_EXCEPTION(scope, false); + if (breakOnSigintOpt) { if (!breakOnSigintOpt.isUndefined()) { if (!breakOnSigintOpt.isBoolean()) { ERR::INVALID_ARG_TYPE(scope, globalObject, "options.breakOnSigint"_s, "boolean"_s, breakOnSigintOpt); diff --git a/src/bun.js/bindings/NodeValidator.cpp b/src/bun.js/bindings/NodeValidator.cpp index 46bde7b9ca..18e84e503e 100644 --- a/src/bun.js/bindings/NodeValidator.cpp +++ b/src/bun.js/bindings/NodeValidator.cpp @@ -567,7 +567,7 @@ JSC_DEFINE_HOST_FUNCTION(jsFunction_validateEncoding, (JSC::JSGlobalObject * glo length = impl->byteLength(); } } else if (auto* object = data.getObject()) { - JSValue lengthValue = object->getIfPropertyExists(globalObject, vm.propertyNames->length); + JSValue lengthValue = object->get(globalObject, vm.propertyNames->length); RETURN_IF_EXCEPTION(scope, {}); length = lengthValue.toLength(globalObject); RETURN_IF_EXCEPTION(scope, {}); @@ -663,6 +663,7 @@ JSC::EncodedJSValue V::validateOneOf(JSC::ThrowScope& scope, JSC::JSGlobalObject JSC::JSString* valueStr = value.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto valueView = valueStr->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); for (ASCIILiteral oneOfStr : oneOf) { diff --git a/src/bun.js/bindings/S3Error.cpp b/src/bun.js/bindings/S3Error.cpp index 52d35f2511..8f90ab38c3 100644 --- a/src/bun.js/bindings/S3Error.cpp +++ b/src/bun.js/bindings/S3Error.cpp @@ -38,6 +38,7 @@ SYSV_ABI JSC::EncodedJSValue S3Error__toErrorInstance(const S3Error* arg0, JSC::JSValue options = JSC::jsUndefined(); auto prototype = defaultGlobalObject(globalObject)->m_S3ErrorStructure.getInitializedOnMainThread(globalObject); JSC::JSObject* result = JSC::ErrorInstance::create(globalObject, prototype, message, options); + RETURN_IF_EXCEPTION(scope, {}); result->putDirect(vm, vm.propertyNames->name, defaultGlobalObject(globalObject)->commonStrings().s3ErrorString(globalObject), JSC::PropertyAttribute::DontEnum | 0); if (err.code.tag != BunStringTag::Empty) { JSC::JSValue code = Bun::toJS(globalObject, err.code); diff --git a/src/bun.js/bindings/SQLClient.cpp b/src/bun.js/bindings/SQLClient.cpp index 8b76c2c81b..af1eab7776 100644 --- a/src/bun.js/bindings/SQLClient.cpp +++ b/src/bun.js/bindings/SQLClient.cpp @@ -126,6 +126,8 @@ public: static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCell& cell) { + auto scope = DECLARE_THROW_SCOPE(vm); + switch (cell.tag) { case DataCellTag::Null: return jsNull(); @@ -134,9 +136,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel Zig::GlobalObject* zigGlobal = jsCast(globalObject); auto* subclassStructure = zigGlobal->JSBufferSubclassStructure(); auto* uint8Array = JSC::JSUint8Array::createUninitialized(globalObject, subclassStructure, cell.value.raw.length); - if (uint8Array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (cell.value.raw.length > 0) { memcpy(uint8Array->vector(), reinterpret_cast(cell.value.raw.ptr), cell.value.raw.length); @@ -173,9 +173,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel Zig::GlobalObject* zigGlobal = jsCast(globalObject); auto* subclassStructure = zigGlobal->JSBufferSubclassStructure(); auto* uint8Array = JSC::JSUint8Array::createUninitialized(globalObject, subclassStructure, cell.value.bytea[1]); - if (uint8Array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (cell.value.bytea[1] > 0) { memcpy(uint8Array->vector(), reinterpret_cast(cell.value.bytea[0]), cell.value.bytea[1]); @@ -210,9 +208,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel switch (type) { case JSC::JSType::Int32ArrayType: { JSC::JSInt32Array* array = JSC::JSInt32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(int32_t)); @@ -222,9 +218,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Uint32ArrayType: { JSC::JSUint32Array* array = JSC::JSUint32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(uint32_t)); @@ -233,9 +227,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Int16ArrayType: { JSC::JSInt16Array* array = JSC::JSInt16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(int16_t)); @@ -245,9 +237,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Uint16ArrayType: { JSC::JSUint16Array* array = JSC::JSUint16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(uint16_t)); @@ -256,9 +246,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Float16ArrayType: { JSC::JSFloat16Array* array = JSC::JSFloat16Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * 2); // sizeof(float16_t) @@ -267,9 +255,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Float32ArrayType: { JSC::JSFloat32Array* array = JSC::JSFloat32Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(float)); @@ -278,9 +264,7 @@ static JSC::JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, DataCel } case JSC::JSType::Float64ArrayType: { JSC::JSFloat64Array* array = JSC::JSFloat64Array::createUninitialized(globalObject, globalObject->typedArrayStructureWithTypedArrayType(), length); - if (array == nullptr) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (length > 0) { memcpy(array->vector(), reinterpret_cast(cell.value.typed_array.data), length * sizeof(double)); diff --git a/src/bun.js/bindings/Serialization.cpp b/src/bun.js/bindings/Serialization.cpp index 83c986f6c4..2a033daa71 100644 --- a/src/bun.js/bindings/Serialization.cpp +++ b/src/bun.js/bindings/Serialization.cpp @@ -31,8 +31,7 @@ extern "C" SerializedValueSlice Bun__serializeJSValue(JSGlobalObject* globalObje auto scope = DECLARE_THROW_SCOPE(vm); if (serialized.hasException()) { - WebCore::propagateException(*globalObject, scope, - serialized.releaseException()); + WebCore::propagateException(*globalObject, scope, serialized.releaseException()); RELEASE_AND_RETURN(scope, { 0 }); } diff --git a/src/bun.js/bindings/SystemError.zig b/src/bun.js/bindings/SystemError.zig index 484ed54489..b9fa36042b 100644 --- a/src/bun.js/bindings/SystemError.zig +++ b/src/bun.js/bindings/SystemError.zig @@ -9,7 +9,7 @@ pub const SystemError = extern struct { errno: c_int = 0, /// label for errno code: String = .empty, - message: String = .empty, + message: String, // it is illegal to have an empty message path: String = .empty, syscall: String = .empty, hostname: String = .empty, @@ -52,7 +52,6 @@ pub const SystemError = extern struct { pub fn toErrorInstance(this: *const SystemError, global: *JSGlobalObject) JSValue { defer this.deref(); - return SystemError__toErrorInstance(this, global); } @@ -77,7 +76,6 @@ pub const SystemError = extern struct { /// to match the error code that `node:os` throws. pub fn toErrorInstanceWithInfoObject(this: *const SystemError, global: *JSGlobalObject) JSValue { defer this.deref(); - return SystemError__toErrorInstanceWithInfoObject(this, global); } diff --git a/src/bun.js/bindings/UtilInspect.cpp b/src/bun.js/bindings/UtilInspect.cpp index cdb3c8ed0e..ae09d5b11c 100644 --- a/src/bun.js/bindings/UtilInspect.cpp +++ b/src/bun.js/bindings/UtilInspect.cpp @@ -28,6 +28,7 @@ Structure* createUtilInspectOptionsStructure(VM& vm, JSC::JSGlobalObject* global JSObject* createInspectOptionsObject(VM& vm, Zig::GlobalObject* globalObject, unsigned max_depth, bool colors) { JSFunction* stylizeFn = colors ? globalObject->utilInspectStylizeColorFunction() : globalObject->utilInspectStylizeNoColorFunction(); + if (!stylizeFn) return nullptr; JSObject* options = JSC::constructEmptyObject(vm, globalObject->utilInspectOptionsStructure()); options->putDirectOffset(vm, 0, stylizeFn); options->putDirectOffset(vm, 1, jsNumber(max_depth)); @@ -41,8 +42,7 @@ extern "C" JSC::EncodedJSValue JSC__JSValue__callCustomInspectFunction( JSC::EncodedJSValue encodedThisValue, unsigned depth, unsigned max_depth, - bool colors, - bool* is_exception) + bool colors) { JSValue functionToCall = JSValue::decode(encodedFunctionValue); JSValue thisValue = JSValue::decode(encodedThisValue); @@ -50,8 +50,10 @@ extern "C" JSC::EncodedJSValue JSC__JSValue__callCustomInspectFunction( auto scope = DECLARE_THROW_SCOPE(vm); JSObject* options = Bun::createInspectOptionsObject(vm, globalObject, max_depth, colors); + RETURN_IF_EXCEPTION(scope, {}); JSFunction* inspectFn = globalObject->utilInspectFunction(); + RETURN_IF_EXCEPTION(scope, {}); auto callData = JSC::getCallData(functionToCall); MarkedArgumentBuffer arguments; arguments.append(jsNumber(depth)); @@ -59,10 +61,7 @@ extern "C" JSC::EncodedJSValue JSC__JSValue__callCustomInspectFunction( arguments.append(inspectFn); auto inspectRet = JSC::profiledCall(globalObject, ProfilingReason::API, functionToCall, callData, thisValue, arguments); - if (scope.exception()) { - *is_exception = true; - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); RELEASE_AND_RETURN(scope, JSValue::encode(inspectRet)); } diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 38ea21cf49..65f2a2631d 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -338,8 +338,9 @@ static JSValue formatStackTraceToJSValue(JSC::VM& vm, Zig::GlobalObject* globalO WTF::StringBuilder sb; - if (JSC::JSValue errorMessage = errorObject->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->message)) { - RETURN_IF_EXCEPTION(scope, {}); + auto errorMessage = errorObject->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->message); + RETURN_IF_EXCEPTION(scope, {}); + if (errorMessage) { auto* str = errorMessage.toString(lexicalGlobalObject); RETURN_IF_EXCEPTION(scope, {}); if (str->length() > 0) { @@ -428,7 +429,7 @@ static JSValue formatStackTraceToJSValueWithoutPrepareStackTrace(JSC::VM& vm, Zi auto* errorConstructor = lexicalGlobalObject->m_errorStructure.constructor(globalObject); prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, JSC::Identifier::fromString(vm, "prepareStackTrace"_s)); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); } } @@ -771,9 +772,9 @@ static JSValue computeErrorInfoToJSValueWithoutSkipping(JSC::VM& vm, VectorglobalObject(); globalObject = jsDynamicCast(lexicalGlobalObject); + auto scope = DECLARE_THROW_SCOPE(vm); // Error.prepareStackTrace - https://v8.dev/docs/stack-trace-api#customizing-stack-traces if (!globalObject) { @@ -781,12 +782,14 @@ static JSValue computeErrorInfoToJSValueWithoutSkipping(JSC::VM& vm, VectorisInsideErrorPrepareStackTraceCallback) { auto* errorConstructor = lexicalGlobalObject->m_errorStructure.constructor(lexicalGlobalObject); - if (JSValue prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "prepareStackTrace"_s))) { + auto prepareStackTrace = errorConstructor->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "prepareStackTrace"_s)); + RETURN_IF_EXCEPTION(scope, {}); + if (prepareStackTrace) { if (prepareStackTrace.isCell() && prepareStackTrace.isObject() && prepareStackTrace.isCallable()) { globalObject->isInsideErrorPrepareStackTraceCallback = true; auto result = computeErrorInfoWithPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, errorInstance, prepareStackTrace.getObject()); globalObject->isInsideErrorPrepareStackTraceCallback = false; - return result; + RELEASE_AND_RETURN(scope, result); } } } @@ -797,13 +800,14 @@ static JSValue computeErrorInfoToJSValueWithoutSkipping(JSC::VM& vm, VectorisInsideErrorPrepareStackTraceCallback = true; auto result = computeErrorInfoWithPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, errorInstance, prepareStackTrace.getObject()); globalObject->isInsideErrorPrepareStackTraceCallback = false; - return result; + RELEASE_AND_RETURN(scope, result); } } } } String result = computeErrorInfoWithoutPrepareStackTrace(vm, globalObject, lexicalGlobalObject, stackTrace, line, column, sourceURL, errorInstance); + RETURN_IF_EXCEPTION(scope, {}); return jsString(vm, result); } @@ -817,7 +821,14 @@ static String computeErrorInfoWrapperToString(JSC::VM& vm, Vector& s OrdinalNumber line = OrdinalNumber::fromOneBasedInt(line_in); OrdinalNumber column = OrdinalNumber::fromOneBasedInt(column_in); + auto scope = DECLARE_CATCH_SCOPE(vm); WTF::String result = computeErrorInfoToString(vm, stackTrace, line, column, sourceURL); + if (scope.exception()) { + // TODO: is this correct? vm.setOnComputeErrorInfo doesnt appear to properly handle a function that can throw + // test/js/node/test/parallel/test-stream-writable-write-writev-finish.js is the one that trips the exception checker + scope.clearException(); + result = WTF::emptyString(); + } line_in = line.oneBasedInt(); column_in = column.oneBasedInt(); @@ -1565,11 +1576,13 @@ JSC_DEFINE_HOST_FUNCTION(functionStructuredClone, (JSC::JSGlobalObject * globalO if (options.isObject()) { JSC::JSObject* optionsObject = options.getObject(); JSC::JSValue transferListValue = optionsObject->get(globalObject, vm.propertyNames->transfer); + RETURN_IF_EXCEPTION(throwScope, {}); if (transferListValue.isObject()) { JSC::JSObject* transferListObject = transferListValue.getObject(); if (auto* transferListArray = jsDynamicCast(transferListObject)) { for (unsigned i = 0; i < transferListArray->length(); i++) { JSC::JSValue transferListValue = transferListArray->get(globalObject, i); + RETURN_IF_EXCEPTION(throwScope, {}); if (transferListValue.isObject()) { JSC::JSObject* transferListObject = transferListValue.getObject(); transferList.append(JSC::Strong(vm, transferListObject)); @@ -1583,10 +1596,12 @@ JSC_DEFINE_HOST_FUNCTION(functionStructuredClone, (JSC::JSGlobalObject * globalO ExceptionOr> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), ports); if (serialized.hasException()) { WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); - return JSValue::encode(jsUndefined()); + RELEASE_AND_RETURN(throwScope, {}); } + throwScope.assertNoException(); JSValue deserialized = serialized.releaseReturnValue()->deserialize(*globalObject, globalObject, ports); + RETURN_IF_EXCEPTION(throwScope, {}); return JSValue::encode(deserialized); } @@ -1738,11 +1753,7 @@ extern "C" JSC::EncodedJSValue Bun__allocUint8ArrayForCopy(JSC::JSGlobalObject* auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(globalObject, globalObject->m_typedArrayUint8.get(globalObject), len); - - if (!array) [[unlikely]] { - JSC::throwOutOfMemoryError(globalObject, scope); - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); *ptr = array->vector(); @@ -1757,10 +1768,7 @@ extern "C" JSC::EncodedJSValue Bun__allocArrayBufferForCopy(JSC::JSGlobalObject* auto* subclassStructure = globalObject->JSBufferSubclassStructure(); auto buf = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, subclassStructure, len); - - if (!buf) [[unlikely]] { - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); *ptr = buf->vector(); @@ -1774,11 +1782,7 @@ extern "C" JSC::EncodedJSValue Bun__createUint8ArrayForCopy(JSC::JSGlobalObject* auto* subclassStructure = isBuffer ? static_cast(globalObject)->JSBufferSubclassStructure() : globalObject->typedArrayStructureWithTypedArrayType(); JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(globalObject, subclassStructure, len); - - if (!array) [[unlikely]] { - JSC::throwOutOfMemoryError(globalObject, scope); - return {}; - } + RETURN_IF_EXCEPTION(scope, {}); if (len > 0 && ptr != nullptr) memcpy(array->vector(), ptr, len); @@ -2014,12 +2018,12 @@ static inline std::optional invokeReadableStreamFunction(JSC::JSGl auto callData = JSC::getCallData(function); auto result = call(&lexicalGlobalObject, function, callData, thisValue, arguments); #if ASSERT_ENABLED - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { Bun__reportError(&lexicalGlobalObject, JSValue::encode(scope.exception())); } #endif EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); - if (scope.exception()) + if (scope.exception()) [[unlikely]] return {}; return result; } @@ -2110,8 +2114,10 @@ extern "C" int32_t ReadableStreamTag__tagged(Zig::GlobalObject* globalObject, JS if (function && !function->isHostFunction() && function->jsExecutable() && function->jsExecutable()->isAsyncGenerator()) { fn = object; target = jsUndefined(); - } else if (auto iterable = object->getIfPropertyExists(globalObject, vm.propertyNames->asyncIteratorSymbol)) { - if (iterable.isCallable()) { + } else { + auto iterable = object->getIfPropertyExists(globalObject, vm.propertyNames->asyncIteratorSymbol); + RETURN_IF_EXCEPTION(throwScope, {}); + if (iterable && iterable.isCallable()) { fn = iterable; } } @@ -2668,6 +2674,7 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb OrdinalNumber column; String sourceURL; JSValue result = computeErrorInfoToJSValue(vm, stackTrace, line, column, sourceURL, errorObject); + RETURN_IF_EXCEPTION(scope, {}); errorObject->putDirect(vm, vm.propertyNames->stack, result, 0); } @@ -2964,9 +2971,14 @@ void GlobalObject::finishCreation(VM& vm) m_utilInspectFunction.initLater( [](const Initializer& init) { + auto scope = DECLARE_THROW_SCOPE(init.vm); JSValue nodeUtilValue = jsCast(init.owner)->internalModuleRegistry()->requireId(init.owner, init.vm, Bun::InternalModuleRegistry::Field::NodeUtil); + RETURN_IF_EXCEPTION(scope, ); RELEASE_ASSERT(nodeUtilValue.isObject()); - init.set(jsCast(nodeUtilValue.getObject()->getIfPropertyExists(init.owner, Identifier::fromString(init.vm, "inspect"_s)))); + auto prop = nodeUtilValue.getObject()->getIfPropertyExists(init.owner, Identifier::fromString(init.vm, "inspect"_s)); + RETURN_IF_EXCEPTION(scope, ); + ASSERT(prop); + init.set(jsCast(prop)); }); m_utilInspectOptionsStructure.initLater( @@ -2985,23 +2997,23 @@ void GlobalObject::finishCreation(VM& vm) m_utilInspectStylizeColorFunction.initLater( [](const Initializer& init) { + auto scope = DECLARE_THROW_SCOPE(init.vm); JSC::MarkedArgumentBuffer args; args.append(jsCast(init.owner)->utilInspectFunction()); + RETURN_IF_EXCEPTION(scope, ); - auto scope = DECLARE_THROW_SCOPE(init.vm); JSC::JSFunction* getStylize = JSC::JSFunction::create(init.vm, init.owner, utilInspectGetStylizeWithColorCodeGenerator(init.vm), init.owner); - // RETURN_IF_EXCEPTION(scope, {}); + RETURN_IF_EXCEPTION(scope, ); JSC::CallData callData = JSC::getCallData(getStylize); - NakedPtr returnedException = nullptr; auto result = JSC::profiledCall(init.owner, ProfilingReason::API, getStylize, callData, jsNull(), args, returnedException); - // RETURN_IF_EXCEPTION(scope, {}); + RETURN_IF_EXCEPTION(scope, ); if (returnedException) { throwException(init.owner, scope, returnedException.get()); } - // RETURN_IF_EXCEPTION(scope, {}); + RETURN_IF_EXCEPTION(scope, ); init.set(jsCast(result)); }); @@ -3515,14 +3527,17 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionToClass, (JSC::JSGlobalObject * globalObject, if (!base) { base = globalObject->functionPrototype(); - } else if (auto proto = base->getIfPropertyExists(globalObject, vm.propertyNames->prototype)) { - if (auto protoObject = proto.getObject()) { - prototypeBase = protoObject; - } } else { + auto proto = base->getIfPropertyExists(globalObject, vm.propertyNames->prototype); RETURN_IF_EXCEPTION(scope, encodedJSValue()); - JSC::throwTypeError(globalObject, scope, "Base class must have a prototype property"_s); - return encodedJSValue(); + if (proto) { + if (auto protoObject = proto.getObject()) { + prototypeBase = protoObject; + } + } else { + JSC::throwTypeError(globalObject, scope, "Base class must have a prototype property"_s); + return encodedJSValue(); + } } JSObject* prototype = prototypeBase ? JSC::constructEmptyObject(globalObject, prototypeBase) : JSC::constructEmptyObject(globalObject); @@ -4108,7 +4123,7 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* j auto result = JSC::importModule(globalObject, resolvedIdentifier, JSC::jsUndefined(), parameters, JSC::jsUndefined()); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto* promise = JSC::JSInternalPromise::create(vm, globalObject->internalPromiseStructure()); return promise->rejectWithCaughtException(globalObject, scope); } @@ -4181,10 +4196,14 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* j // Therefore, we modify it in place. if (parameters && parameters.isObject()) { auto* object = parameters.toObject(globalObject); - if (auto withObject = object->getIfPropertyExists(globalObject, vm.propertyNames->withKeyword)) { + auto withObject = object->getIfPropertyExists(globalObject, vm.propertyNames->withKeyword); + RETURN_IF_EXCEPTION(scope, {}); + if (withObject) { if (withObject.isObject()) { auto* with = jsCast(withObject); - if (auto type = with->getIfPropertyExists(globalObject, vm.propertyNames->type)) { + auto type = with->getIfPropertyExists(globalObject, vm.propertyNames->type); + RETURN_IF_EXCEPTION(scope, {}); + if (type) { if (type.isString()) { const auto typeString = type.toWTFString(globalObject); parameters = JSC::JSScriptFetchParameters::create(vm, ScriptFetchParameters::create(typeString)); @@ -4196,7 +4215,7 @@ JSC::JSInternalPromise* GlobalObject::moduleLoaderImportModule(JSGlobalObject* j auto result = JSC::importModule(globalObject, resolvedIdentifier, JSC::jsUndefined(), parameters, jsUndefined()); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { return JSC::JSInternalPromise::rejectedPromiseWithCaughtException(globalObject, scope); } diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index aa44127ddb..983943a557 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -238,21 +238,18 @@ extern "C" int8_t AsymmetricMatcherConstructorType__fromJS(JSC::JSGlobalObject* auto stringConstructorValue = globalObject->stringPrototype()->getIfPropertyExists(globalObject, vm.propertyNames->constructor); RETURN_IF_EXCEPTION(scope, -1); - if (stringConstructorValue == object) { return static_cast(AsymmetricMatcherConstructorType::String); } auto symbolConstructorValue = globalObject->symbolPrototype()->getIfPropertyExists(globalObject, vm.propertyNames->constructor); RETURN_IF_EXCEPTION(scope, -1); - if (symbolConstructorValue == object) { return static_cast(AsymmetricMatcherConstructorType::Symbol); } auto bigIntConstructorValue = globalObject->bigIntPrototype()->getIfPropertyExists(globalObject, vm.propertyNames->constructor); RETURN_IF_EXCEPTION(scope, -1); - if (bigIntConstructorValue == object) { return static_cast(AsymmetricMatcherConstructorType::BigInt); } @@ -1627,7 +1624,6 @@ bool Bun__deepMatch( for (const auto& property : subsetProps) { JSValue prop = obj->getIfPropertyExists(globalObject, property); RETURN_IF_EXCEPTION(*throwScope, false); - if (prop.isEmpty()) { return false; } @@ -1735,8 +1731,8 @@ void WebCore__FetchHeaders__append(WebCore::FetchHeaders* headers, const ZigStri JSC::JSGlobalObject* lexicalGlobalObject) { auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm()); - WebCore::propagateException(*lexicalGlobalObject, throwScope, - headers->append(Zig::toString(*arg1), Zig::toString(*arg2))); + WebCore::propagateException(*lexicalGlobalObject, throwScope, headers->append(Zig::toString(*arg1), Zig::toString(*arg2))); + RELEASE_AND_RETURN(throwScope, ); } WebCore::FetchHeaders* WebCore__FetchHeaders__cast_(JSC::EncodedJSValue JSValue0, JSC::VM* vm) { @@ -1785,8 +1781,7 @@ WebCore::FetchHeaders* WebCore__FetchHeaders__createFromJS(JSC::JSGlobalObject* // `fill` doesn't set an exception on the VM if it fails, it returns an // ExceptionOr. So we need to check for the exception and, if set, // translate it to JSValue and throw it. - WebCore::propagateException(*lexicalGlobalObject, throwScope, - headers->fill(WTFMove(init.value()))); + WebCore::propagateException(*lexicalGlobalObject, throwScope, headers->fill(WTFMove(init.value()))); // If there's an exception, it will be thrown by the above call to fill(). // in that case, let's also free the headers to make memory leaks harder. @@ -1820,8 +1815,7 @@ JSC::EncodedJSValue WebCore__FetchHeaders__clone(WebCore::FetchHeaders* headers, auto throwScope = DECLARE_THROW_SCOPE(arg1->vm()); Zig::GlobalObject* globalObject = reinterpret_cast(arg1); auto* clone = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} }); - WebCore::propagateException(*arg1, throwScope, - clone->fill(*headers)); + WebCore::propagateException(*arg1, throwScope, clone->fill(*headers)); return JSC::JSValue::encode(WebCore::toJSNewlyCreated(arg1, globalObject, WTFMove(clone))); } @@ -1830,8 +1824,7 @@ WebCore::FetchHeaders* WebCore__FetchHeaders__cloneThis(WebCore::FetchHeaders* h auto throwScope = DECLARE_THROW_SCOPE(lexicalGlobalObject->vm()); auto* clone = new WebCore::FetchHeaders({ WebCore::FetchHeaders::Guard::None, {} }); clone->relaxAdoptionRequirement(); - WebCore::propagateException(*lexicalGlobalObject, throwScope, - clone->fill(*headers)); + WebCore::propagateException(*lexicalGlobalObject, throwScope, clone->fill(*headers)); return clone; } @@ -2003,8 +1996,7 @@ JSC::EncodedJSValue WebCore__FetchHeaders__createValue(JSC::JSGlobalObject* arg0 } Ref headers = WebCore::FetchHeaders::create(); - WebCore::propagateException(*arg0, throwScope, - headers->fill(WebCore::FetchHeaders::Init(WTFMove(pairs)))); + WebCore::propagateException(*arg0, throwScope, headers->fill(WebCore::FetchHeaders::Init(WTFMove(pairs)))); JSValue value = WebCore::toJSNewlyCreated(arg0, reinterpret_cast(arg0), WTFMove(headers)); @@ -2157,17 +2149,14 @@ JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::J auto& vm = JSC::getVM(globalObject); - auto scope = DECLARE_THROW_SCOPE(vm); - JSC::JSValue message = JSC::jsUndefined(); + WTF::String message = WTF::emptyString(); if (err.message.tag != BunStringTag::Empty) { - message = Bun::toJS(globalObject, err.message); + message = err.message.toWTFString(); } auto& names = WebCore::builtinNames(vm); - JSC::JSValue options = JSC::jsUndefined(); - - JSC::JSObject* result = JSC::ErrorInstance::create(globalObject, globalObject->errorStructureWithErrorType(), message, options); + JSC::JSObject* result = createError(globalObject, ErrorType::Error, message); auto clientData = WebCore::clientData(vm); @@ -2203,9 +2192,7 @@ JSC::EncodedJSValue SystemError__toErrorInstance(const SystemError* arg0, JSC::J result->putDirect(vm, names.errnoPublicName(), jsNumber(err.errno_), JSC::PropertyAttribute::DontDelete | 0); - RETURN_IF_EXCEPTION(scope, {}); - scope.release(); - + ASSERT_NO_PENDING_EXCEPTION(globalObject); return JSC::JSValue::encode(result); } @@ -2222,10 +2209,9 @@ JSC::EncodedJSValue SystemError__toErrorInstanceWithInfoObject(const SystemError auto syscallString = err.syscall.toWTFString(); auto messageString = err.message.toWTFString(); - JSC::JSValue message = JSC::jsString(vm, makeString("A system error occurred: "_s, syscallString, " returned "_s, codeString, " ("_s, messageString, ")"_s)); + auto message = makeString("A system error occurred: "_s, syscallString, " returned "_s, codeString, " ("_s, messageString, ")"_s); - JSC::JSValue options = JSC::jsUndefined(); - JSC::JSObject* result = JSC::ErrorInstance::create(globalObject, JSC::ErrorInstance::createStructure(vm, globalObject, globalObject->errorPrototype()), message, options); + JSC::JSObject* result = JSC::ErrorInstance::create(vm, JSC::ErrorInstance::createStructure(vm, globalObject, globalObject->errorPrototype()), message, {}); JSC::JSObject* info = JSC::constructEmptyObject(globalObject, globalObject->objectPrototype(), 0); auto clientData = WebCore::clientData(vm); @@ -2352,7 +2338,9 @@ double JSC__JSValue__getLengthIfPropertyExistsInternal(JSC::EncodedJSValue value if (auto* object = jsDynamicCast(cell)) { auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); scope.release(); // zig binding handles exceptions - if (JSValue lengthValue = object->getIfPropertyExists(globalObject, globalObject->vm().propertyNames->length)) { + JSValue lengthValue = object->getIfPropertyExists(globalObject, globalObject->vm().propertyNames->length); + RETURN_IF_EXCEPTION(scope, 0); + if (lengthValue) { return lengthValue.toNumber(globalObject); } } @@ -2543,10 +2531,12 @@ void JSC__JSValue___then(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1 JSC::EncodedJSValue JSC__JSGlobalObject__getCachedObject(JSC::JSGlobalObject* globalObject, const ZigString* arg1) { auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); WTF::String string = Zig::toString(*arg1); auto symbol = vm.privateSymbolRegistry().symbolForKey(string); JSC::Identifier ident = JSC::Identifier::fromUid(symbol); JSC::JSValue result = globalObject->getIfPropertyExists(globalObject, ident); + RETURN_IF_EXCEPTION(scope, {}); return JSC::JSValue::encode(result); } @@ -2839,7 +2829,7 @@ JSC::EncodedJSValue JSC__JSModuleLoader__evaluate(JSC::JSGlobalObject* globalObj auto scope = DECLARE_THROW_SCOPE(vm); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { promise->rejectWithCaughtException(globalObject, scope); } @@ -3273,7 +3263,7 @@ void JSC__AnyPromise__wrap(JSC::JSGlobalObject* globalObject, EncodedJSValue enc ASSERT(!promiseValue.isEmpty()); JSValue result = JSC::JSValue::decode(func(ctx, globalObject)); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto* exception = scope.exception(); scope.clearException(); @@ -3328,7 +3318,7 @@ JSC::EncodedJSValue JSC__JSPromise__wrap(JSC::JSGlobalObject* globalObject, void auto scope = DECLARE_THROW_SCOPE(vm); JSValue result = JSC::JSValue::decode(func(ctx, globalObject)); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto* exception = scope.exception(); scope.clearException(); RELEASE_AND_RETURN(scope, JSValue::encode(JSC::JSPromise::rejectedPromise(globalObject, exception->value()))); @@ -4234,27 +4224,12 @@ int32_t JSC__JSValue__toInt32(JSC::EncodedJSValue JSValue0) return JSC::JSValue::decode(JSValue0).asInt32(); } -CPP_DECL double JSC__JSValue__coerceToDouble(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1) +CPP_DECL double Bun__JSValue__toNumber(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1) { ASSERT_NO_PENDING_EXCEPTION(arg1); - JSC::JSValue value = JSC::JSValue::decode(JSValue0); auto scope = DECLARE_THROW_SCOPE(arg1->vm()); - double result = value.toNumber(arg1); - if (scope.exception()) { - result = PNaN; - } - - return result; -} -CPP_DECL double Bun__JSValue__toNumber(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1, bool* had_exception) -{ - ASSERT_NO_PENDING_EXCEPTION(arg1); - auto catchScope = DECLARE_CATCH_SCOPE(arg1->vm()); double result = JSC::JSValue::decode(JSValue0).toNumber(arg1); - if (catchScope.exception()) { - *had_exception = true; - return PNaN; - } + RETURN_IF_EXCEPTION(scope, PNaN); return result; } @@ -4731,14 +4706,10 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, bool getFromSourceURL = false; if (stackTrace != nullptr && stackTrace->size() > 0) { populateStackTrace(vm, *stackTrace, &except->stack, global, flags); - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } + } else if (err->stackTrace() != nullptr && err->stackTrace()->size() > 0) { populateStackTrace(vm, *err->stackTrace(), &except->stack, global, flags); - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } + } else { getFromSourceURL = true; } @@ -4751,16 +4722,13 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, } if (except->type == SYNTAX_ERROR_CODE) { except->message = Bun::toStringRef(err->sanitizedMessageString(global)); - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } + } else if (JSC::JSValue message = obj->getIfPropertyExists(global, vm.propertyNames->message)) { + except->message = Bun::toStringRef(global, message); } else { + except->message = Bun::toStringRef(err->sanitizedMessageString(global)); - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } } if (!scope.clearExceptionExceptTermination()) [[unlikely]] { @@ -4777,55 +4745,50 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, const auto& names = builtinNames(vm); if (except->type != SYNTAX_ERROR_CODE) { - if (JSC::JSValue syscall = getNonObservable(vm, global, obj, names.syscallPublicName())) { + JSC::JSValue syscall = getNonObservable(vm, global, obj, names.syscallPublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (syscall) { if (syscall.isString()) { except->syscall = Bun::toStringRef(global, syscall); } } - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { + JSC::JSValue code = getNonObservable(vm, global, obj, names.codePublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] return; - } - - if (JSC::JSValue code = getNonObservable(vm, global, obj, names.codePublicName())) { + if (code) { if (code.isString() || code.isNumber()) { except->system_code = Bun::toStringRef(global, code); } } - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { + JSC::JSValue path = getNonObservable(vm, global, obj, names.pathPublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] return; - } - - if (JSC::JSValue path = getNonObservable(vm, global, obj, names.pathPublicName())) { + if (path) { if (path.isString()) { except->path = Bun::toStringRef(global, path); } } - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { + JSC::JSValue fd = getNonObservable(vm, global, obj, names.fdPublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] return; - } - - if (JSC::JSValue fd = getNonObservable(vm, global, obj, names.fdPublicName())) { + if (fd) { if (fd.isNumber()) { except->fd = fd.toInt32(global); } } - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { + JSC::JSValue errno_ = getNonObservable(vm, global, obj, names.errnoPublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] return; - } - - if (JSC::JSValue errno_ = getNonObservable(vm, global, obj, names.errnoPublicName())) { + if (errno_) { if (errno_.isNumber()) { except->errno_ = errno_.toInt32(global); } } - - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } } if (getFromSourceURL) { @@ -4835,7 +4798,10 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, // so in this case, we parse the stack trace as a string // This one intentionally calls getters. - if (JSC::JSValue stackValue = obj->getIfPropertyExists(global, vm.propertyNames->stack)) { + JSC::JSValue stackValue = obj->getIfPropertyExists(global, vm.propertyNames->stack); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (stackValue) { if (stackValue.isString()) { WTF::String stack = stackValue.toWTFString(global); if (!scope.clearExceptionExceptTermination()) [[unlikely]] { @@ -4882,29 +4848,37 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, } } } - - if (!scope.clearExceptionExceptTermination()) [[unlikely]] { - return; - } } - if (JSC::JSValue sourceURL = getNonObservable(vm, global, obj, vm.propertyNames->sourceURL)) { + JSC::JSValue sourceURL = getNonObservable(vm, global, obj, vm.propertyNames->sourceURL); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (sourceURL) { if (sourceURL.isString()) { except->stack.frames_ptr[0].source_url = Bun::toStringRef(global, sourceURL); // Take care not to make these getter calls observable. - if (JSC::JSValue column = getNonObservable(vm, global, obj, vm.propertyNames->column)) { + JSC::JSValue column = getNonObservable(vm, global, obj, vm.propertyNames->column); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (column) { if (column.isNumber()) { except->stack.frames_ptr[0].position.column_zero_based = OrdinalNumber::fromOneBasedInt(column.toInt32(global)).zeroBasedInt(); } } - if (JSC::JSValue line = getNonObservable(vm, global, obj, vm.propertyNames->line)) { + JSC::JSValue line = getNonObservable(vm, global, obj, vm.propertyNames->line); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (line) { if (line.isNumber()) { except->stack.frames_ptr[0].position.line_zero_based = OrdinalNumber::fromOneBasedInt(line.toInt32(global)).zeroBasedInt(); - if (JSC::JSValue lineText = getNonObservable(vm, global, obj, builtinNames(vm).lineTextPublicName())) { + JSC::JSValue lineText = getNonObservable(vm, global, obj, builtinNames(vm).lineTextPublicName()); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; + if (lineText) { if (lineText.isString()) { if (JSC::JSString* jsStr = lineText.toStringOrNull(global)) { auto str = jsStr->value(global); @@ -4923,6 +4897,8 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, except->stack.frames_len = 1; PropertySlot slot = PropertySlot(obj, PropertySlot::InternalMethodType::VMInquiry, &vm); except->stack.frames_ptr[0].remapped = obj->getNonIndexPropertySlot(global, names.originalLinePublicName(), slot); + if (!scope.clearExceptionExceptTermination()) [[unlikely]] + return; } } } @@ -4942,7 +4918,11 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal // Fallback case for when it's a user-defined ErrorLike-object that doesn't inherit from // ErrorInstance if (JSC::JSObject* obj = JSC::jsDynamicCast(value)) { - if (auto name_value = obj->getIfPropertyExists(global, vm.propertyNames->name)) { + auto name_value = obj->getIfPropertyExists(global, vm.propertyNames->name); + if (scope.exception()) [[unlikely]] { + scope.clearExceptionExceptTermination(); + } + if (name_value) { if (name_value.isString()) { auto name_str = name_value.toWTFString(global); except->name = Bun::toStringRef(name_str); @@ -4966,25 +4946,24 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal } } + auto message = obj->getIfPropertyExists(global, vm.propertyNames->message); if (scope.exception()) [[unlikely]] { scope.clearExceptionExceptTermination(); } - - if (JSC::JSValue message = obj->getIfPropertyExists(global, vm.propertyNames->message)) { + if (message) { if (message.isString()) { except->message = Bun::toStringRef( message.toWTFString(global)); } } + auto sourceURL = obj->getIfPropertyExists(global, vm.propertyNames->sourceURL); if (scope.exception()) [[unlikely]] { scope.clearExceptionExceptTermination(); } - - if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, vm.propertyNames->sourceURL)) { + if (sourceURL) { if (sourceURL.isString()) { - except->stack.frames_ptr[0].source_url = Bun::toStringRef( - sourceURL.toWTFString(global)); + except->stack.frames_ptr[0].source_url = Bun::toStringRef(sourceURL.toWTFString(global)); except->stack.frames_len = 1; } } @@ -4993,12 +4972,20 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal scope.clearExceptionExceptTermination(); } - if (JSC::JSValue line = obj->getIfPropertyExists(global, vm.propertyNames->line)) { + auto line = obj->getIfPropertyExists(global, vm.propertyNames->line); + if (scope.exception()) [[unlikely]] { + scope.clearExceptionExceptTermination(); + } + if (line) { if (line.isNumber()) { except->stack.frames_ptr[0].position.line_zero_based = OrdinalNumber::fromOneBasedInt(line.toInt32(global)).zeroBasedInt(); // TODO: don't sourcemap it twice - if (auto originalLine = obj->getIfPropertyExists(global, builtinNames(vm).originalLinePublicName())) { + auto originalLine = obj->getIfPropertyExists(global, builtinNames(vm).originalLinePublicName()); + if (scope.exception()) [[unlikely]] { + scope.clearExceptionExceptTermination(); + } + if (originalLine) { if (originalLine.isNumber()) { except->stack.frames_ptr[0].position.line_zero_based = OrdinalNumber::fromOneBasedInt(originalLine.toInt32(global)).zeroBasedInt(); } @@ -5094,6 +5081,7 @@ void JSC__JSValue__getNameProperty(JSC::EncodedJSValue JSValue0, JSC::JSGlobalOb { JSC::JSObject* obj = JSC::JSValue::decode(JSValue0).getObject(); JSC::VM& vm = arg1->vm(); + auto scope = DECLARE_THROW_SCOPE(vm); if (obj == nullptr) { arg2->len = 0; @@ -5101,6 +5089,7 @@ void JSC__JSValue__getNameProperty(JSC::EncodedJSValue JSValue0, JSC::JSGlobalOb } JSC::JSValue name = obj->getIfPropertyExists(arg1, vm.propertyNames->toStringTagSymbol); + RETURN_IF_EXCEPTION(scope, ); if (name && name.isString()) { auto str = name.toWTFString(arg1); @@ -5146,13 +5135,15 @@ extern "C" void JSC__JSValue__getName(JSC::EncodedJSValue JSValue0, JSC::JSGloba // JSC doesn't include @@toStringTag in calculated display name if (displayName.isEmpty()) { - if (auto toStringTagValue = object->getIfPropertyExists(globalObject, vm.propertyNames->toStringTagSymbol)) { + auto toStringTagValue = object->getIfPropertyExists(globalObject, vm.propertyNames->toStringTagSymbol); + RETURN_IF_EXCEPTION(scope, ); + if (toStringTagValue) { if (toStringTagValue.isString()) { displayName = toStringTagValue.toWTFString(globalObject); } } } - if (scope.exception()) + if (scope.exception()) [[unlikely]] scope.clearException(); *arg2 = Bun::toStringRef(displayName); @@ -5679,7 +5670,7 @@ restart: } // Ignore exceptions due to getters. - if (scope.exception()) + if (scope.exception()) [[unlikely]] scope.clearException(); if (!propertyValue) @@ -5702,7 +5693,7 @@ restart: }); // Propagate exceptions from callbacks. - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { return; } @@ -5759,7 +5750,7 @@ restart: if (!object->getPropertySlot(globalObject, property, slot)) continue; // Ignore exceptions from "Get" proxy traps. - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); } @@ -5809,7 +5800,7 @@ restart: } // Ignore exceptions from getters. - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); propertyValue = jsUndefined(); } @@ -5842,7 +5833,7 @@ restart: properties.releaseData(); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); return; } @@ -5872,7 +5863,7 @@ void JSC__JSValue__forEachPropertyOrdered(JSC::EncodedJSValue JSValue0, JSC::JSG { JSC::JSObject::getOwnPropertyNames(object, globalObject, properties, DontEnumPropertiesMode::Include); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); return; } @@ -6527,8 +6518,9 @@ extern "C" EncodedJSValue Bun__JSObject__getCodePropertyVMInquiry(JSC::JSGlobalO PropertySlot slot(object, PropertySlot::InternalMethodType::VMInquiry, &vm); scope.assertNoExceptionExceptTermination(); - if (!object->getNonIndexPropertySlot(global, builtinNames.codePublicName(), slot)) { - scope.assertNoExceptionExceptTermination(); + auto has = object->getNonIndexPropertySlot(global, builtinNames.codePublicName(), slot); + scope.assertNoExceptionExceptTermination(); + if (!has) { return {}; } diff --git a/src/bun.js/bindings/headers.h b/src/bun.js/bindings/headers.h index c41dda57be..826862234d 100644 --- a/src/bun.js/bindings/headers.h +++ b/src/bun.js/bindings/headers.h @@ -199,7 +199,6 @@ CPP_DECL JSC::JSCell* JSC__JSValue__asCell(JSC::EncodedJSValue JSValue0); CPP_DECL JSC::JSInternalPromise* JSC__JSValue__asInternalPromise(JSC::EncodedJSValue JSValue0); CPP_DECL JSC::JSPromise* JSC__JSValue__asPromise(JSC::EncodedJSValue JSValue0); CPP_DECL JSC::JSString* JSC__JSValue__asString(JSC::EncodedJSValue JSValue0); -CPP_DECL double JSC__JSValue__coerceToDouble(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1); CPP_DECL int32_t JSC__JSValue__coerceToInt32(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1); CPP_DECL int64_t JSC__JSValue__coerceToInt64(JSC::EncodedJSValue JSValue0, JSC::JSGlobalObject* arg1); CPP_DECL JSC::EncodedJSValue JSC__JSValue__createEmptyArray(JSC::JSGlobalObject* arg0, size_t arg1); diff --git a/src/bun.js/bindings/helpers.h b/src/bun.js/bindings/helpers.h index 1e402c3123..c726b4b312 100644 --- a/src/bun.js/bindings/helpers.h +++ b/src/bun.js/bindings/helpers.h @@ -281,14 +281,14 @@ static ZigString toZigString(JSC::JSValue val, JSC::JSGlobalObject* global) auto scope = DECLARE_THROW_SCOPE(global->vm()); auto* str = val.toString(global); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); scope.release(); return ZigStringEmpty; } auto view = str->view(global); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); scope.release(); return ZigStringEmpty; diff --git a/src/bun.js/bindings/napi.cpp b/src/bun.js/bindings/napi.cpp index fcbe5c986f..6f172101c5 100644 --- a/src/bun.js/bindings/napi.cpp +++ b/src/bun.js/bindings/napi.cpp @@ -1248,7 +1248,7 @@ extern "C" napi_status napi_get_and_clear_last_exception(napi_env env, auto globalObject = toJS(env); auto scope = DECLARE_CATCH_SCOPE(JSC::getVM(globalObject)); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { *result = toNapi(JSValue(scope.exception()->value()), globalObject); } else { *result = toNapi(JSC::jsUndefined(), globalObject); @@ -2395,6 +2395,7 @@ extern "C" napi_status napi_get_value_bigint_uint64(napi_env env, napi_value val // toBigInt64 can throw if the value is not a bigint. we have already checked, so we shouldn't // hit an exception here and it's okay to assert at the end *result = jsValue.toBigUInt64(toJS(env)); + NAPI_RETURN_IF_EXCEPTION(env); // bigint to uint64 conversion is lossless if and only if there aren't multiple digits and the // value is positive diff --git a/src/bun.js/bindings/node/crypto/CryptoGenKeyPair.cpp b/src/bun.js/bindings/node/crypto/CryptoGenKeyPair.cpp index 95dea54c75..ef8c2415ff 100644 --- a/src/bun.js/bindings/node/crypto/CryptoGenKeyPair.cpp +++ b/src/bun.js/bindings/node/crypto/CryptoGenKeyPair.cpp @@ -45,7 +45,7 @@ void KeyPairJobCtx::runFromJS(JSGlobalObject* lexicalGlobalObject, JSValue callb } JSValue publicKeyValue = m_keyObj.exportPublic(lexicalGlobalObject, scope, m_publicKeyEncoding); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { JSValue exceptionValue = scope.exception(); scope.clearException(); exceptionCallback(exceptionValue); @@ -53,7 +53,7 @@ void KeyPairJobCtx::runFromJS(JSGlobalObject* lexicalGlobalObject, JSValue callb } JSValue privateKeyValue = m_keyObj.exportPrivate(lexicalGlobalObject, scope, m_privateKeyEncoding); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { JSValue exceptionValue = scope.exception(); scope.clearException(); exceptionCallback(exceptionValue); diff --git a/src/bun.js/bindings/node/crypto/CryptoPrimes.cpp b/src/bun.js/bindings/node/crypto/CryptoPrimes.cpp index 3d226f8887..10159a63ec 100644 --- a/src/bun.js/bindings/node/crypto/CryptoPrimes.cpp +++ b/src/bun.js/bindings/node/crypto/CryptoPrimes.cpp @@ -207,7 +207,7 @@ void GeneratePrimeJobCtx::runFromJS(JSGlobalObject* globalObject, JSValue callba JSValue result = GeneratePrimeJob::result(globalObject, scope, m_prime, m_bigint); ASSERT(result.isEmpty() == !!scope.exception()); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { auto* err = scope.exception(); scope.clearException(); Bun__EventLoop__runCallback1( diff --git a/src/bun.js/bindings/node/crypto/JSCipherPrototype.cpp b/src/bun.js/bindings/node/crypto/JSCipherPrototype.cpp index 1fbf84289c..5baa0d0c88 100644 --- a/src/bun.js/bindings/node/crypto/JSCipherPrototype.cpp +++ b/src/bun.js/bindings/node/crypto/JSCipherPrototype.cpp @@ -237,6 +237,7 @@ JSC_DEFINE_HOST_FUNCTION(jsCipherGetAuthTag, (JSC::JSGlobalObject * lexicalGloba auto* globalObject = defaultGlobalObject(lexicalGlobalObject); JSC::JSUint8Array* buf = JSC::JSUint8Array::createUninitialized(lexicalGlobalObject, globalObject->JSBufferSubclassStructure(), *cipher->m_authTagLen); + RETURN_IF_EXCEPTION(scope, {}); if (!buf) { throwOutOfMemoryError(lexicalGlobalObject, scope); return {}; diff --git a/src/bun.js/bindings/node/crypto/JSKeyObjectConstructor.cpp b/src/bun.js/bindings/node/crypto/JSKeyObjectConstructor.cpp index 8f40f24945..52f0fe0448 100644 --- a/src/bun.js/bindings/node/crypto/JSKeyObjectConstructor.cpp +++ b/src/bun.js/bindings/node/crypto/JSKeyObjectConstructor.cpp @@ -95,6 +95,7 @@ JSC_DEFINE_HOST_FUNCTION(jsKeyObjectConstructor_from, (JSGlobalObject * lexicalG auto keyObjectResult = KeyObject::create(wrappedKey); if (keyObjectResult.hasException()) [[unlikely]] { WebCore::propagateException(*lexicalGlobalObject, scope, keyObjectResult.releaseException()); + RELEASE_AND_RETURN(scope, {}); return {}; } diff --git a/src/bun.js/bindings/node/crypto/KeyObject.cpp b/src/bun.js/bindings/node/crypto/KeyObject.cpp index 563c186c3a..aff9e9deaf 100644 --- a/src/bun.js/bindings/node/crypto/KeyObject.cpp +++ b/src/bun.js/bindings/node/crypto/KeyObject.cpp @@ -1220,7 +1220,7 @@ KeyObject::PrepareAsymmetricKeyResult KeyObject::prepareAsymmetricKey(JSC::JSGlo auto keyObject = create(key); if (keyObject.hasException()) [[unlikely]] { WebCore::propagateException(*globalObject, scope, keyObject.releaseException()); - return {}; + RELEASE_AND_RETURN(scope, {}); } KeyObject handle = keyObject.releaseReturnValue(); RETURN_IF_EXCEPTION(scope, {}); @@ -1288,6 +1288,7 @@ KeyObject::PrepareAsymmetricKeyResult KeyObject::prepareAsymmetricKey(JSC::JSGlo auto keyObject = create(key); if (keyObject.hasException()) [[unlikely]] { WebCore::propagateException(*globalObject, scope, keyObject.releaseException()); + RELEASE_AND_RETURN(scope, {}); } KeyObject handle = keyObject.releaseReturnValue(); return { .keyData = handle.data() }; diff --git a/src/bun.js/bindings/node/http/NodeHTTPParser.cpp b/src/bun.js/bindings/node/http/NodeHTTPParser.cpp index c7986785b3..2320ca1655 100644 --- a/src/bun.js/bindings/node/http/NodeHTTPParser.cpp +++ b/src/bun.js/bindings/node/http/NodeHTTPParser.cpp @@ -541,7 +541,7 @@ int HTTPParser::onBody(const char* at, size_t length) JSC::profiledCall(lexicalGlobalObject, ProfilingReason::API, onBodyCallback, callData, m_thisParser, args); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { llhttp_set_error_reason(&m_parserData, "HPE_USER:JS Exception"); return HPE_USER; } @@ -583,7 +583,7 @@ int HTTPParser::onMessageComplete() MarkedArgumentBuffer args; JSC::profiledCall(globalObject, ProfilingReason::API, onMessageCompleteCallback, callData, thisParser, args); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { return -1; } diff --git a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp index 7c580590ef..a88d49ed91 100644 --- a/src/bun.js/bindings/sqlite/JSSQLStatement.cpp +++ b/src/bun.js/bindings/sqlite/JSSQLStatement.cpp @@ -520,7 +520,9 @@ static JSValue toJS(JSC::VM& vm, JSC::JSGlobalObject* globalObject, sqlite3_stmt size_t len = sqlite3_column_bytes(stmt, i); const void* blob = len > 0 ? sqlite3_column_blob(stmt, i) : nullptr; if (len > 0 && blob != nullptr) [[likely]] { + auto scope = DECLARE_THROW_SCOPE(vm); JSC::JSUint8Array* array = JSC::JSUint8Array::createUninitialized(globalObject, globalObject->m_typedArrayUint8.get(globalObject), len); + RETURN_IF_EXCEPTION(scope, {}); memcpy(array->vector(), blob, len); return array; } diff --git a/src/bun.js/bindings/v8/V8Object.cpp b/src/bun.js/bindings/v8/V8Object.cpp index f6f0bdc096..0149532350 100644 --- a/src/bun.js/bindings/v8/V8Object.cpp +++ b/src/bun.js/bindings/v8/V8Object.cpp @@ -55,7 +55,7 @@ Maybe Object::Set(Local context, Local key, Local v scope.clearExceptionExceptTermination(); return Nothing(); } - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); return Nothing(); } diff --git a/src/bun.js/bindings/webcore/InternalWritableStream.cpp b/src/bun.js/bindings/webcore/InternalWritableStream.cpp index e630db19cb..e227ac6167 100644 --- a/src/bun.js/bindings/webcore/InternalWritableStream.cpp +++ b/src/bun.js/bindings/webcore/InternalWritableStream.cpp @@ -89,7 +89,7 @@ bool InternalWritableStream::locked() const ASSERT(!arguments.hasOverflowed()); auto result = invokeWritableStreamFunction(*globalObject, privateName, arguments); - if (scope.exception()) + if (scope.exception()) [[unlikely]] scope.clearException(); return result.hasException() ? false : result.returnValue().isTrue(); diff --git a/src/bun.js/bindings/webcore/JSBroadcastChannel.cpp b/src/bun.js/bindings/webcore/JSBroadcastChannel.cpp index 728bc13e30..55be2327e6 100644 --- a/src/bun.js/bindings/webcore/JSBroadcastChannel.cpp +++ b/src/bun.js/bindings/webcore/JSBroadcastChannel.cpp @@ -212,6 +212,7 @@ JSC_DEFINE_HOST_FUNCTION(jsBroadcastChannelPrototype_inspectCustom, (JSC::JSGlob inputObj->putDirect(vm, Identifier::fromString(vm, "active"_s), jsBoolean(!channel->isClosed()), 0); JSFunction* utilInspect = globalObject->utilInspectFunction(); + RETURN_IF_EXCEPTION(throwScope, {}); auto callData = JSC::getCallData(utilInspect); MarkedArgumentBuffer arguments; arguments.append(inputObj); diff --git a/src/bun.js/bindings/webcore/JSCookie.cpp b/src/bun.js/bindings/webcore/JSCookie.cpp index b1d25e9c50..f0873240f6 100644 --- a/src/bun.js/bindings/webcore/JSCookie.cpp +++ b/src/bun.js/bindings/webcore/JSCookie.cpp @@ -108,78 +108,94 @@ static std::optional cookieInitFromJS(JSC::VM& vm, JSGlobalObject* l if (auto* optionsObj = options.getObject()) { if (checkName) { - if (auto nameValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->name)) { - name = convert(*lexicalGlobalObject, nameValue); - } + auto nameValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->name); RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (nameValue) { + name = convert(*lexicalGlobalObject, nameValue); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + } if (name.isEmpty()) { throwVMTypeError(lexicalGlobalObject, throwScope, "name is required"_s); return std::nullopt; } - if (auto valueValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->value)) { + auto valueValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->value); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (valueValue) { value = convert(*lexicalGlobalObject, valueValue); } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); } // domain - if (auto domainValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.domainPublicName())) { + auto domainValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.domainPublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (domainValue) { if (!domainValue.isUndefined() && !domainValue.isNull()) { domain = convert(*lexicalGlobalObject, domainValue); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // path - if (auto pathValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.pathPublicName())) { + auto pathValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.pathPublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (pathValue) { if (!pathValue.isUndefined() && !pathValue.isNull()) { path = convert(*lexicalGlobalObject, pathValue); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // expires - if (auto expiresValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.expiresPublicName())) { - expires = getExpiresValue(lexicalGlobalObject, throwScope, expiresValue); - } + auto expiresValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.expiresPublicName()); RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (expiresValue) { + expires = getExpiresValue(lexicalGlobalObject, throwScope, expiresValue); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + } // maxAge - if (auto maxAgeValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.maxAgePublicName())) { + auto maxAgeValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.maxAgePublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (maxAgeValue) { if (!maxAgeValue.isUndefined() && !maxAgeValue.isNull() && maxAgeValue.isNumber()) { maxAge = maxAgeValue.asNumber(); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // secure - if (auto secureValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.securePublicName())) { + auto secureValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.securePublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (secureValue) { if (!secureValue.isUndefined()) { secure = secureValue.toBoolean(lexicalGlobalObject); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // httpOnly - if (auto httpOnlyValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.httpOnlyPublicName())) { + auto httpOnlyValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.httpOnlyPublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (httpOnlyValue) { if (!httpOnlyValue.isUndefined()) { httpOnly = httpOnlyValue.toBoolean(lexicalGlobalObject); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // partitioned - if (auto partitionedValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.partitionedPublicName())) { + auto partitionedValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.partitionedPublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (partitionedValue) { if (!partitionedValue.isUndefined()) { partitioned = partitionedValue.toBoolean(lexicalGlobalObject); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); // sameSite - if (auto sameSiteValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.sameSitePublicName())) { + auto sameSiteValue = optionsObj->getIfPropertyExists(lexicalGlobalObject, names.sameSitePublicName()); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); + if (sameSiteValue) { if (!sameSiteValue.isUndefined() && !sameSiteValue.isNull()) { String sameSiteStr = convert(*lexicalGlobalObject, sameSiteValue); @@ -191,9 +207,9 @@ static std::optional cookieInitFromJS(JSC::VM& vm, JSGlobalObject* l sameSite = CookieSameSite::None; else throwVMTypeError(lexicalGlobalObject, throwScope, "Invalid sameSite value. Must be 'strict', 'lax', or 'none'"_s); + RETURN_IF_EXCEPTION(throwScope, std::nullopt); } } - RETURN_IF_EXCEPTION(throwScope, std::nullopt); } } @@ -304,8 +320,8 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCookieDOMConstructor:: auto cookie_exception = Cookie::parse(cookieString); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); auto* globalObject = castedThis->globalObject(); @@ -326,8 +342,8 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCookieDOMConstructor:: auto cookie_exception = Cookie::create(*cookieInit); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); auto* globalObject = castedThis->globalObject(); RELEASE_AND_RETURN(throwScope, JSValue::encode(toJS(lexicalGlobalObject, globalObject, WTFMove(cookie)))); @@ -361,8 +377,8 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCookieDOMConstructor:: auto cookie_exception = Cookie::create(cookieInit); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); auto* globalObject = castedThis->globalObject(); @@ -527,8 +543,8 @@ JSC_DEFINE_HOST_FUNCTION(jsCookieStaticFunctionParse, (JSGlobalObject * lexicalG auto cookie_exception = Cookie::create(CookieInit {}); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); return JSValue::encode(toJSNewlyCreated(lexicalGlobalObject, defaultGlobalObject(lexicalGlobalObject), WTFMove(cookie))); } @@ -541,8 +557,8 @@ JSC_DEFINE_HOST_FUNCTION(jsCookieStaticFunctionParse, (JSGlobalObject * lexicalG auto cookie_exception = Cookie::parse(cookieString); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); auto* globalObject = defaultGlobalObject(lexicalGlobalObject); @@ -581,8 +597,8 @@ JSC_DEFINE_HOST_FUNCTION(jsCookieStaticFunctionFrom, (JSGlobalObject * lexicalGl auto cookie_exception = Cookie::create(cookieInit); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); auto* globalObject = jsCast(lexicalGlobalObject); return JSValue::encode(toJSNewlyCreated(lexicalGlobalObject, globalObject, WTFMove(cookie))); diff --git a/src/bun.js/bindings/webcore/JSCookieMap.cpp b/src/bun.js/bindings/webcore/JSCookieMap.cpp index e225f9f8c8..0f1aacd447 100644 --- a/src/bun.js/bindings/webcore/JSCookieMap.cpp +++ b/src/bun.js/bindings/webcore/JSCookieMap.cpp @@ -176,8 +176,8 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSCookieMapDOMConstructo auto result_exception = CookieMap::create(WTFMove(init)); if (result_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, result_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto result = result_exception.releaseReturnValue(); RELEASE_AND_RETURN(throwScope, JSValue::encode(toJSNewlyCreated(lexicalGlobalObject, castedThis->globalObject(), WTFMove(result)))); @@ -407,8 +407,8 @@ static inline JSC::EncodedJSValue jsCookieMapPrototypeFunction_setBody(JSC::JSGl auto cookie_exception = Cookie::create(cookieInit); if (cookie_exception.hasException()) { WebCore::propagateException(lexicalGlobalObject, throwScope, cookie_exception.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } - RETURN_IF_EXCEPTION(throwScope, {}); auto cookie = cookie_exception.releaseReturnValue(); impl.set(WTFMove(cookie)); @@ -456,10 +456,12 @@ static inline JSC::EncodedJSValue jsCookieMapPrototypeFunction_deleteBody(JSC::J // Extract name if (nameValue.isUndefined()) nameValue = options->getIfPropertyExists(lexicalGlobalObject, PropertyName(vm.propertyNames->name)); + RETURN_IF_EXCEPTION(throwScope, {}); // Extract optional domain - if (auto domainValue = options->getIfPropertyExists(lexicalGlobalObject, names.domainPublicName())) { - RETURN_IF_EXCEPTION(throwScope, {}); + auto domainValue = options->getIfPropertyExists(lexicalGlobalObject, names.domainPublicName()); + RETURN_IF_EXCEPTION(throwScope, {}); + if (domainValue) { if (!domainValue.isUndefined() && !domainValue.isNull()) { deleteOptions.domain = convert(*lexicalGlobalObject, domainValue); @@ -468,9 +470,9 @@ static inline JSC::EncodedJSValue jsCookieMapPrototypeFunction_deleteBody(JSC::J } // Extract optional path - if (auto pathValue = options->getIfPropertyExists(lexicalGlobalObject, names.pathPublicName())) { - RETURN_IF_EXCEPTION(throwScope, {}); - + auto pathValue = options->getIfPropertyExists(lexicalGlobalObject, names.pathPublicName()); + RETURN_IF_EXCEPTION(throwScope, {}); + if (pathValue) { if (!pathValue.isUndefined() && !pathValue.isNull()) { deleteOptions.path = convert(*lexicalGlobalObject, pathValue); RETURN_IF_EXCEPTION(throwScope, {}); diff --git a/src/bun.js/bindings/webcore/JSDOMConvertPromise.h b/src/bun.js/bindings/webcore/JSDOMConvertPromise.h index c3ca6bb158..cf4a7ea4cd 100644 --- a/src/bun.js/bindings/webcore/JSDOMConvertPromise.h +++ b/src/bun.js/bindings/webcore/JSDOMConvertPromise.h @@ -48,7 +48,7 @@ template struct Converter> : DefaultConverterscriptExecutionContext(); // if (is(scriptExecutionContext)) { // auto* scriptController = downcast(*scriptExecutionContext).script(); diff --git a/src/bun.js/bindings/webcore/JSDOMPromise.cpp b/src/bun.js/bindings/webcore/JSDOMPromise.cpp index db1597552f..fbcf8cc54e 100644 --- a/src/bun.js/bindings/webcore/JSDOMPromise.cpp +++ b/src/bun.js/bindings/webcore/JSDOMPromise.cpp @@ -58,7 +58,7 @@ auto DOMPromise::whenPromiseIsSettled(JSDOMGlobalObject* globalObject, JSC::JSOb auto thenFunction = promise->get(&lexicalGlobalObject, privateName); EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); - if (scope.exception()) + if (scope.exception()) [[unlikely]] return IsCallbackRegistered::No; ASSERT(thenFunction.isCallable()); diff --git a/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp b/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp index ce367f441b..1bd1fc8a4e 100644 --- a/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp +++ b/src/bun.js/bindings/webcore/JSEventEmitterCustom.cpp @@ -64,6 +64,7 @@ JSEventEmitter* jsEventEmitterCastFast(VM& vm, JSC::JSGlobalObject* lexicalGloba return jsCast(asObject(_events)); } } + // TODO: properly propagate exception upwards (^ getIfPropertyExists) auto scope = DECLARE_CATCH_SCOPE(vm); auto* globalObject = reinterpret_cast(lexicalGlobalObject); @@ -75,7 +76,7 @@ JSEventEmitter* jsEventEmitterCastFast(VM& vm, JSC::JSGlobalObject* lexicalGloba thisObject->putDirect(vm, name, result, 0); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); return nullptr; } diff --git a/src/bun.js/bindings/webcore/JSEventTarget.cpp b/src/bun.js/bindings/webcore/JSEventTarget.cpp index 953bc19363..32ae670f65 100644 --- a/src/bun.js/bindings/webcore/JSEventTarget.cpp +++ b/src/bun.js/bindings/webcore/JSEventTarget.cpp @@ -233,6 +233,7 @@ static inline JSC::EncodedJSValue jsEventTargetPrototypeFunction_addEventListene warningMessage = "addEventListener called with undefined listener, which has no effect."_s; } auto errorInstance = JSC::ErrorInstance::create(vm, lexicalGlobalObject->errorStructure(JSC::ErrorType::Error), warningMessage, JSValue(), nullptr, RuntimeType::TypeNothing, JSC::ErrorType::Error); + RETURN_IF_EXCEPTION(throwScope, {}); errorInstance->putDirect(vm, vm.propertyNames->name, jsString(vm, String("AddEventListenerArgumentTypeWarning"_s))); JSObject& target = *castedThis; errorInstance->putDirect(vm, vm.propertyNames->target, &target); diff --git a/src/bun.js/bindings/webcore/JSMIMEType.cpp b/src/bun.js/bindings/webcore/JSMIMEType.cpp index 106cf85fee..cb92824bd0 100644 --- a/src/bun.js/bindings/webcore/JSMIMEType.cpp +++ b/src/bun.js/bindings/webcore/JSMIMEType.cpp @@ -560,6 +560,7 @@ JSC_DEFINE_HOST_FUNCTION(constructMIMEType, (JSGlobalObject * globalObject, Call auto* jsInputString = inputArg.toString(globalObject); RETURN_IF_EXCEPTION(scope, {}); auto inputString = jsInputString->view(globalObject); + RETURN_IF_EXCEPTION(scope, {}); // 2. Parse type and subtype String type, subtype; diff --git a/src/bun.js/bindings/webcore/JSWebSocket.cpp b/src/bun.js/bindings/webcore/JSWebSocket.cpp index 8fc8c4985f..b6e032ab6a 100644 --- a/src/bun.js/bindings/webcore/JSWebSocket.cpp +++ b/src/bun.js/bindings/webcore/JSWebSocket.cpp @@ -213,30 +213,42 @@ static inline JSC::EncodedJSValue constructJSWebSocket3(JSGlobalObject* lexicalG auto headersInit = std::optional>, IDLRecord>>::ReturnType>(); if (JSC::JSObject* options = optionsObjectValue.getObject()) { const auto& builtinnames = WebCore::builtinNames(vm); - if (JSValue headersValue = options->getIfPropertyExists(globalObject, builtinnames.headersPublicName())) { + auto headersValue = options->getIfPropertyExists(globalObject, builtinnames.headersPublicName()); + RETURN_IF_EXCEPTION(throwScope, {}); + if (headersValue) { if (!headersValue.isUndefinedOrNull()) { headersInit = convert>, IDLRecord>>(*lexicalGlobalObject, headersValue); RETURN_IF_EXCEPTION(throwScope, {}); } } - if (JSValue protocolsValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "protocols"_s)))) { + auto protocolsValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "protocols"_s))); + RETURN_IF_EXCEPTION(throwScope, {}); + if (protocolsValue) { if (!protocolsValue.isUndefinedOrNull()) { protocols = convert>(*lexicalGlobalObject, protocolsValue); RETURN_IF_EXCEPTION(throwScope, {}); } - } else if (JSValue protocolValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "protocol"_s)))) { - if (!protocolValue.isUndefinedOrNull()) { - protocols = Vector { convert(*lexicalGlobalObject, protocolValue) }; - RETURN_IF_EXCEPTION(throwScope, {}); + } else { + auto protocolValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "protocol"_s))); + RETURN_IF_EXCEPTION(throwScope, {}); + if (protocolValue) { + if (!protocolValue.isUndefinedOrNull()) { + protocols = Vector { convert(*lexicalGlobalObject, protocolValue) }; + RETURN_IF_EXCEPTION(throwScope, {}); + } } } - if (JSValue tlsOptionsValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "tls"_s)))) { + auto tlsOptionsValue = options->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "tls"_s))); + RETURN_IF_EXCEPTION(throwScope, {}); + if (tlsOptionsValue) { if (!tlsOptionsValue.isUndefinedOrNull() && tlsOptionsValue.isObject()) { if (JSC::JSObject* tlsOptions = tlsOptionsValue.getObject()) { - if (JSValue rejectUnauthorizedValue = tlsOptions->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "rejectUnauthorized"_s)))) { + auto rejectUnauthorizedValue = tlsOptions->getIfPropertyExists(globalObject, PropertyName(Identifier::fromString(vm, "rejectUnauthorized"_s))); + RETURN_IF_EXCEPTION(throwScope, {}); + if (rejectUnauthorizedValue) { if (!rejectUnauthorizedValue.isUndefinedOrNull() && rejectUnauthorizedValue.isBoolean()) { rejectUnauthorized = rejectUnauthorizedValue.asBoolean() ? 1 : 0; } @@ -246,7 +258,6 @@ static inline JSC::EncodedJSValue constructJSWebSocket3(JSGlobalObject* lexicalG } } - RETURN_IF_EXCEPTION(throwScope, {}); auto object = (rejectUnauthorized == -1) ? WebSocket::create(*context, WTFMove(url), protocols, WTFMove(headersInit)) : WebSocket::create(*context, WTFMove(url), protocols, WTFMove(headersInit), rejectUnauthorized ? true : false); if constexpr (IsExceptionOr) diff --git a/src/bun.js/bindings/webcore/JSWorker.cpp b/src/bun.js/bindings/webcore/JSWorker.cpp index a4bc10d9e7..d7b52f90cd 100644 --- a/src/bun.js/bindings/webcore/JSWorker.cpp +++ b/src/bun.js/bindings/webcore/JSWorker.cpp @@ -153,30 +153,36 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor:: Vector> transferList; if (JSObject* optionsObject = JSC::jsDynamicCast(argument1.value())) { - if (auto nameValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->name)) { + auto nameValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, vm.propertyNames->name); + RETURN_IF_EXCEPTION(throwScope, {}); + if (nameValue) { if (nameValue.isString()) { options.name = nameValue.toWTFString(lexicalGlobalObject); RETURN_IF_EXCEPTION(throwScope, {}); } } - RETURN_IF_EXCEPTION(throwScope, {}); - if (auto miniModeValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "smol"_s))) { + auto miniModeValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "smol"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (miniModeValue) { options.mini = miniModeValue.toBoolean(lexicalGlobalObject); } - RETURN_IF_EXCEPTION(throwScope, {}); - if (auto ref = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "ref"_s))) { + auto ref = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "ref"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (ref) { options.unref = !ref.toBoolean(lexicalGlobalObject); } - RETURN_IF_EXCEPTION(throwScope, {}); - if (auto eval = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "eval"_s))) { + auto eval = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "eval"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (eval) { options.evalMode = eval.toBoolean(lexicalGlobalObject); } - RETURN_IF_EXCEPTION(throwScope, {}); - if (auto preloadModulesValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "preload"_s))) { + auto preloadModulesValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "preload"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (preloadModulesValue) { if (!preloadModulesValue.isUndefinedOrNull()) { if (preloadModulesValue.isString()) { auto str = preloadModulesValue.toWTFString(lexicalGlobalObject); @@ -201,13 +207,16 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor:: } workerData = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "workerData"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); if (!workerData) { workerData = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "data"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); if (!workerData) workerData = jsUndefined(); } - RETURN_IF_EXCEPTION(throwScope, {}); - if (JSValue transferListValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transferList"_s))) { + auto transferListValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transferList"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (transferListValue) { if (transferListValue.isObject()) { JSC::JSObject* transferListObject = transferListValue.getObject(); if (auto* transferListArray = jsDynamicCast(transferListObject)) { @@ -217,6 +226,7 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor:: } return true; }); + RETURN_IF_EXCEPTION(throwScope, {}); } } } @@ -307,7 +317,7 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor:: ExceptionOr> serialized = SerializedScriptValue::create(*lexicalGlobalObject, valueToTransfer, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); if (serialized.hasException()) { WebCore::propagateException(*lexicalGlobalObject, throwScope, serialized.releaseException()); - return encodedJSValue(); + RELEASE_AND_RETURN(throwScope, {}); } Vector transferredPorts; @@ -316,7 +326,7 @@ template<> JSC::EncodedJSValue JSC_HOST_CALL_ATTRIBUTES JSWorkerDOMConstructor:: auto disentangleResult = MessagePort::disentanglePorts(WTFMove(ports)); if (disentangleResult.hasException()) { WebCore::propagateException(*lexicalGlobalObject, throwScope, disentangleResult.releaseException()); - return encodedJSValue(); + RELEASE_AND_RETURN(throwScope, {}); } transferredPorts = disentangleResult.releaseReturnValue(); } @@ -574,7 +584,9 @@ static inline JSC::EncodedJSValue jsWorkerPrototypeFunction_postMessage2Body(JSC StructuredSerializeOptions options; if (optionsValue.isObject()) { JSObject* optionsObject = asObject(optionsValue); - if (auto transferListValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transfer"_s))) { + auto transferListValue = optionsObject->getIfPropertyExists(lexicalGlobalObject, Identifier::fromString(vm, "transfer"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (transferListValue) { auto transferList = convert>(*lexicalGlobalObject, transferListValue); RETURN_IF_EXCEPTION(throwScope, {}); options.transfer = WTFMove(transferList); diff --git a/src/bun.js/bindings/webcore/ReadableStream.cpp b/src/bun.js/bindings/webcore/ReadableStream.cpp index 6f267a0b35..90f1ebd756 100644 --- a/src/bun.js/bindings/webcore/ReadableStream.cpp +++ b/src/bun.js/bindings/webcore/ReadableStream.cpp @@ -107,7 +107,7 @@ static inline std::optional invokeReadableStreamFunction(JSC::JSGl auto callData = JSC::getCallData(function); auto result = call(&lexicalGlobalObject, function, callData, thisValue, arguments); EXCEPTION_ASSERT(!scope.exception() || vm.hasPendingTerminationException()); - if (scope.exception()) + if (scope.exception()) [[unlikely]] return {}; return result; } diff --git a/src/bun.js/bindings/webcore/SerializedScriptValue.cpp b/src/bun.js/bindings/webcore/SerializedScriptValue.cpp index ad0fa35bc1..681c16c4d9 100644 --- a/src/bun.js/bindings/webcore/SerializedScriptValue.cpp +++ b/src/bun.js/bindings/webcore/SerializedScriptValue.cpp @@ -5641,13 +5641,13 @@ static void maybeThrowExceptionIfSerializationFailed(JSGlobalObject& lexicalGlob break; case SerializationReturnCode::StackOverflowError: throwException(&lexicalGlobalObject, scope, createStackOverflowError(&lexicalGlobalObject)); - break; + RELEASE_AND_RETURN(scope, ); case SerializationReturnCode::ValidationError: throwTypeError(&lexicalGlobalObject, scope, "Unable to deserialize data."_s); - break; + RELEASE_AND_RETURN(scope, ); case SerializationReturnCode::DataCloneError: throwDataCloneError(lexicalGlobalObject, scope); - break; + RELEASE_AND_RETURN(scope, ); case SerializationReturnCode::ExistingExceptionError: case SerializationReturnCode::UnspecifiedError: break; @@ -5773,7 +5773,7 @@ ExceptionOr> SerializedScriptValue::create(JSGlobalOb if (arrayBuffer->isLocked()) { auto scope = DECLARE_THROW_SCOPE(vm); throwVMTypeError(&lexicalGlobalObject, scope, errorMessageForTransfer(arrayBuffer)); - return Exception { ExistingExceptionError }; + RELEASE_AND_RETURN(scope, Exception { ExistingExceptionError }); } arrayBuffers.append(WTFMove(arrayBuffer)); continue; @@ -5886,11 +5886,11 @@ ExceptionOr> SerializedScriptValue::create(JSGlobalOb // If we rethrew an exception just now, or we failed with a status code other than success, // we should exit right now. if (scope.exception() || code != SerializationReturnCode::SuccessfullyCompleted) [[unlikely]] - return exceptionForSerializationFailure(code); + RELEASE_AND_RETURN(scope, exceptionForSerializationFailure(code)); auto arrayBufferContentsArray = transferArrayBuffers(vm, arrayBuffers); if (arrayBufferContentsArray.hasException()) { - return arrayBufferContentsArray.releaseException(); + RELEASE_AND_RETURN(scope, arrayBufferContentsArray.releaseException()); } // auto backingStores = ImageBitmap::detachBitmaps(WTFMove(imageBitmaps)); @@ -5932,6 +5932,7 @@ ExceptionOr> SerializedScriptValue::create(JSGlobalOb // WTFMove(serializedVideoChunks), WTFMove(serializedVideoFrameData) // #endif // )); + scope.releaseAssertNoException(); return adoptRef(*new SerializedScriptValue(WTFMove(buffer), arrayBufferContentsArray.releaseReturnValue(), context == SerializationContext::WorkerPostMessage ? WTFMove(sharedBuffers) : nullptr #if ENABLE(OFFSCREEN_CANVAS_IN_WORKERS) , diff --git a/src/bun.js/bindings/webcore/Worker.cpp b/src/bun.js/bindings/webcore/Worker.cpp index ae0ad8654b..c2bd4deeef 100644 --- a/src/bun.js/bindings/webcore/Worker.cpp +++ b/src/bun.js/bindings/webcore/Worker.cpp @@ -417,9 +417,11 @@ bool Worker::dispatchErrorWithValue(Zig::GlobalObject* workerGlobalObject, JSVal ScriptExecutionContext::postTaskTo(ctx->identifier(), [protectedThis = Ref { *this }, serialized](ScriptExecutionContext& context) -> void { auto* globalObject = context.globalObject(); + auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); ErrorEvent::Init init; JSValue deserialized = serialized->deserialize(*globalObject, globalObject, SerializationErrorMode::NonThrowing); - if (!deserialized) return; + RETURN_IF_EXCEPTION(scope, ); init.error = deserialized; auto event = ErrorEvent::create(eventNames().errorEvent, init, EventIsTrusted::Yes); @@ -474,8 +476,13 @@ extern "C" void WebWorker__dispatchExit(Zig::GlobalObject* globalObject, Worker* vm.setHasTerminationRequest(); { - globalObject->esmRegistryMap()->clear(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); + auto* esmRegistryMap = globalObject->esmRegistryMap(); + scope.exception(); // TODO: handle or assert none? + esmRegistryMap->clear(globalObject); + scope.exception(); // TODO: handle or assert none? globalObject->requireMap()->clear(globalObject); + scope.exception(); // TODO: handle or assert none? vm.deleteAllCode(JSC::DeleteAllCodeEffort::PreventCollectionAndDeleteAllCode); gcUnprotect(globalObject); globalObject = nullptr; @@ -612,8 +619,6 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, if (!context) return JSValue::encode(jsUndefined()); - auto throwScope = DECLARE_THROW_SCOPE(vm); - JSC::JSValue value = callFrame->argument(0); JSC::JSValue options = callFrame->argument(1); @@ -639,15 +644,17 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionPostMessage, Vector> ports; ExceptionOr> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), ports, SerializationForStorage::No, SerializationContext::WorkerPostMessage); if (serialized.hasException()) { - WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); - return JSValue::encode(jsUndefined()); + WebCore::propagateException(*globalObject, scope, serialized.releaseException()); + RELEASE_AND_RETURN(scope, {}); } + scope.assertNoException(); ExceptionOr> disentangledPorts = MessagePort::disentanglePorts(WTFMove(ports)); if (disentangledPorts.hasException()) { - WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); - return JSValue::encode(jsUndefined()); + WebCore::propagateException(*globalObject, scope, serialized.releaseException()); + RELEASE_AND_RETURN(scope, {}); } + scope.assertNoException(); MessageWithMessagePorts messageWithMessagePorts { serialized.releaseReturnValue(), disentangledPorts.releaseReturnValue() }; diff --git a/src/bun.js/event_loop/JSCScheduler.zig b/src/bun.js/event_loop/JSCScheduler.zig index 57babb283f..6a9a9dacd8 100644 --- a/src/bun.js/event_loop/JSCScheduler.zig +++ b/src/bun.js/event_loop/JSCScheduler.zig @@ -2,7 +2,14 @@ const JSCScheduler = @This(); pub const JSCDeferredWorkTask = opaque { extern fn Bun__runDeferredWork(task: *JSCScheduler.JSCDeferredWorkTask) void; - pub const run = Bun__runDeferredWork; + pub fn run(task: *JSCScheduler.JSCDeferredWorkTask) void { + const globalThis = bun.jsc.VirtualMachine.get().global; + var scope: bun.jsc.CatchScope = undefined; + scope.init(globalThis, @src(), .assertions_only); + defer scope.deinit(); + Bun__runDeferredWork(task); + scope.assertNoExceptionExceptTermination() catch return; + } }; export fn Bun__eventLoop__incrementRefConcurrently(jsc_vm: *VirtualMachine, delta: c_int) void { diff --git a/src/bun.js/jsc.zig b/src/bun.js/jsc.zig index db9e03fc76..9cc215aeb4 100644 --- a/src/bun.js/jsc.zig +++ b/src/bun.js/jsc.zig @@ -35,6 +35,7 @@ pub const toJSHostFn = host_fn.toJSHostFn; pub const toJSHostFnWithContext = host_fn.toJSHostFnWithContext; pub const toJSHostCall = host_fn.toJSHostCall; pub const fromJSHostCall = host_fn.fromJSHostCall; +pub const fromJSHostCallVoid = host_fn.fromJSHostCallVoid; pub const createCallback = host_fn.createCallback; // JSC Classes Bindings diff --git a/src/bun.js/jsc/array_buffer.zig b/src/bun.js/jsc/array_buffer.zig index 8904402659..aafb6a04ea 100644 --- a/src/bun.js/jsc/array_buffer.zig +++ b/src/bun.js/jsc/array_buffer.zig @@ -55,7 +55,7 @@ pub const ArrayBuffer = extern struct { } }, .err => |err| { - return globalObject.throwValue(err.toJSC(globalObject)) catch .zero; + return globalObject.throwValue(err.toJS(globalObject)) catch .zero; }, } } @@ -72,7 +72,7 @@ pub const ArrayBuffer = extern struct { const stat = switch (bun.sys.fstat(fd)) { .err => |err| { fd.close(); - return globalObject.throwValue(err.toJSC(globalObject)); + return globalObject.throwValue(err.toJS(globalObject)); }, .result => |fstat| fstat, }; @@ -109,7 +109,7 @@ pub const ArrayBuffer = extern struct { return JSBuffer__fromMmap(globalObject, buf.ptr, buf.len); }, .err => |err| { - return globalObject.throwValue(err.toJSC(globalObject)); + return globalObject.throwValue(err.toJS(globalObject)); }, } } @@ -141,34 +141,32 @@ pub const ArrayBuffer = extern struct { return Stream{ .pos = 0, .buf = this.slice() }; } - // TODO: this can throw an error! should use JSError!JSValue - pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSC.JSValue.JSType) JSC.JSValue { + pub fn create(globalThis: *JSC.JSGlobalObject, bytes: []const u8, comptime kind: JSC.JSValue.JSType) bun.JSError!JSC.JSValue { JSC.markBinding(@src()); return switch (comptime kind) { - .Uint8Array => Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, false), - .ArrayBuffer => Bun__createArrayBufferForCopy(globalThis, bytes.ptr, bytes.len), + .Uint8Array => bun.jsc.fromJSHostCall(globalThis, @src(), Bun__createUint8ArrayForCopy, .{ globalThis, bytes.ptr, bytes.len, false }), + .ArrayBuffer => bun.jsc.fromJSHostCall(globalThis, @src(), Bun__createArrayBufferForCopy, .{ globalThis, bytes.ptr, bytes.len }), else => @compileError("Not implemented yet"), }; } - pub fn createEmpty(globalThis: *JSC.JSGlobalObject, comptime kind: JSC.JSValue.JSType) JSC.JSValue { + pub fn createEmpty(globalThis: *JSC.JSGlobalObject, comptime kind: JSC.JSValue.JSType) bun.JSError!JSC.JSValue { JSC.markBinding(@src()); - return switch (comptime kind) { - .Uint8Array => Bun__createUint8ArrayForCopy(globalThis, null, 0, false), - .ArrayBuffer => Bun__createArrayBufferForCopy(globalThis, null, 0), + .Uint8Array => bun.jsc.fromJSHostCall(Bun__createUint8ArrayForCopy, .{ globalThis, null, 0, false }), + .ArrayBuffer => bun.jsc.fromJSHostCall(Bun__createArrayBufferForCopy, .{ globalThis, null, 0 }), else => @compileError("Not implemented yet"), }; } - pub fn createBuffer(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSC.JSValue { + pub fn createBuffer(globalThis: *JSC.JSGlobalObject, bytes: []const u8) bun.JSError!JSC.JSValue { JSC.markBinding(@src()); - return Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, true); + return bun.jsc.fromJSHostCall(globalThis, @src(), Bun__createUint8ArrayForCopy, .{ globalThis, bytes.ptr, bytes.len, true }); } - pub fn createUint8Array(globalThis: *JSC.JSGlobalObject, bytes: []const u8) JSC.JSValue { + pub fn createUint8Array(globalThis: *JSC.JSGlobalObject, bytes: []const u8) bun.JSError!JSC.JSValue { JSC.markBinding(@src()); - return Bun__createUint8ArrayForCopy(globalThis, bytes.ptr, bytes.len, false); + return bun.jsc.fromJSHostCall(globalThis, @src(), Bun__createUint8ArrayForCopy, .{ globalThis, bytes.ptr, bytes.len, false }); } extern "c" fn Bun__allocUint8ArrayForCopy(*JSC.JSGlobalObject, usize, **anyopaque) JSC.JSValue; @@ -177,13 +175,10 @@ pub const ArrayBuffer = extern struct { pub fn alloc(global: *JSC.JSGlobalObject, comptime kind: JSC.JSValue.JSType, len: u32) JSError!struct { JSC.JSValue, []u8 } { var ptr: [*]u8 = undefined; const buf = switch (comptime kind) { - .Uint8Array => Bun__allocUint8ArrayForCopy(global, len, @ptrCast(&ptr)), - .ArrayBuffer => Bun__allocArrayBufferForCopy(global, len, @ptrCast(&ptr)), + .Uint8Array => try bun.jsc.fromJSHostCall(global, @src(), Bun__allocUint8ArrayForCopy, .{ global, len, @ptrCast(&ptr) }), + .ArrayBuffer => try bun.jsc.fromJSHostCall(global, @src(), Bun__allocArrayBufferForCopy, .{ global, len, @ptrCast(&ptr) }), else => @compileError("Not implemented yet"), }; - if (buf == .zero) { - return error.JSError; - } return .{ buf, ptr[0..len] }; } @@ -215,7 +210,7 @@ pub const ArrayBuffer = extern struct { return ArrayBuffer{ .offset = 0, .len = @as(u32, @intCast(bytes.len)), .byte_len = @as(u32, @intCast(bytes.len)), .typed_array_type = typed_array_type, .ptr = bytes.ptr }; } - pub fn toJSUnchecked(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) JSC.JSValue { + pub fn toJSUnchecked(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) bun.JSError!JSC.JSValue { // The reason for this is // JSC C API returns a detached arraybuffer @@ -258,7 +253,7 @@ pub const ArrayBuffer = extern struct { const log = Output.scoped(.ArrayBuffer, false); - pub fn toJS(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) JSC.JSValue { + pub fn toJS(this: ArrayBuffer, ctx: *JSC.JSGlobalObject, exception: JSC.C.ExceptionRef) bun.JSError!JSC.JSValue { if (this.value != .zero) { return this.value; } @@ -434,7 +429,7 @@ pub const ArrayBuffer = extern struct { } /// This clones bytes - pub fn toJS(this: BinaryType, bytes: []const u8, globalThis: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJS(this: BinaryType, bytes: []const u8, globalThis: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { switch (this) { .Buffer => return JSC.ArrayBuffer.createBuffer(globalThis, bytes), .ArrayBuffer => return JSC.ArrayBuffer.create(globalThis, bytes, .ArrayBuffer), @@ -442,7 +437,7 @@ pub const ArrayBuffer = extern struct { // These aren't documented, but they are supported .Uint16Array, .Uint32Array, .Int8Array, .Int16Array, .Int32Array, .Float16Array, .Float32Array, .Float64Array => { - const buffer = JSC.ArrayBuffer.create(globalThis, bytes, .ArrayBuffer); + const buffer = try JSC.ArrayBuffer.create(globalThis, bytes, .ArrayBuffer); return JSC.JSValue.c(JSC.C.JSObjectMakeTypedArrayWithArrayBuffer(globalThis, this.toTypedArrayType(), buffer.asObjectRef(), null)); }, } diff --git a/src/bun.js/modules/BunJSCModule.h b/src/bun.js/modules/BunJSCModule.h index 9647d14fb2..3c107c8c95 100644 --- a/src/bun.js/modules/BunJSCModule.h +++ b/src/bun.js/modules/BunJSCModule.h @@ -770,7 +770,9 @@ JSC_DEFINE_HOST_FUNCTION(functionSerialize, bool asNodeBuffer = false; if (optionsObject.isObject()) { JSC::JSObject* options = optionsObject.getObject(); - if (JSC::JSValue binaryTypeValue = options->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "binaryType"_s))) { + auto binaryTypeValue = options->getIfPropertyExists(globalObject, JSC::Identifier::fromString(vm, "binaryType"_s)); + RETURN_IF_EXCEPTION(throwScope, {}); + if (binaryTypeValue) { if (!binaryTypeValue.isString()) { throwTypeError(globalObject, throwScope, "binaryType must be a string"_s); return {}; @@ -786,9 +788,8 @@ JSC_DEFINE_HOST_FUNCTION(functionSerialize, ExceptionOr> serialized = SerializedScriptValue::create(*globalObject, value, WTFMove(transferList), dummyPorts); if (serialized.hasException()) { - WebCore::propagateException(*globalObject, throwScope, - serialized.releaseException()); - return JSValue::encode(jsUndefined()); + WebCore::propagateException(*globalObject, throwScope, serialized.releaseException()); + RELEASE_AND_RETURN(throwScope, {}); } auto serializedValue = serialized.releaseReturnValue(); diff --git a/src/bun.js/modules/NodeModuleModule.cpp b/src/bun.js/modules/NodeModuleModule.cpp index 52cc334a54..e26286c65e 100644 --- a/src/bun.js/modules/NodeModuleModule.cpp +++ b/src/bun.js/modules/NodeModuleModule.cpp @@ -315,27 +315,21 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName, JSC::CallFrame* callFrame)) { auto& vm = JSC::getVM(globalObject); + auto scope = DECLARE_THROW_SCOPE(vm); switch (callFrame->argumentCount()) { case 0: { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); // not "requires" because "require" could be confusing - JSC::throwTypeError( - globalObject, scope, - "Module._resolveFilename needs 2+ arguments (a string)"_s); - scope.release(); - return JSC::JSValue::encode(JSC::JSValue {}); + JSC::throwTypeError(globalObject, scope, "Module._resolveFilename needs 2+ arguments (a string)"_s); + return {}; } default: { JSC::JSValue moduleName = callFrame->argument(0); JSC::JSValue fromValue = callFrame->argument(1); if (moduleName.isUndefinedOrNull()) { - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); - JSC::throwTypeError(globalObject, scope, - "Module._resolveFilename expects a string"_s); - scope.release(); - return JSC::JSValue::encode(JSC::JSValue {}); + JSC::throwTypeError(globalObject, scope, "Module._resolveFilename expects a string"_s); + return {}; } if ( @@ -347,28 +341,23 @@ JSC_DEFINE_HOST_FUNCTION(jsFunctionResolveFileName, // weird thing. (fromValue.isObject()) { - if (auto idValue = fromValue.getObject()->getIfPropertyExists( - globalObject, builtinNames(vm).filenamePublicName())) { + auto idValue = fromValue.getObject()->getIfPropertyExists(globalObject, builtinNames(vm).filenamePublicName()); + RETURN_IF_EXCEPTION(scope, {}); + if (idValue) { if (idValue.isString()) { fromValue = idValue; } } } - auto scope = DECLARE_THROW_SCOPE(globalObject->vm()); - auto result = Bun__resolveSync( - globalObject, - JSC::JSValue::encode(moduleName), JSValue::encode(fromValue), - false, - true); + auto result = Bun__resolveSync(globalObject, JSC::JSValue::encode(moduleName), JSValue::encode(fromValue), false, true); RETURN_IF_EXCEPTION(scope, {}); if (!JSC::JSValue::decode(result).isString()) { JSC::throwException(globalObject, scope, JSC::JSValue::decode(result)); - return JSC::JSValue::encode(JSC::JSValue {}); + return {}; } - scope.release(); return result; } } @@ -612,9 +601,7 @@ static JSValue getBuiltinModulesObject(VM& vm, JSObject* moduleObject) } auto* globalObject = defaultGlobalObject(moduleObject->globalObject()); - return JSC::constructArray( - globalObject, static_cast(nullptr), - JSC::ArgList(args)); + return JSC::constructArray(globalObject, static_cast(nullptr), JSC::ArgList(args)); } static JSValue getConstantsObject(VM& vm, JSObject* moduleObject) @@ -1016,8 +1003,7 @@ void generateNativeModule_NodeModule(JSC::JSGlobalObject* lexicalGlobalObject, Zig::GlobalObject* globalObject = defaultGlobalObject(lexicalGlobalObject); auto& vm = JSC::getVM(globalObject); auto catchScope = DECLARE_CATCH_SCOPE(vm); - auto* constructor = globalObject->m_nodeModuleConstructor.getInitializedOnMainThread( - globalObject); + auto* constructor = globalObject->m_nodeModuleConstructor.getInitializedOnMainThread(globalObject); if (constructor->hasNonReifiedStaticProperties()) { constructor->reifyAllStaticProperties(globalObject); if (catchScope.exception()) { @@ -1031,19 +1017,15 @@ void generateNativeModule_NodeModule(JSC::JSGlobalObject* lexicalGlobalObject, exportNames.append(vm.propertyNames->defaultKeyword); exportValues.append(constructor); - for (unsigned i = 0; i < Bun::countof(Bun::nodeModuleObjectTableValues); - ++i) { + for (unsigned i = 0; i < Bun::countof(Bun::nodeModuleObjectTableValues); ++i) { const auto& entry = Bun::nodeModuleObjectTableValues[i]; const auto& property = Identifier::fromString(vm, entry.m_key); - JSValue value = constructor->getIfPropertyExists(globalObject, property); + JSValue value = constructor->get(globalObject, property); if (catchScope.exception()) [[unlikely]] { value = {}; catchScope.clearException(); } - if (value.isEmpty()) [[unlikely]] { - value = JSC::jsUndefined(); - } exportNames.append(property); exportValues.append(value); diff --git a/src/bun.js/modules/NodeProcessModule.h b/src/bun.js/modules/NodeProcessModule.h index 605095387b..7022433828 100644 --- a/src/bun.js/modules/NodeProcessModule.h +++ b/src/bun.js/modules/NodeProcessModule.h @@ -15,13 +15,13 @@ DEFINE_NATIVE_MODULE(NodeProcess) Bun::Process* process = globalObject->processObject(); if (!process->staticPropertiesReified()) { process->reifyAllStaticProperties(globalObject); - if (scope.exception()) + if (scope.exception()) [[unlikely]] return; } PropertyNameArray properties(vm, PropertyNameMode::Strings, PrivateSymbolMode::Exclude); process->getPropertyNames(globalObject, properties, DontEnumPropertiesMode::Exclude); - if (scope.exception()) + if (scope.exception()) [[unlikely]] return; exportNames.append(vm.propertyNames->defaultKeyword); diff --git a/src/bun.js/modules/ObjectModule.cpp b/src/bun.js/modules/ObjectModule.cpp index fa37494a80..125cd79481 100644 --- a/src/bun.js/modules/ObjectModule.cpp +++ b/src/bun.js/modules/ObjectModule.cpp @@ -26,7 +26,7 @@ generateObjectModuleSourceCode(JSC::JSGlobalObject* globalObject, auto scope = DECLARE_CATCH_SCOPE(vm); JSValue value = object->get(globalObject, entry); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); value = jsUndefined(); } @@ -66,7 +66,7 @@ generateObjectModuleSourceCodeForJSON(JSC::JSGlobalObject* globalObject, auto scope = DECLARE_CATCH_SCOPE(vm); JSValue value = object->get(globalObject, entry); - if (scope.exception()) { + if (scope.exception()) [[unlikely]] { scope.clearException(); value = jsUndefined(); } diff --git a/src/bun.js/node.zig b/src/bun.js/node.zig index 0c12e67007..83cde3e878 100644 --- a/src/bun.js/node.zig +++ b/src/bun.js/node.zig @@ -193,7 +193,7 @@ pub fn Maybe(comptime ReturnTypeT: type, comptime ErrorTypeT: type) type { }; } - pub fn toJS(this: @This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJS(this: @This(), globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return switch (this) { .result => |r| switch (ReturnType) { JSC.JSValue => r, @@ -215,14 +215,14 @@ pub fn Maybe(comptime ReturnTypeT: type, comptime ErrorTypeT: type) type { }, }, }, - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(globalObject), }; } pub fn toArrayBuffer(this: @This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue { return switch (this) { .result => |r| JSC.ArrayBuffer.fromBytes(r, .ArrayBuffer).toJS(globalObject, null), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(globalObject), }; } diff --git a/src/bun.js/node/Stat.zig b/src/bun.js/node/Stat.zig index a873f604a5..3a3e77ef4b 100644 --- a/src/bun.js/node/Stat.zig +++ b/src/bun.js/node/Stat.zig @@ -44,7 +44,7 @@ pub fn StatType(comptime big: bool) type { } } - pub fn toJS(this: *const @This(), globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJS(this: *const @This(), globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return statToJS(&this.value, globalObject); } @@ -56,7 +56,7 @@ pub fn StatType(comptime big: bool) type { return @intCast(@min(@max(value, 0), std.math.maxInt(i64))); } - fn statToJS(stat_: *const bun.Stat, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + fn statToJS(stat_: *const bun.Stat, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { const aTime = stat_.atime(); const mTime = stat_.mtime(); const cTime = stat_.ctime(); @@ -80,7 +80,7 @@ pub fn StatType(comptime big: bool) type { const birthtime_ns: u64 = if (big and !Environment.isLinux) toNanoseconds(stat_.birthtime()) else 0; if (big) { - return Bun__createJSBigIntStatsObject( + return bun.jsc.fromJSHostCall(globalObject, @src(), Bun__createJSBigIntStatsObject, .{ globalObject, dev, ino, @@ -100,7 +100,7 @@ pub fn StatType(comptime big: bool) type { mtime_ns, ctime_ns, birthtime_ns, - ); + }); } return Bun__createJSStatsObject( @@ -188,7 +188,7 @@ pub const Stats = union(enum) { } } - pub fn toJSNewlyCreated(this: *const Stats, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJSNewlyCreated(this: *const Stats, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return switch (this.*) { .big => this.big.toJS(globalObject), .small => this.small.toJS(globalObject), diff --git a/src/bun.js/node/StatFS.zig b/src/bun.js/node/StatFS.zig index a8414a2ba4..8066f87b1d 100644 --- a/src/bun.js/node/StatFS.zig +++ b/src/bun.js/node/StatFS.zig @@ -15,13 +15,13 @@ pub fn StatFSType(comptime big: bool) type { const This = @This(); - pub fn toJS(this: *const This, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJS(this: *const This, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return statfsToJS(this, globalObject); } - fn statfsToJS(this: *const This, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + fn statfsToJS(this: *const This, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { if (big) { - return Bun__createJSBigIntStatFSObject( + return bun.jsc.fromJSHostCall(globalObject, @src(), Bun__createJSBigIntStatFSObject, .{ globalObject, this._fstype, this._bsize, @@ -30,7 +30,7 @@ pub fn StatFSType(comptime big: bool) type { this._bavail, this._files, this._ffree, - ); + }); } return Bun__createJSStatFSObject( @@ -121,7 +121,7 @@ pub const StatFS = union(enum) { } } - pub fn toJSNewlyCreated(this: *const StatFS, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJSNewlyCreated(this: *const StatFS, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return switch (this.*) { .big => |*big| big.toJS(globalObject), .small => |*small| small.toJS(globalObject), diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index 3bbe2deca5..9e28710e71 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -296,7 +296,7 @@ pub const Async = struct { var promise_value = this.promise.value(); var promise = this.promise.get(); const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), + .err => |err| err.toJS(globalObject), .result => |*res| brk: { break :brk globalObject.toJS(res) catch return promise.reject(globalObject, error.JSError); }, @@ -395,7 +395,7 @@ pub const Async = struct { var promise_value = this.promise.value(); var promise = this.promise.get(); const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), + .err => |err| err.toJS(globalObject), .result => |*res| brk: { break :brk globalObject.toJS(res) catch return promise.reject(globalObject, error.JSError); }, @@ -669,7 +669,7 @@ pub fn NewAsyncCpTask(comptime is_shell: bool) type { var promise_value = this.promise.value(); var promise = this.promise.get(); const result = switch (this.result) { - .err => |err| err.toJSC(globalObject), + .err => |err| err.toJS(globalObject), .result => |*res| brk: { break :brk globalObject.toJS(res) catch return promise.reject(globalObject, error.JSError); }, @@ -1220,7 +1220,7 @@ pub const AsyncReaddirRecursiveTask = struct { const success = this.pending_err == null; var promise_value = this.promise.value(); var promise = this.promise.get(); - const result = if (this.pending_err) |*err| err.toJSC(globalObject) else brk: { + const result = if (this.pending_err) |*err| err.toJS(globalObject) else brk: { const res = switch (this.result_list) { .with_file_types => |*res| Return.Readdir{ .with_file_types = res.moveToUnmanaged().items }, .buffers => |*res| Return.Readdir{ .buffers = res.moveToUnmanaged().items }, @@ -1577,7 +1577,7 @@ pub const Arguments = struct { }; errdefer path.deinit(); - const atime = JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { + const atime = try JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { return ctx.throwInvalidArguments("atime is required", .{}); }) orelse { return ctx.throwInvalidArguments("atime must be a number or a Date", .{}); @@ -1585,7 +1585,7 @@ pub const Arguments = struct { arguments.eat(); - const mtime = JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { + const mtime = try JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { return ctx.throwInvalidArguments("mtime is required", .{}); }) orelse { return ctx.throwInvalidArguments("mtime must be a number or a Date", .{}); @@ -2360,14 +2360,14 @@ pub const Arguments = struct { return throwInvalidFdError(ctx, fd_value); }; - const atime = JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { + const atime = try JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { return ctx.throwInvalidArguments("atime is required", .{}); }) orelse { return ctx.throwInvalidArguments("atime must be a number or a Date", .{}); }; arguments.eat(); - const mtime = JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { + const mtime = try JSC.Node.timeLikeFromJS(ctx, arguments.next() orelse { return ctx.throwInvalidArguments("mtime is required", .{}); }) orelse { return ctx.throwInvalidArguments("mtime must be a number or a Date", .{}); @@ -3085,7 +3085,7 @@ pub const Arguments = struct { if (arguments.next()) |arg| { arguments.eat(); if (arg.isNumber()) { - mode = arg.coerce(i32, ctx); + mode = try arg.coerce(i32, ctx); } } @@ -3148,7 +3148,7 @@ pub const StatOrNotFound = union(enum) { }; } - pub fn toJSNewlyCreated(this: *const StatOrNotFound, globalObject: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJSNewlyCreated(this: *const StatOrNotFound, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { return switch (this.*) { .stats => this.stats.toJSNewlyCreated(globalObject), .not_found => .js_undefined, @@ -3283,13 +3283,8 @@ const Return = struct { var array = try JSC.JSValue.createEmptyArray(globalObject, this.with_file_types.len); var previous_jsstring: ?*JSC.JSString = null; for (this.with_file_types, 0..) |*item, i| { - const res = item.toJSNewlyCreated(globalObject, &previous_jsstring); - if (res == .zero) return .zero; - array.putIndex( - globalObject, - @truncate(i), - res, - ); + const res = try item.toJSNewlyCreated(globalObject, &previous_jsstring); + array.putIndex(globalObject, @truncate(i), res); } return array; }, @@ -5044,7 +5039,7 @@ pub const NodeFS = struct { if (this.vm) |vm| { // Attempt to create the buffer in JSC's heap. // This avoids creating a WastefulTypedArray. - const array_buffer = JSC.ArrayBuffer.createBuffer(vm.global, temporary_read_buffer); + const array_buffer = JSC.ArrayBuffer.createBuffer(vm.global, temporary_read_buffer) catch .zero; // TODO: properly propagate exception upwards array_buffer.ensureStillAlive(); return .{ .result = .{ diff --git a/src/bun.js/node/node_fs_binding.zig b/src/bun.js/node/node_fs_binding.zig index 7d8a7f17b1..77488ca1b6 100644 --- a/src/bun.js/node/node_fs_binding.zig +++ b/src/bun.js/node/node_fs_binding.zig @@ -34,7 +34,7 @@ fn Bindings(comptime function_name: NodeFSFunctionEnum) type { var result = function(&this.node_fs, args, .sync); return switch (result) { - .err => |err| globalObject.throwValue(JSC.JSValue.c(err.toJS(globalObject))), + .err => |err| globalObject.throwValue(err.toJS(globalObject)), .result => |*res| globalObject.toJS(res), }; } @@ -232,7 +232,7 @@ pub fn createMemfdForTesting(globalObject: *JSC.JSGlobalObject, callFrame: *JSC. return JSC.JSValue.jsNumber(fd.cast()); }, .err => |err| { - return globalObject.throwValue(err.toJSC(globalObject)); + return globalObject.throwValue(err.toJS(globalObject)); }, } } diff --git a/src/bun.js/node/node_fs_stat_watcher.zig b/src/bun.js/node/node_fs_stat_watcher.zig index 8fcb3fe33a..281a11b964 100644 --- a/src/bun.js/node/node_fs_stat_watcher.zig +++ b/src/bun.js/node/node_fs_stat_watcher.zig @@ -18,7 +18,7 @@ const StatsBig = bun.JSC.Node.StatsBig; const log = bun.Output.scoped(.StatWatcher, false); -fn statToJSStats(globalThis: *JSC.JSGlobalObject, stats: *const bun.Stat, bigint: bool) JSC.JSValue { +fn statToJSStats(globalThis: *JSC.JSGlobalObject, stats: *const bun.Stat, bigint: bool) bun.JSError!JSC.JSValue { if (bigint) { return StatsBig.init(stats).toJS(globalThis); } else { @@ -279,7 +279,7 @@ pub const StatWatcher = struct { if (!interval_.isNumber() and !interval_.isAnyInt()) { return global.throwInvalidArguments("interval must be a number", .{}); } - interval = interval_.coerce(i32, global); + interval = try interval_.coerce(i32, global); } } } @@ -392,7 +392,7 @@ pub const StatWatcher = struct { return; } - const jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint); + const jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint) catch return; // TODO: properly propagate exception upwards this.last_jsvalue = .create(jsvalue, this.globalThis); this.scheduler.data.append(this); @@ -403,7 +403,7 @@ pub const StatWatcher = struct { return; } - const jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint); + const jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint) catch return; // TODO: properly propagate exception upwards this.last_jsvalue = .create(jsvalue, this.globalThis); _ = js.listenerGetCached(this.js_this).?.call( @@ -449,7 +449,7 @@ pub const StatWatcher = struct { /// After a restat found the file changed, this calls the listener function. pub fn swapAndCallListenerOnMainThread(this: *StatWatcher) void { const prev_jsvalue = this.last_jsvalue.swap(); - const current_jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint); + const current_jsvalue = statToJSStats(this.globalThis, &this.last_stat, this.bigint) catch return; // TODO: properly propagate exception upwards this.last_jsvalue.set(this.globalThis, current_jsvalue); _ = js.listenerGetCached(this.js_this).?.call( diff --git a/src/bun.js/node/node_fs_watcher.zig b/src/bun.js/node/node_fs_watcher.zig index b5df617bf7..0f9417e421 100644 --- a/src/bun.js/node/node_fs_watcher.zig +++ b/src/bun.js/node/node_fs_watcher.zig @@ -501,7 +501,7 @@ pub const FSWatcher = struct { const globalObject = this.globalThis; var args = [_]JSC.JSValue{ EventType.@"error".toJS(globalObject), - err.toJSC(globalObject), + err.toJS(globalObject), }; _ = listener.callWithGlobalThis( globalObject, @@ -527,7 +527,7 @@ pub const FSWatcher = struct { var filename: JSC.JSValue = .js_undefined; if (file_name.len > 0) { if (this.encoding == .buffer) - filename = JSC.ArrayBuffer.createBuffer(globalObject, file_name) + filename = JSC.ArrayBuffer.createBuffer(globalObject, file_name) catch return // TODO: properly propagate exception upwards else if (this.encoding == .utf8) { filename = JSC.ZigString.fromUTF8(file_name).toJS(globalObject); } else { diff --git a/src/bun.js/node/node_os.zig b/src/bun.js/node/node_os.zig index 6a4b9aa8f5..a6300c1b47 100644 --- a/src/bun.js/node/node_os.zig +++ b/src/bun.js/node/node_os.zig @@ -318,7 +318,7 @@ pub fn homedir(global: *JSC.JSGlobalObject) !bun.String { var out: bun.PathBuffer = undefined; var size: usize = out.len; if (libuv.uv_os_homedir(&out, &size).toError(.uv_os_homedir)) |err| { - return global.throwValue(err.toJSC(global)); + return global.throwValue(err.toJS(global)); } return bun.String.createUTF8(out[0..size]); } else { @@ -372,7 +372,7 @@ pub fn homedir(global: *JSC.JSGlobalObject) !bun.String { return global.throwValue(bun.sys.Error.fromCode( @enumFromInt(ret), .uv_os_homedir, - ).toJSC(global)); + ).toJS(global)); } if (result == null) { @@ -380,7 +380,7 @@ pub fn homedir(global: *JSC.JSGlobalObject) !bun.String { return global.throwValue(bun.sys.Error.fromCode( .NOENT, .uv_os_homedir, - ).toJSC(global)); + ).toJS(global)); } return if (pw.pw_dir) |dir| diff --git a/src/bun.js/node/node_process.zig b/src/bun.js/node/node_process.zig index f30e60cd23..5d8b791ec3 100644 --- a/src/bun.js/node/node_process.zig +++ b/src/bun.js/node/node_process.zig @@ -208,7 +208,7 @@ fn getCwd_(globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { switch (bun.api.node.path.getCwd(&buf)) { .result => |r| return JSC.ZigString.init(r).withEncoding().toJS(globalObject), .err => |e| { - return globalObject.throwValue(e.toJSC(globalObject)); + return globalObject.throwValue(e.toJS(globalObject)); }, } } @@ -233,7 +233,7 @@ fn setCwd_(globalObject: *JSC.JSGlobalObject, to: *JSC.ZigString) bun.JSError!JS .result => |r| r, .err => |err| { _ = Syscall.chdir(fs.top_level_dir, fs.top_level_dir); - return globalObject.throwValue(err.toJSC(globalObject)); + return globalObject.throwValue(err.toJS(globalObject)); }, }; @memcpy(fs.top_level_dir_buf[0..into_cwd_buf.len], into_cwd_buf); @@ -252,7 +252,7 @@ fn setCwd_(globalObject: *JSC.JSGlobalObject, to: *JSC.ZigString) bun.JSError!JS return str.transferToJS(globalObject); }, .err => |e| { - return globalObject.throwValue(e.toJSC(globalObject)); + return globalObject.throwValue(e.toJS(globalObject)); }, } } diff --git a/src/bun.js/node/path.zig b/src/bun.js/node/path.zig index 59d67d9501..fe7fe3966d 100644 --- a/src/bun.js/node/path.zig +++ b/src/bun.js/node/path.zig @@ -2325,14 +2325,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| bun.String.createUTF8ForJS(globalObject, r), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(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| bun.String.createUTF8ForJS(globalObject, r), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(globalObject), }; } @@ -2779,14 +2779,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| bun.String.createUTF8ForJS(globalObject, r), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(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| bun.String.createUTF8ForJS(globalObject, r), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(globalObject), }; } @@ -2925,7 +2925,7 @@ 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| bun.String.createUTF8ForJS(globalObject, r), - .err => |e| e.toJSC(globalObject), + .err => |e| e.toJS(globalObject), }; } diff --git a/src/bun.js/node/time_like.zig b/src/bun.js/node/time_like.zig index fbf722ec36..f9ba19cea5 100644 --- a/src/bun.js/node/time_like.zig +++ b/src/bun.js/node/time_like.zig @@ -7,7 +7,7 @@ pub const TimeLike = if (Environment.isWindows) f64 else std.posix.timespec; // Node.js docs: // > Values can be either numbers representing Unix epoch time in seconds, Dates, or a numeric string like '123456789.0'. // > If the value can not be converted to a number, or is NaN, Infinity, or -Infinity, an Error will be thrown. -pub fn fromJS(globalObject: *JSGlobalObject, value: JSValue) ?TimeLike { +pub fn fromJS(globalObject: *JSGlobalObject, value: JSValue) bun.JSError!?TimeLike { // Number is most common case if (value.isNumber()) { const seconds = value.asNumber(); @@ -26,7 +26,7 @@ pub fn fromJS(globalObject: *JSGlobalObject, value: JSValue) ?TimeLike { } }, .String => { - const seconds = value.coerceToDouble(globalObject); + const seconds = try value.toNumber(globalObject); if (std.math.isFinite(seconds)) { return fromSeconds(seconds); } diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 64ae53630c..f884d5c411 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -400,7 +400,7 @@ pub const Encoding = enum(u8) { return globalObject.ERR(.INVALID_ARG_VALUE, "encoding '{}' is an invalid encoding", .{value.fmtString(globalObject)}).throw(); } - pub fn encodeWithSize(encoding: Encoding, globalObject: *JSC.JSGlobalObject, comptime size: usize, input: *const [size]u8) JSC.JSValue { + pub fn encodeWithSize(encoding: Encoding, globalObject: *JSC.JSGlobalObject, comptime size: usize, input: *const [size]u8) bun.JSError!JSC.JSValue { switch (encoding) { .base64 => { var buf: [std.base64.standard.Encoder.calcSize(size)]u8 = undefined; @@ -425,14 +425,14 @@ pub const Encoding = enum(u8) { inline else => |enc| { const res = JSC.WebCore.encoding.toStringComptime(input, globalObject, enc); if (res.isError()) { - return globalObject.throwValue(res) catch .zero; + return globalObject.throwValue(res); } return res; }, } } - pub fn encodeWithMaxSize(encoding: Encoding, globalObject: *JSC.JSGlobalObject, comptime max_size: usize, input: []const u8) JSC.JSValue { + pub fn encodeWithMaxSize(encoding: Encoding, globalObject: *JSC.JSGlobalObject, comptime max_size: usize, input: []const u8) bun.JSError!JSC.JSValue { switch (encoding) { .base64 => { var base64_buf: [std.base64.standard.Encoder.calcSize(max_size * 4)]u8 = undefined; @@ -459,7 +459,7 @@ pub const Encoding = enum(u8) { inline else => |enc| { const res = JSC.WebCore.encoding.toStringComptime(input, globalObject, enc); if (res.isError()) { - return globalObject.throwValue(res) catch .zero; + return globalObject.throwValue(res); } return res; @@ -1017,7 +1017,7 @@ pub const FileSystemFlags = enum(c_int) { if (!val.isInt32()) { return ctx.throwValue(ctx.ERR(.OUT_OF_RANGE, "The value of \"flags\" is out of range. It must be an integer. Received {d}", .{val.asNumber()}).toJS()); } - const number = val.coerce(i32, ctx); + const number = try val.coerce(i32, ctx); return @as(FileSystemFlags, @enumFromInt(@max(number, 0))); } @@ -1126,8 +1126,8 @@ pub const Dirent = struct { pub const getConstructor = Bun__JSDirentObjectConstructor; extern fn Bun__Dirent__toJS(*JSC.JSGlobalObject, i32, *bun.String, *bun.String, cached_previous_path_jsvalue: ?*?*JSC.JSString) JSC.JSValue; - pub fn toJS(this: *Dirent, globalObject: *JSC.JSGlobalObject, cached_previous_path_jsvalue: ?*?*JSC.JSString) JSC.JSValue { - return Bun__Dirent__toJS( + pub fn toJS(this: *Dirent, globalObject: *JSC.JSGlobalObject, cached_previous_path_jsvalue: ?*?*JSC.JSString) bun.JSError!JSC.JSValue { + return bun.jsc.fromJSHostCall(globalObject, @src(), Bun__Dirent__toJS, .{ globalObject, switch (this.kind) { .file => bun.windows.libuv.UV_DIRENT_FILE, @@ -1136,19 +1136,17 @@ pub const Dirent = struct { .directory => bun.windows.libuv.UV_DIRENT_DIR, // event_port is deliberate there. .event_port, .named_pipe => bun.windows.libuv.UV_DIRENT_FIFO, - .unix_domain_socket => bun.windows.libuv.UV_DIRENT_SOCKET, .sym_link => bun.windows.libuv.UV_DIRENT_LINK, - .whiteout, .door, .unknown => bun.windows.libuv.UV_DIRENT_UNKNOWN, }, &this.name, &this.path, cached_previous_path_jsvalue, - ); + }); } - pub fn toJSNewlyCreated(this: *Dirent, globalObject: *JSC.JSGlobalObject, previous_jsstring: ?*?*JSC.JSString) JSC.JSValue { + pub fn toJSNewlyCreated(this: *Dirent, globalObject: *JSC.JSGlobalObject, previous_jsstring: ?*?*JSC.JSString) bun.JSError!JSC.JSValue { // Shouldn't techcnically be necessary. defer this.deref(); return this.toJS(globalObject, previous_jsstring); diff --git a/src/bun.js/test/expect.zig b/src/bun.js/test/expect.zig index 64a44c91e8..6521562fd8 100644 --- a/src/bun.js/test/expect.zig +++ b/src/bun.js/test/expect.zig @@ -880,7 +880,7 @@ pub const Expect = struct { // jest-extended checks for truthiness before calling hasOwnProperty // https://github.com/jest-community/jest-extended/blob/711fdcc54d68c2b2c1992c7cfbdf0d0bd6be0f4d/src/matchers/toContainKeys.js#L1-L6 - if (!value.coerce(bool, globalThis)) break :brk count == 0; + if (!value.toBoolean()) break :brk count == 0; var i: u32 = 0; @@ -4256,7 +4256,7 @@ pub const Expect = struct { return globalThis.throwInvalidArguments("toHaveBeenCalledTimes() requires 1 non-negative integer argument", .{}); } - const times = arguments[0].coerce(i32, globalThis); + const times = try arguments[0].coerce(i32, globalThis); var pass = @as(i32, @intCast(try calls.getLength(globalThis))) == times; @@ -4466,7 +4466,7 @@ pub const Expect = struct { return globalThis.throw("Expected value must be a mock function: {}", .{value}); } - const nthCallNum = if (arguments.len > 0 and arguments[0].isUInt32AsAnyInt()) arguments[0].coerce(i32, globalThis) else 0; + const nthCallNum = if (arguments.len > 0 and arguments[0].isUInt32AsAnyInt()) try arguments[0].coerce(i32, globalThis) else 0; if (nthCallNum < 1) { return globalThis.throwInvalidArguments("toHaveBeenNthCalledWith() requires a positive integer argument", .{}); } @@ -4546,7 +4546,7 @@ pub const Expect = struct { return globalThis.throwInvalidArguments(name ++ "() requires 1 non-negative integer argument", .{}); } - break :brk arguments[0].coerce(i32, globalThis); + break :brk try arguments[0].coerce(i32, globalThis); }; var pass = false; @@ -5645,7 +5645,7 @@ pub const ExpectMatcherUtils = struct { return globalThis.throw("matcherHint: options must be an object (or undefined)", .{}); } if (try options.get(globalThis, "isNot")) |val| { - is_not = val.coerce(bool, globalThis); + is_not = val.toBoolean(); } if (try options.get(globalThis, "comment")) |val| { comment = try val.toJSString(globalThis); diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index b541296ca2..db590730f1 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -499,7 +499,7 @@ pub const Jest = struct { return globalObject.throw("setTimeout() expects a number (milliseconds)", .{}); } - const timeout_ms: u32 = @intCast(@max(arguments[0].coerce(i32, globalObject), 0)); + const timeout_ms: u32 = @intCast(@max(try arguments[0].coerce(i32, globalObject), 0)); if (Jest.runner) |test_runner| { test_runner.default_timeout_override = timeout_ms; @@ -1776,25 +1776,25 @@ inline fn createScope( var timeout_ms: u32 = std.math.maxInt(u32); if (options.isNumber()) { - timeout_ms = @as(u32, @intCast(@max(args[2].coerce(i32, globalThis), 0))); + timeout_ms = @as(u32, @intCast(@max(try args[2].coerce(i32, globalThis), 0))); } else if (options.isObject()) { if (try options.get(globalThis, "timeout")) |timeout| { if (!timeout.isNumber()) { return globalThis.throwPretty("{s} expects timeout to be a number", .{signature}); } - timeout_ms = @as(u32, @intCast(@max(timeout.coerce(i32, globalThis), 0))); + timeout_ms = @as(u32, @intCast(@max(try timeout.coerce(i32, globalThis), 0))); } if (try options.get(globalThis, "retry")) |retries| { if (!retries.isNumber()) { return globalThis.throwPretty("{s} expects retry to be a number", .{signature}); } - // TODO: retry_count = @intCast(u32, @max(retries.coerce(i32, globalThis), 0)); + // TODO: retry_count = @intCast(u32, @max(try retries.coerce(i32, globalThis), 0)); } if (try options.get(globalThis, "repeats")) |repeats| { if (!repeats.isNumber()) { return globalThis.throwPretty("{s} expects repeats to be a number", .{signature}); } - // TODO: repeat_count = @intCast(u32, @max(repeats.coerce(i32, globalThis), 0)); + // TODO: repeat_count = @intCast(u32, @max(try repeats.coerce(i32, globalThis), 0)); } } else if (!options.isEmptyOrUndefinedOrNull()) { return globalThis.throwPretty("{s} expects options to be a number or object", .{signature}); @@ -2023,25 +2023,25 @@ fn eachBind(globalThis: *JSGlobalObject, callframe: *CallFrame) bun.JSError!JSVa var timeout_ms: u32 = std.math.maxInt(u32); if (options.isNumber()) { - timeout_ms = @as(u32, @intCast(@max(args[2].coerce(i32, globalThis), 0))); + timeout_ms = @as(u32, @intCast(@max(try args[2].coerce(i32, globalThis), 0))); } else if (options.isObject()) { if (try options.get(globalThis, "timeout")) |timeout| { if (!timeout.isNumber()) { return globalThis.throwPretty("{s} expects timeout to be a number", .{signature}); } - timeout_ms = @as(u32, @intCast(@max(timeout.coerce(i32, globalThis), 0))); + timeout_ms = @as(u32, @intCast(@max(try timeout.coerce(i32, globalThis), 0))); } if (try options.get(globalThis, "retry")) |retries| { if (!retries.isNumber()) { return globalThis.throwPretty("{s} expects retry to be a number", .{signature}); } - // TODO: retry_count = @intCast(u32, @max(retries.coerce(i32, globalThis), 0)); + // TODO: retry_count = @intCast(u32, @max(try retries.coerce(i32, globalThis), 0)); } if (try options.get(globalThis, "repeats")) |repeats| { if (!repeats.isNumber()) { return globalThis.throwPretty("{s} expects repeats to be a number", .{signature}); } - // TODO: repeat_count = @intCast(u32, @max(repeats.coerce(i32, globalThis), 0)); + // TODO: repeat_count = @intCast(u32, @max(try repeats.coerce(i32, globalThis), 0)); } } else if (!options.isEmptyOrUndefinedOrNull()) { return globalThis.throwPretty("{s} expects options to be a number or object", .{signature}); diff --git a/src/bun.js/webcore/ArrayBufferSink.zig b/src/bun.js/webcore/ArrayBufferSink.zig index 8f9f3a209c..387861a51c 100644 --- a/src/bun.js/webcore/ArrayBufferSink.zig +++ b/src/bun.js/webcore/ArrayBufferSink.zig @@ -45,8 +45,8 @@ pub fn flush(_: *ArrayBufferSink) JSC.Maybe(void) { pub fn flushFromJS(this: *ArrayBufferSink, globalThis: *JSGlobalObject, wait: bool) JSC.Maybe(JSValue) { if (this.streaming) { const value: JSValue = switch (this.as_uint8array) { - true => JSC.ArrayBuffer.create(globalThis, this.bytes.slice(), .Uint8Array), - false => JSC.ArrayBuffer.create(globalThis, this.bytes.slice(), .ArrayBuffer), + true => JSC.ArrayBuffer.create(globalThis, this.bytes.slice(), .Uint8Array) catch .zero, // TODO: properly propagate exception upwards + false => JSC.ArrayBuffer.create(globalThis, this.bytes.slice(), .ArrayBuffer) catch .zero, // TODO: properly propagate exception upwards }; this.bytes.len = 0; if (wait) {} diff --git a/src/bun.js/webcore/Blob.zig b/src/bun.js/webcore/Blob.zig index aa9e30105a..0a71a36479 100644 --- a/src/bun.js/webcore/Blob.zig +++ b/src/bun.js/webcore/Blob.zig @@ -248,7 +248,7 @@ const FormDataContext = struct { switch (res) { .err => |err| { - globalThis.throwValue(err.toJSC(globalThis)) catch {}; + globalThis.throwValue(err.toJS(globalThis)) catch {}; this.failed = true; }, .result => |result| { @@ -813,11 +813,7 @@ pub noinline fn mkdirIfNotExists(this: anytype, err: bun.sys.Error, path_string: /// Returns an encoded `*JSPromise` that resolves if the file /// - doesn't exist and is created /// - exists and is truncated -fn writeFileWithEmptySourceToDestination( - ctx: *JSC.JSGlobalObject, - destination_blob: *Blob, - options: WriteFileOptions, -) JSC.JSValue { +fn writeFileWithEmptySourceToDestination(ctx: *JSC.JSGlobalObject, destination_blob: *Blob, options: WriteFileOptions) bun.JSError!JSC.JSValue { // SAFETY: null-checked by caller const destination_store = destination_blob.store.?; defer destination_blob.detach(); @@ -894,7 +890,7 @@ fn writeFileWithEmptySourceToDestination( } result.err = result.err.withPathLike(file.pathlike); - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, result.toJS(ctx)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(ctx, try result.toJS(ctx)); } }, .s3 => |*s3| { @@ -958,12 +954,7 @@ fn writeFileWithEmptySourceToDestination( return JSC.JSPromise.resolvedPromiseValue(ctx, JSC.JSValue.jsNumber(0)); } -pub fn writeFileWithSourceDestination( - ctx: *JSC.JSGlobalObject, - source_blob: *Blob, - destination_blob: *Blob, - options: WriteFileOptions, -) JSC.JSValue { +pub fn writeFileWithSourceDestination(ctx: *JSC.JSGlobalObject, source_blob: *Blob, destination_blob: *Blob, options: WriteFileOptions) bun.JSError!JSC.JSValue { const destination_store = destination_blob.store orelse Output.panic("Destination blob is detached", .{}); const destination_type = std.meta.activeTag(destination_store.data); @@ -1546,7 +1537,7 @@ fn writeStringToFileFast( return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, - err.withPath(pathlike.path.slice()).toJSC(globalThis), + err.withPath(pathlike.path.slice()).toJS(globalThis), ); }, } @@ -1587,11 +1578,11 @@ fn writeStringToFileFast( return .zero; } if (comptime !needs_open) { - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); } return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, - err.withPath(pathlike.path.slice()).toJSC(globalThis), + err.withPath(pathlike.path.slice()).toJS(globalThis), ); }, } @@ -1633,7 +1624,7 @@ fn writeBytesToFileFast( return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, - err.withPath(pathlike.path.slice()).toJSC(globalThis), + err.withPath(pathlike.path.slice()).toJS(globalThis), ); }, } @@ -1666,12 +1657,12 @@ fn writeBytesToFileFast( if (comptime !needs_open) { return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, - err.toJSC(globalThis), + err.toJS(globalThis), ); } return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM( globalThis, - err.withPath(pathlike.path.slice()).toJSC(globalThis), + err.withPath(pathlike.path.slice()).toJS(globalThis), ); }, } @@ -1777,7 +1768,7 @@ pub fn JSDOMFile__construct_(globalThis: *JSC.JSGlobalObject, callframe: *JSC.Ca if (try options.getTruthy(globalThis, "lastModified")) |last_modified| { set_last_modified = true; - blob.last_modified = last_modified.coerce(f64, globalThis); + blob.last_modified = try last_modified.coerce(f64, globalThis); } } } @@ -1876,7 +1867,7 @@ pub fn constructBunFile( } } if (try opts.getTruthy(globalObject, "lastModified")) |last_modified| { - blob.last_modified = last_modified.coerce(f64, globalObject); + blob.last_modified = try last_modified.coerce(f64, globalObject); } } } @@ -2407,7 +2398,7 @@ pub fn pipeReadableStreamToBlob(this: *Blob, globalThis: *JSC.JSGlobalObject, re break :brk result; }, .err => |err| { - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.withPath(path).toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.withPath(path).toJS(globalThis)); }, } unreachable; @@ -2440,7 +2431,7 @@ pub fn pipeReadableStreamToBlob(this: *Blob, globalThis: *JSC.JSGlobalObject, re switch (sink.writer.startSync(fd, false)) { .err => |err| { sink.deref(); - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); }, else => {}, } @@ -2448,7 +2439,7 @@ pub fn pipeReadableStreamToBlob(this: *Blob, globalThis: *JSC.JSGlobalObject, re switch (sink.writer.start(fd, true)) { .err => |err| { sink.deref(); - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); }, else => {}, } @@ -2483,7 +2474,7 @@ pub fn pipeReadableStreamToBlob(this: *Blob, globalThis: *JSC.JSGlobalObject, re switch (sink.start(stream_start)) { .err => |err| { sink.deref(); - return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + return JSC.JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); }, else => {}, } @@ -2650,7 +2641,7 @@ pub fn getWriter( break :brk result; }, .err => |err| { - return globalThis.throwValue(err.withPath(pathlike.path.slice()).toJSC(globalThis)); + return globalThis.throwValue(err.withPath(pathlike.path.slice()).toJS(globalThis)); }, } @compileError(unreachable); @@ -2683,7 +2674,7 @@ pub fn getWriter( switch (sink.writer.startSync(fd, false)) { .err => |err| { sink.deref(); - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => {}, } @@ -2691,7 +2682,7 @@ pub fn getWriter( switch (sink.writer.start(fd, true)) { .err => |err| { sink.deref(); - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => {}, } @@ -2731,7 +2722,7 @@ pub fn getWriter( switch (sink.start(stream_start)) { .err => |err| { sink.deref(); - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => {}, } diff --git a/src/bun.js/webcore/FileReader.zig b/src/bun.js/webcore/FileReader.zig index bf4bbe747b..74fac23c40 100644 --- a/src/bun.js/webcore/FileReader.zig +++ b/src/bun.js/webcore/FileReader.zig @@ -613,13 +613,10 @@ pub fn onReaderDone(this: *FileReader) void { globalThis, .js_undefined, &.{ - JSC.ArrayBuffer.fromBytes( - buffered.items, - .Uint8Array, - ).toJS( - globalThis, - null, - ), + JSC.ArrayBuffer.fromBytes(buffered.items, .Uint8Array).toJS(globalThis, null) catch |err| { + this.pending.result = .{ .err = .{ .WeakJSValue = globalThis.takeException(err) } }; + return; + }, }, ); } diff --git a/src/bun.js/webcore/ReadableStream.zig b/src/bun.js/webcore/ReadableStream.zig index 7913cc8a2c..df32ec91d2 100644 --- a/src/bun.js/webcore/ReadableStream.zig +++ b/src/bun.js/webcore/ReadableStream.zig @@ -571,7 +571,7 @@ pub fn NewSource( } return switch (this.context.setRawMode(flag == .true)) { .result => .js_undefined, - .err => |e| e.toJSC(global), + .err => |e| e.toJS(global), }; } @@ -636,7 +636,7 @@ pub fn NewSource( .ready => return JSValue.jsNumber(16384), .chunk_size => |size| return JSValue.jsNumber(size), .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); }, else => |rc| { return rc.toJS(globalThis); @@ -653,7 +653,7 @@ pub fn NewSource( switch (result) { .err => |err| { if (err == .Error) { - return globalThis.throwValue(err.Error.toJSC(globalThis)); + return globalThis.throwValue(err.Error.toJS(globalThis)); } else { const js_err = err.JSValue; js_err.ensureStillAlive(); @@ -662,7 +662,7 @@ pub fn NewSource( } }, .pending => { - const out = result.toJS(globalThis); + const out = try result.toJS(globalThis); js.pendingPromiseSetCached(this_jsvalue, globalThis, out); return out; }, diff --git a/src/bun.js/webcore/Sink.zig b/src/bun.js/webcore/Sink.zig index c6081017f8..00105bec52 100644 --- a/src/bun.js/webcore/Sink.zig +++ b/src/bun.js/webcore/Sink.zig @@ -471,7 +471,7 @@ pub fn JSSink(comptime SinkType: type, comptime abi_name: []const u8) type { } } - return this.sink.end(null).toJS(globalThis); + return this.sink.end(null).toJS(globalThis) catch .zero; // TODO: properly propagate exception upwards } pub fn flush(globalThis: *JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue { @@ -496,7 +496,7 @@ pub fn JSSink(comptime SinkType: type, comptime abi_name: []const u8) type { const maybe_value: JSC.Maybe(JSValue) = this.sink.flushFromJS(globalThis, wait); return switch (maybe_value) { .result => |value| value, - .err => |err| return globalThis.throwValue(err.toJSC(globalThis)), + .err => |err| return globalThis.throwValue(err.toJS(globalThis)), }; } @@ -568,7 +568,7 @@ pub fn JSSink(comptime SinkType: type, comptime abi_name: []const u8) type { } } - return this.sink.endFromJS(globalThis).toJS(globalThis); + return this.sink.endFromJS(globalThis).toJS(globalThis) catch .zero; // TODO: properly propagate exception upwards } pub fn updateRef(ptr: *anyopaque, value: bool) callconv(.C) void { diff --git a/src/bun.js/webcore/TextDecoder.zig b/src/bun.js/webcore/TextDecoder.zig index 78903e2828..4dbc8dd798 100644 --- a/src/bun.js/webcore/TextDecoder.zig +++ b/src/bun.js/webcore/TextDecoder.zig @@ -171,11 +171,7 @@ pub fn decode(this: *TextDecoder, globalThis: *JSC.JSGlobalObject, callframe: *J const stream = stream: { if (arguments.len > 1 and arguments[1].isObject()) { if (try arguments[1].fastGet(globalThis, .stream)) |stream_value| { - const stream_bool = stream_value.coerce(bool, globalThis); - if (globalThis.hasException()) { - return .zero; - } - break :stream stream_bool; + break :stream stream_value.toBoolean(); } } diff --git a/src/bun.js/webcore/TextEncoder.zig b/src/bun.js/webcore/TextEncoder.zig index caf57f14e8..e7f867e3cf 100644 --- a/src/bun.js/webcore/TextEncoder.zig +++ b/src/bun.js/webcore/TextEncoder.zig @@ -16,7 +16,7 @@ pub export fn TextEncoder__encode8( if (slice.len <= buf.len / 2) { const result = strings.copyLatin1IntoUTF8(&buf, []const u8, slice); - const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written); + const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written) catch return .zero; bun.assert(result.written <= buf.len); bun.assert(result.read == slice.len); const array_buffer = uint8array.asArrayBuffer(globalThis) orelse return .zero; @@ -28,7 +28,7 @@ pub export fn TextEncoder__encode8( return globalThis.throwOutOfMemoryValue(); }; bun.assert(bytes.len >= slice.len); - return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null); + return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null) catch .zero; } } @@ -53,13 +53,13 @@ pub export fn TextEncoder__encode16( if (slice.len <= buf.len / 4) { const result = strings.copyUTF16IntoUTF8(&buf, @TypeOf(slice), slice); if (result.read == 0 or result.written == 0) { - const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3); + const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3) catch return .zero; const array_buffer = uint8array.asArrayBuffer(globalThis).?; const replacement_char = [_]u8{ 239, 191, 189 }; @memcpy(array_buffer.slice()[0..replacement_char.len], &replacement_char); return uint8array; } - const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written); + const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written) catch return .zero; bun.assert(result.written <= buf.len); bun.assert(result.read == slice.len); const array_buffer = uint8array.asArrayBuffer(globalThis).?; @@ -74,7 +74,7 @@ pub export fn TextEncoder__encode16( ) catch { return globalThis.toInvalidArguments("Out of memory", .{}); }; - return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null); + return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null) catch .zero; } } @@ -99,13 +99,13 @@ pub export fn c( if (slice.len <= buf.len / 4) { const result = strings.copyUTF16IntoUTF8(&buf, @TypeOf(slice), slice); if (result.read == 0 or result.written == 0) { - const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3); + const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, 3) catch return .zero; const array_buffer = uint8array.asArrayBuffer(globalThis).?; const replacement_char = [_]u8{ 239, 191, 189 }; @memcpy(array_buffer.slice()[0..replacement_char.len], &replacement_char); return uint8array; } - const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written); + const uint8array = JSC.JSValue.createUninitializedUint8Array(globalThis, result.written) catch return .zero; bun.assert(result.written <= buf.len); bun.assert(result.read == slice.len); const array_buffer = uint8array.asArrayBuffer(globalThis).?; @@ -120,7 +120,7 @@ pub export fn c( ) catch { return globalThis.throwOutOfMemoryValue(); }; - return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null); + return ArrayBuffer.fromBytes(bytes, .Uint8Array).toJSUnchecked(globalThis, null) catch .zero; } } @@ -186,7 +186,7 @@ pub export fn TextEncoder__encodeRopeString( const length = rope_str.length(); var array: JSValue = .zero; if (length > stack_buf.len / 2) { - array = JSC.JSValue.createUninitializedUint8Array(globalThis, length); + array = JSC.JSValue.createUninitializedUint8Array(globalThis, length) catch return .zero; array.ensureStillAlive(); buf_to_use = array.asArrayBuffer(globalThis).?.slice(); } @@ -204,7 +204,7 @@ pub export fn TextEncoder__encodeRopeString( } if (array == .zero) { - array = JSC.JSValue.createUninitializedUint8Array(globalThis, length); + array = JSC.JSValue.createUninitializedUint8Array(globalThis, length) catch return .zero; array.ensureStillAlive(); @memcpy(array.asArrayBuffer(globalThis).?.ptr[0..length], buf_to_use[0..length]); } diff --git a/src/bun.js/webcore/blob/copy_file.zig b/src/bun.js/webcore/blob/copy_file.zig index 4396dc8d94..7c35e7e369 100644 --- a/src/bun.js/webcore/blob/copy_file.zig +++ b/src/bun.js/webcore/blob/copy_file.zig @@ -63,7 +63,7 @@ pub const CopyFile = struct { pub fn reject(this: *CopyFile, promise: *JSC.JSPromise) void { const globalThis = this.globalThis; - var system_error: SystemError = this.system_error orelse SystemError{}; + var system_error: SystemError = this.system_error orelse SystemError{ .message = .empty }; if (this.source_file_store.pathlike == .path and system_error.path.isEmpty()) { system_error.path = bun.String.createUTF8(this.source_file_store.pathlike.path.slice()); } @@ -997,7 +997,7 @@ pub const CopyFileWindows = struct { pub fn throw(this: *CopyFileWindows, err: bun.sys.Error) void { const globalThis = this.event_loop.global; const promise = this.promise.swap(); - const err_instance = err.toJSC(globalThis); + const err_instance = err.toJS(globalThis); var event_loop = this.event_loop; event_loop.enter(); diff --git a/src/bun.js/webcore/blob/write_file.zig b/src/bun.js/webcore/blob/write_file.zig index fac6648cd3..11302547fb 100644 --- a/src/bun.js/webcore/blob/write_file.zig +++ b/src/bun.js/webcore/blob/write_file.zig @@ -693,7 +693,13 @@ pub const WriteFileWaitFromLockedValueTask = struct { => { var blob = value.use(); // TODO: this should be one promise not two! - const new_promise = Blob.writeFileWithSourceDestination(globalThis, &blob, &file_blob, .{ .mkdirp_if_not_exists = this.mkdirp_if_not_exists }); + const new_promise = Blob.writeFileWithSourceDestination(globalThis, &blob, &file_blob, .{ .mkdirp_if_not_exists = this.mkdirp_if_not_exists }) catch |err| { + file_blob.detach(); + this.promise.deinit(); + bun.destroy(this); + promise.reject(globalThis, err); + return; + }; if (new_promise.asAnyPromise()) |p| { switch (p.unwrap(globalThis.vm(), .mark_handled)) { // Fulfill the new promise using the pending promise diff --git a/src/bun.js/webcore/fetch.zig b/src/bun.js/webcore/fetch.zig index 2a3da09bbe..2c279aec12 100644 --- a/src/bun.js/webcore/fetch.zig +++ b/src/bun.js/webcore/fetch.zig @@ -2406,7 +2406,7 @@ pub fn Bun__fetch_( const opened_fd = switch (opened_fd_res) { .err => |err| { - const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); is_error = true; return rejected_value; }, @@ -2478,7 +2478,7 @@ pub fn Bun__fetch_( switch (res) { .err => |err| { is_error = true; - const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJSC(globalThis)); + const rejected_value = JSPromise.dangerouslyCreateRejectedPromiseValueWithoutNotifyingVM(globalThis, err.toJS(globalThis)); body.detach(); return rejected_value; diff --git a/src/bun.js/webcore/streams.zig b/src/bun.js/webcore/streams.zig index 93734ecb7e..d5e3ed22ab 100644 --- a/src/bun.js/webcore/streams.zig +++ b/src/bun.js/webcore/streams.zig @@ -29,7 +29,7 @@ pub const Start = union(Tag) { done, }; - pub fn toJS(this: Start, globalThis: *JSGlobalObject) JSC.JSValue { + pub fn toJS(this: Start, globalThis: *JSGlobalObject) bun.JSError!JSC.JSValue { switch (this) { .empty, .ready => { return .js_undefined; @@ -38,7 +38,7 @@ pub const Start = union(Tag) { return JSC.JSValue.jsNumber(@as(Blob.SizeType, @intCast(chunk))); }, .err => |err| { - return globalThis.throwValue(err.toJSC(globalThis)) catch .zero; + return globalThis.throwValue(err.toJS(globalThis)); }, .owned_and_done => |list| { return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJS(globalThis, null); @@ -234,7 +234,7 @@ pub const Result = union(Tag) { pub fn toJSWeak(this: *const @This(), globalObject: *JSC.JSGlobalObject) struct { JSC.JSValue, WasStrong } { return switch (this.*) { .Error => |err| { - return .{ err.toJSC(globalObject), WasStrong.Weak }; + return .{ err.toJS(globalObject), WasStrong.Weak }; }, .JSValue => .{ this.JSValue, WasStrong.Strong }, .WeakJSValue => .{ this.WeakJSValue, WasStrong.Weak }, @@ -381,7 +381,7 @@ pub const Result = union(Tag) { defer promise.toJS().unprotect(); switch (result) { .err => |err| { - promise.reject(globalThis, err.toJSC(globalThis)); + promise.reject(globalThis, err.toJS(globalThis)); }, .done => { promise.resolve(globalThis, JSValue.jsBoolean(false)); @@ -394,7 +394,7 @@ pub const Result = union(Tag) { pub fn toJS(this: Writable, globalThis: *JSGlobalObject) JSValue { return switch (this) { - .err => |err| JSC.JSPromise.rejectedPromise(globalThis, JSValue.c(err.toJS(globalThis))).toJS(), + .err => |err| JSC.JSPromise.rejectedPromise(globalThis, err.toJS(globalThis)).toJS(), .owned => |len| JSC.JSValue.jsNumber(len), .owned_and_done => |len| JSC.JSValue.jsNumber(len), @@ -543,7 +543,11 @@ pub const Result = union(Tag) { promise.resolve(globalThis, JSValue.jsBoolean(false)); }, else => { - const value = result.toJS(globalThis); + const value = result.toJS(globalThis) catch |err| { + result.* = .{ .temporary = .{} }; + promise.reject(globalThis, err); + return; + }; value.ensureStillAlive(); result.* = .{ .temporary = .{} }; @@ -552,7 +556,7 @@ pub const Result = union(Tag) { } } - pub fn toJS(this: *const Result, globalThis: *JSGlobalObject) JSValue { + pub fn toJS(this: *const Result, globalThis: *JSGlobalObject) bun.JSError!JSValue { if (JSC.VirtualMachine.get().isShuttingDown()) { var that = this.*; that.deinit(); @@ -567,14 +571,14 @@ pub const Result = union(Tag) { return JSC.ArrayBuffer.fromBytes(list.slice(), .Uint8Array).toJS(globalThis, null); }, .temporary => |temp| { - var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); + var array = try JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); var slice_ = array.asArrayBuffer(globalThis).?.slice(); const temp_slice = temp.slice(); @memcpy(slice_[0..temp_slice.len], temp_slice); return array; }, .temporary_and_done => |temp| { - var array = JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); + var array = try JSC.JSValue.createUninitializedUint8Array(globalThis, temp.len); var slice_ = array.asArrayBuffer(globalThis).?.slice(); const temp_slice = temp.slice(); @memcpy(slice_[0..temp_slice.len], temp_slice); diff --git a/src/css/values/color_js.zig b/src/css/values/color_js.zig index 5d4b84b0dc..0565847ade 100644 --- a/src/css/values/color_js.zig +++ b/src/css/values/color_js.zig @@ -60,7 +60,7 @@ fn colorIntFromJS(globalThis: *JSC.JSGlobalObject, input: JSC.JSValue, comptime } // CSS spec says to clamp values to their valid range so we'll respect that here - return std.math.clamp(input.coerce(i32, globalThis), 0, 255); + return std.math.clamp(try input.coerce(i32, globalThis), 0, 255); } // https://github.com/tmux/tmux/blob/dae2868d1227b95fd076fb4a5efa6256c7245943/colour.c#L44-L55 diff --git a/src/deps/c_ares.zig b/src/deps/c_ares.zig index 44dbc53791..370b854be6 100644 --- a/src/deps/c_ares.zig +++ b/src/deps/c_ares.zig @@ -1697,7 +1697,10 @@ pub const Error = enum(i32) { const system_error = JSC.SystemError{ .errno = @intFromEnum(this.errno), .code = bun.String.static(this.errno.code()), - .message = if (this.hostname) |hostname| bun.String.createFormat("{s} {s} {s}", .{ this.syscall, this.errno.code()[4..], hostname }) catch bun.outOfMemory() else bun.String.empty, + .message = if (this.hostname) |hostname| + bun.String.createFormat("{s} {s} {s}", .{ this.syscall, this.errno.code()[4..], hostname }) catch bun.outOfMemory() + else + bun.String.createFormat("{s} {s}", .{ this.syscall, this.errno.code()[4..] }) catch bun.outOfMemory(), .syscall = bun.String.createUTF8(this.syscall), .hostname = this.hostname orelse bun.String.empty, }; @@ -1745,31 +1748,23 @@ pub const Error = enum(i32) { return Deferred.init(this, syscall, host_string, promise.*); } - pub fn toJS(this: Error, globalThis: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJSWithSyscall(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: [:0]const u8) JSC.JSValue { const instance = (JSC.SystemError{ .errno = @intFromEnum(this), - .code = bun.String.static(this.code()), + .code = bun.String.static(this.code()[4..]), + .syscall = bun.String.static(syscall), + .message = bun.String.createFormat("{s} {s}", .{ syscall, this.code()[4..] }) catch bun.outOfMemory(), }).toErrorInstance(globalThis); instance.put(globalThis, "name", bun.String.static("DNSException").toJS(globalThis)); return instance; } - pub fn toJSWithSyscall(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8) JSC.JSValue { + pub fn toJSWithSyscallAndHostname(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: [:0]const u8, hostname: []const u8) JSC.JSValue { const instance = (JSC.SystemError{ .errno = @intFromEnum(this), - .code = bun.String.static(this.code()), - .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), - }).toErrorInstance(globalThis); - instance.put(globalThis, "name", bun.String.static("DNSException").toJS(globalThis)); - return instance; - } - - pub fn toJSWithSyscallAndHostname(this: Error, globalThis: *JSC.JSGlobalObject, comptime syscall: []const u8, hostname: []const u8) JSC.JSValue { - const instance = (JSC.SystemError{ - .errno = @intFromEnum(this), - .code = bun.String.static(this.code()), + .code = bun.String.static(this.code()[4..]), .message = bun.String.createFormat("{s} {s} {s}", .{ syscall, this.code()[4..], hostname }) catch bun.outOfMemory(), - .syscall = bun.String.static((syscall ++ "\x00")[0..syscall.len :0]), + .syscall = bun.String.static(syscall), .hostname = bun.String.createUTF8(hostname), }).toErrorInstance(globalThis); instance.put(globalThis, "name", bun.String.static("DNSException").toJS(globalThis)); diff --git a/src/deps/uws/UpgradedDuplex.zig b/src/deps/uws/UpgradedDuplex.zig index 31a0896828..8008abd6d8 100644 --- a/src/deps/uws/UpgradedDuplex.zig +++ b/src/deps/uws/UpgradedDuplex.zig @@ -96,7 +96,10 @@ fn callWriteOrEnd(this: *UpgradedDuplex, data: ?[]const u8, msg_more: bool) void const globalThis = this.global.?; const writeOrEnd = if (msg_more) duplex.getFunction(globalThis, "write") catch return orelse return else duplex.getFunction(globalThis, "end") catch return orelse return; if (data) |data_| { - const buffer = JSC.ArrayBuffer.BinaryType.toJS(.Buffer, data_, globalThis); + const buffer = JSC.ArrayBuffer.BinaryType.toJS(.Buffer, data_, globalThis) catch |err| { + this.handlers.onError(this.handlers.ctx, globalThis.takeException(err)); + return; + }; buffer.ensureStillAlive(); _ = writeOrEnd.call(globalThis, duplex, &.{buffer}) catch |err| { diff --git a/src/dns.zig b/src/dns.zig index f43455d59b..38e6b2b957 100644 --- a/src/dns.zig +++ b/src/dns.zig @@ -108,7 +108,7 @@ pub const GetAddrInfo = struct { if (!flags.isNumber()) return error.InvalidFlags; - options.flags = flags.coerce(std.c.AI, globalObject); + options.flags = try flags.coerce(std.c.AI, globalObject); // hints & ~(AI_ADDRCONFIG | AI_ALL | AI_V4MAPPED)) !== 0 const filter = ~@as(u32, @bitCast(std.c.AI{ .ALL = true, .ADDRCONFIG = true, .V4MAPPED = true })); @@ -146,7 +146,7 @@ pub const GetAddrInfo = struct { return .unspecified; if (value.isNumber()) { - return switch (value.coerce(i32, globalObject)) { + return switch (try value.coerce(i32, globalObject)) { 0 => .unspecified, 4 => .inet, 6 => .inet6, diff --git a/src/patch.zig b/src/patch.zig index 027bdd0258..56b70f4ddd 100644 --- a/src/patch.zig +++ b/src/patch.zig @@ -1132,7 +1132,7 @@ pub const TestingAPIs = struct { defer args.deinit(); if (args.patchfile.apply(bun.default_allocator, args.dirfd)) |err| { - return globalThis.throwValue(err.toJSC(globalThis)); + return globalThis.throwValue(err.toJS(globalThis)); } return .true; @@ -1179,7 +1179,7 @@ pub const TestingAPIs = struct { break :brk switch (bun.sys.open(path, bun.O.DIRECTORY | bun.O.RDONLY, 0)) { .err => |e| { - globalThis.throwValue(e.withPath(path).toJSC(globalThis)) catch {}; + globalThis.throwValue(e.withPath(path).toJS(globalThis)) catch {}; return .initErr(.js_undefined); }, .result => |fd| fd, diff --git a/src/shell/Yield.zig b/src/shell/Yield.zig index c87a3f2140..ad79aab824 100644 --- a/src/shell/Yield.zig +++ b/src/shell/Yield.zig @@ -55,7 +55,7 @@ pub const Yield = union(enum) { }, suspended, - /// Failed and throwed a JS error + /// Failed and threw a JS error failed, done, diff --git a/src/shell/interpreter.zig b/src/shell/interpreter.zig index eb7a6b7a40..1da175db59 100644 --- a/src/shell/interpreter.zig +++ b/src/shell/interpreter.zig @@ -84,7 +84,6 @@ const Yield = shell.Yield; pub const Pipe = [2]bun.FileDescriptor; const shell = bun.shell; -const ShellError = shell.ShellError; const ast = shell.AST; pub const SmolList = shell.SmolList; @@ -657,9 +656,9 @@ pub const Interpreter = struct { syscall: Syscall.Error, other: ShellErrorKind, - fn toJSC(this: ShellErrorCtx, globalThis: *JSGlobalObject) JSValue { + fn toJS(this: ShellErrorCtx, globalThis: *JSGlobalObject) JSValue { return switch (this) { - .syscall => |err| err.toJSC(globalThis), + .syscall => |err| err.toJS(globalThis), .other => |err| bun.JSC.ZigString.fromBytes(@errorName(err)).toJS(globalThis), }; } @@ -1165,12 +1164,12 @@ pub const Interpreter = struct { if (this.event_loop == .js) { defer this.deinitAfterJSRun(); this.exit_code = exit_code; - if (this.this_jsvalue != .zero) { - const this_jsvalue = this.this_jsvalue; + const this_jsvalue = this.this_jsvalue; + if (this_jsvalue != .zero) { if (JSC.Codegen.JSShellInterpreter.resolveGetCached(this_jsvalue)) |resolve| { - this.this_jsvalue = .zero; - const globalThis = this.globalThis; const loop = this.event_loop.js; + const globalThis = this.globalThis; + this.this_jsvalue = .zero; this.keep_alive.disable(); loop.enter(); _ = resolve.call(globalThis, .js_undefined, &.{ @@ -1191,34 +1190,6 @@ pub const Interpreter = struct { return .done; } - fn errored(this: *ThisInterpreter, the_error: ShellError) void { - _ = the_error; // autofix - defer decrPendingActivityFlag(&this.has_pending_activity); - - if (this.event_loop == .js) { - const this_jsvalue = this.this_jsvalue; - if (this_jsvalue != .zero) { - if (JSC.Codegen.JSShellInterpreter.rejectGetCached(this_jsvalue)) |reject| { - const loop = this.event_loop.js; - const globalThis = this.globalThis; - this.this_jsvalue = .zero; - this.keep_alive.disable(); - - loop.enter(); - _ = reject.call(globalThis, &[_]JSValue{ - JSValue.jsNumberFromChar(1), - this.getBufferedStdout(globalThis), - this.getBufferedStderr(globalThis), - }) catch |err| globalThis.reportActiveExceptionAsUnhandled(err); - JSC.Codegen.JSShellInterpreter.resolveSetCached(this_jsvalue, globalThis, .js_undefined); - JSC.Codegen.JSShellInterpreter.rejectSetCached(this_jsvalue, globalThis, .js_undefined); - - loop.exit(); - } - } - } - } - fn deinitAfterJSRun(this: *ThisInterpreter) void { log("Interpreter(0x{x}) deinitAfterJSRun", .{@intFromPtr(this)}); for (this.jsobjs) |jsobj| { @@ -1270,7 +1241,7 @@ pub const Interpreter = struct { defer slice.deinit(); switch (this.root_shell.changeCwd(this, slice.slice())) { .err => |e| { - return globalThis.throwValue(e.toJSC(globalThis)); + return globalThis.throwValue(e.toJS(globalThis)); }, .result => {}, } @@ -1313,42 +1284,26 @@ pub const Interpreter = struct { return .js_undefined; } - pub fn isRunning( - this: *ThisInterpreter, - _: *JSGlobalObject, - _: *JSC.CallFrame, - ) bun.JSError!JSC.JSValue { + pub fn isRunning(this: *ThisInterpreter, _: *JSGlobalObject, _: *JSC.CallFrame) bun.JSError!JSC.JSValue { return JSC.JSValue.jsBoolean(this.hasPendingActivity()); } - pub fn getStarted( - this: *ThisInterpreter, - globalThis: *JSGlobalObject, - callframe: *JSC.CallFrame, - ) bun.JSError!JSC.JSValue { + pub fn getStarted(this: *ThisInterpreter, globalThis: *JSGlobalObject, callframe: *JSC.CallFrame) bun.JSError!JSC.JSValue { _ = globalThis; // autofix _ = callframe; // autofix return JSC.JSValue.jsBoolean(this.started.load(.seq_cst)); } - pub fn getBufferedStdout( - this: *ThisInterpreter, - globalThis: *JSGlobalObject, - ) JSC.JSValue { + pub fn getBufferedStdout(this: *ThisInterpreter, globalThis: *JSGlobalObject) JSC.JSValue { return ioToJSValue(globalThis, this.root_shell.buffered_stdout()); } - pub fn getBufferedStderr( - this: *ThisInterpreter, - globalThis: *JSGlobalObject, - ) JSC.JSValue { + pub fn getBufferedStderr(this: *ThisInterpreter, globalThis: *JSGlobalObject) JSC.JSValue { return ioToJSValue(globalThis, this.root_shell.buffered_stderr()); } - pub fn finalize( - this: *ThisInterpreter, - ) void { + pub fn finalize(this: *ThisInterpreter) void { log("Interpreter(0x{x}) finalize", .{@intFromPtr(this)}); this.deinitFromFinalizer(); } diff --git a/src/shell/shell.zig b/src/shell/shell.zig index 389a467904..01eaa54bc0 100644 --- a/src/shell/shell.zig +++ b/src/shell/shell.zig @@ -199,7 +199,7 @@ pub const GlobalJS = struct { } pub inline fn throwError(this: @This(), err: bun.sys.Error) void { - this.globalThis.throwValue(err.toJSC(this.globalThis)); + this.globalThis.throwValue(err.toJS(this.globalThis)); } pub inline fn handleError(this: @This(), err: anytype, comptime fmt: []const u8) ShellErr { diff --git a/src/shell/states/Expansion.zig b/src/shell/states/Expansion.zig index f838900355..177dce86bf 100644 --- a/src/shell/states/Expansion.zig +++ b/src/shell/states/Expansion.zig @@ -756,9 +756,9 @@ pub const ShellGlobTask = struct { syscall: Syscall.Error, unknown: anyerror, - pub fn toJSC(this: Err, globalThis: *JSGlobalObject) JSValue { + pub fn toJS(this: Err, globalThis: *JSGlobalObject) JSValue { return switch (this) { - .syscall => |err| err.toJSC(globalThis), + .syscall => |err| err.toJS(globalThis), .unknown => |err| JSC.ZigString.fromBytes(@errorName(err)).toJS(globalThis), }; } diff --git a/src/sql/postgres.zig b/src/sql/postgres.zig index 5608ee9bcf..2e36888fe7 100644 --- a/src/sql/postgres.zig +++ b/src/sql/postgres.zig @@ -641,7 +641,7 @@ pub const PostgresSQLQuery = struct { return globalObject.throwInvalidArgumentType("setMode", "mode", "Number"); } - const mode = js_mode.coerce(i32, globalObject); + const mode = try js_mode.coerce(i32, globalObject); this.flags.result_mode = std.meta.intToEnum(PostgresSQLQueryResultMode, mode) catch { return globalObject.throwInvalidArgumentTypeValue("mode", "Number", js_mode); }; @@ -1801,7 +1801,7 @@ pub const PostgresSQLConnection = struct { const arguments = callframe.arguments_old(15).slice(); const hostname_str = try arguments[0].toBunString(globalObject); defer hostname_str.deref(); - const port = arguments[1].coerce(i32, globalObject); + const port = try arguments[1].coerce(i32, globalObject); const username_str = try arguments[2].toBunString(globalObject); defer username_str.deref(); diff --git a/src/string.zig b/src/string.zig index 24380fad21..be35bbd54e 100644 --- a/src/string.zig +++ b/src/string.zig @@ -666,16 +666,10 @@ pub const String = extern struct { return false; } - extern fn BunString__toJSON( - globalObject: *bun.JSC.JSGlobalObject, - this: *String, - ) JSC.JSValue; + extern fn BunString__toJSON(globalObject: *bun.JSC.JSGlobalObject, this: *String) JSC.JSValue; pub fn toJSByParseJSON(self: *String, globalObject: *JSC.JSGlobalObject) bun.JSError!JSC.JSValue { - JSC.markBinding(@src()); - const result = BunString__toJSON(globalObject, self); - if (result == .zero) return error.JSError; - return result; + return bun.jsc.fromJSHostCall(globalObject, @src(), BunString__toJSON, .{ globalObject, self }); } pub fn encodeInto(self: String, out: []u8, comptime enc: JSC.Node.Encoding) !usize { diff --git a/src/sys.zig b/src/sys.zig index 6f7c47fa79..84490643ba 100644 --- a/src/sys.zig +++ b/src/sys.zig @@ -540,6 +540,7 @@ pub const Error = struct { var err = SystemError{ .errno = @as(c_int, this.errno) * -1, .syscall = bun.String.static(@tagName(this.syscall)), + .message = .empty, }; // errno label @@ -575,6 +576,7 @@ pub const Error = struct { var err = SystemError{ .errno = -%@as(c_int, this.errno), .syscall = bun.String.static(@tagName(this.syscall)), + .message = .empty, }; // errno label @@ -641,11 +643,7 @@ pub const Error = struct { return Error{ .errno = todo_errno, .syscall = .TODO }; } - pub fn toJS(this: Error, ctx: *JSC.JSGlobalObject) JSC.C.JSObjectRef { - return this.toSystemError().toErrorInstance(ctx).asObjectRef(); - } - - pub fn toJSC(this: Error, ptr: *JSC.JSGlobalObject) JSC.JSValue { + pub fn toJS(this: Error, ptr: *JSC.JSGlobalObject) JSC.JSValue { return this.toSystemError().toErrorInstance(ptr); } }; diff --git a/src/valkey/valkey_protocol.zig b/src/valkey/valkey_protocol.zig index f7f3e76e87..c11c29201b 100644 --- a/src/valkey/valkey_protocol.zig +++ b/src/valkey/valkey_protocol.zig @@ -255,7 +255,7 @@ pub const RESPValue = union(RESPType) { fn valkeyStrToJSValue(globalObject: *JSC.JSGlobalObject, str: []const u8, options: *const ToJSOptions) bun.JSError!JSC.JSValue { if (options.return_as_buffer) { // TODO: handle values > 4.7 GB - const buf = JSC.ArrayBuffer.createBuffer(globalObject, str); + const buf = try JSC.ArrayBuffer.createBuffer(globalObject, str); return buf.toJS(globalObject); } else { return bun.String.createUTF8ForJS(globalObject, str); diff --git a/test/internal/ban-words.test.ts b/test/internal/ban-words.test.ts index a69db2e993..27f2e9ac46 100644 --- a/test/internal/ban-words.test.ts +++ b/test/internal/ban-words.test.ts @@ -42,11 +42,11 @@ const words: Record ".stdFile()": { reason: "Prefer bun.sys + bun.FD instead of std.fs.File. Zig hides 'errno' when Bun wants to match libuv", limit: 18 }, ".stdDir()": { reason: "Prefer bun.sys + bun.FD instead of std.fs.File. Zig hides 'errno' when Bun wants to match libuv", limit: 49 }, ".arguments_old(": { reason: "Please migrate to .argumentsAsArray() or another argument API", limit: 284 }, - "// autofix": { reason: "Evaluate if this variable should be deleted entirely or explicitly discarded.", limit: 175 }, + "// autofix": { reason: "Evaluate if this variable should be deleted entirely or explicitly discarded.", limit: 174 }, - "global.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 29 }, - "globalObject.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 49 }, - "globalThis.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 139 }, + "global.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 28 }, + "globalObject.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 48 }, + "globalThis.hasException": { reason: "Incompatible with strict exception checks. Use a CatchScope instead.", limit: 136 }, }; const words_keys = [...Object.keys(words)]; diff --git a/test/no-validate-exceptions.txt b/test/no-validate-exceptions.txt index 2471699589..1f9c444550 100644 --- a/test/no-validate-exceptions.txt +++ b/test/no-validate-exceptions.txt @@ -380,68 +380,6 @@ test/js/node/test/parallel/test-blocklist-clone.js test/js/node/test/parallel/test-blocklist.js test/js/node/test/parallel/test-broadcastchannel-custom-inspect.js test/js/node/test/parallel/test-btoa-atob.js -test/js/node/test/parallel/test-buffer-alloc.js -test/js/node/test/parallel/test-buffer-arraybuffer.js -test/js/node/test/parallel/test-buffer-ascii.js -test/js/node/test/parallel/test-buffer-backing-arraybuffer.js -test/js/node/test/parallel/test-buffer-badhex.js -test/js/node/test/parallel/test-buffer-bigint64.js -test/js/node/test/parallel/test-buffer-bytelength.js -test/js/node/test/parallel/test-buffer-compare-offset.js -test/js/node/test/parallel/test-buffer-compare.js -test/js/node/test/parallel/test-buffer-concat.js -test/js/node/test/parallel/test-buffer-constants.js -test/js/node/test/parallel/test-buffer-constructor-deprecation-error.js -test/js/node/test/parallel/test-buffer-constructor-node-modules-paths.js -test/js/node/test/parallel/test-buffer-constructor-node-modules.js -test/js/node/test/parallel/test-buffer-constructor-outside-node-modules.js -test/js/node/test/parallel/test-buffer-copy.js -test/js/node/test/parallel/test-buffer-equals.js -test/js/node/test/parallel/test-buffer-failed-alloc-typed-arrays.js -test/js/node/test/parallel/test-buffer-fakes.js -test/js/node/test/parallel/test-buffer-fill.js -test/js/node/test/parallel/test-buffer-from.js -test/js/node/test/parallel/test-buffer-includes.js -test/js/node/test/parallel/test-buffer-indexof.js -test/js/node/test/parallel/test-buffer-inheritance.js -test/js/node/test/parallel/test-buffer-inspect.js -test/js/node/test/parallel/test-buffer-isascii.js -test/js/node/test/parallel/test-buffer-isencoding.js -test/js/node/test/parallel/test-buffer-isutf8.js -test/js/node/test/parallel/test-buffer-iterator.js -test/js/node/test/parallel/test-buffer-new.js -test/js/node/test/parallel/test-buffer-no-negative-allocation.js -test/js/node/test/parallel/test-buffer-nopendingdep-map.js -test/js/node/test/parallel/test-buffer-of-no-deprecation.js -test/js/node/test/parallel/test-buffer-over-max-length.js -test/js/node/test/parallel/test-buffer-parent-property.js -test/js/node/test/parallel/test-buffer-pending-deprecation.js -test/js/node/test/parallel/test-buffer-pool-untransferable.js -test/js/node/test/parallel/test-buffer-prototype-inspect.js -test/js/node/test/parallel/test-buffer-read.js -test/js/node/test/parallel/test-buffer-readdouble.js -test/js/node/test/parallel/test-buffer-readfloat.js -test/js/node/test/parallel/test-buffer-readint.js -test/js/node/test/parallel/test-buffer-readuint.js -test/js/node/test/parallel/test-buffer-safe-unsafe.js -test/js/node/test/parallel/test-buffer-set-inspect-max-bytes.js -test/js/node/test/parallel/test-buffer-sharedarraybuffer.js -test/js/node/test/parallel/test-buffer-slice.js -test/js/node/test/parallel/test-buffer-slow.js -test/js/node/test/parallel/test-buffer-swap.js -test/js/node/test/parallel/test-buffer-tojson.js -test/js/node/test/parallel/test-buffer-tostring-range.js -test/js/node/test/parallel/test-buffer-tostring-rangeerror.js -test/js/node/test/parallel/test-buffer-tostring.js -test/js/node/test/parallel/test-buffer-write-fast.js -test/js/node/test/parallel/test-buffer-write.js -test/js/node/test/parallel/test-buffer-writedouble.js -test/js/node/test/parallel/test-buffer-writefloat.js -test/js/node/test/parallel/test-buffer-writeint.js -test/js/node/test/parallel/test-buffer-writeuint.js -test/js/node/test/parallel/test-buffer-zero-fill-cli.js -test/js/node/test/parallel/test-buffer-zero-fill-reset.js -test/js/node/test/parallel/test-buffer-zero-fill.js test/js/node/test/parallel/test-c-ares.js test/js/node/test/parallel/test-child-process-advanced-serialization-largebuffer.js test/js/node/test/parallel/test-child-process-advanced-serialization.js @@ -881,218 +819,6 @@ test/js/node/test/parallel/test-eventtarget.js test/js/node/test/parallel/test-exception-handler.js test/js/node/test/parallel/test-exception-handler2.js test/js/node/test/parallel/test-fetch.mjs -test/js/node/test/parallel/test-file-read-noexist.js -test/js/node/test/parallel/test-file-validate-mode-flag.js -test/js/node/test/parallel/test-file-write-stream.js -test/js/node/test/parallel/test-file-write-stream2.js -test/js/node/test/parallel/test-file-write-stream3.js -test/js/node/test/parallel/test-file-write-stream4.js -test/js/node/test/parallel/test-filehandle-close.js -test/js/node/test/parallel/test-finalization-registry-shutdown.js -test/js/node/test/parallel/test-fs-access.js -test/js/node/test/parallel/test-fs-append-file-flush.js -test/js/node/test/parallel/test-fs-append-file-sync.js -test/js/node/test/parallel/test-fs-append-file.js -test/js/node/test/parallel/test-fs-assert-encoding-error.js -test/js/node/test/parallel/test-fs-buffer.js -test/js/node/test/parallel/test-fs-buffertype-writesync.js -test/js/node/test/parallel/test-fs-chmod-mask.js -test/js/node/test/parallel/test-fs-chmod.js -test/js/node/test/parallel/test-fs-chown-type-check.js -test/js/node/test/parallel/test-fs-close-errors.js -test/js/node/test/parallel/test-fs-close.js -test/js/node/test/parallel/test-fs-constants.js -test/js/node/test/parallel/test-fs-copyfile-respect-permissions.js -test/js/node/test/parallel/test-fs-copyfile.js -test/js/node/test/parallel/test-fs-empty-readStream.js -test/js/node/test/parallel/test-fs-exists.js -test/js/node/test/parallel/test-fs-existssync-false.js -test/js/node/test/parallel/test-fs-fchmod.js -test/js/node/test/parallel/test-fs-fchown.js -test/js/node/test/parallel/test-fs-filehandle-use-after-close.js -test/js/node/test/parallel/test-fs-fsync.js -test/js/node/test/parallel/test-fs-lchmod.js -test/js/node/test/parallel/test-fs-lchown.js -test/js/node/test/parallel/test-fs-link.js -test/js/node/test/parallel/test-fs-long-path.js -test/js/node/test/parallel/test-fs-make-callback.js -test/js/node/test/parallel/test-fs-makeStatsCallback.js -test/js/node/test/parallel/test-fs-mkdir-mode-mask.js -test/js/node/test/parallel/test-fs-mkdir-recursive-eaccess.js -test/js/node/test/parallel/test-fs-mkdir-rmdir.js -test/js/node/test/parallel/test-fs-mkdir.js -test/js/node/test/parallel/test-fs-mkdtemp-prefix-check.js -test/js/node/test/parallel/test-fs-mkdtemp.js -test/js/node/test/parallel/test-fs-non-number-arguments-throw.js -test/js/node/test/parallel/test-fs-null-bytes.js -test/js/node/test/parallel/test-fs-open-mode-mask.js -test/js/node/test/parallel/test-fs-open-no-close.js -test/js/node/test/parallel/test-fs-open-numeric-flags.js -test/js/node/test/parallel/test-fs-open.js -test/js/node/test/parallel/test-fs-options-immutable.js -test/js/node/test/parallel/test-fs-promises-exists.js -test/js/node/test/parallel/test-fs-promises-file-handle-append-file.js -test/js/node/test/parallel/test-fs-promises-file-handle-chmod.js -test/js/node/test/parallel/test-fs-promises-file-handle-dispose.js -test/js/node/test/parallel/test-fs-promises-file-handle-read-worker.js -test/js/node/test/parallel/test-fs-promises-file-handle-read.js -test/js/node/test/parallel/test-fs-promises-file-handle-readFile.js -test/js/node/test/parallel/test-fs-promises-file-handle-stat.js -test/js/node/test/parallel/test-fs-promises-file-handle-stream.js -test/js/node/test/parallel/test-fs-promises-file-handle-sync.js -test/js/node/test/parallel/test-fs-promises-file-handle-truncate.js -test/js/node/test/parallel/test-fs-promises-file-handle-write.js -test/js/node/test/parallel/test-fs-promises-file-handle-writeFile.js -test/js/node/test/parallel/test-fs-promises-readfile-empty.js -test/js/node/test/parallel/test-fs-promises-readfile-with-fd.js -test/js/node/test/parallel/test-fs-promises-readfile.js -test/js/node/test/parallel/test-fs-promises-write-optional-params.js -test/js/node/test/parallel/test-fs-promises-writefile-typedarray.js -test/js/node/test/parallel/test-fs-promises-writefile-with-fd.js -test/js/node/test/parallel/test-fs-promises-writefile.js -test/js/node/test/parallel/test-fs-promisified.js -test/js/node/test/parallel/test-fs-read-empty-buffer.js -test/js/node/test/parallel/test-fs-read-file-assert-encoding.js -test/js/node/test/parallel/test-fs-read-file-sync-hostname.js -test/js/node/test/parallel/test-fs-read-file-sync.js -test/js/node/test/parallel/test-fs-read-offset-null.js -test/js/node/test/parallel/test-fs-read-optional-params.js -test/js/node/test/parallel/test-fs-read-position-validation.mjs -test/js/node/test/parallel/test-fs-read-promises-optional-params.js -test/js/node/test/parallel/test-fs-read-promises-position-validation.mjs -test/js/node/test/parallel/test-fs-read-stream-autoClose.js -test/js/node/test/parallel/test-fs-read-stream-concurrent-reads.js -test/js/node/test/parallel/test-fs-read-stream-double-close.js -test/js/node/test/parallel/test-fs-read-stream-encoding.js -test/js/node/test/parallel/test-fs-read-stream-err.js -test/js/node/test/parallel/test-fs-read-stream-fd-leak.js -test/js/node/test/parallel/test-fs-read-stream-fd.js -test/js/node/test/parallel/test-fs-read-stream-file-handle.js -test/js/node/test/parallel/test-fs-read-stream-inherit.js -test/js/node/test/parallel/test-fs-read-stream-patch-open.js -test/js/node/test/parallel/test-fs-read-stream-resume.js -test/js/node/test/parallel/test-fs-read-stream-throw-type-error.js -test/js/node/test/parallel/test-fs-read-type.js -test/js/node/test/parallel/test-fs-read-zero-length.js -test/js/node/test/parallel/test-fs-read.js -test/js/node/test/parallel/test-fs-readdir-buffer.js -test/js/node/test/parallel/test-fs-readdir-pipe.js -test/js/node/test/parallel/test-fs-readdir-recursive.js -test/js/node/test/parallel/test-fs-readdir-stack-overflow.js -test/js/node/test/parallel/test-fs-readdir-types-symlinks.js -test/js/node/test/parallel/test-fs-readdir-types.js -test/js/node/test/parallel/test-fs-readdir-ucs2.js -test/js/node/test/parallel/test-fs-readdir.js -test/js/node/test/parallel/test-fs-readfile-empty.js -test/js/node/test/parallel/test-fs-readfile-eof.js -test/js/node/test/parallel/test-fs-readfile-error.js -test/js/node/test/parallel/test-fs-readfile-fd.js -test/js/node/test/parallel/test-fs-readfile-flags.js -test/js/node/test/parallel/test-fs-readfile-pipe-large.js -test/js/node/test/parallel/test-fs-readfile-pipe.js -test/js/node/test/parallel/test-fs-readfile-unlink.js -test/js/node/test/parallel/test-fs-readfile-zero-byte-liar.js -test/js/node/test/parallel/test-fs-readfile.js -test/js/node/test/parallel/test-fs-readfilesync-enoent.js -test/js/node/test/parallel/test-fs-readfilesync-pipe-large.js -test/js/node/test/parallel/test-fs-readlink-type-check.js -test/js/node/test/parallel/test-fs-readSync-optional-params.js -test/js/node/test/parallel/test-fs-readSync-position-validation.mjs -test/js/node/test/parallel/test-fs-readv-promises.js -test/js/node/test/parallel/test-fs-readv-promisify.js -test/js/node/test/parallel/test-fs-readv-sync.js -test/js/node/test/parallel/test-fs-readv.js -test/js/node/test/parallel/test-fs-ready-event-stream.js -test/js/node/test/parallel/test-fs-realpath-buffer-encoding.js -test/js/node/test/parallel/test-fs-realpath-native.js -test/js/node/test/parallel/test-fs-realpath-on-substed-drive.js -test/js/node/test/parallel/test-fs-realpath-pipe.js -test/js/node/test/parallel/test-fs-realpath.js -test/js/node/test/parallel/test-fs-rename-type-check.js -test/js/node/test/parallel/test-fs-rmdir-recursive-sync-warns-not-found.js -test/js/node/test/parallel/test-fs-rmdir-recursive-sync-warns-on-file.js -test/js/node/test/parallel/test-fs-rmdir-recursive-throws-not-found.js -test/js/node/test/parallel/test-fs-rmdir-recursive-throws-on-file.js -test/js/node/test/parallel/test-fs-rmdir-recursive-warns-not-found.js -test/js/node/test/parallel/test-fs-rmdir-recursive-warns-on-file.js -test/js/node/test/parallel/test-fs-rmdir-recursive.js -test/js/node/test/parallel/test-fs-rmdir-type-check.js -test/js/node/test/parallel/test-fs-sir-writes-alot.js -test/js/node/test/parallel/test-fs-stat-bigint.js -test/js/node/test/parallel/test-fs-stat-date.mjs -test/js/node/test/parallel/test-fs-stat.js -test/js/node/test/parallel/test-fs-statfs.js -test/js/node/test/parallel/test-fs-stream-construct-compat-error-read.js -test/js/node/test/parallel/test-fs-stream-construct-compat-error-write.js -test/js/node/test/parallel/test-fs-stream-construct-compat-graceful-fs.js -test/js/node/test/parallel/test-fs-stream-construct-compat-old-node.js -test/js/node/test/parallel/test-fs-stream-destroy-emit-error.js -test/js/node/test/parallel/test-fs-stream-double-close.js -test/js/node/test/parallel/test-fs-stream-fs-options.js -test/js/node/test/parallel/test-fs-stream-options.js -test/js/node/test/parallel/test-fs-symlink-buffer-path.js -test/js/node/test/parallel/test-fs-symlink-dir-junction-relative.js -test/js/node/test/parallel/test-fs-symlink-dir-junction.js -test/js/node/test/parallel/test-fs-symlink-dir.js -test/js/node/test/parallel/test-fs-symlink-longpath.js -test/js/node/test/parallel/test-fs-symlink.js -test/js/node/test/parallel/test-fs-syncwritestream.js -test/js/node/test/parallel/test-fs-timestamp-parsing-error.js -test/js/node/test/parallel/test-fs-truncate-clear-file-zero.js -test/js/node/test/parallel/test-fs-truncate-fd.js -test/js/node/test/parallel/test-fs-truncate-sync.js -test/js/node/test/parallel/test-fs-truncate.js -test/js/node/test/parallel/test-fs-unlink-type-check.js -test/js/node/test/parallel/test-fs-utimes-y2K38.js -test/js/node/test/parallel/test-fs-watch-abort-signal.js -test/js/node/test/parallel/test-fs-watch-close-when-destroyed.js -test/js/node/test/parallel/test-fs-watch-encoding.js -test/js/node/test/parallel/test-fs-watch-file-enoent-after-deletion.js -test/js/node/test/parallel/test-fs-watch-recursive-add-file-to-existing-subfolder.js -test/js/node/test/parallel/test-fs-watch-recursive-add-file-with-url.js -test/js/node/test/parallel/test-fs-watch-recursive-add-file.js -test/js/node/test/parallel/test-fs-watch-recursive-add-folder.js -test/js/node/test/parallel/test-fs-watch-recursive-assert-leaks.js -test/js/node/test/parallel/test-fs-watch-recursive-delete.js -test/js/node/test/parallel/test-fs-watch-recursive-sync-write.js -test/js/node/test/parallel/test-fs-watch-recursive-validate.js -test/js/node/test/parallel/test-fs-watch-ref-unref.js -test/js/node/test/parallel/test-fs-watch-stop-sync.js -test/js/node/test/parallel/test-fs-watchfile-ref-unref.js -test/js/node/test/parallel/test-fs-whatwg-url.js -test/js/node/test/parallel/test-fs-write-buffer-large.js -test/js/node/test/parallel/test-fs-write-buffer.js -test/js/node/test/parallel/test-fs-write-file-buffer.js -test/js/node/test/parallel/test-fs-write-file-flush.js -test/js/node/test/parallel/test-fs-write-file-invalid-path.js -test/js/node/test/parallel/test-fs-write-file-sync.js -test/js/node/test/parallel/test-fs-write-file-typedarrays.js -test/js/node/test/parallel/test-fs-write-file.js -test/js/node/test/parallel/test-fs-write-negativeoffset.js -test/js/node/test/parallel/test-fs-write-no-fd.js -test/js/node/test/parallel/test-fs-write-optional-params.js -test/js/node/test/parallel/test-fs-write-reuse-callback.js -test/js/node/test/parallel/test-fs-write-sigxfsz.js -test/js/node/test/parallel/test-fs-write-stream-autoclose-option.js -test/js/node/test/parallel/test-fs-write-stream-change-open.js -test/js/node/test/parallel/test-fs-write-stream-close-without-callback.js -test/js/node/test/parallel/test-fs-write-stream-double-close.js -test/js/node/test/parallel/test-fs-write-stream-encoding.js -test/js/node/test/parallel/test-fs-write-stream-end.js -test/js/node/test/parallel/test-fs-write-stream-err.js -test/js/node/test/parallel/test-fs-write-stream-file-handle-2.js -test/js/node/test/parallel/test-fs-write-stream-file-handle.js -test/js/node/test/parallel/test-fs-write-stream-flush.js -test/js/node/test/parallel/test-fs-write-stream-fs.js -test/js/node/test/parallel/test-fs-write-stream-patch-open.js -test/js/node/test/parallel/test-fs-write-stream-throw-type-error.js -test/js/node/test/parallel/test-fs-write-stream.js -test/js/node/test/parallel/test-fs-write-sync.js -test/js/node/test/parallel/test-fs-writefile-with-fd.js -test/js/node/test/parallel/test-fs-writestream-open-write.js -test/js/node/test/parallel/test-fs-writev-promises.js -test/js/node/test/parallel/test-fs-writev-sync.js -test/js/node/test/parallel/test-fs-writev.js test/js/node/test/parallel/test-global-domexception.js test/js/node/test/parallel/test-global-encoder.js test/js/node/test/parallel/test-global-webcrypto.js @@ -1831,196 +1557,6 @@ test/js/node/test/parallel/test-stdout-pipeline-destroy.js test/js/node/test/parallel/test-stdout-stderr-reading.js test/js/node/test/parallel/test-stdout-stderr-write.js test/js/node/test/parallel/test-stdout-to-file.js -test/js/node/test/parallel/test-stream-aliases-legacy.js -test/js/node/test/parallel/test-stream-auto-destroy.js -test/js/node/test/parallel/test-stream-await-drain-writers-in-synchronously-recursion-write.js -test/js/node/test/parallel/test-stream-backpressure.js -test/js/node/test/parallel/test-stream-base-prototype-accessors-enumerability.js -test/js/node/test/parallel/test-stream-big-packet.js -test/js/node/test/parallel/test-stream-big-push.js -test/js/node/test/parallel/test-stream-catch-rejections.js -test/js/node/test/parallel/test-stream-compose-operator.js -test/js/node/test/parallel/test-stream-compose.js -test/js/node/test/parallel/test-stream-construct.js -test/js/node/test/parallel/test-stream-consumers.js -test/js/node/test/parallel/test-stream-decoder-objectmode.js -test/js/node/test/parallel/test-stream-destroy-event-order.js -test/js/node/test/parallel/test-stream-drop-take.js -test/js/node/test/parallel/test-stream-duplex-destroy.js -test/js/node/test/parallel/test-stream-duplex-end.js -test/js/node/test/parallel/test-stream-duplex-from.js -test/js/node/test/parallel/test-stream-duplex-props.js -test/js/node/test/parallel/test-stream-duplex-readable-end.js -test/js/node/test/parallel/test-stream-duplex-readable-writable.js -test/js/node/test/parallel/test-stream-duplex-writable-finished.js -test/js/node/test/parallel/test-stream-duplex.js -test/js/node/test/parallel/test-stream-duplexpair.js -test/js/node/test/parallel/test-stream-end-of-streams.js -test/js/node/test/parallel/test-stream-end-paused.js -test/js/node/test/parallel/test-stream-err-multiple-callback-construction.js -test/js/node/test/parallel/test-stream-error-once.js -test/js/node/test/parallel/test-stream-event-names.js -test/js/node/test/parallel/test-stream-events-prepend.js -test/js/node/test/parallel/test-stream-filter.js -test/js/node/test/parallel/test-stream-finished.js -test/js/node/test/parallel/test-stream-flatMap.js -test/js/node/test/parallel/test-stream-forEach.js -test/js/node/test/parallel/test-stream-inheritance.js -test/js/node/test/parallel/test-stream-ispaused.js -test/js/node/test/parallel/test-stream-iterator-helpers-test262-tests.mjs -test/js/node/test/parallel/test-stream-map.js -test/js/node/test/parallel/test-stream-objectmode-undefined.js -test/js/node/test/parallel/test-stream-once-readable-pipe.js -test/js/node/test/parallel/test-stream-passthrough-drain.js -test/js/node/test/parallel/test-stream-pipe-after-end.js -test/js/node/test/parallel/test-stream-pipe-await-drain-manual-resume.js -test/js/node/test/parallel/test-stream-pipe-await-drain-push-while-write.js -test/js/node/test/parallel/test-stream-pipe-await-drain.js -test/js/node/test/parallel/test-stream-pipe-cleanup-pause.js -test/js/node/test/parallel/test-stream-pipe-cleanup.js -test/js/node/test/parallel/test-stream-pipe-deadlock.js -test/js/node/test/parallel/test-stream-pipe-error-handling.js -test/js/node/test/parallel/test-stream-pipe-error-unhandled.js -test/js/node/test/parallel/test-stream-pipe-event.js -test/js/node/test/parallel/test-stream-pipe-flow-after-unpipe.js -test/js/node/test/parallel/test-stream-pipe-flow.js -test/js/node/test/parallel/test-stream-pipe-manual-resume.js -test/js/node/test/parallel/test-stream-pipe-multiple-pipes.js -test/js/node/test/parallel/test-stream-pipe-needDrain.js -test/js/node/test/parallel/test-stream-pipe-same-destination-twice.js -test/js/node/test/parallel/test-stream-pipe-unpipe-streams.js -test/js/node/test/parallel/test-stream-pipe-without-listenerCount.js -test/js/node/test/parallel/test-stream-pipeline-async-iterator.js -test/js/node/test/parallel/test-stream-pipeline-duplex.js -test/js/node/test/parallel/test-stream-pipeline-listeners.js -test/js/node/test/parallel/test-stream-pipeline-process.js -test/js/node/test/parallel/test-stream-pipeline-queued-end-in-destroy.js -test/js/node/test/parallel/test-stream-pipeline-uncaught.js -test/js/node/test/parallel/test-stream-pipeline-with-empty-string.js -test/js/node/test/parallel/test-stream-preprocess.js -test/js/node/test/parallel/test-stream-promises.js -test/js/node/test/parallel/test-stream-push-order.js -test/js/node/test/parallel/test-stream-push-strings.js -test/js/node/test/parallel/test-stream-readable-aborted.js -test/js/node/test/parallel/test-stream-readable-add-chunk-during-data.js -test/js/node/test/parallel/test-stream-readable-constructor-set-methods.js -test/js/node/test/parallel/test-stream-readable-data.js -test/js/node/test/parallel/test-stream-readable-default-encoding.js -test/js/node/test/parallel/test-stream-readable-destroy.js -test/js/node/test/parallel/test-stream-readable-didRead.js -test/js/node/test/parallel/test-stream-readable-dispose.js -test/js/node/test/parallel/test-stream-readable-emit-readable-short-stream.js -test/js/node/test/parallel/test-stream-readable-emittedReadable.js -test/js/node/test/parallel/test-stream-readable-end-destroyed.js -test/js/node/test/parallel/test-stream-readable-ended.js -test/js/node/test/parallel/test-stream-readable-error-end.js -test/js/node/test/parallel/test-stream-readable-event.js -test/js/node/test/parallel/test-stream-readable-flow-recursion.js -test/js/node/test/parallel/test-stream-readable-from-web-termination.js -test/js/node/test/parallel/test-stream-readable-hwm-0-async.js -test/js/node/test/parallel/test-stream-readable-hwm-0-no-flow-data.js -test/js/node/test/parallel/test-stream-readable-hwm-0.js -test/js/node/test/parallel/test-stream-readable-infinite-read.js -test/js/node/test/parallel/test-stream-readable-invalid-chunk.js -test/js/node/test/parallel/test-stream-readable-needReadable.js -test/js/node/test/parallel/test-stream-readable-next-no-null.js -test/js/node/test/parallel/test-stream-readable-no-unneeded-readable.js -test/js/node/test/parallel/test-stream-readable-object-multi-push-async.js -test/js/node/test/parallel/test-stream-readable-pause-and-resume.js -test/js/node/test/parallel/test-stream-readable-readable-then-resume.js -test/js/node/test/parallel/test-stream-readable-readable.js -test/js/node/test/parallel/test-stream-readable-reading-readingMore.js -test/js/node/test/parallel/test-stream-readable-resume-hwm.js -test/js/node/test/parallel/test-stream-readable-resumeScheduled.js -test/js/node/test/parallel/test-stream-readable-setEncoding-existing-buffers.js -test/js/node/test/parallel/test-stream-readable-setEncoding-null.js -test/js/node/test/parallel/test-stream-readable-strategy-option.js -test/js/node/test/parallel/test-stream-readable-to-web-termination.js -test/js/node/test/parallel/test-stream-readable-to-web.js -test/js/node/test/parallel/test-stream-readable-unpipe-resume.js -test/js/node/test/parallel/test-stream-readable-unshift.js -test/js/node/test/parallel/test-stream-readable-with-unimplemented-_read.js -test/js/node/test/parallel/test-stream-readableListening-state.js -test/js/node/test/parallel/test-stream-reduce.js -test/js/node/test/parallel/test-stream-set-default-hwm.js -test/js/node/test/parallel/test-stream-some-find-every.mjs -test/js/node/test/parallel/test-stream-toArray.js -test/js/node/test/parallel/test-stream-toWeb-allows-server-response.js -test/js/node/test/parallel/test-stream-transform-callback-twice.js -test/js/node/test/parallel/test-stream-transform-constructor-set-methods.js -test/js/node/test/parallel/test-stream-transform-destroy.js -test/js/node/test/parallel/test-stream-transform-final-sync.js -test/js/node/test/parallel/test-stream-transform-final.js -test/js/node/test/parallel/test-stream-transform-flush-data.js -test/js/node/test/parallel/test-stream-transform-hwm0.js -test/js/node/test/parallel/test-stream-transform-objectmode-falsey-value.js -test/js/node/test/parallel/test-stream-transform-split-highwatermark.js -test/js/node/test/parallel/test-stream-transform-split-objectmode.js -test/js/node/test/parallel/test-stream-typedarray.js -test/js/node/test/parallel/test-stream-uint8array.js -test/js/node/test/parallel/test-stream-unpipe-event.js -test/js/node/test/parallel/test-stream-unshift-empty-chunk.js -test/js/node/test/parallel/test-stream-unshift-read-race.js -test/js/node/test/parallel/test-stream-writable-aborted.js -test/js/node/test/parallel/test-stream-writable-change-default-encoding.js -test/js/node/test/parallel/test-stream-writable-clear-buffer.js -test/js/node/test/parallel/test-stream-writable-constructor-set-methods.js -test/js/node/test/parallel/test-stream-writable-decoded-encoding.js -test/js/node/test/parallel/test-stream-writable-destroy.js -test/js/node/test/parallel/test-stream-writable-end-cb-error.js -test/js/node/test/parallel/test-stream-writable-end-cb-uncaught.js -test/js/node/test/parallel/test-stream-writable-end-multiple.js -test/js/node/test/parallel/test-stream-writable-ended-state.js -test/js/node/test/parallel/test-stream-writable-final-async.js -test/js/node/test/parallel/test-stream-writable-final-destroy.js -test/js/node/test/parallel/test-stream-writable-final-throw.js -test/js/node/test/parallel/test-stream-writable-finish-destroyed.js -test/js/node/test/parallel/test-stream-writable-finished-state.js -test/js/node/test/parallel/test-stream-writable-finished.js -test/js/node/test/parallel/test-stream-writable-invalid-chunk.js -test/js/node/test/parallel/test-stream-writable-needdrain-state.js -test/js/node/test/parallel/test-stream-writable-null.js -test/js/node/test/parallel/test-stream-writable-properties.js -test/js/node/test/parallel/test-stream-writable-writable.js -test/js/node/test/parallel/test-stream-writable-write-cb-error.js -test/js/node/test/parallel/test-stream-writable-write-cb-twice.js -test/js/node/test/parallel/test-stream-writable-write-error.js -test/js/node/test/parallel/test-stream-writable-write-writev-finish.js -test/js/node/test/parallel/test-stream-writableState-ending.js -test/js/node/test/parallel/test-stream-writableState-uncorked-bufferedRequestCount.js -test/js/node/test/parallel/test-stream-write-destroy.js -test/js/node/test/parallel/test-stream-write-drain.js -test/js/node/test/parallel/test-stream-write-final.js -test/js/node/test/parallel/test-stream-writev.js -test/js/node/test/parallel/test-stream2-base64-single-char-read-end.js -test/js/node/test/parallel/test-stream2-basic.js -test/js/node/test/parallel/test-stream2-compatibility.js -test/js/node/test/parallel/test-stream2-decode-partial.js -test/js/node/test/parallel/test-stream2-finish-pipe-error.js -test/js/node/test/parallel/test-stream2-finish-pipe.js -test/js/node/test/parallel/test-stream2-large-read-stall.js -test/js/node/test/parallel/test-stream2-objects.js -test/js/node/test/parallel/test-stream2-pipe-error-handling.js -test/js/node/test/parallel/test-stream2-pipe-error-once-listener.js -test/js/node/test/parallel/test-stream2-push.js -test/js/node/test/parallel/test-stream2-read-sync-stack.js -test/js/node/test/parallel/test-stream2-readable-empty-buffer-no-eof.js -test/js/node/test/parallel/test-stream2-readable-legacy-drain.js -test/js/node/test/parallel/test-stream2-readable-non-empty-end.js -test/js/node/test/parallel/test-stream2-readable-wrap-destroy.js -test/js/node/test/parallel/test-stream2-readable-wrap-empty.js -test/js/node/test/parallel/test-stream2-readable-wrap-error.js -test/js/node/test/parallel/test-stream2-readable-wrap.js -test/js/node/test/parallel/test-stream2-set-encoding.js -test/js/node/test/parallel/test-stream2-transform.js -test/js/node/test/parallel/test-stream2-unpipe-drain.js -test/js/node/test/parallel/test-stream2-unpipe-leak.js -test/js/node/test/parallel/test-stream2-writable.js -test/js/node/test/parallel/test-stream3-cork-end.js -test/js/node/test/parallel/test-stream3-cork-uncork.js -test/js/node/test/parallel/test-stream3-pause-then-read.js -test/js/node/test/parallel/test-stream3-pipeline-async-iterator.js -test/js/node/test/parallel/test-streams-highwatermark.js test/js/node/test/parallel/test-string-decoder-end.js test/js/node/test/parallel/test-string-decoder.js test/js/node/test/parallel/test-stringbytes-external.js @@ -2384,61 +1920,6 @@ test/js/node/test/parallel/test-worker-type-check.js test/js/node/test/parallel/test-worker-workerdata-sharedarraybuffer.js test/js/node/test/parallel/test-worker.js test/js/node/test/parallel/test-worker.mjs -test/js/node/test/parallel/test-zlib-brotli-16GB.js -test/js/node/test/parallel/test-zlib-brotli-flush.js -test/js/node/test/parallel/test-zlib-brotli-from-brotli.js -test/js/node/test/parallel/test-zlib-brotli-from-string.js -test/js/node/test/parallel/test-zlib-brotli-kmaxlength-rangeerror.js -test/js/node/test/parallel/test-zlib-brotli.js -test/js/node/test/parallel/test-zlib-close-after-error.js -test/js/node/test/parallel/test-zlib-close-after-write.js -test/js/node/test/parallel/test-zlib-close-in-ondata.js -test/js/node/test/parallel/test-zlib-const.js -test/js/node/test/parallel/test-zlib-convenience-methods.js -test/js/node/test/parallel/test-zlib-crc32.js -test/js/node/test/parallel/test-zlib-create-raw.js -test/js/node/test/parallel/test-zlib-deflate-constructors.js -test/js/node/test/parallel/test-zlib-deflate-raw-inherits.js -test/js/node/test/parallel/test-zlib-destroy-pipe.js -test/js/node/test/parallel/test-zlib-destroy.js -test/js/node/test/parallel/test-zlib-dictionary-fail.js -test/js/node/test/parallel/test-zlib-dictionary.js -test/js/node/test/parallel/test-zlib-empty-buffer.js -test/js/node/test/parallel/test-zlib-failed-init.js -test/js/node/test/parallel/test-zlib-flush-drain-longblock.js -test/js/node/test/parallel/test-zlib-flush-drain.js -test/js/node/test/parallel/test-zlib-flush-flags.js -test/js/node/test/parallel/test-zlib-flush-write-sync-interleaved.js -test/js/node/test/parallel/test-zlib-flush.js -test/js/node/test/parallel/test-zlib-from-concatenated-gzip.js -test/js/node/test/parallel/test-zlib-from-gzip-with-trailing-garbage.js -test/js/node/test/parallel/test-zlib-from-gzip.js -test/js/node/test/parallel/test-zlib-from-string.js -test/js/node/test/parallel/test-zlib-invalid-arg-value-brotli-compress.js -test/js/node/test/parallel/test-zlib-invalid-input.js -test/js/node/test/parallel/test-zlib-kmaxlength-rangeerror.js -test/js/node/test/parallel/test-zlib-maxOutputLength.js -test/js/node/test/parallel/test-zlib-not-string-or-buffer.js -test/js/node/test/parallel/test-zlib-object-write.js -test/js/node/test/parallel/test-zlib-params.js -test/js/node/test/parallel/test-zlib-premature-end.js -test/js/node/test/parallel/test-zlib-random-byte-pipes.js -test/js/node/test/parallel/test-zlib-reset-before-write.js -test/js/node/test/parallel/test-zlib-sync-no-event.js -test/js/node/test/parallel/test-zlib-truncated.js -test/js/node/test/parallel/test-zlib-unzip-one-byte-chunks.js -test/js/node/test/parallel/test-zlib-write-after-close.js -test/js/node/test/parallel/test-zlib-write-after-end.js -test/js/node/test/parallel/test-zlib-write-after-flush.js -test/js/node/test/parallel/test-zlib-zero-byte.js -test/js/node/test/parallel/test-zlib-zero-windowBits.js -test/js/node/test/parallel/test-zlib-zstd-flush.js -test/js/node/test/parallel/test-zlib-zstd-from-string.js -test/js/node/test/parallel/test-zlib-zstd-from-zstd.js -test/js/node/test/parallel/test-zlib-zstd-kmaxlength-rangeerror.js -test/js/node/test/parallel/test-zlib-zstd-pledged-src-size.js -test/js/node/test/parallel/test-zlib-zstd.js -test/js/node/test/parallel/test-zlib.js test/js/node/test/sequential/test-buffer-creation-regression.js test/js/node/test/sequential/test-child-process-emfile.js test/js/node/test/sequential/test-child-process-execsync.js @@ -2818,3 +2299,26 @@ vendor/elysia/test/ws/aot.test.ts vendor/elysia/test/ws/connection.test.ts vendor/elysia/test/ws/destructuring.test.ts vendor/elysia/test/ws/message.test.ts + +# List of tests that potentially throw inside of reifyStaticProperties +test/js/node/test/parallel/test-stream-iterator-helpers-test262-tests.mjs +test/js/node/test/parallel/test-stream-some-find-every.mjs +test/js/node/test/parallel/test-fs-stat-date.mjs +test/js/node/test/parallel/test-fs-readSync-position-validation.mjs +test/js/node/test/parallel/test-fs-read-promises-position-validation.mjs +test/js/node/test/parallel/test-fs-read-position-validation.mjs + +# uses node:test +test/js/node/test/parallel/test-fs-write-stream-flush.js +test/js/node/test/parallel/test-fs-write-file-flush.js +test/js/node/test/parallel/test-fs-operations-with-surrogate-pairs.js +test/js/node/test/parallel/test-fs-append-file-flush.js +test/js/node/test/parallel/test-file-write-stream5.js + +# trips asan on my macos test machine +test/js/node/test/parallel/test-fs-watch.js +test/js/node/test/parallel/test-fs-watch-recursive-watch-file.js + +# uses jsobjectref +test/js/node/test/parallel/test-fs-readdir-buffer.js +test/js/node/test/parallel/test-stream-finished.js