Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit e5014d5

Browse files
committedSep 27, 2023
fs: use fast api calls for existsSync
1 parent 31e727d commit e5014d5

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed
 

‎src/node_external_reference.h

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ using CFunctionCallbackWithStrings =
2727
const v8::FastOneByteString& base);
2828
using CFunctionWithUint32 = uint32_t (*)(v8::Local<v8::Value>,
2929
const uint32_t input);
30+
using CFunctionCallbackWithStringOptions =
31+
bool (*)(v8::Local<v8::Object>, const v8::FastOneByteString& input,
32+
// NOLINTNEXTLINE(runtime/references) This is V8 api.
33+
v8::FastApiCallbackOptions& options);
3034

3135
// This class manages the external references from the V8 heap
3236
// to the C++ addresses in Node.js.
@@ -41,6 +45,7 @@ class ExternalReferenceRegistry {
4145
V(CFunctionCallbackWithInt64) \
4246
V(CFunctionCallbackWithBool) \
4347
V(CFunctionCallbackWithString) \
48+
V(CFunctionCallbackWithStringOptions) \
4449
V(CFunctionCallbackWithStrings) \
4550
V(CFunctionWithUint32) \
4651
V(const v8::CFunctionInfo*) \

‎src/node_file.cc

+49-1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "node_stat_watcher.h"
3232
#include "permission/permission.h"
3333
#include "util-inl.h"
34+
#include "v8-fast-api-calls.h"
3435

3536
#include "tracing/trace_event.h"
3637

@@ -57,8 +58,11 @@ namespace fs {
5758

5859
using v8::Array;
5960
using v8::BigInt;
61+
using v8::CFunction;
6062
using v8::Context;
6163
using v8::EscapableHandleScope;
64+
using v8::FastApiCallbackOptions;
65+
using v8::FastOneByteString;
6266
using v8::Function;
6367
using v8::FunctionCallbackInfo;
6468
using v8::FunctionTemplate;
@@ -1095,6 +1099,47 @@ static void ExistsSync(const FunctionCallbackInfo<Value>& args) {
10951099
args.GetReturnValue().Set(err == 0);
10961100
}
10971101

1102+
bool FastExistsSync(v8::Local<v8::Object> recv,
1103+
const FastOneByteString& string,
1104+
// NOLINTNEXTLINE(runtime/references) This is V8 api.
1105+
FastApiCallbackOptions& options) {
1106+
Environment* env = Environment::GetCurrent(recv->GetCreationContextChecked());
1107+
1108+
MaybeStackBuffer<char> path;
1109+
1110+
path.AllocateSufficientStorage(string.length + 1);
1111+
memcpy(path.out(), string.data, string.length);
1112+
path.SetLengthAndZeroTerminate(string.length);
1113+
1114+
if (UNLIKELY(!env->permission()
1115+
->is_granted(permission::PermissionScope::kFileSystemRead,
1116+
path.ToStringView()))) {
1117+
options.fallback = true;
1118+
return false;
1119+
}
1120+
1121+
uv_fs_t req;
1122+
auto make = OnScopeLeave([&req]() { uv_fs_req_cleanup(&req); });
1123+
FS_SYNC_TRACE_BEGIN(access);
1124+
int err = uv_fs_access(nullptr, &req, path.out(), 0, nullptr);
1125+
FS_SYNC_TRACE_END(access);
1126+
1127+
#ifdef _WIN32
1128+
// In case of an invalid symlink, `uv_fs_access` on win32
1129+
// will **not** return an error and is therefore not enough.
1130+
// Double check with `uv_fs_stat()`.
1131+
if (err == 0) {
1132+
FS_SYNC_TRACE_BEGIN(stat);
1133+
err = uv_fs_stat(nullptr, &req, path.out(), nullptr);
1134+
FS_SYNC_TRACE_END(stat);
1135+
}
1136+
#endif // _WIN32
1137+
1138+
return err == 0;
1139+
}
1140+
1141+
CFunction fast_exists_sync_(CFunction::Make(FastExistsSync));
1142+
10981143
// Used to speed up module loading. Returns an array [string, boolean]
10991144
static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) {
11001145
Environment* env = Environment::GetCurrent(args);
@@ -3364,7 +3409,8 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
33643409
SetMethodNoSideEffect(isolate, target, "accessSync", AccessSync);
33653410
SetMethod(isolate, target, "close", Close);
33663411
SetMethod(isolate, target, "closeSync", CloseSync);
3367-
SetMethodNoSideEffect(isolate, target, "existsSync", ExistsSync);
3412+
SetFastMethodNoSideEffect(isolate, target, "existsSync",
3413+
ExistsSync, &fast_exists_sync_);
33683414
SetMethod(isolate, target, "open", Open);
33693415
SetMethod(isolate, target, "openSync", OpenSync);
33703416
SetMethod(isolate, target, "openFileHandle", OpenFileHandle);
@@ -3490,6 +3536,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
34903536
registry->Register(Close);
34913537
registry->Register(CloseSync);
34923538
registry->Register(ExistsSync);
3539+
registry->Register(FastExistsSync);
3540+
registry->Register(fast_exists_sync_.GetTypeInfo());
34933541
registry->Register(Open);
34943542
registry->Register(OpenSync);
34953543
registry->Register(OpenFileHandle);

0 commit comments

Comments
 (0)
Please sign in to comment.