diff options
-rw-r--r-- | src/bun.js/bindings/ZigGlobalObject.cpp | 4 | ||||
-rw-r--r-- | src/bun.js/bindings/bindings.cpp | 69 | ||||
-rw-r--r-- | src/bun.js/bindings/exports.zig | 130 | ||||
-rw-r--r-- | src/bun.js/bindings/headers-handwritten.h | 16 | ||||
-rw-r--r-- | src/bun.js/javascript.zig | 72 | ||||
-rw-r--r-- | src/bun.js/test/jest.zig | 18 | ||||
-rw-r--r-- | src/js/out/modules/node/path.js | 2 | ||||
-rw-r--r-- | src/js/out/modules/node/stream.web.js | 2 | ||||
-rw-r--r-- | src/logger.zig | 4 | ||||
-rw-r--r-- | src/string.zig | 24 |
10 files changed, 198 insertions, 143 deletions
diff --git a/src/bun.js/bindings/ZigGlobalObject.cpp b/src/bun.js/bindings/ZigGlobalObject.cpp index 4b4edf097..9ff3ebf93 100644 --- a/src/bun.js/bindings/ZigGlobalObject.cpp +++ b/src/bun.js/bindings/ZigGlobalObject.cpp @@ -390,7 +390,7 @@ static String computeErrorInfoWithoutPrepareStackTrace(JSC::VM& vm, Vector<Stack frame.computeLineAndColumn(thisLine, thisColumn); remappedFrames[i].position.line = thisLine; remappedFrames[i].position.column_start = thisColumn; - remappedFrames[i].source_url = Zig::toZigString(frame.sourceURL(vm)); + remappedFrames[i].source_url = Bun::toString(frame.sourceURL(vm)); // This ensures the lifetime of the sourceURL is accounted for correctly Bun__remapStackFramePositions(globalObject, remappedFrames + i, 1); @@ -2779,7 +2779,7 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncCaptureStackTrace, (JSC::JSGlobalOb size_t framesCount = stackTrace.size(); ZigStackFrame remappedFrames[framesCount]; for (int i = 0; i < framesCount; i++) { - remappedFrames[i].source_url = Zig::toZigString(stackTrace.at(i).sourceURL(), lexicalGlobalObject); + remappedFrames[i].source_url = Bun::toString(lexicalGlobalObject, stackTrace.at(i).sourceURL()); if (JSCStackFrame::SourcePositions* sourcePositions = stackTrace.at(i).getSourcePositions()) { remappedFrames[i].position.line = sourcePositions->line.zeroBasedInt(); remappedFrames[i].position.column_start = sourcePositions->startColumn.zeroBasedInt() + 1; diff --git a/src/bun.js/bindings/bindings.cpp b/src/bun.js/bindings/bindings.cpp index 68aef29dd..141215ebe 100644 --- a/src/bun.js/bindings/bindings.cpp +++ b/src/bun.js/bindings/bindings.cpp @@ -3303,7 +3303,7 @@ bool JSC__JSValue__stringIncludes(JSC__JSValue value, JSC__JSGlobalObject* globa static void populateStackFrameMetadata(JSC::VM& vm, const JSC::StackFrame* stackFrame, ZigStackFrame* frame) { - frame->source_url = Zig::toZigString(stackFrame->sourceURL(vm)); + frame->source_url = Bun::toString(stackFrame->sourceURL(vm)); if (stackFrame->isWasmFrame()) { frame->code_type = ZigStackFrameCodeWasm; @@ -3340,37 +3340,11 @@ static void populateStackFrameMetadata(JSC::VM& vm, const JSC::StackFrame* stack JSC::JSObject* callee = JSC::jsCast<JSC::JSObject*>(calleeCell); - // Does the code block have a user-defined name property? - JSC::JSValue name = callee->getDirect(vm, vm.propertyNames->name); - if (name && name.isString()) { - auto str = name.toWTFString(m_codeBlock->globalObject()); - frame->function_name = Zig::toZigString(str); - return; - } - - /* For functions (either JSFunction or InternalFunction), fallback to their "native" name - * property. Based on JSC::getCalculatedDisplayName, "inlining" the - * JSFunction::calculatedDisplayName\InternalFunction::calculatedDisplayName calls */ - if (JSC::JSFunction* function = JSC::jsDynamicCast<JSC::JSFunction*>(callee)) { - - WTF::String actualName = function->name(vm); - if (!actualName.isEmpty() || function->isHostOrBuiltinFunction()) { - frame->function_name = Zig::toZigString(actualName); - return; - } - - auto inferred_name = function->jsExecutable()->name(); - frame->function_name = Zig::toZigString(inferred_name.string()); - } - - if (JSC::InternalFunction* function = JSC::jsDynamicCast<JSC::InternalFunction*>(callee)) { - // Based on JSC::InternalFunction::calculatedDisplayName, skipping the "displayName" property - frame->function_name = Zig::toZigString(function->name()); - } + frame->function_name = Bun::toString(JSC::getCalculatedDisplayName(vm, callee)); } // Based on // https://github.com/mceSystems/node-jsc/blob/master/deps/jscshim/src/shim/JSCStackTrace.cpp#L298 -static void populateStackFramePosition(const JSC::StackFrame* stackFrame, ZigString* source_lines, +static void populateStackFramePosition(const JSC::StackFrame* stackFrame, BunString* source_lines, int32_t* source_line_numbers, uint8_t source_lines_count, ZigStackFramePosition* position) { @@ -3440,7 +3414,7 @@ static void populateStackFramePosition(const JSC::StackFrame* stackFrame, ZigStr // Most of the time, when you look at a stack trace, you want a couple lines above - source_lines[0] = { &chars[lineStart], lineStop - lineStart }; + source_lines[0] = Bun::toString(sourceString.substring(lineStart, lineStop - lineStart).toStringWithoutCopying()); source_line_numbers[0] = line; if (lineStart > 0) { @@ -3457,8 +3431,7 @@ static void populateStackFramePosition(const JSC::StackFrame* stackFrame, ZigStr } // We are at the beginning of the line - source_lines[source_line_i] = { &chars[byte_offset_in_source_string], - end_of_line_offset - byte_offset_in_source_string + 1 }; + source_lines[source_line_i] = Bun::toString(sourceString.substring(byte_offset_in_source_string, end_of_line_offset - byte_offset_in_source_string + 1).toStringWithoutCopying()); source_line_numbers[source_line_i] = line - source_line_i; source_line_i++; @@ -3546,30 +3519,30 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, except->code = 8; } if (except->code == SYNTAX_ERROR_CODE) { - except->message = Zig::toZigString(err->sanitizedMessageString(global)); + except->message = Bun::toString(err->sanitizedMessageString(global)); } else if (JSC::JSValue message = obj->getIfPropertyExists(global, vm.propertyNames->message)) { - except->message = Zig::toZigString(message, global); + except->message = Bun::toString(global, message); } else { - except->message = Zig::toZigString(err->sanitizedMessageString(global)); + except->message = Bun::toString(err->sanitizedMessageString(global)); } - except->name = Zig::toZigString(err->sanitizedNameString(global)); + except->name = Bun::toString(err->sanitizedNameString(global)); except->runtime_type = err->runtimeTypeForCause(); auto clientData = WebCore::clientData(vm); if (except->code != SYNTAX_ERROR_CODE) { if (JSC::JSValue syscall = obj->getIfPropertyExists(global, clientData->builtinNames().syscallPublicName())) { - except->syscall = Zig::toZigString(syscall, global); + except->syscall = Bun::toString(global, syscall); } if (JSC::JSValue code = obj->getIfPropertyExists(global, clientData->builtinNames().codePublicName())) { - except->code_ = Zig::toZigString(code, global); + except->code_ = Bun::toString(global, code); } if (JSC::JSValue path = obj->getIfPropertyExists(global, clientData->builtinNames().pathPublicName())) { - except->path = Zig::toZigString(path, global); + except->path = Bun::toString(global, path); } if (JSC::JSValue fd = obj->getIfPropertyExists(global, Identifier::fromString(vm, "fd"_s))) { @@ -3585,7 +3558,7 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, if (getFromSourceURL) { if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, vm.propertyNames->sourceURL)) { - except->stack.frames_ptr[0].source_url = Zig::toZigString(sourceURL, global); + except->stack.frames_ptr[0].source_url = Bun::toString(global, sourceURL); if (JSC::JSValue column = obj->getIfPropertyExists(global, vm.propertyNames->column)) { except->stack.frames_ptr[0].position.column_start = column.toInt32(global); @@ -3597,7 +3570,7 @@ static void fromErrorInstance(ZigException* except, JSC::JSGlobalObject* global, if (JSC::JSValue lineText = obj->getIfPropertyExists(global, JSC::Identifier::fromString(vm, "lineText"_s))) { if (JSC::JSString* jsStr = lineText.toStringOrNull(global)) { auto str = jsStr->value(global); - except->stack.source_lines_ptr[0] = Zig::toZigString(str); + except->stack.source_lines_ptr[0] = Bun::toString(str); except->stack.source_lines_numbers[0] = except->stack.frames_ptr[0].position.line; except->stack.source_lines_len = 1; except->remapped = true; @@ -3620,7 +3593,7 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal if (JSC::JSObject* obj = JSC::jsDynamicCast<JSC::JSObject*>(value)) { if (obj->hasProperty(global, global->vm().propertyNames->name)) { auto name_str = obj->getIfPropertyExists(global, global->vm().propertyNames->name).toWTFString(global); - except->name = Zig::toZigString(name_str); + except->name = Bun::toString(name_str); if (name_str == "Error"_s) { except->code = JSErrorCodeError; } else if (name_str == "EvalError"_s) { @@ -3642,14 +3615,14 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal if (JSC::JSValue message = obj->getIfPropertyExists(global, global->vm().propertyNames->message)) { if (message) { - except->message = Zig::toZigString( + except->message = Bun::toString( message.toWTFString(global)); } } if (JSC::JSValue sourceURL = obj->getIfPropertyExists(global, global->vm().propertyNames->sourceURL)) { if (sourceURL) { - except->stack.frames_ptr[0].source_url = Zig::toZigString( + except->stack.frames_ptr[0].source_url = Bun::toString( sourceURL.toWTFString(global)); except->stack.frames_len = 1; } @@ -3678,9 +3651,7 @@ void exceptionFromString(ZigException* except, JSC::JSValue value, JSC::JSGlobal } scope.release(); - auto ref = OpaqueJSString::tryCreate(str); - except->message = ZigString { ref->characters8(), ref->length() }; - ref->ref(); + except->message = Bun::toString(str); } void JSC__VM__releaseWeakRefs(JSC__VM* arg0) @@ -3790,8 +3761,8 @@ void JSC__JSValue__toZigException(JSC__JSValue JSValue0, JSC__JSGlobalObject* ar JSC::JSValue value = JSC::JSValue::decode(JSValue0); if (value == JSC::JSValue {}) { exception->code = JSErrorCodeError; - exception->name = Zig::toZigString("Error"_s); - exception->message = Zig::toZigString("Unknown error"_s); + exception->name = Bun::toString("Error"_s); + exception->message = Bun::toString("Unknown error"_s); return; } diff --git a/src/bun.js/bindings/exports.zig b/src/bun.js/bindings/exports.zig index 213291e7b..73a26e4be 100644 --- a/src/bun.js/bindings/exports.zig +++ b/src/bun.js/bindings/exports.zig @@ -29,6 +29,7 @@ const Backtrace = @import("../../crash_reporter.zig"); const JSPrinter = bun.js_printer; const JSLexer = bun.js_lexer; const typeBaseName = @import("../../meta.zig").typeBaseName; +const String = bun.String; pub const ZigGlobalObject = extern struct { pub const shim = Shimmer("Zig", "GlobalObject", @This()); @@ -438,7 +439,7 @@ pub const Process = extern struct { }; pub const ZigStackTrace = extern struct { - source_lines_ptr: [*c]ZigString, + source_lines_ptr: [*c]bun.String, source_lines_numbers: [*c]i32, source_lines_len: u8, source_lines_to_collect: u8, @@ -456,23 +457,24 @@ pub const ZigStackTrace = extern struct { { var source_lines_iter = this.sourceLineIterator(); - var source_line_len: usize = 0; - var count: usize = 0; - while (source_lines_iter.next()) |source| { - count += 1; - source_line_len += source.text.len; - } + var source_line_len = source_lines_iter.getLength(); - if (count > 0 and source_line_len > 0) { - var source_lines = try allocator.alloc(Api.SourceLine, count); + if (source_line_len > 0) { + var source_lines = try allocator.alloc(Api.SourceLine, @intCast(usize, @max(source_lines_iter.i, 0))); var source_line_buf = try allocator.alloc(u8, source_line_len); source_lines_iter = this.sourceLineIterator(); var remain_buf = source_line_buf[0..]; var i: usize = 0; while (source_lines_iter.next()) |source| { - bun.copy(u8, remain_buf, source.text); - const copied_line = remain_buf[0..source.text.len]; - remain_buf = remain_buf[source.text.len..]; + const text = source.text.slice(); + defer source.text.deinit(); + defer bun.copy( + u8, + remain_buf, + text, + ); + const copied_line = remain_buf[0..text.len]; + remain_buf = remain_buf[text.len..]; source_lines[i] = .{ .text = copied_line, .line = source.line }; i += 1; } @@ -508,9 +510,18 @@ pub const ZigStackTrace = extern struct { pub const SourceLine = struct { line: i32, - text: string, + text: ZigString.Slice, }; + pub fn getLength(this: *SourceLineIterator) usize { + var count: usize = 0; + for (this.trace.source_lines_ptr[0..@intCast(usize, this.i)]) |*line| { + count += line.length(); + } + + return count; + } + pub fn untilLast(this: *SourceLineIterator) ?SourceLine { if (this.i < 1) return null; return this.next(); @@ -522,7 +533,7 @@ pub const ZigStackTrace = extern struct { const source_line = this.trace.source_lines_ptr[@intCast(usize, this.i)]; const result = SourceLine{ .line = this.trace.source_lines_numbers[@intCast(usize, this.i)], - .text = source_line.slice(), + .text = source_line.toUTF8(bun.default_allocator), }; this.i -= 1; return result; @@ -541,21 +552,28 @@ pub const ZigStackTrace = extern struct { }; pub const ZigStackFrame = extern struct { - function_name: ZigString, - source_url: ZigString, + function_name: String, + source_url: String, position: ZigStackFramePosition, code_type: ZigStackFrameCode, /// This informs formatters whether to display as a blob URL or not remapped: bool = false, + pub fn deinit(this: *ZigStackFrame) void { + this.function_name.deref(); + this.source_url.deref(); + } + pub fn toAPI(this: *const ZigStackFrame, root_path: string, origin: ?*const ZigURL, allocator: std.mem.Allocator) !Api.StackFrame { var frame: Api.StackFrame = comptime std.mem.zeroes(Api.StackFrame); - if (this.function_name.len > 0) { - frame.function_name = try allocator.dupe(u8, this.function_name.slice()); + if (!this.function_name.isEmpty()) { + var slicer = this.function_name.toUTF8(allocator); + defer slicer.deinit(); + frame.function_name = (try slicer.clone(allocator)).slice(); } - if (this.source_url.len > 0) { + if (!this.source_url.isEmpty()) { frame.file = try std.fmt.allocPrint(allocator, "{any}", .{this.sourceURLFormatter(root_path, origin, true, false)}); } @@ -576,7 +594,7 @@ pub const ZigStackFrame = extern struct { } pub const SourceURLFormatter = struct { - source_url: ZigString, + source_url: bun.String, position: ZigStackFramePosition, enable_color: bool, origin: ?*const ZigURL, @@ -588,7 +606,9 @@ pub const ZigStackFrame = extern struct { try writer.writeAll(Output.prettyFmt("<r><cyan>", true)); } - var source_slice = this.source_url.slice(); + var source_slice_ = this.source_url.toUTF8(bun.default_allocator); + var source_slice = source_slice_.slice(); + defer source_slice_.deinit(); if (!this.remapped) { if (this.origin) |origin| { @@ -647,12 +667,12 @@ pub const ZigStackFrame = extern struct { }; pub const NameFormatter = struct { - function_name: ZigString, + function_name: String, code_type: ZigStackFrameCode, enable_color: bool, pub fn format(this: NameFormatter, comptime _: []const u8, _: std.fmt.FormatOptions, writer: anytype) !void { - const name = this.function_name.slice(); + const name = this.function_name; switch (this.code_type) { .Eval => { @@ -662,26 +682,26 @@ pub const ZigStackFrame = extern struct { // try writer.writeAll("(esm)"); }, .Function => { - if (name.len > 0) { + if (!name.isEmpty()) { if (this.enable_color) { - try std.fmt.format(writer, comptime Output.prettyFmt("<r><b><i>{s}<r>", true), .{name}); + try std.fmt.format(writer, comptime Output.prettyFmt("<r><b><i>{}<r>", true), .{name}); } else { - try std.fmt.format(writer, "{s}", .{name}); + try std.fmt.format(writer, "{}", .{name}); } } }, .Global => { - if (name.len > 0) { - try std.fmt.format(writer, "globalThis {s}", .{name}); + if (!name.isEmpty()) { + try std.fmt.format(writer, "globalThis {}", .{name}); } else { try writer.writeAll("globalThis"); } }, .Wasm => { - try std.fmt.format(writer, "WASM {s}", .{name}); + try std.fmt.format(writer, "WASM {}", .{name}); }, .Constructor => { - try std.fmt.format(writer, "new {s}", .{name}); + try std.fmt.format(writer, "new {}", .{name}); }, else => {}, } @@ -689,9 +709,9 @@ pub const ZigStackFrame = extern struct { }; pub const Zero: ZigStackFrame = ZigStackFrame{ - .function_name = ZigString{ ._unsafe_ptr_do_not_use = "", .len = 0 }, + .function_name = String.empty, .code_type = ZigStackFrameCode.None, - .source_url = ZigString{ ._unsafe_ptr_do_not_use = "", .len = 0 }, + .source_url = String.empty, .position = ZigStackFramePosition.Invalid, }; @@ -744,14 +764,14 @@ pub const ZigException = extern struct { /// SystemError only errno: c_int = 0, /// SystemError only - syscall: ZigString = ZigString.Empty, + syscall: String = String.empty, /// SystemError only - system_code: ZigString = ZigString.Empty, + system_code: String = String.empty, /// SystemError only - path: ZigString = ZigString.Empty, + path: String = String.empty, - name: ZigString, - message: ZigString, + name: String, + message: String, stack: ZigStackTrace, exception: ?*anyopaque, @@ -760,6 +780,19 @@ pub const ZigException = extern struct { fd: i32 = -1, + pub fn deinit(this: *ZigException) void { + this.syscall.deref(); + this.system_code.deref(); + this.path.deref(); + + this.name.deref(); + this.message.deref(); + + for (this.stack.frames_ptr[0..this.stack.frames_len]) |*frame| { + frame.deinit(); + } + } + pub const shim = Shimmer("Zig", "Exception", @This()); pub const name = "ZigException"; pub const namespace = shim.namespace; @@ -768,7 +801,7 @@ pub const ZigException = extern struct { const frame_count = 32; pub const source_lines_count = 6; source_line_numbers: [source_lines_count]i32, - source_lines: [source_lines_count]ZigString, + source_lines: [source_lines_count]String, frames: [frame_count]ZigStackFrame, loaded: bool, zig_exception: ZigException, @@ -786,8 +819,8 @@ pub const ZigException = extern struct { }, .source_lines = brk: { - var lines: [source_lines_count]ZigString = undefined; - @memset(&lines, ZigString.Empty); + var lines: [source_lines_count]String = undefined; + @memset(&lines, String.empty); break :brk lines; }, .zig_exception = undefined, @@ -798,13 +831,17 @@ pub const ZigException = extern struct { return Holder.Zero; } + pub fn deinit(this: *Holder) void { + this.zigException().deinit(); + } + pub fn zigException(this: *Holder) *ZigException { if (!this.loaded) { this.zig_exception = ZigException{ .code = @enumFromInt(JSErrorCode, 255), .runtime_type = JSRuntimeType.Nothing, - .name = ZigString.Empty, - .message = ZigString.Empty, + .name = String.empty, + .message = String.empty, .exception = null, .stack = ZigStackTrace{ .source_lines_ptr = &this.source_lines, @@ -832,8 +869,13 @@ pub const ZigException = extern struct { root_path: string, origin: ?*const ZigURL, ) !void { - const _name: string = @field(this, "name").slice(); - const message: string = @field(this, "message").slice(); + const name_slice = @field(this, "name").toUTF8(bun.default_allocator); + const message_slice = @field(this, "message").toUTF8(bun.default_allocator); + + const _name = name_slice.slice(); + defer name_slice.deinit(); + const message = message_slice.slice(); + defer message_slice.deinit(); var is_empty = true; var api_exception = Api.JsException{ diff --git a/src/bun.js/bindings/headers-handwritten.h b/src/bun.js/bindings/headers-handwritten.h index db1e38d3e..c7429b633 100644 --- a/src/bun.js/bindings/headers-handwritten.h +++ b/src/bun.js/bindings/headers-handwritten.h @@ -120,15 +120,15 @@ typedef struct ZigStackFramePosition { } ZigStackFramePosition; typedef struct ZigStackFrame { - ZigString function_name; - ZigString source_url; + BunString function_name; + BunString source_url; ZigStackFramePosition position; ZigStackFrameCode code_type; bool remapped; } ZigStackFrame; typedef struct ZigStackTrace { - ZigString* source_lines_ptr; + BunString* source_lines_ptr; int32_t* source_lines_numbers; uint8_t source_lines_len; uint8_t source_lines_to_collect; @@ -140,11 +140,11 @@ typedef struct ZigException { unsigned char code; uint16_t runtime_type; int errno_; - ZigString syscall; - ZigString code_; - ZigString path; - ZigString name; - ZigString message; + BunString syscall; + BunString code_; + BunString path; + BunString name; + BunString message; ZigStackTrace stack; void* exception; bool remapped; diff --git a/src/bun.js/javascript.zig b/src/bun.js/javascript.zig index cf6a65841..605cc0c25 100644 --- a/src/bun.js/javascript.zig +++ b/src/bun.js/javascript.zig @@ -1805,6 +1805,7 @@ pub const VirtualMachine = struct { if (exception) |exception_| { var holder = ZigException.Holder.init(); var zig_exception: *ZigException = holder.zigException(); + defer zig_exception.deinit(); exception_.getStackTrace(&zig_exception.stack); if (zig_exception.stack.frames_len > 0) { if (allow_ansi_color) { @@ -1932,8 +1933,14 @@ pub const VirtualMachine = struct { while (i < stack.len) : (i += 1) { const frame = stack[@intCast(usize, i)]; - const file = frame.source_url.slice(); - const func = frame.function_name.slice(); + const file_slice = frame.source_url.toSlice(bun.default_allocator); + defer file_slice.deinit(); + const func_slice = frame.function_name.toSlice(bun.default_allocator); + defer func_slice.deinit(); + + const file = file_slice.slice(); + const func = func_slice.slice(); + if (file.len == 0 and func.len == 0) continue; const has_name = std.fmt.count("{any}", .{frame.nameFormatter( @@ -1985,7 +1992,7 @@ pub const VirtualMachine = struct { pub fn remapStackFramePositions(this: *VirtualMachine, frames: [*]JSC.ZigStackFrame, frames_count: usize) void { for (frames[0..frames_count]) |*frame| { if (frame.position.isInvalid() or frame.remapped) continue; - var sourceURL = frame.source_url.toSlice(bun.default_allocator); + var sourceURL = frame.source_url.toUTF8(bun.default_allocator); defer sourceURL.deinit(); if (this.source_mappings.resolveMapping( @@ -2049,8 +2056,10 @@ pub const VirtualMachine = struct { if (frames.len == 0) return; var top = &frames[0]; + var top_source_url = top.source_url.toUTF8(bun.default_allocator); + defer top_source_url.deinit(); if (this.source_mappings.resolveMapping( - top.source_url.slice(), + top_source_url.slice(), @max(top.position.line, 0), @max(top.position.column_start, 0), )) |mapping| { @@ -2078,18 +2087,18 @@ pub const VirtualMachine = struct { )) |lines| { var source_lines = exception.stack.source_lines_ptr[0..JSC.ZigException.Holder.source_lines_count]; var source_line_numbers = exception.stack.source_lines_numbers[0..JSC.ZigException.Holder.source_lines_count]; - @memset(source_lines, ZigString.Empty); + @memset(source_lines, String.empty); @memset(source_line_numbers, 0); var lines_ = lines[0..@min(lines.len, source_lines.len)]; for (lines_, 0..) |line, j| { - source_lines[(lines_.len - 1) - j] = ZigString.init(line); + source_lines[(lines_.len - 1) - j] = String.init(line); source_line_numbers[j] = top.position.line - @intCast(i32, j) + 1; } exception.stack.source_lines_len = @intCast(u8, lines_.len); - top.position.column_stop = @intCast(i32, source_lines[lines_.len - 1].len); + top.position.column_stop = @intCast(i32, source_lines[lines_.len - 1].length()); top.position.line_stop = top.position.column_stop; // This expression range is no longer accurate @@ -2101,8 +2110,10 @@ pub const VirtualMachine = struct { if (frames.len > 1) { for (frames[1..]) |*frame| { if (frame.position.isInvalid()) continue; + const source_url = frame.source_url.toUTF8(bun.default_allocator); + defer source_url.deinit(); if (this.source_mappings.resolveMapping( - frame.source_url.slice(), + source_url.slice(), @max(frame.position.line, 0), @max(frame.position.column_start, 0), )) |mapping| { @@ -2117,6 +2128,7 @@ pub const VirtualMachine = struct { pub fn printErrorInstance(this: *VirtualMachine, error_instance: JSValue, exception_list: ?*ExceptionList, comptime Writer: type, writer: Writer, comptime allow_ansi_color: bool, comptime allow_side_effects: bool) !void { var exception_holder = ZigException.Holder.init(); var exception = exception_holder.zigException(); + defer exception_holder.deinit(); this.remapZigException(exception, error_instance, exception_list); this.had_errors = true; @@ -2134,15 +2146,18 @@ pub const VirtualMachine = struct { var source_lines = exception.stack.sourceLineIterator(); var last_pad: u64 = 0; while (source_lines.untilLast()) |source| { + defer source.text.deinit(); + const int_size = std.fmt.count("{d}", .{source.line}); const pad = max_line_number_pad - int_size; last_pad = pad; try writer.writeByteNTimes(' ', pad); + try writer.print( comptime Output.prettyFmt("<r><d>{d} | <r>{s}\n", allow_ansi_color), .{ source.line, - std.mem.trim(u8, source.text, "\n"), + std.mem.trim(u8, source.text.slice(), "\n"), }, ); } @@ -2158,7 +2173,8 @@ pub const VirtualMachine = struct { const top_frame = if (exception.stack.frames_len > 0) exception.stack.frames()[0] else null; if (top_frame == null or top_frame.?.position.isInvalid()) { defer did_print_name = true; - var text = std.mem.trim(u8, source.text, "\n"); + defer source.text.deinit(); + var text = std.mem.trim(u8, source.text.slice(), "\n"); try writer.print( comptime Output.prettyFmt( @@ -2176,7 +2192,9 @@ pub const VirtualMachine = struct { const int_size = std.fmt.count("{d}", .{source.line}); const pad = max_line_number_pad - int_size; try writer.writeByteNTimes(' ', pad); - var remainder = std.mem.trim(u8, source.text, "\n"); + defer source.text.deinit(); + const text = source.text.slice(); + var remainder = std.mem.trim(u8, text, "\n"); try writer.print( comptime Output.prettyFmt( @@ -2188,7 +2206,7 @@ pub const VirtualMachine = struct { if (!top.position.isInvalid()) { var first_non_whitespace = @intCast(u32, top.position.column_start); - while (first_non_whitespace < source.text.len and source.text[first_non_whitespace] == ' ') { + while (first_non_whitespace < text.len and text[first_non_whitespace] == ' ') { first_non_whitespace += 1; } const indent = @intCast(usize, pad) + " | ".len + first_non_whitespace; @@ -2219,10 +2237,10 @@ pub const VirtualMachine = struct { }; var show = Show{ - .system_code = exception.system_code.len > 0 and !strings.eql(exception.system_code.slice(), name.slice()), - .syscall = exception.syscall.len > 0, + .system_code = !exception.system_code.eql(name) and !exception.system_code.isEmpty(), + .syscall = !exception.syscall.isEmpty(), .errno = exception.errno < 0, - .path = exception.path.len > 0, + .path = !exception.path.isEmpty(), .fd = exception.fd != -1, }; @@ -2262,7 +2280,7 @@ pub const VirtualMachine = struct { } else if (show.errno) { try writer.writeAll(" "); } - try writer.print(comptime Output.prettyFmt(" path<d>: <r><cyan>\"{s}\"<r>\n", allow_ansi_color), .{exception.path}); + try writer.print(comptime Output.prettyFmt(" path<d>: <r><cyan>\"{}\"<r>\n", allow_ansi_color), .{exception.path}); } if (show.fd) { @@ -2281,12 +2299,12 @@ pub const VirtualMachine = struct { } else if (show.errno) { try writer.writeAll(" "); } - try writer.print(comptime Output.prettyFmt(" code<d>: <r><cyan>\"{s}\"<r>\n", allow_ansi_color), .{exception.system_code}); + try writer.print(comptime Output.prettyFmt(" code<d>: <r><cyan>\"{}\"<r>\n", allow_ansi_color), .{exception.system_code}); add_extra_line = true; } if (show.syscall) { - try writer.print(comptime Output.prettyFmt(" syscall<d>: <r><cyan>\"{s}\"<r>\n", allow_ansi_color), .{exception.syscall}); + try writer.print(comptime Output.prettyFmt(" syscall<d>: <r><cyan>\"{}\"<r>\n", allow_ansi_color), .{exception.syscall}); add_extra_line = true; } @@ -2303,22 +2321,22 @@ pub const VirtualMachine = struct { try printStackTrace(@TypeOf(writer), writer, exception.stack, allow_ansi_color); } - fn printErrorNameAndMessage(_: *VirtualMachine, name: ZigString, message: ZigString, comptime Writer: type, writer: Writer, comptime allow_ansi_color: bool) !void { - if (name.len > 0 and message.len > 0) { - const display_name: ZigString = if (!name.is16Bit() and strings.eqlComptime(name.slice(), "Error")) ZigString.init("error") else name; + fn printErrorNameAndMessage(_: *VirtualMachine, name: String, message: String, comptime Writer: type, writer: Writer, comptime allow_ansi_color: bool) !void { + if (!name.isEmpty() and !message.isEmpty()) { + const display_name: String = if (name.eqlComptime("Error")) String.init("error") else name; try writer.print(comptime Output.prettyFmt("<r><red>{any}<r><d>:<r> <b>{s}<r>\n", allow_ansi_color), .{ display_name, message, }); - } else if (name.len > 0) { - if (name.is16Bit() or !strings.hasPrefixComptime(name.slice(), "error")) { - try writer.print(comptime Output.prettyFmt("<r><red>error<r><d>:<r> <b>{s}<r>\n", allow_ansi_color), .{name}); + } else if (!name.isEmpty()) { + if (!name.hasPrefixComptime("error")) { + try writer.print(comptime Output.prettyFmt("<r><red>error<r><d>:<r> <b>{}<r>\n", allow_ansi_color), .{name}); } else { - try writer.print(comptime Output.prettyFmt("<r><red>{s}<r>\n", allow_ansi_color), .{name}); + try writer.print(comptime Output.prettyFmt("<r><red>{}<r>\n", allow_ansi_color), .{name}); } - } else if (message.len > 0) { - try writer.print(comptime Output.prettyFmt("<r><red>error<r><d>:<r> <b>{s}<r>\n", allow_ansi_color), .{message}); + } else if (!message.isEmpty()) { + try writer.print(comptime Output.prettyFmt("<r><red>error<r><d>:<r> <b>{}<r>\n", allow_ansi_color), .{message}); } else { try writer.print(comptime Output.prettyFmt("<r><red>error<r>\n", allow_ansi_color), .{}); } diff --git a/src/bun.js/test/jest.zig b/src/bun.js/test/jest.zig index d3bb90747..5ae2337f9 100644 --- a/src/bun.js/test/jest.zig +++ b/src/bun.js/test/jest.zig @@ -1532,8 +1532,8 @@ inline fn createIfScope( // In Github Actions, emit an annotation that renders the error and location. // https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#setting-an-error-message pub fn printGithubAnnotation(exception: *JSC.ZigException) void { - const name = exception.name; - const message = exception.message; + const name = @field(exception, "name"); + const message = @field(exception, "message"); const frames = exception.stack.frames(); const top_frame = if (frames.len > 0) frames[0] else null; const dir = bun.getenvZ("GITHUB_WORKSPACE") orelse bun.fs.FileSystem.instance.top_level_dir; @@ -1543,7 +1543,7 @@ pub fn printGithubAnnotation(exception: *JSC.ZigException) void { if (top_frame) |frame| { if (!frame.position.isInvalid()) { - const source_url = frame.source_url.toSlice(allocator); + const source_url = frame.source_url.toUTF8(allocator); defer source_url.deinit(); const file = bun.path.relative(dir, source_url.slice()); Output.printError("\n::error file={s},line={d},col={d},title=", .{ @@ -1559,14 +1559,14 @@ pub fn printGithubAnnotation(exception: *JSC.ZigException) void { Output.printError("\n::error title=", .{}); } - if (name.len == 0 or name.eqlComptime("Error")) { + if (name.isEmpty() or name.eqlComptime("Error")) { Output.printError("error", .{}); } else { Output.printError("{s}", .{name.githubAction()}); } - if (message.len > 0) { - const message_slice = message.toSlice(allocator); + if (!message.isEmpty()) { + const message_slice = message.toUTF8(allocator); defer message_slice.deinit(); const msg = message_slice.slice(); @@ -1574,7 +1574,7 @@ pub fn printGithubAnnotation(exception: *JSC.ZigException) void { while (strings.indexOfNewlineOrNonASCIIOrANSI(msg, cursor)) |i| { cursor = i + 1; if (msg[i] == '\n') { - const first_line = ZigString.init(msg[0..i]); + const first_line = bun.String.fromUTF8(msg[0..i]); Output.printError(": {s}::", .{first_line.githubAction()}); break; } @@ -1605,10 +1605,10 @@ pub fn printGithubAnnotation(exception: *JSC.ZigException) void { var i: i16 = 0; while (i < frames.len) : (i += 1) { const frame = frames[@intCast(usize, i)]; - const source_url = frame.source_url.toSlice(allocator); + const source_url = frame.source_url.toUTF8(allocator); defer source_url.deinit(); const file = bun.path.relative(dir, source_url.slice()); - const func = frame.function_name.toSlice(allocator); + const func = frame.function_name.toUTF8(allocator); if (file.len == 0 and func.len == 0) continue; diff --git a/src/js/out/modules/node/path.js b/src/js/out/modules/node/path.js index f8cc1ec08..3a3a75207 100644 --- a/src/js/out/modules/node/path.js +++ b/src/js/out/modules/node/path.js @@ -1 +1 @@ -var g=function(i){var f=m({basename:i.basename.bind(i),dirname:i.dirname.bind(i),extname:i.extname.bind(i),format:i.format.bind(i),isAbsolute:i.isAbsolute.bind(i),join:i.join.bind(i),normalize:i.normalize.bind(i),parse:i.parse.bind(i),relative:i.relative.bind(i),resolve:i.resolve.bind(i),toNamespacedPath:i.toNamespacedPath.bind(i),sep:i.sep,delimiter:i.delimiter});return f.default=f,f},m=(i)=>Object.assign(Object.create(null),i),k=g(Bun._Path()),q=g(Bun._Path(!1)),v=g(Bun._Path(!0));k.win32=v;k.posix=q;var{basename:y,dirname:z,extname:A,format:B,isAbsolute:C,join:D,normalize:E,parse:F,relative:G,resolve:H,toNamespacedPath:I,sep:J,delimiter:K,__esModule:L}=k;k[Symbol.for("CommonJS")]=0;k.__esModule=!0;var O=k;export{v as win32,I as toNamespacedPath,J as sep,H as resolve,G as relative,q as posix,F as parse,E as normalize,D as join,C as isAbsolute,B as format,A as extname,z as dirname,K as delimiter,O as default,m as createModule,y as basename,L as __esModule}; +var i=function(N){var m=g({basename:N.basename.bind(N),dirname:N.dirname.bind(N),extname:N.extname.bind(N),format:N.format.bind(N),isAbsolute:N.isAbsolute.bind(N),join:N.join.bind(N),normalize:N.normalize.bind(N),parse:N.parse.bind(N),relative:N.relative.bind(N),resolve:N.resolve.bind(N),toNamespacedPath:N.toNamespacedPath.bind(N),sep:N.sep,delimiter:N.delimiter});return m.default=m,m},g=(N)=>Object.assign(Object.create(null),N),f=i(Bun._Path()),J=i(Bun._Path(!1)),k=i(Bun._Path(!0));f.win32=k;f.posix=J;var{basename:q,dirname:v,extname:y,format:z,isAbsolute:A,join:B,normalize:K,parse:C,relative:D,resolve:E,toNamespacedPath:F,sep:G,delimiter:H,__esModule:I}=f;f[Symbol.for("CommonJS")]=0;f.__esModule=!0;var O=f;export{k as win32,F as toNamespacedPath,G as sep,E as resolve,D as relative,J as posix,C as parse,K as normalize,B as join,A as isAbsolute,z as format,y as extname,v as dirname,H as delimiter,O as default,g as createModule,q as basename,I as __esModule}; diff --git a/src/js/out/modules/node/stream.web.js b/src/js/out/modules/node/stream.web.js index bb906418c..f91ee03b4 100644 --- a/src/js/out/modules/node/stream.web.js +++ b/src/js/out/modules/node/stream.web.js @@ -1 +1 @@ -var{ReadableStream:c,ReadableStreamDefaultController:j,WritableStream:k,WritableStreamDefaultController:p,WritableStreamDefaultWriter:v,TransformStream:w,TransformStreamDefaultController:x,ByteLengthQueuingStrategy:z,CountQueuingStrategy:A,ReadableStreamBYOBReader:E,ReadableStreamBYOBRequest:F,ReadableStreamDefaultReader:G}=globalThis,H={ReadableStream:c,ReadableStreamDefaultController:j,WritableStream:k,WritableStreamDefaultController:p,WritableStreamDefaultWriter:v,TransformStream:w,TransformStreamDefaultController:x,ByteLengthQueuingStrategy:z,CountQueuingStrategy:A,ReadableStreamBYOBReader:E,ReadableStreamBYOBRequest:F,ReadableStreamDefaultReader:G,[Symbol.for("CommonJS")]:0};export{H as default,v as WritableStreamDefaultWriter,p as WritableStreamDefaultController,k as WritableStream,x as TransformStreamDefaultController,w as TransformStream,G as ReadableStreamDefaultReader,j as ReadableStreamDefaultController,F as ReadableStreamBYOBRequest,E as ReadableStreamBYOBReader,c as ReadableStream,A as CountQueuingStrategy,z as ByteLengthQueuingStrategy}; +var{ReadableStream:k,ReadableStreamDefaultController:v,WritableStream:w,WritableStreamDefaultController:x,WritableStreamDefaultWriter:z,TransformStream:A,TransformStreamDefaultController:E,ByteLengthQueuingStrategy:F,CountQueuingStrategy:c,ReadableStreamBYOBReader:j,ReadableStreamBYOBRequest:G,ReadableStreamDefaultReader:p}=globalThis,H={ReadableStream:k,ReadableStreamDefaultController:v,WritableStream:w,WritableStreamDefaultController:x,WritableStreamDefaultWriter:z,TransformStream:A,TransformStreamDefaultController:E,ByteLengthQueuingStrategy:F,CountQueuingStrategy:c,ReadableStreamBYOBReader:j,ReadableStreamBYOBRequest:G,ReadableStreamDefaultReader:p,[Symbol.for("CommonJS")]:0};export{H as default,z as WritableStreamDefaultWriter,x as WritableStreamDefaultController,w as WritableStream,E as TransformStreamDefaultController,A as TransformStream,p as ReadableStreamDefaultReader,v as ReadableStreamDefaultController,G as ReadableStreamBYOBRequest,j as ReadableStreamBYOBReader,k as ReadableStream,c as CountQueuingStrategy,F as ByteLengthQueuingStrategy}; diff --git a/src/logger.zig b/src/logger.zig index 3279e9fd5..fc25541de 100644 --- a/src/logger.zig +++ b/src/logger.zig @@ -421,12 +421,12 @@ pub const Msg = struct { if (err.toError()) |value| { value.toZigException(globalObject, zig_exception_holder.zigException()); } else { - zig_exception_holder.zig_exception.message = JSC.ZigString.fromUTF8(err.toSlice(globalObject, allocator).slice()); + zig_exception_holder.zig_exception.message = err.toBunString(globalObject); } return Msg{ .data = .{ - .text = zig_exception_holder.zigException().message.toSliceClone(allocator).slice(), + .text = try zig_exception_holder.zigException().message.toOwnedSlice(allocator), .location = Location{ .file = file, }, diff --git a/src/string.zig b/src/string.zig index 54af2ba68..3c0c99ce5 100644 --- a/src/string.zig +++ b/src/string.zig @@ -247,6 +247,26 @@ pub const String = extern struct { extern fn BunString__fromLatin1(bytes: [*]const u8, len: usize) String; extern fn BunString__fromBytes(bytes: [*]const u8, len: usize) String; + pub fn toOwnedSlice(this: String, allocator: std.mem.Allocator) ![]u8 { + switch (this.tag) { + .ZigString => return try this.value.ZigString.toOwnedSlice(allocator), + .WTFStringImpl => { + var utf8_slice = this.value.WTFStringImpl.toUTF8(allocator); + + if (utf8_slice.allocator.get()) |alloc| { + if (isWTFAllocator(alloc)) { + return @constCast((try utf8_slice.clone(allocator)).slice()); + } + } + + return @constCast(utf8_slice.slice()); + }, + .StaticZigString => return try this.value.StaticZigString.toOwnedSlice(allocator), + .Empty => return &[_]u8{}, + else => unreachable, + } + } + pub fn createLatin1(bytes: []const u8) String { JSC.markBinding(@src()); return BunString__fromLatin1(bytes.ptr, bytes.len); @@ -429,6 +449,10 @@ pub const String = extern struct { return .latin1; } + pub fn githubAction(self: String) ZigString.GithubActionFormatter { + return self.toZigString().githubAction(); + } + pub fn byteSlice(this: String) []const u8 { return switch (this.tag) { .ZigString, .StaticZigString => this.value.ZigString.byteSlice(), |