diff --git a/src/bun.js/event_loop.zig b/src/bun.js/event_loop.zig index b418729795..83562c98ac 100644 --- a/src/bun.js/event_loop.zig +++ b/src/bun.js/event_loop.zig @@ -233,11 +233,27 @@ pub const AnyTaskWithExtraContext = struct { callback: *const (fn (*anyopaque, *anyopaque) void) = undefined, next: ?*AnyTaskWithExtraContext = null, - pub fn fromCallbackAutoDeinit(of: anytype, comptime callback: anytype) *AnyTaskWithExtraContext { - const TheTask = NewManaged(std.meta.Child(@TypeOf(of)), void, @field(std.meta.Child(@TypeOf(of)), callback)); - const task = bun.default_allocator.create(AnyTaskWithExtraContext) catch bun.outOfMemory(); - task.* = TheTask.init(of); - return task; + pub fn fromCallbackAutoDeinit(ptr: anytype, comptime fieldName: [:0]const u8) *AnyTaskWithExtraContext { + const Ptr = std.meta.Child(@TypeOf(ptr)); + const Wrapper = struct { + any_task: AnyTaskWithExtraContext = undefined, + wrapped: *Ptr, + pub fn function(this: *anyopaque, extra: *anyopaque) void { + const that: *@This() = @ptrCast(@alignCast(this)); + defer bun.default_allocator.destroy(that); + const ctx = that.wrapped; + @field(Ptr, fieldName)(ctx, extra); + } + }; + const task = bun.default_allocator.create(Wrapper) catch bun.outOfMemory(); + task.* = Wrapper{ + .any_task = AnyTaskWithExtraContext{ + .callback = &Wrapper.function, + .ctx = task, + }, + .wrapped = ptr, + }; + return &task.any_task; } pub fn from(this: *@This(), of: anytype, comptime field: []const u8) *@This() { @@ -274,30 +290,6 @@ pub const AnyTaskWithExtraContext = struct { } }; } - - pub fn NewManaged(comptime Type: type, comptime ContextType: type, comptime Callback: anytype) type { - return struct { - pub fn init(ctx: *Type) AnyTaskWithExtraContext { - return AnyTaskWithExtraContext{ - .callback = wrap, - .ctx = ctx, - }; - } - - pub fn wrap(this: ?*anyopaque, extra: ?*anyopaque) void { - @call( - .always_inline, - Callback, - .{ - @as(*Type, @ptrCast(@alignCast(this.?))), - @as(*ContextType, @ptrCast(@alignCast(extra.?))), - }, - ); - const anytask: *AnyTaskWithExtraContext = @fieldParentPtr("ctx", @as(*?*anyopaque, @ptrCast(@alignCast(this.?)))); - bun.default_allocator.destroy(anytask); - } - }; - } }; pub const CppTask = opaque { diff --git a/src/bun.js/node/node_fs.zig b/src/bun.js/node/node_fs.zig index d0e65e7409..4479681a50 100644 --- a/src/bun.js/node/node_fs.zig +++ b/src/bun.js/node/node_fs.zig @@ -697,7 +697,7 @@ pub fn NewAsyncCpTask(comptime is_shell: bool) type { } } - pub fn runFromJSThreadMini(this: *ThisAsyncCpTask, _: *void) void { + pub fn runFromJSThreadMini(this: *ThisAsyncCpTask, _: *anyopaque) void { this.runFromJSThread(); } diff --git a/src/shell/builtin/cp.zig b/src/shell/builtin/cp.zig index 445d5edbba..5cd4cdccb6 100644 --- a/src/shell/builtin/cp.zig +++ b/src/shell/builtin/cp.zig @@ -215,11 +215,9 @@ pub fn onShellCpTaskDone(this: *Cp, task: *ShellCpTask) void { log("task done: 0x{x} {d}", .{ @intFromPtr(task), this.state.exec.tasks_count }); this.state.exec.tasks_count -= 1; - const err_ = task.err; - if (comptime bun.Environment.isWindows) { - if (err_) |err| { - if (err == .sys and + if (task.err) |*err| { + if (err.* == .sys and err.sys.getErrno() == .BUSY and (task.tgt_absolute != null and err.sys.path.eqlUTF8(task.tgt_absolute.?)) or @@ -248,7 +246,6 @@ pub fn printShellCpTask(this: *Cp, task: *ShellCpTask) void { // Deinitialize this task as we are starting a new one defer task.deinit(); - const err_ = task.err; var output = task.takeOutput(); const output_task: *ShellCpOutputTask = bun.new(ShellCpOutputTask, .{ @@ -256,9 +253,9 @@ pub fn printShellCpTask(this: *Cp, task: *ShellCpTask) void { .output = .{ .arrlist = output.moveToUnmanaged() }, .state = .waiting_write_err, }); - if (err_) |err| { + if (bun.take(&task.err)) |err| { this.state.exec.err = err; - const error_string = this.bltn().taskErrorToString(.cp, err); + const error_string = this.bltn().taskErrorToString(.cp, this.state.exec.err.?); output_task.start(error_string); return; } @@ -330,7 +327,7 @@ pub const ShellCpTask = struct { fn deinit(this: *ShellCpTask) void { debug("deinit", .{}); this.verbose_output.deinit(); - if (this.err) |e| { + if (this.err) |*e| { e.deinit(bun.default_allocator); } if (this.src_absolute) |sc| { diff --git a/src/shell/builtin/ls.zig b/src/shell/builtin/ls.zig index 0a93977fff..70a83f1b55 100644 --- a/src/shell/builtin/ls.zig +++ b/src/shell/builtin/ls.zig @@ -112,7 +112,6 @@ pub fn onShellLsTaskDone(this: *Ls, task: *ShellLsTask) void { defer task.deinit(true); this.state.exec.tasks_done += 1; var output = task.takeOutput(); - const err_ = task.err; // TODO: Reuse the *ShellLsTask allocation const output_task: *ShellLsOutputTask = bun.new(ShellLsOutputTask, .{ @@ -121,9 +120,10 @@ pub fn onShellLsTaskDone(this: *Ls, task: *ShellLsTask) void { .state = .waiting_write_err, }); - if (err_) |err| { - this.state.exec.err = err; - const error_string = this.bltn().taskErrorToString(.ls, err); + if (task.err) |*err| { + this.state.exec.err = err.*; + task.err = null; + const error_string = this.bltn().taskErrorToString(.ls, this.state.exec.err.?); output_task.start(error_string); return; } diff --git a/src/shell/builtin/touch.zig b/src/shell/builtin/touch.zig index 5b881d65a7..d8cf4c4c80 100644 --- a/src/shell/builtin/touch.zig +++ b/src/shell/builtin/touch.zig @@ -191,7 +191,7 @@ pub const ShellTouchTask = struct { } pub fn deinit(this: *ShellTouchTask) void { - if (this.err) |e| { + if (this.err) |*e| { e.deref(); } bun.default_allocator.destroy(this); diff --git a/src/shell/interpreter.zig b/src/shell/interpreter.zig index 4a1d089f24..bb151676bc 100644 --- a/src/shell/interpreter.zig +++ b/src/shell/interpreter.zig @@ -4263,7 +4263,9 @@ pub const Interpreter = struct { if (child.ptr.is(Assigns)) { if (exit_code != 0) { const err = this.state.expanding_assigns.state.err; + this.state.expanding_assigns.state.err = .{ .custom = "" }; defer err.deinit(bun.default_allocator); + this.state.expanding_assigns.deinit(); this.writeFailingError("{}\n", .{err}); return; diff --git a/src/shell/shell.zig b/src/shell/shell.zig index bb4728adfd..39c9de5236 100644 --- a/src/shell/shell.zig +++ b/src/shell/shell.zig @@ -79,9 +79,7 @@ pub const ShellErr = union(enum) { return globalThis.throwValue(err); }, .custom => { - var str = JSC.ZigString.init(this.custom); - str.markUTF8(); - const err_value = str.toErrorInstance(globalThis); + const err_value = bun.String.createUTF8(this.custom).toErrorInstance(globalThis); return globalThis.throwValue(err_value); // this.bunVM().allocator.free(JSC.ZigString.untagged(str._unsafe_ptr_do_not_use)[0..str.len]); }, @@ -113,10 +111,10 @@ pub const ShellErr = union(enum) { bun.Global.exit(1); } - pub fn deinit(this: @This(), allocator: Allocator) void { - switch (this) { + pub fn deinit(this: *const @This(), allocator: Allocator) void { + switch (this.*) { .sys => { - // this.sys. + this.sys.deref(); }, .custom => allocator.free(this.custom), .invalid_arguments => {}, diff --git a/test/internal/ban-words.test.ts b/test/internal/ban-words.test.ts index 2acaeeba81..43350d79fd 100644 --- a/test/internal/ban-words.test.ts +++ b/test/internal/ban-words.test.ts @@ -27,7 +27,7 @@ const words: Record "alloc.ptr !=": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, "== alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, "!= alloc.ptr": { reason: "The std.mem.Allocator context pointer can be undefined, which makes this comparison undefined behavior" }, - [String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 244, regex: true }, + [String.raw`: [a-zA-Z0-9_\.\*\?\[\]\(\)]+ = undefined,`]: { reason: "Do not default a struct field to undefined", limit: 245, regex: true }, "usingnamespace": { reason: "Zig deprecates this, and will not support it in incremental compilation.", limit: 492 }, }; const words_keys = [...Object.keys(words)]; diff --git a/test/js/bun/shell/test_builder.ts b/test/js/bun/shell/test_builder.ts index 1efefa45d8..930e762941 100644 --- a/test/js/bun/shell/test_builder.ts +++ b/test/js/bun/shell/test_builder.ts @@ -187,7 +187,7 @@ export function createTestBuilder(path: string) { static tmpdir(): string { const tmp = os.tmpdir(); - return fs.mkdtempSync(join(tmp, "test_builder")); + return fs.realpathSync(fs.mkdtempSync(join(tmp, "test_builder"))); } setTempdir(tempdir: string): this {