diff options
author | 2023-02-06 21:18:58 -0800 | |
---|---|---|
committer | 2023-02-06 21:18:58 -0800 | |
commit | 7ddbbc53b48b32b7a78f6654facfe8d7dd88a229 (patch) | |
tree | 7704b42907df5573f6859c28967371d4f95c1e4d | |
parent | 85611272c6ecc2c9a4912e717c796022467c21b0 (diff) | |
download | bun-7ddbbc53b48b32b7a78f6654facfe8d7dd88a229.tar.gz bun-7ddbbc53b48b32b7a78f6654facfe8d7dd88a229.tar.zst bun-7ddbbc53b48b32b7a78f6654facfe8d7dd88a229.zip |
Make `Stat` functions fast
-rw-r--r-- | src/bun.js/bindings/ZigGeneratedClasses.cpp | 140 | ||||
-rw-r--r-- | src/bun.js/bindings/generated_classes.zig | 42 | ||||
-rw-r--r-- | src/bun.js/node/node.classes.ts | 35 | ||||
-rw-r--r-- | src/bun.js/node/types.zig | 34 | ||||
-rw-r--r-- | src/bun.js/scripts/generate-classes.ts | 47 | ||||
-rw-r--r-- | test/bun.js/fs.test.js | 29 |
6 files changed, 305 insertions, 22 deletions
diff --git a/src/bun.js/bindings/ZigGeneratedClasses.cpp b/src/bun.js/bindings/ZigGeneratedClasses.cpp index 7db79d1d4..157082a19 100644 --- a/src/bun.js/bindings/ZigGeneratedClasses.cpp +++ b/src/bun.js/bindings/ZigGeneratedClasses.cpp @@ -9981,24 +9981,150 @@ JSC_DECLARE_CUSTOM_GETTER(StatsPrototype__inoGetterWrap); extern "C" EncodedJSValue StatsPrototype__isBlockDevice_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isBlockDeviceCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isBlockDeviceWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isBlockDevice_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isBlockDevice(StatsPrototype__isBlockDeviceWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isBlockDeviceWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isBlockDevice_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isCharacterDevice_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isCharacterDeviceCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isCharacterDeviceWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isCharacterDevice_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isCharacterDevice(StatsPrototype__isCharacterDeviceWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isCharacterDeviceWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isCharacterDevice_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isDirectory_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isDirectoryCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isDirectoryWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isDirectory_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isDirectory(StatsPrototype__isDirectoryWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isDirectoryWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isDirectory_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isFIFO_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isFIFOCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isFIFOWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isFIFO_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isFIFO(StatsPrototype__isFIFOWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isFIFOWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isFIFO_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isFile_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isFileCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isFileWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isFile_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isFile(StatsPrototype__isFileWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isFileWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isFile_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isSocket_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isSocketCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isSocketWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isSocket_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isSocket(StatsPrototype__isSocketWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isSocketWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isSocket_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" EncodedJSValue StatsPrototype__isSymbolicLink_(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject, JSC::CallFrame* callFrame); JSC_DECLARE_HOST_FUNCTION(StatsPrototype__isSymbolicLinkCallback); +extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(StatsPrototype__isSymbolicLinkWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)); +extern "C" EncodedJSValue StatsPrototype__isSymbolicLink_WithoutTypeChecks(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); + +static const JSC::DOMJIT::Signature DOMJITSignatureForStatsPrototype__isSymbolicLink(StatsPrototype__isSymbolicLinkWithoutTypeChecksWrapper, + JSStats::info(), + JSC::DOMJIT::Effect::forPure(), + JSC::SpecHeapTop); + +JSC_DEFINE_JIT_OPERATION(StatsPrototype__isSymbolicLinkWithoutTypeChecksWrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue)) +{ + VM& vm = JSC::getVM(lexicalGlobalObject); + IGNORE_WARNINGS_BEGIN("frame-address") + CallFrame* callFrame = DECLARE_CALL_FRAME(vm); + IGNORE_WARNINGS_END + JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); + return StatsPrototype__isSymbolicLink_WithoutTypeChecks(reinterpret_cast<JSStats*>(thisValue)->wrapped(), lexicalGlobalObject); +} + extern "C" JSC::EncodedJSValue StatsPrototype__mode(void* ptr, JSC::JSGlobalObject* lexicalGlobalObject); JSC_DECLARE_CUSTOM_GETTER(StatsPrototype__modeGetterWrap); @@ -10034,13 +10160,13 @@ static const HashTableValue JSStatsPrototypeTableValues[] = { { "dev"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__devGetterWrap, 0 } }, { "gid"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__gidGetterWrap, 0 } }, { "ino"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__inoGetterWrap, 0 } }, - { "isBlockDevice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isBlockDeviceCallback, 0 } }, - { "isCharacterDevice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isCharacterDeviceCallback, 0 } }, - { "isDirectory"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isDirectoryCallback, 0 } }, - { "isFIFO"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isFIFOCallback, 0 } }, - { "isFile"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isFileCallback, 0 } }, - { "isSocket"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isSocketCallback, 0 } }, - { "isSymbolicLink"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::NativeFunctionType, StatsPrototype__isSymbolicLinkCallback, 0 } }, + { "isBlockDevice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isBlockDeviceCallback, &DOMJITSignatureForStatsPrototype__isBlockDevice } }, + { "isCharacterDevice"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isCharacterDeviceCallback, &DOMJITSignatureForStatsPrototype__isCharacterDevice } }, + { "isDirectory"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isDirectoryCallback, &DOMJITSignatureForStatsPrototype__isDirectory } }, + { "isFIFO"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isFIFOCallback, &DOMJITSignatureForStatsPrototype__isFIFO } }, + { "isFile"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isFileCallback, &DOMJITSignatureForStatsPrototype__isFile } }, + { "isSocket"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isSocketCallback, &DOMJITSignatureForStatsPrototype__isSocket } }, + { "isSymbolicLink"_s, static_cast<unsigned>(JSC::PropertyAttribute::Function | JSC::PropertyAttribute::DOMJITFunction | PropertyAttribute::DontEnum), NoIntrinsic, { HashTableValue::DOMJITFunctionType, StatsPrototype__isSymbolicLinkCallback, &DOMJITSignatureForStatsPrototype__isSymbolicLink } }, { "mode"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__modeGetterWrap, 0 } }, { "mtime"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__mtimeGetterWrap, 0 } }, { "mtimeMs"_s, static_cast<unsigned>(JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::CustomAccessor | JSC::PropertyAttribute::DOMAttribute), NoIntrinsic, { HashTableValue::GetterSetterType, StatsPrototype__mtimeMsGetterWrap, 0 } }, diff --git a/src/bun.js/bindings/generated_classes.zig b/src/bun.js/bindings/generated_classes.zig index 7bfe4fffc..2f4e7b0b6 100644 --- a/src/bun.js/bindings/generated_classes.zig +++ b/src/bun.js/bindings/generated_classes.zig @@ -2898,18 +2898,53 @@ pub const JSStats = struct { if (@TypeOf(Stats.ino) != GetterType) @compileLog("Expected Stats.ino to be a getter"); + if (@TypeOf(Stats.isBlockDevice_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isBlockDevice_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isBlockDevice_) != CallbackType) @compileLog("Expected Stats.isBlockDevice_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isBlockDevice_))); + if (@TypeOf(Stats.isCharacterDevice_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isCharacterDevice_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isCharacterDevice_) != CallbackType) @compileLog("Expected Stats.isCharacterDevice_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isCharacterDevice_))); + if (@TypeOf(Stats.isDirectory_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isDirectory_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isDirectory_) != CallbackType) @compileLog("Expected Stats.isDirectory_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isDirectory_))); + if (@TypeOf(Stats.isFIFO_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isFIFO_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isFIFO_) != CallbackType) @compileLog("Expected Stats.isFIFO_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isFIFO_))); + if (@TypeOf(Stats.isFile_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isFile_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isFile_) != CallbackType) @compileLog("Expected Stats.isFile_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isFile_))); + if (@TypeOf(Stats.isSocket_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isSocket_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isSocket_) != CallbackType) @compileLog("Expected Stats.isSocket_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isSocket_))); + if (@TypeOf(Stats.isSymbolicLink_WithoutTypeChecks) != fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue) + @compileLog("Expected Stats.isSymbolicLink_WithoutTypeChecks to be a DOMJIT function"); if (@TypeOf(Stats.isSymbolicLink_) != CallbackType) @compileLog("Expected Stats.isSymbolicLink_ to be a callback but received " ++ @typeName(@TypeOf(Stats.isSymbolicLink_))); if (@TypeOf(Stats.mode) != GetterType) @@ -2948,12 +2983,19 @@ pub const JSStats = struct { @export(Stats.gid, .{ .name = "StatsPrototype__gid" }); @export(Stats.ino, .{ .name = "StatsPrototype__ino" }); @export(Stats.isBlockDevice_, .{ .name = "StatsPrototype__isBlockDevice_" }); + @export(Stats.isBlockDevice_WithoutTypeChecks, .{ .name = "StatsPrototype__isBlockDevice_WithoutTypeChecks" }); @export(Stats.isCharacterDevice_, .{ .name = "StatsPrototype__isCharacterDevice_" }); + @export(Stats.isCharacterDevice_WithoutTypeChecks, .{ .name = "StatsPrototype__isCharacterDevice_WithoutTypeChecks" }); @export(Stats.isDirectory_, .{ .name = "StatsPrototype__isDirectory_" }); + @export(Stats.isDirectory_WithoutTypeChecks, .{ .name = "StatsPrototype__isDirectory_WithoutTypeChecks" }); @export(Stats.isFIFO_, .{ .name = "StatsPrototype__isFIFO_" }); + @export(Stats.isFIFO_WithoutTypeChecks, .{ .name = "StatsPrototype__isFIFO_WithoutTypeChecks" }); @export(Stats.isFile_, .{ .name = "StatsPrototype__isFile_" }); + @export(Stats.isFile_WithoutTypeChecks, .{ .name = "StatsPrototype__isFile_WithoutTypeChecks" }); @export(Stats.isSocket_, .{ .name = "StatsPrototype__isSocket_" }); + @export(Stats.isSocket_WithoutTypeChecks, .{ .name = "StatsPrototype__isSocket_WithoutTypeChecks" }); @export(Stats.isSymbolicLink_, .{ .name = "StatsPrototype__isSymbolicLink_" }); + @export(Stats.isSymbolicLink_WithoutTypeChecks, .{ .name = "StatsPrototype__isSymbolicLink_WithoutTypeChecks" }); @export(Stats.mode, .{ .name = "StatsPrototype__mode" }); @export(Stats.mtime, .{ .name = "StatsPrototype__mtime" }); @export(Stats.mtimeMs, .{ .name = "StatsPrototype__mtimeMs" }); diff --git a/src/bun.js/node/node.classes.ts b/src/bun.js/node/node.classes.ts index edf92fcfb..d053821c0 100644 --- a/src/bun.js/node/node.classes.ts +++ b/src/bun.js/node/node.classes.ts @@ -12,36 +12,71 @@ export default [ fn: "isBlockDevice_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isCharacterDevice: { fn: "isCharacterDevice_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isDirectory: { fn: "isDirectory_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isFIFO: { fn: "isFIFO_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isFile: { fn: "isFile_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isSocket: { fn: "isSocket_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, isSymbolicLink: { fn: "isSymbolicLink_", length: 0, enumerable: false, + DOMJIT: { + returns: "bool", + args: [], + pure: true, + }, }, dev: { getter: "dev", diff --git a/src/bun.js/node/types.zig b/src/bun.js/node/types.zig index 3b856009c..109497a93 100644 --- a/src/bun.js/node/types.zig +++ b/src/bun.js/node/types.zig @@ -1071,6 +1071,7 @@ fn StatsDataType(comptime T: type) type { const atime = stat_.atime(); const mtime = stat_.mtime(); const ctime = stat_.ctime(); + return @This(){ .dev = @truncate(T, @intCast(i64, stat_.dev)), .ino = @truncate(T, @intCast(i64, stat_.ino)), @@ -1131,6 +1132,29 @@ pub const Stats = union(enum) { pub const isSocket_ = JSC.wrapInstanceMethod(Stats, "isSocket", false); pub const isSymbolicLink_ = JSC.wrapInstanceMethod(Stats, "isSymbolicLink", false); + pub const isBlockDevice_WithoutTypeChecks = domCall(.isBlockDevice); + pub const isCharacterDevice_WithoutTypeChecks = domCall(.isCharacterDevice); + pub const isDirectory_WithoutTypeChecks = domCall(.isDirectory); + pub const isFIFO_WithoutTypeChecks = domCall(.isFIFO); + pub const isFile_WithoutTypeChecks = domCall(.isFile); + pub const isSocket_WithoutTypeChecks = domCall(.isSocket); + pub const isSymbolicLink_WithoutTypeChecks = domCall(.isSymbolicLink); + + const DOMCallFn = fn ( + *Stats, + *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue; + fn domCall(comptime decl: std.meta.DeclEnum(Stats)) DOMCallFn { + return struct { + pub fn run( + this: *Stats, + _: *JSC.JSGlobalObject, + ) callconv(.C) JSC.JSValue { + return @call(.auto, @field(Stats, @tagName(decl)), .{this}); + } + }.run; + } + pub const dev = unionGetter(.dev); pub const ino = unionGetter(.ino); pub const mode = unionGetter(.mode); @@ -1213,6 +1237,16 @@ pub const Stats = union(enum) { return null; } + + comptime { + _ = isBlockDevice_WithoutTypeChecks; + _ = isCharacterDevice_WithoutTypeChecks; + _ = isDirectory_WithoutTypeChecks; + _ = isFIFO_WithoutTypeChecks; + _ = isFile_WithoutTypeChecks; + _ = isSocket_WithoutTypeChecks; + _ = isSymbolicLink_WithoutTypeChecks; + } }; /// A class representing a directory stream. diff --git a/src/bun.js/scripts/generate-classes.ts b/src/bun.js/scripts/generate-classes.ts index 473de5bba..883abfcd9 100644 --- a/src/bun.js/scripts/generate-classes.ts +++ b/src/bun.js/scripts/generate-classes.ts @@ -93,38 +93,47 @@ function DOMJITReturnType(type) { }[type]; } -function DOMJITFunctionDeclaration(jsClassName, fnName, { args, returns }) { +function DOMJITFunctionDeclaration(jsClassName, fnName, symName, { args, returns, pure = false }) { const argNames = args.map((arg, i) => `${argTypeName(arg)} arg${i}`); + const formattedArgs = argNames.length > 0 ? `, ${argNames.join(", ")}` : ""; + const domJITArgs = args.length > 0 ? `, ${args.map(DOMJITType).join(", ")}` : ""; return ` extern "C" JSC_DECLARE_JIT_OPERATION_WITHOUT_WTF_INTERNAL(${DOMJITName( fnName, - )}Wrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, ${argNames.join(", ")})); - extern "C" EncodedJSValue ${DOMJITName(fnName)}(void* ptr, JSC::JSGlobalObject * lexicalGlobalObject, ${argNames.join( - ", ", - )}); + )}Wrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue${formattedArgs})); + extern "C" EncodedJSValue ${DOMJITName( + symName, + )}(void* ptr, JSC::JSGlobalObject * lexicalGlobalObject${formattedArgs}); static const JSC::DOMJIT::Signature DOMJITSignatureFor${fnName}(${DOMJITName(fnName)}Wrapper, ${jsClassName}::info(), - JSC::DOMJIT::Effect::forReadWrite(JSC::DOMJIT::HeapRange::top(), JSC::DOMJIT::HeapRange::top()), - ${returns === "JSString" ? "JSC::SpecString" : DOMJITType("JSValue")}, ${args.map(DOMJITType).join(", ")}); + ${ + pure + ? "JSC::DOMJIT::Effect::forPure()" + : "JSC::DOMJIT::Effect::forReadWrite(JSC::DOMJIT::HeapRange::top(), JSC::DOMJIT::HeapRange::top())" + }, + ${returns === "JSString" ? "JSC::SpecString" : DOMJITType("JSValue")}${domJITArgs}); `.trim(); } -function DOMJITFunctionDefinition(jsClassName, fnName, { args }) { +function DOMJITFunctionDefinition(jsClassName, fnName, symName, { args }) { const argNames = args.map((arg, i) => `${argTypeName(arg)} arg${i}`); + const formattedArgs = argNames.length > 0 ? `, ${argNames.join(", ")}` : ""; + const retArgs = argNames.length > 0 ? `, ${args.map((b, i) => "arg" + i).join(", ")}` : ""; + return ` JSC_DEFINE_JIT_OPERATION(${DOMJITName( fnName, - )}Wrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue, ${argNames.join(", ")})) + )}Wrapper, EncodedJSValue, (JSC::JSGlobalObject * lexicalGlobalObject, void* thisValue${formattedArgs})) { VM& vm = JSC::getVM(lexicalGlobalObject); IGNORE_WARNINGS_BEGIN("frame-address") CallFrame* callFrame = DECLARE_CALL_FRAME(vm); IGNORE_WARNINGS_END JSC::JITOperationPrologueCallFrameTracer tracer(vm, callFrame); - return ${DOMJITName(fnName)}(reinterpret_cast<${jsClassName}*>(thisValue)->wrapped(), lexicalGlobalObject, ${args - .map((b, i) => "arg" + i) - .join(", ")}); + return ${DOMJITName( + symName, + )}(reinterpret_cast<${jsClassName}*>(thisValue)->wrapped(), lexicalGlobalObject${retArgs}); } `; } @@ -568,8 +577,18 @@ function renderDecls(symbolName, typeName, proto) { if (proto[name].DOMJIT) { rows.push( - DOMJITFunctionDeclaration(className(typeName), symbolName(typeName, name), proto[name].DOMJIT), - DOMJITFunctionDefinition(className(typeName), symbolName(typeName, name), proto[name].DOMJIT), + DOMJITFunctionDeclaration( + className(typeName), + symbolName(typeName, name), + symbolName(typeName, proto[name].fn), + proto[name].DOMJIT, + ), + DOMJITFunctionDefinition( + className(typeName), + symbolName(typeName, name), + symbolName(typeName, proto[name].fn), + proto[name].DOMJIT, + ), ); } } diff --git a/test/bun.js/fs.test.js b/test/bun.js/fs.test.js index f78ce13da..a203a47b4 100644 --- a/test/bun.js/fs.test.js +++ b/test/bun.js/fs.test.js @@ -356,12 +356,24 @@ describe("writeFileSync", () => { }); }); +function triggerDOMJIT(target, fn, result) { + for (let i = 0; i < 9999; i++) { + if (fn.apply(target) !== result) { + throw new Error("DOMJIT failed"); + } + } +} + describe("lstat", () => { it("file metadata is correct", () => { const fileStats = lstatSync(new URL("./fs-stream.js", import.meta.url).toString().slice("file://".length - 1)); expect(fileStats.isSymbolicLink()).toBe(false); expect(fileStats.isFile()).toBe(true); expect(fileStats.isDirectory()).toBe(false); + + triggerDOMJIT(fileStats, fileStats.isFile, true); + triggerDOMJIT(fileStats, fileStats.isDirectory, false); + triggerDOMJIT(fileStats, fileStats.isSymbolicLink, false); }); it("folder metadata is correct", () => { @@ -369,6 +381,10 @@ describe("lstat", () => { expect(fileStats.isSymbolicLink()).toBe(false); expect(fileStats.isFile()).toBe(false); expect(fileStats.isDirectory()).toBe(true); + + triggerDOMJIT(fileStats, fileStats.isFile, false); + triggerDOMJIT(fileStats, fileStats.isDirectory, true); + triggerDOMJIT(fileStats, fileStats.isSymbolicLink, false); }); it("symlink metadata is correct", () => { @@ -376,6 +392,10 @@ describe("lstat", () => { expect(linkStats.isSymbolicLink()).toBe(true); expect(linkStats.isFile()).toBe(false); expect(linkStats.isDirectory()).toBe(false); + + triggerDOMJIT(linkStats, linkStats.isFile, false); + triggerDOMJIT(linkStats, linkStats.isDirectory, false); + triggerDOMJIT(linkStats, linkStats.isSymbolicLink, true); }); }); @@ -385,6 +405,10 @@ describe("stat", () => { expect(fileStats.isSymbolicLink()).toBe(false); expect(fileStats.isFile()).toBe(true); expect(fileStats.isDirectory()).toBe(false); + + triggerDOMJIT(fileStats, fileStats.isFile, true); + triggerDOMJIT(fileStats, fileStats.isDirectory, false); + triggerDOMJIT(fileStats, fileStats.isSymbolicLink, false); }); it("folder metadata is correct", () => { @@ -410,6 +434,10 @@ describe("stat", () => { expect(typeof fileStats.mtime).toBe("object"); expect(typeof fileStats.ctime).toBe("object"); expect(typeof fileStats.birthtime).toBe("object"); + + triggerDOMJIT(fileStats, fileStats.isFile, false); + triggerDOMJIT(fileStats, fileStats.isDirectory, true); + triggerDOMJIT(fileStats, fileStats.isSymbolicLink, false); }); it("stat returns ENOENT", () => { @@ -770,7 +798,6 @@ it("fs.constants", () => { expect(constants.S_IWOTH).toBeDefined(); }); - it("fs.Dirent", () => { expect(Dirent).toBeDefined(); }); |