Skip to content

Commit

Permalink
zig: assert there is an exception when .zero is returned (#15362)
Browse files Browse the repository at this point in the history
Co-authored-by: Jarred Sumner <[email protected]>
  • Loading branch information
nektro and Jarred-Sumner authored Nov 25, 2024
1 parent a6f37b3 commit bb3d570
Show file tree
Hide file tree
Showing 21 changed files with 167 additions and 179 deletions.
42 changes: 21 additions & 21 deletions src/bun.js/api/BunObject.zig
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ pub fn shellEscape(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b
const arguments = callframe.arguments_old(1);
if (arguments.len < 1) {
globalThis.throw("shell escape expected at least 1 argument", .{});
return .undefined;
return .zero;
}

const jsval = arguments.ptr[0];
Expand All @@ -277,11 +277,11 @@ pub fn shellEscape(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b
if (bun.shell.needsEscapeBunstr(bunstr)) {
const result = bun.shell.escapeBunStr(bunstr, &outbuf, true) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};
if (!result) {
globalThis.throw("String has invalid utf-16: {s}", .{bunstr.byteSlice()});
return .undefined;
return .zero;
}
var str = bun.String.createUTF8(outbuf.items[0..]);
return str.transferToJS(globalThis);
Expand All @@ -297,7 +297,7 @@ pub fn braces(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS

const brace_str_js = arguments.nextEat() orelse {
globalThis.throw("braces: expected at least 1 argument, got 0", .{});
return .undefined;
return .zero;
};
const brace_str = brace_str_js.toBunString(globalThis);
defer brace_str.deref();
Expand Down Expand Up @@ -337,7 +337,7 @@ pub fn braces(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS
if (tokenize) {
const str = std.json.stringifyAlloc(globalThis.bunVM().allocator, lexer_output.tokens.items[0..], .{}) catch {
globalThis.throwOutOfMemory();
return JSValue.undefined;
return .zero;
};
defer globalThis.bunVM().allocator.free(str);
var bun_str = bun.String.fromBytes(str);
Expand All @@ -350,7 +350,7 @@ pub fn braces(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS
};
const str = std.json.stringifyAlloc(globalThis.bunVM().allocator, ast_node, .{}) catch {
globalThis.throwOutOfMemory();
return JSValue.undefined;
return .zero;
};
defer globalThis.bunVM().allocator.free(str);
var bun_str = bun.String.fromBytes(str);
Expand All @@ -363,7 +363,7 @@ pub fn braces(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS

var expanded_strings = arena.allocator().alloc(std.ArrayList(u8), expansion_count) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};

for (0..expansion_count) |i| {
Expand All @@ -377,12 +377,12 @@ pub fn braces(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JS
lexer_output.contains_nested,
) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};

var out_strings = arena.allocator().alloc(bun.String, expansion_count) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};
for (0..expansion_count) |i| {
out_strings[i] = bun.String.fromBytes(expanded_strings[i].items[0..]);
Expand All @@ -398,7 +398,7 @@ pub fn which(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSE
defer arguments.deinit();
const path_arg = arguments.nextEat() orelse {
globalThis.throw("which: expected 1 argument, got 0", .{});
return .undefined;
return .zero;
};

var path_str: ZigString.Slice = ZigString.Slice.empty;
Expand All @@ -421,7 +421,7 @@ pub fn which(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) bun.JSE

if (bin_str.len >= bun.MAX_PATH_BYTES) {
globalThis.throw("bin path is too long", .{});
return .undefined;
return .zero;
}

if (bin_str.len == 0) {
Expand Down Expand Up @@ -611,7 +611,7 @@ pub fn registerMacro(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFram
if (!arguments[1].isCell() or !arguments[1].isCallable(globalObject.vm())) {
// TODO: add "toTypeOf" helper
globalObject.throw("Macro must be a function", .{});
return .undefined;
return .zero;
}

const get_or_put_result = VirtualMachine.get().macros.getOrPut(id) catch unreachable;
Expand Down Expand Up @@ -755,7 +755,7 @@ pub fn openInEditor(globalThis: js.JSContextRef, callframe: *JSC.CallFrame) bun.
if (editor_choice == null) {
edit.* = prev;
globalThis.throw("Could not find editor \"{s}\"", .{sliced.slice()});
return .undefined;
return .zero;
} else if (edit.name.ptr == edit.path.ptr) {
edit.name = arguments.arena.allocator().dupe(u8, edit.path) catch unreachable;
edit.path = edit.path;
Expand Down Expand Up @@ -858,7 +858,7 @@ pub fn sleepSync(globalObject: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) b
// The argument must be a number
if (!arg.isNumber()) {
globalObject.throwInvalidArgumentType("sleepSync", "milliseconds", "number");
return .undefined;
return .zero;
}

//NOTE: if argument is > max(i32) then it will be truncated
Expand Down Expand Up @@ -2078,7 +2078,7 @@ pub const Crypto = struct {
.err => {
const error_instance = value.toErrorInstance(globalObject);
globalObject.throwValue(error_instance);
return JSC.JSValue.undefined;
return .zero;
},
.pass => |pass| {
return JSC.JSValue.jsBoolean(pass);
Expand Down Expand Up @@ -2316,7 +2316,7 @@ pub const Crypto = struct {
if (arguments.len > 2 and !arguments[2].isEmptyOrUndefinedOrNull()) {
if (!arguments[2].isString()) {
globalObject.throwInvalidArgumentType("verify", "algorithm", "string");
return JSC.JSValue.undefined;
return .zero;
}

const algorithm_string = arguments[2].getZigString(globalObject);
Expand All @@ -2325,23 +2325,23 @@ pub const Crypto = struct {
if (!globalObject.hasException()) {
globalObject.throwInvalidArgumentType("verify", "algorithm", unknown_password_algorithm_message);
}
return JSC.JSValue.undefined;
return .zero;
};
}

var password = JSC.Node.StringOrBuffer.fromJS(globalObject, bun.default_allocator, arguments[0]) orelse {
if (!globalObject.hasException()) {
globalObject.throwInvalidArgumentType("verify", "password", "string or TypedArray");
}
return JSC.JSValue.undefined;
return .zero;
};

var hash_ = JSC.Node.StringOrBuffer.fromJS(globalObject, bun.default_allocator, arguments[1]) orelse {
password.deinit();
if (!globalObject.hasException()) {
globalObject.throwInvalidArgumentType("verify", "hash", "string or TypedArray");
}
return JSC.JSValue.undefined;
return .zero;
};

defer password.deinit();
Expand Down Expand Up @@ -3225,7 +3225,7 @@ pub export fn Bun__escapeHTML16(globalObject: *JSC.JSGlobalObject, input_value:
const input_slice = ptr[0..len];
const escaped = strings.escapeHTMLForUTF16Input(globalObject.bunVM().allocator, input_slice) catch {
globalObject.vm().throwError(globalObject, bun.String.static("Out of memory").toJS(globalObject));
return .undefined;
return .zero;
};

switch (escaped) {
Expand All @@ -3248,7 +3248,7 @@ pub export fn Bun__escapeHTML8(globalObject: *JSC.JSGlobalObject, input_value: J

const escaped = strings.escapeHTMLForLatin1Input(allocator, input_slice) catch {
globalObject.vm().throwError(globalObject, bun.String.static("Out of memory").toJS(globalObject));
return .undefined;
return .zero;
};

switch (escaped) {
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/api/JSBundler.zig
Original file line number Diff line number Diff line change
Expand Up @@ -858,7 +858,7 @@ pub const JSBundler = struct {
) JSValue {
if (this.called_defer) {
globalObject.throw("can't call .defer() more than once within an onLoad plugin", .{});
return .undefined;
return .zero;
}
this.called_defer = true;

Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/api/bun/h2_frame_parser.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3254,7 +3254,7 @@ pub const H2FrameParser = struct {
const args_list = callframe.arguments_old(1);
if (args_list.len < 1) {
globalObject.throw("Expected error argument", .{});
return .undefined;
return .zero;
}

var it = StreamResumableIterator.init(this);
Expand Down
2 changes: 2 additions & 0 deletions src/bun.js/api/bun/socket.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3465,11 +3465,13 @@ fn NewSocket(comptime ssl: bool) type {
// If BoringSSL gave us an error code, let's use it.
if (err != 0 and !globalObject.hasException()) {
globalObject.throwValue(BoringSSL.ERR_toJS(globalObject, err));
return .zero;
}

// If BoringSSL did not give us an error code, let's throw a generic error.
if (!globalObject.hasException()) {
globalObject.throw("Failed to upgrade socket from TCP -> TLS. Is the TLS config correct?", .{});
return .zero;
}

return JSValue.jsUndefined();
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/api/filesystem_router.zig
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ pub const FileSystemRouter = struct {

const url_path = URLPath.parse(path.slice()) catch |err| {
globalThis.throw("{s} parsing path: {s}", .{ @errorName(err), path.slice() });
return JSValue.zero;
return .zero;
};
var params = Router.Param.List{};
defer params.deinit(globalThis.allocator());
Expand Down
12 changes: 6 additions & 6 deletions src/bun.js/api/glob.zig
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ const ScanOpts = struct {
return out;
}
globalThis.throw("{s}: expected first argument to be an object", .{fnName});
return null;
return error.JSError;
}

if (try optsObj.getTruthy(globalThis, "onlyFiles")) |only_files| {
Expand All @@ -135,7 +135,7 @@ const ScanOpts = struct {
if (try optsObj.getTruthy(globalThis, "cwd")) |cwdVal| {
if (!cwdVal.isString()) {
globalThis.throw("{s}: invalid `cwd`, not a string", .{fnName});
return null;
return error.JSError;
}

{
Expand Down Expand Up @@ -428,12 +428,12 @@ pub fn match(this: *Glob, globalThis: *JSGlobalObject, callframe: *JSC.CallFrame
defer arguments.deinit();
const str_arg = arguments.nextEat() orelse {
globalThis.throw("Glob.matchString: expected 1 arguments, got 0", .{});
return .undefined;
return .zero;
};

if (!str_arg.isString()) {
globalThis.throw("Glob.matchString: first argument is not a string", .{});
return .undefined;
return .zero;
}

var str = str_arg.toSlice(globalThis, arena.allocator());
Expand All @@ -446,13 +446,13 @@ pub fn match(this: *Glob, globalThis: *JSGlobalObject, callframe: *JSC.CallFrame

var codepoints = std.ArrayList(u32).initCapacity(alloc, this.pattern.len * 2) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};
errdefer codepoints.deinit();

convertUtf8(&codepoints, this.pattern) catch {
globalThis.throwOutOfMemory();
return .undefined;
return .zero;
};

this.pattern_codepoints = codepoints;
Expand Down
2 changes: 1 addition & 1 deletion src/bun.js/api/server.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5070,7 +5070,7 @@ pub const ServerWebSocket = struct {

if (result.isAnyError()) {
globalThis.throwValue(result);
return JSValue.jsUndefined();
return .zero;
}

return result;
Expand Down
27 changes: 22 additions & 5 deletions src/bun.js/bindings/bindings.zig
Original file line number Diff line number Diff line change
Expand Up @@ -737,7 +737,7 @@ pub const ZigString = extern struct {
if (len > String.max_length()) {
bun.default_allocator.free(ptr[0..len]);
global.ERR_STRING_TOO_LONG("Cannot create a string longer than 2^32-1 characters", .{}).throw();
return JSValue.zero;
return .zero;
}
return shim.cppFn("toExternalU16", .{ ptr, len, global });
}
Expand Down Expand Up @@ -5723,8 +5723,10 @@ pub const JSValue = enum(i64) {
}

/// same as `JSValue.deepEquals`, but with jest asymmetric matchers enabled
pub fn jestDeepEquals(this: JSValue, other: JSValue, global: *JSGlobalObject) bool {
return cppFn("jestDeepEquals", .{ this, other, global });
pub fn jestDeepEquals(this: JSValue, other: JSValue, global: *JSGlobalObject) bun.JSError!bool {
const result = cppFn("jestDeepEquals", .{ this, other, global });
if (global.hasException()) return error.JSError;
return result;
}

pub fn strictDeepEquals(this: JSValue, other: JSValue, global: *JSGlobalObject) bool {
Expand Down Expand Up @@ -6483,7 +6485,7 @@ pub const VM = extern struct {
// TODO: rewrite all `throwError` to use `JSError`
pub fn throwError2(vm: *VM, global_object: *JSGlobalObject, value: JSValue) JSError {
vm.throwError(global_object, value);
return JSError.JSError;
return error.JSError;
}

pub fn releaseWeakRefs(vm: *VM) void {
Expand Down Expand Up @@ -6770,6 +6772,14 @@ pub fn toJSHostFunction(comptime Function: JSHostZigFunction) JSC.JSHostFunction
globalThis: *JSC.JSGlobalObject,
callframe: *JSC.CallFrame,
) callconv(JSC.conv) JSC.JSValue {
if (bun.Environment.allow_assert and bun.Environment.is_canary) {
const value = Function(globalThis, callframe) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
};
bun.assert((value == .zero) == globalThis.hasException());
return value;
}
return @call(.always_inline, Function, .{ globalThis, callframe }) catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
Expand All @@ -6778,8 +6788,15 @@ pub fn toJSHostFunction(comptime Function: JSHostZigFunction) JSC.JSHostFunction
}.function;
}

// XXX: temporary
pub fn toJSHostValue(globalThis: *JSGlobalObject, value: error{ OutOfMemory, JSError }!JSValue) JSValue {
if (bun.Environment.allow_assert and bun.Environment.is_canary) {
const normal = value catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
};
bun.assert((normal == .zero) == globalThis.hasException());
return normal;
}
return value catch |err| switch (err) {
error.JSError => .zero,
error.OutOfMemory => globalThis.throwOutOfMemoryValue(),
Expand Down
Loading

0 comments on commit bb3d570

Please sign in to comment.