Skip to content

Commit

Permalink
fs: add fast api for InternalModuleStat
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Jan 2, 2024
1 parent 477d6d7 commit 11cea33
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 7 deletions.
4 changes: 2 additions & 2 deletions lib/internal/modules/cjs/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const { containsModuleSyntax } = internalBinding('contextify');
const assert = require('internal/assert');
const fs = require('fs');
const path = require('path');
const { internalModuleStat } = internalBinding('fs');
const internalFsBinding = internalBinding('fs');
const { safeGetenv } = internalBinding('credentials');
const {
privateSymbols: {
Expand Down Expand Up @@ -194,7 +194,7 @@ function stat(filename) {
const result = statCache.get(filename);
if (result !== undefined) { return result; }
}
const result = internalModuleStat(filename);
const result = internalFsBinding.internalModuleStat(filename);
if (statCache !== null && result >= 0) {
// Only set cache when `internalModuleStat(filename)` succeeds.
statCache.set(filename, result);
Expand Down
9 changes: 5 additions & 4 deletions lib/internal/modules/esm/resolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const {
const { Module: CJSModule } = require('internal/modules/cjs/loader');
const { getConditionsSet } = require('internal/modules/esm/utils');
const packageJsonReader = require('internal/modules/package_json_reader');
const { internalModuleStat } = internalBinding('fs');
const internalFsBinding = internalBinding('fs');

/**
* @typedef {import('internal/modules/esm/package_config.js').PackageConfig} PackageConfig
Expand Down Expand Up @@ -249,7 +249,7 @@ function finalizeResolution(resolved, base, preserveSymlinks) {
throw err;
}

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

// Check for stats.isDirectory()
Expand Down Expand Up @@ -809,8 +809,9 @@ function packageResolve(specifier, base, conditions) {
let packageJSONPath = fileURLToPath(packageJSONUrl);
let lastPath;
do {
const stat = internalModuleStat(toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0,
packageJSONPath.length - 13)));
const stat = internalFsBinding.internalModuleStat(
toNamespacedPath(StringPrototypeSlice(packageJSONPath, 0, packageJSONPath.length - 13)),
);
// Check for !stat.isDirectory()
if (stat !== 1) {
lastPath = packageJSONPath;
Expand Down
6 changes: 6 additions & 0 deletions src/node_external_reference.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ using CFunctionCallbackWithOneByteString =
using CFunctionCallback = void (*)(v8::Local<v8::Value> receiver);
using CFunctionCallbackReturnDouble =
double (*)(v8::Local<v8::Object> receiver);
using CFunctionCallbackReturnInt32 =
int32_t (*)(v8::Local<v8::Object> receiver,
const v8::FastOneByteString& input,
// NOLINTNEXTLINE(runtime/references) This is V8 api.
v8::FastApiCallbackOptions& options);
using CFunctionCallbackValueReturnDouble =
double (*)(v8::Local<v8::Value> receiver);
using CFunctionCallbackWithInt64 = void (*)(v8::Local<v8::Object> receiver,
Expand Down Expand Up @@ -46,6 +51,7 @@ class ExternalReferenceRegistry {
V(CFunctionCallback) \
V(CFunctionCallbackWithOneByteString) \
V(CFunctionCallbackReturnDouble) \
V(CFunctionCallbackReturnInt32) \
V(CFunctionCallbackValueReturnDouble) \
V(CFunctionCallbackWithInt64) \
V(CFunctionCallbackWithBool) \
Expand Down
39 changes: 38 additions & 1 deletion src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "req_wrap-inl.h"
#include "stream_base-inl.h"
#include "string_bytes.h"
#include "v8-fast-api-calls.h"

#if defined(__MINGW32__) || defined(_MSC_VER)
# include <io.h>
Expand All @@ -51,6 +52,8 @@ using v8::Array;
using v8::BigInt;
using v8::Context;
using v8::EscapableHandleScope;
using v8::FastApiCallbackOptions;
using v8::FastOneByteString;
using v8::Function;
using v8::FunctionCallbackInfo;
using v8::FunctionTemplate;
Expand Down Expand Up @@ -1051,6 +1054,34 @@ static void InternalModuleStat(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(rc);
}

static int32_t FastInternalModuleStat(
Local<Object> recv,
const FastOneByteString& input,
// NOLINTNEXTLINE(runtime/references) This is V8 api.
FastApiCallbackOptions& options) {
Environment* env = Environment::GetCurrent(recv->GetCreationContextChecked());

std::string_view path(input.data, input.length);
if (UNLIKELY(!env->permission()->is_granted(
permission::PermissionScope::kFileSystemRead, path))) {
options.fallback = true;
return -1;
}

uv_fs_t req;
int rc = uv_fs_stat(env->event_loop(), &req, path.data(), nullptr);
if (rc == 0) {
const uv_stat_t* const s = static_cast<const uv_stat_t*>(req.ptr);
rc = !!(s->st_mode & S_IFDIR);
}
uv_fs_req_cleanup(&req);

return rc;
}

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;
}
Expand Down Expand Up @@ -3145,7 +3176,11 @@ static void CreatePerIsolateProperties(IsolateData* isolate_data,
SetMethod(isolate, target, "rmdir", RMDir);
SetMethod(isolate, target, "mkdir", MKDir);
SetMethod(isolate, target, "readdir", ReadDir);
SetMethod(isolate, target, "internalModuleStat", InternalModuleStat);
SetFastMethod(isolate,
target,
"internalModuleStat",
InternalModuleStat,
&fast_internal_module_stat_);
SetMethod(isolate, target, "stat", Stat);
SetMethod(isolate, target, "lstat", LStat);
SetMethod(isolate, target, "fstat", FStat);
Expand Down Expand Up @@ -3266,6 +3301,8 @@ 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);
Expand Down

0 comments on commit 11cea33

Please sign in to comment.