node tests

This commit is contained in:
Meghan Denny
2025-10-16 22:26:47 -07:00
parent 1ddfe7d83d
commit 831ae976e8
13 changed files with 38 additions and 35 deletions

View File

@@ -37,7 +37,7 @@ export default [
define({
name: "Crypto",
construct: true,
finalize: false,
finalize: true,
proto: {
getRandomValues: {

View File

@@ -207,9 +207,7 @@ pub fn BindgenArray(comptime Child: type) type {
return .fromUnmanaged(.{}, new_unmanaged);
}
defer unmanaged.deinit(
if (bun.use_mimalloc) bun.default_allocator else std.heap.raw_c_allocator,
);
defer if (bun.use_mimalloc) unmanaged.deinit(bun.default_allocator);
var result = bun.handleOom(ZigType.initCapacity(length));
for (unmanaged.items) |*item| {
result.appendAssumeCapacity(Child.convertFromExtern(item.*));

View File

@@ -2,13 +2,13 @@ const JSCScheduler = @This();
pub const JSCDeferredWorkTask = opaque {
extern fn Bun__runDeferredWork(task: *JSCScheduler.JSCDeferredWorkTask) void;
pub fn run(task: *JSCScheduler.JSCDeferredWorkTask) bun.JSTerminated!void {
pub fn run(task: *JSCScheduler.JSCDeferredWorkTask) bun.JSError!void {
const globalThis = bun.jsc.VirtualMachine.get().global;
var scope: bun.jsc.ExceptionValidationScope = undefined;
var scope: bun.jsc.CatchScope = undefined;
scope.init(globalThis, @src());
defer scope.deinit();
Bun__runDeferredWork(task);
try scope.assertNoExceptionExceptTermination();
try scope.returnIfException();
}
};

View File

@@ -237,7 +237,7 @@ pub fn tickQueueWithCount(this: *EventLoop, virtual_machine: *VirtualMachine, co
@field(Task.Tag, @typeName(JSCDeferredWorkTask)) => {
var jsc_task: *JSCDeferredWorkTask = task.get(JSCDeferredWorkTask).?;
jsc.markBinding(@src());
try jsc_task.run();
jsc_task.run() catch |err| try reportErrorOrTerminate(global, err);
},
@field(Task.Tag, @typeName(WriteFileTask)) => {
var transform_task: *WriteFileTask = task.get(WriteFileTask).?;

View File

@@ -746,7 +746,6 @@ pub const PathWatcher = struct {
bun.default_allocator.destroy(this);
return err;
};
this.resolved_path = resolved_path;
this.* = PathWatcher{
.path = path,
.callback = callback,
@@ -766,8 +765,8 @@ pub const PathWatcher = struct {
.file_paths = .{},
.ctx = ctx,
.mutex = .{},
.resolved_path = resolved_path,
};
errdefer this.deinit();
// TODO: unify better FSEvents with PathWatcherManager

View File

@@ -4789,6 +4789,7 @@ export fn Blob__ref(self: *Blob) void {
export fn Blob__deref(self: *Blob) void {
bun.assertf(self.isHeapAllocated(), "cannot deref: this Blob is not heap-allocated", .{});
if (self.#ref_count.decrement() == .should_destroy) {
self.#ref_count.increment(); // deinit has its own isHeapAllocated() guard around bun.destroy(this), so this is needed to ensure that returns true.
self.deinit();
}
}

View File

@@ -277,6 +277,10 @@ pub export fn CryptoObject__create(globalThis: *jsc.JSGlobalObject) jsc.JSValue
return ptr.toJS(globalThis);
}
pub fn finalize(this: *Crypto) void {
bun.default_allocator.destroy(this);
}
const std = @import("std");
const UUID = @import("../uuid.zig");

View File

@@ -556,7 +556,7 @@ pub const Result = union(Tag) {
if (jsc.VirtualMachine.get().isShuttingDown()) {
var that = this.*;
that.deinit();
return .zero;
return .js_undefined;
}
switch (this.*) {

View File

@@ -29,8 +29,8 @@ pub fn default_malloc_usable_size(p: ?*const anyopaque) usize {
};
}
pub const callmod_inline: std.builtin.CallModifier = if (builtin.mode == .Debug) .auto else .always_inline;
pub const callconv_inline: std.builtin.CallingConvention = if (builtin.mode == .Debug) .Unspecified else .Inline;
pub const callmod_inline: std.builtin.CallModifier = if (builtin.mode == .Debug or Environment.enable_asan) .auto else .always_inline;
pub const callconv_inline: std.builtin.CallingConvention = if (builtin.mode == .Debug or Environment.enable_asan) .Unspecified else .Inline;
/// In debug builds, this will catch memory leaks. In release builds, it is mimalloc.
pub const debug_allocator: std.mem.Allocator = if (Environment.isDebug or Environment.enable_asan)
@@ -2691,12 +2691,12 @@ pub const heap_breakdown = @import("./heap_breakdown.zig");
/// - Additional assertions when freeing memory.
///
/// On macOS, you can use `Bun.unsafe.mimallocDump()` to dump the heap.
pub inline fn new(comptime T: type, init: T) *T {
pub fn new(comptime T: type, init: T) *T {
return handleOom(tryNew(T, init));
}
/// Error-returning version of `new`.
pub inline fn tryNew(comptime T: type, init: T) OOM!*T {
pub fn tryNew(comptime T: type, init: T) OOM!*T {
const pointer = if (heap_breakdown.enabled)
try heap_breakdown.getZoneT(T).tryCreate(T, init)
else pointer: {
@@ -2718,7 +2718,7 @@ pub inline fn tryNew(comptime T: type, init: T) OOM!*T {
/// Destruction performs additional safety checks:
/// - Generic assertions can be added to T.assertBeforeDestroy()
/// - Automatic integration with `RefCount`
pub inline fn destroy(pointer: anytype) void {
pub fn destroy(pointer: anytype) void {
const T = std.meta.Child(@TypeOf(pointer));
if (Environment.allow_assert) {
@@ -2740,7 +2740,7 @@ pub inline fn destroy(pointer: anytype) void {
}
}
pub inline fn dupe(comptime T: type, t: *T) *T {
pub fn dupe(comptime T: type, t: *T) *T {
return new(T, t.*);
}

View File

@@ -2170,7 +2170,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${classSymbolName(typeName, "finalize")}(thisValue: *${typeName}) callconv(jsc.conv) void {
if (comptime Environment.enable_logs) log_zig_finalize("${typeName}", thisValue);
@call(.always_inline, ${typeName}.finalize, .{thisValue});
@call(bun.callmod_inline, ${typeName}.finalize, .{thisValue});
}
`;
}
@@ -2213,7 +2213,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${classSymbolName(typeName, "call")}(globalObject: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_call("${typeName}", callFrame);
return @call(.always_inline, jsc.toJSHostFn(${typeName}.call), .{globalObject, callFrame});
return @call(bun.callmod_inline, jsc.toJSHostFn(${typeName}.call), .{globalObject, callFrame});
}
`;
}
@@ -2223,7 +2223,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${classSymbolName(typeName, "getInternalProperties")}(thisValue: *${typeName}, globalObject: *jsc.JSGlobalObject, thisValue: jsc.JSValue) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_get_internal_properties("${typeName}");
return @call(.always_inline, ${typeName}.getInternalProperties, .{thisValue, globalObject, thisValue});
return @call(bun.callmod_inline, ${typeName}.getInternalProperties, .{thisValue, globalObject, thisValue});
}
`;
}
@@ -2239,9 +2239,9 @@ const JavaScriptCoreBindings = struct {
if (comptime Environment.enable_logs) log_zig_getter("${typeName}", "${name}");
return switch (@typeInfo(@typeInfo(@TypeOf(${typeName}.${getter})).@"fn".return_type.?)) {
.error_union => {
return @call(.always_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${getter}, .{this, ${thisValue ? "thisValue," : ""} globalObject}});
return @call(bun.callmod_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${getter}, .{this, ${thisValue ? "thisValue," : ""} globalObject}});
},
else => @call(.always_inline, ${typeName}.${getter}, .{this, ${thisValue ? "thisValue," : ""} globalObject}),
else => @call(bun.callmod_inline, ${typeName}.${getter}, .{this, ${thisValue ? "thisValue," : ""} globalObject}),
};
}
`;
@@ -2256,10 +2256,10 @@ const JavaScriptCoreBindings = struct {
if (error_union.payload != void) {
@compileError("Setter return type must be JSError!void or void");
}
return @call(.always_inline, jsc.host_fn.toJSHostSetterValue, .{globalObject, @call(.always_inline, ${typeName}.${setter}, .{this, ${thisValue ? "thisValue," : ""} globalObject, value})});
return @call(bun.callmod_inline, jsc.host_fn.toJSHostSetterValue, .{globalObject, @call(bun.callmod_inline, ${typeName}.${setter}, .{this, ${thisValue ? "thisValue," : ""} globalObject, value})});
},
.void => {
@call(.always_inline, ${typeName}.${setter}, .{this, ${thisValue ? "thisValue," : ""} globalObject, value});
@call(bun.callmod_inline, ${typeName}.${setter}, .{this, ${thisValue ? "thisValue," : ""} globalObject, value});
return true;
},
else => @compileError("Setter return type must be JSError!void or void"),
@@ -2283,7 +2283,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${names.fn}(thisValue: *${typeName}, globalObject: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame${proto[name].passThis ? ", js_this_value: jsc.JSValue" : ""}) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_method("${typeName}", "${name}", callFrame);
return @call(.always_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${fn}, .{thisValue, globalObject, callFrame${proto[name].passThis ? ", js_this_value" : ""}}});
return @call(bun.callmod_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${fn}, .{thisValue, globalObject, callFrame${proto[name].passThis ? ", js_this_value" : ""}}});
}
`;
}
@@ -2301,10 +2301,10 @@ const JavaScriptCoreBindings = struct {
if (comptime Environment.enable_logs) log_zig_class_getter("${typeName}", "${name}");
return switch (@typeInfo(@typeInfo(@TypeOf(${typeName}.${getter})).@"fn".return_type.?)) {
.error_union => {
return @call(.always_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${getter}, .{globalObject, ${thisValue ? "thisValue," : ""} propertyName}});
return @call(bun.callmod_inline, jsc.toJSHostCall, .{globalObject, @src(), ${typeName}.${getter}, .{globalObject, ${thisValue ? "thisValue," : ""} propertyName}});
},
else => {
return @call(.always_inline, ${typeName}.${getter}, .{globalObject, ${thisValue ? "thisValue," : ""} propertyName});
return @call(bun.callmod_inline, ${typeName}.${getter}, .{globalObject, ${thisValue ? "thisValue," : ""} propertyName});
},
};
}
@@ -2315,7 +2315,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${names.setter}(globalObject: *jsc.JSGlobalObject, thisValue: jsc.JSValue, target: jsc.JSValue) callconv(jsc.conv) bool {
if (comptime Environment.enable_logs) log_zig_class_setter("${typeName}", "${name}", target);
return @call(.always_inline, ${typeName}.${setter || accessor.setter}, .{thisValue, globalObject, target});
return @call(bun.callmod_inline, ${typeName}.${setter || accessor.setter}, .{thisValue, globalObject, target});
}
`;
}
@@ -2329,7 +2329,7 @@ const JavaScriptCoreBindings = struct {
.map(ZigDOMJITArgTypeDefinition)
.join(", ")}) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_class_domjit("${typeName}", "${name}");
return @call(.always_inline, ${typeName}.${DOMJITName(fn)}, .{thisValue, globalObject, ${args.map((_, i) => `arg${i}`).join(", ")}});
return @call(bun.callmod_inline, ${typeName}.${DOMJITName(fn)}, .{thisValue, globalObject, ${args.map((_, i) => `arg${i}`).join(", ")}});
}
`;
}
@@ -2337,7 +2337,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${names.fn}(globalObject: *jsc.JSGlobalObject, callFrame: *jsc.CallFrame) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_class_method("${typeName}", "${name}", callFrame);
return @call(.always_inline, jsc.toJSHostFn(${typeName}.${fn}), .{globalObject, callFrame});
return @call(bun.callmod_inline, jsc.toJSHostFn(${typeName}.${fn}), .{globalObject, callFrame});
}
`;
}
@@ -2349,7 +2349,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${symbolName(typeName, "onStructuredCloneSerialize")}(thisValue: *${typeName}, globalObject: *jsc.JSGlobalObject, ctx: *anyopaque, writeBytes: WriteBytesFn) callconv(jsc.conv) void {
if (comptime Environment.enable_logs) log_zig_structured_clone_serialize("${typeName}");
@call(.always_inline, ${typeName}.onStructuredCloneSerialize, .{thisValue, globalObject, ctx, writeBytes});
@call(bun.callmod_inline, ${typeName}.onStructuredCloneSerialize, .{thisValue, globalObject, ctx, writeBytes});
}
`;
@@ -2358,7 +2358,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${exports.get("structuredClone_transferable")}(thisValue: *${typeName}, globalObject: *jsc.JSGlobalObject, ctx: *anyopaque, write: WriteBytesFn) callconv(jsc.conv) void {
if (comptime Environment.enable_logs) log_zig_structured_clone_transfer("${typeName}");
@call(.always_inline, ${typeName}.onStructuredCloneTransfer, .{thisValue, globalObject, ctx, write});
@call(bun.callmod_inline, ${typeName}.onStructuredCloneTransfer, .{thisValue, globalObject, ctx, write});
}
`;
}
@@ -2368,7 +2368,7 @@ const JavaScriptCoreBindings = struct {
output += `
pub fn ${symbolName(typeName, "onStructuredCloneDeserialize")}(globalObject: *jsc.JSGlobalObject, ptr: *[*]u8, end: [*]u8) callconv(jsc.conv) jsc.JSValue {
if (comptime Environment.enable_logs) log_zig_structured_clone_deserialize("${typeName}");
return @call(.always_inline, jsc.toJSHostCall, .{ globalObject, @src(), ${typeName}.onStructuredCloneDeserialize, .{globalObject, ptr, end} });
return @call(bun.callmod_inline, jsc.toJSHostCall, .{ globalObject, @src(), ${typeName}.onStructuredCloneDeserialize, .{globalObject, ptr, end} });
}
`;
} else {

View File

@@ -1,7 +1,7 @@
/// POSIX-like stat structure with birthtime support for node:fs
/// This extends the standard POSIX stat with birthtime (creation time)
pub const PosixStat = extern struct {
dev: u64,
dev: i64,
ino: u64,
mode: u32,
nlink: u64,

View File

@@ -96,7 +96,6 @@ leak:sql.postgres.protocol.FieldMessage.FieldMessage.init
leak:JSC::intlCollatorAvailableLocales
leak:Bun__canonicalizeIP
leak:dlopen
leak:Bun::evaluateCommonJSModuleOnce
leak:fse_run_loop
leak:Zig::NapiClass_ConstructorFunction
leak:bun.js.webcore.fetch.FetchTasklet.toResponse
@@ -194,3 +193,4 @@ leak:ast.parseStmt.ParseStmt
leak:bun.js.ModuleLoader.RuntimeTranspilerStore.TranspilerJob.run
leak:bun.js.BuildMessage.BuildMessage.getNotes
leak:sql.postgres.PostgresSQLQuery.doRun
leak:bun.js.node.node_fs.Arguments.Realpath.fromJS

View File

@@ -193,6 +193,7 @@ test/regression/issue/02499/02499.test.ts
test/js/node/test/parallel/test-http-server-stale-close.js
test/js/third_party/comlink/comlink.test.ts
test/regression/issue/22635/22635.test.ts
test/js/node/test/parallel/test-child-process-silent.js
# Bun::JSNodeHTTPServerSocket::clearSocketData