From 469a547f8d1307343407426481d4e8aaea0405e7 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Wed, 28 May 2025 10:30:58 +0200 Subject: [PATCH 1/2] src: remove fast API for InternalModuleStat There are several motivation for removing this: 1. The implementation does not align with InternalModuleStat, most noticably it does not namespace the path or convert it to UTF-16 before using it with std::filesystem::path on Windows which could crash on non-English locale. 2. It needs the Environment - if not for decoding the string, at least for env->exec_path() to resolve the path for namespacing - and therefore needs a handle to the Context which requires a handle scope which actually makes the fast API version slower than the normal binding. For simplicity this just removes the fast API to fix the bug and improve the performance. --- src/node_file.cc | 35 +---------------------------------- 1 file changed, 1 insertion(+), 34 deletions(-) diff --git a/src/node_file.cc b/src/node_file.cc index ba8a1c464d5799..af24a5b18c539a 100644 --- a/src/node_file.cc +++ b/src/node_file.cc @@ -64,7 +64,6 @@ using v8::Array; using v8::BigInt; using v8::Context; using v8::EscapableHandleScope; -using v8::FastApiCallbackOptions; using v8::FunctionCallbackInfo; using v8::FunctionTemplate; using v8::HandleScope; @@ -1073,32 +1072,6 @@ static void InternalModuleStat(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(rc); } -static int32_t FastInternalModuleStat( - Local recv, - Local input_, - // NOLINTNEXTLINE(runtime/references) This is V8 api. - FastApiCallbackOptions& options) { - TRACK_V8_FAST_API_CALL("fs.internalModuleStat"); - HandleScope scope(options.isolate); - - CHECK(input_->IsString()); - Utf8Value input(options.isolate, input_.As()); - - auto path = std::filesystem::path(input.ToStringView()); - - switch (std::filesystem::status(path).type()) { - case std::filesystem::file_type::directory: - return 1; - case std::filesystem::file_type::regular: - return 0; - default: - return -1; - } -} - -v8::CFunction fast_internal_module_stat_( - v8::CFunction::Make(FastInternalModuleStat)); - constexpr bool is_uv_error_except_no_entry(int result) { return result < 0 && result != UV_ENOENT; } @@ -3722,11 +3695,7 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data, SetMethod(isolate, target, "rmSync", RmSync); SetMethod(isolate, target, "mkdir", MKDir); SetMethod(isolate, target, "readdir", ReadDir); - SetFastMethod(isolate, - target, - "internalModuleStat", - InternalModuleStat, - &fast_internal_module_stat_); + SetMethod(isolate, target, "internalModuleStat", InternalModuleStat); SetMethod(isolate, target, "stat", Stat); SetMethod(isolate, target, "lstat", LStat); SetMethod(isolate, target, "fstat", FStat); @@ -3851,8 +3820,6 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) { registry->Register(MKDir); registry->Register(ReadDir); registry->Register(InternalModuleStat); - registry->Register(FastInternalModuleStat); - registry->Register(fast_internal_module_stat_.GetTypeInfo()); registry->Register(Stat); registry->Register(LStat); registry->Register(FStat); From 7a995aec6106f8ad046586d70765dea8162a7f2e Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Fri, 30 May 2025 11:12:17 +0200 Subject: [PATCH 2/2] fixup! src: remove fast API for InternalModuleStat --- .../test-permission-fs-internal-module-stat.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/test/parallel/test-permission-fs-internal-module-stat.js b/test/parallel/test-permission-fs-internal-module-stat.js index 5b1dd6679c7019..db7129e8554f23 100644 --- a/test/parallel/test-permission-fs-internal-module-stat.js +++ b/test/parallel/test-permission-fs-internal-module-stat.js @@ -20,19 +20,3 @@ const blockedFile = fixtures.path('permission', 'deny', 'protected-file.md'); const internalFsBinding = internalBinding('fs'); strictEqual(internalFsBinding.internalModuleStat(blockedFile), 0); - -// Only javascript methods can be optimized through %OptimizeFunctionOnNextCall -// This is why we surround the C++ method we want to optimize with a JS function. -function testFastPaths(file) { - return internalFsBinding.internalModuleStat(file); -} - -eval('%PrepareFunctionForOptimization(testFastPaths)'); -testFastPaths(blockedFile); -eval('%OptimizeFunctionOnNextCall(testFastPaths)'); -strictEqual(testFastPaths(blockedFile), 0); - -if (common.isDebug) { - const { getV8FastApiCallCount } = internalBinding('debug'); - strictEqual(getV8FastApiCallCount('fs.internalModuleStat'), 1); -}