Skip to content

Commit 11cea33

Browse files
committed
fs: add fast api for InternalModuleStat
1 parent 477d6d7 commit 11cea33

File tree

4 files changed

+51
-7
lines changed

4 files changed

+51
-7
lines changed

lib/internal/modules/cjs/loader.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ const { containsModuleSyntax } = internalBinding('contextify');
102102
const assert = require('internal/assert');
103103
const fs = require('fs');
104104
const path = require('path');
105-
const { internalModuleStat } = internalBinding('fs');
105+
const internalFsBinding = internalBinding('fs');
106106
const { safeGetenv } = internalBinding('credentials');
107107
const {
108108
privateSymbols: {
@@ -194,7 +194,7 @@ function stat(filename) {
194194
const result = statCache.get(filename);
195195
if (result !== undefined) { return result; }
196196
}
197-
const result = internalModuleStat(filename);
197+
const result = internalFsBinding.internalModuleStat(filename);
198198
if (statCache !== null && result >= 0) {
199199
// Only set cache when `internalModuleStat(filename)` succeeds.
200200
statCache.set(filename, result);

lib/internal/modules/esm/resolve.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ const {
5757
const { Module: CJSModule } = require('internal/modules/cjs/loader');
5858
const { getConditionsSet } = require('internal/modules/esm/utils');
5959
const packageJsonReader = require('internal/modules/package_json_reader');
60-
const { internalModuleStat } = internalBinding('fs');
60+
const internalFsBinding = internalBinding('fs');
6161

6262
/**
6363
* @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig
@@ -249,7 +249,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
249249
throw err;
250250
}
251251

252-
const stats = internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ?
252+
const stats = internalFsBinding.internalModuleStat(toNamespacedPath(StringPrototypeEndsWith(path, '/') ?
253253
StringPrototypeSlice(path, -1) : path));
254254

255255
// Check for stats.isDirectory()
@@ -809,8 +809,9 @@ function packageResolve(specifier, base, conditions) {
809809
let packageJSONPath = fileURLToPath(packageJSONUrl);
810810
let lastPath;
811811
do {
812-
const stat = internalModuleStat(toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0,
813-
packageJSONPath.length - 13)));
812+
const stat = internalFsBinding.internalModuleStat(
813+
toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0, packageJSONPath.length - 13)),
814+
);
814815
// Check for !stat.isDirectory()
815816
if (stat !== 1) {
816817
lastPath = packageJSONPath;

src/node_external_reference.h

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ using CFunctionCallbackWithOneByteString =
1515
using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
1616
using CFunctionCallbackReturnDouble =
1717
double (*)(v8::Local<v8::Object> receiver);
18+
using CFunctionCallbackReturnInt32 =
19+
int32_t (*)(v8::Local<v8::Object> receiver,
20+
const v8::FastOneByteString& input,
21+
// NOLINTNEXTLINE(runtime/references) This is V8 api.
22+
v8::FastApiCallbackOptions& options);
1823
using CFunctionCallbackValueReturnDouble =
1924
double (*)(v8::Local<v8::Value> receiver);
2025
using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> receiver,
@@ -46,6 +51,7 @@ class ExternalReferenceRegistry {
4651
V(CFunctionCallback) \
4752
V(CFunctionCallbackWithOneByteString) \
4853
V(CFunctionCallbackReturnDouble) \
54+
V(CFunctionCallbackReturnInt32) \
4955
V(CFunctionCallbackValueReturnDouble) \
5056
V(CFunctionCallbackWithInt64) \
5157
V(CFunctionCallbackWithBool) \

src/node_file.cc

+38-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "req_wrap-inl.h"
3939
#include "stream_base-inl.h"
4040
#include "string_bytes.h"
41+
#include "v8-fast-api-calls.h"
4142

4243
#if defined(__MINGW32__) || defined(_MSC_VER)
4344
# include <io.h>
@@ -51,6 +52,8 @@ using v8::Array;
5152
using v8::BigInt;
5253
using v8::Context;
5354
using v8::EscapableHandleScope;
55+
using v8::FastApiCallbackOptions;
56+
using v8::FastOneByteString;
5457
using v8::Function;
5558
using v8::FunctionCallbackInfo;
5659
using v8::FunctionTemplate;
@@ -1051,6 +1054,34 @@ static void InternalModuleStat(const FunctionCallbackInfo<Value>& args) {
10511054
args.GetReturnValue().Set(rc);
10521055
}
10531056

1057+
static int32_t FastInternalModuleStat(
1058+
Local<Object> recv,
1059+
const FastOneByteString& input,
1060+
// NOLINTNEXTLINE(runtime/references) This is V8 api.
1061+
FastApiCallbackOptions& options) {
1062+
Environment* env = Environment::GetCurrent(recv->GetCreationContextChecked());
1063+
1064+
std::string_view path(input.data, input.length);
1065+
if (UNLIKELY(!env->permission()->is_granted(
1066+
permission::PermissionScope::kFileSystemRead, path))) {
1067+
options.fallback = true;
1068+
return -1;
1069+
}
1070+
1071+
uv_fs_t req;
1072+
int rc = uv_fs_stat(env->event_loop(), &req, path.data(), nullptr);
1073+
if (rc == 0) {
1074+
const uv_stat_t* const s = static_cast<const uv_stat_t*>(req.ptr);
1075+
rc = !!(s->st_mode & S_IFDIR);
1076+
}
1077+
uv_fs_req_cleanup(&req);
1078+
1079+
return rc;
1080+
}
1081+
1082+
v8::CFunction fast_internal_module_stat_(
1083+
v8::CFunction::Make(FastInternalModuleStat));
1084+
10541085
constexpr bool is_uv_error_except_no_entry(int result) {
10551086
return result < 0 && result != UV_ENOENT;
10561087
}
@@ -3145,7 +3176,11 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
31453176
SetMethod(isolate, target, "rmdir", RMDir);
31463177
SetMethod(isolate, target, "mkdir", MKDir);
31473178
SetMethod(isolate, target, "readdir", ReadDir);
3148-
SetMethod(isolate, target, "internalModuleStat", InternalModuleStat);
3179+
SetFastMethod(isolate,
3180+
target,
3181+
"internalModuleStat",
3182+
InternalModuleStat,
3183+
&fast_internal_module_stat_);
31493184
SetMethod(isolate, target, "stat", Stat);
31503185
SetMethod(isolate, target, "lstat", LStat);
31513186
SetMethod(isolate, target, "fstat", FStat);
@@ -3266,6 +3301,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
32663301
registry->Register(MKDir);
32673302
registry->Register(ReadDir);
32683303
registry->Register(InternalModuleStat);
3304+
registry->Register(FastInternalModuleStat);
3305+
registry->Register(fast_internal_module_stat_.GetTypeInfo());
32693306
registry->Register(Stat);
32703307
registry->Register(LStat);
32713308
registry->Register(FStat);

0 commit comments

Comments
 (0)