31
31
#include " node_stat_watcher.h"
32
32
#include " permission/permission.h"
33
33
#include " util-inl.h"
34
+ #include " v8-fast-api-calls.h"
34
35
35
36
#include " tracing/trace_event.h"
36
37
@@ -57,8 +58,11 @@ namespace fs {
57
58
58
59
using v8::Array;
59
60
using v8::BigInt;
61
+ using v8::CFunction;
60
62
using v8::Context;
61
63
using v8::EscapableHandleScope;
64
+ using v8::FastApiCallbackOptions;
65
+ using v8::FastOneByteString;
62
66
using v8::Function;
63
67
using v8::FunctionCallbackInfo;
64
68
using v8::FunctionTemplate;
@@ -1095,6 +1099,47 @@ static void ExistsSync(const FunctionCallbackInfo<Value>& args) {
1095
1099
args.GetReturnValue ().Set (err == 0 );
1096
1100
}
1097
1101
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
+
1098
1143
// Used to speed up module loading. Returns an array [string, boolean]
1099
1144
static void InternalModuleReadJSON (const FunctionCallbackInfo<Value>& args) {
1100
1145
Environment* env = Environment::GetCurrent (args);
@@ -3364,7 +3409,8 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
3364
3409
SetMethodNoSideEffect (isolate, target, " accessSync" , AccessSync);
3365
3410
SetMethod (isolate, target, " close" , Close);
3366
3411
SetMethod (isolate, target, " closeSync" , CloseSync);
3367
- SetMethodNoSideEffect (isolate, target, " existsSync" , ExistsSync);
3412
+ SetFastMethodNoSideEffect (isolate, target, " existsSync" ,
3413
+ ExistsSync, &fast_exists_sync_);
3368
3414
SetMethod (isolate, target, " open" , Open);
3369
3415
SetMethod (isolate, target, " openSync" , OpenSync);
3370
3416
SetMethod (isolate, target, " openFileHandle" , OpenFileHandle);
@@ -3490,6 +3536,8 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
3490
3536
registry->Register (Close);
3491
3537
registry->Register (CloseSync);
3492
3538
registry->Register (ExistsSync);
3539
+ registry->Register (FastExistsSync);
3540
+ registry->Register (fast_exists_sync_.GetTypeInfo ());
3493
3541
registry->Register (Open);
3494
3542
registry->Register (OpenSync);
3495
3543
registry->Register (OpenFileHandle);
0 commit comments