Skip to content

Commit

Permalink
fixup! fs: move getValidMode to c++ for better performance
Browse files Browse the repository at this point in the history
  • Loading branch information
andremralves committed Oct 1, 2023
1 parent 354e343 commit 1b6b918
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 23 deletions.
68 changes: 45 additions & 23 deletions src/node_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ using v8::HandleScope;
using v8::Int32;
using v8::Integer;
using v8::Isolate;
using v8::Just;
using v8::JustVoid;
using v8::Local;
using v8::Maybe;
Expand All @@ -89,6 +90,12 @@ constexpr char kPathSeparator = '/';
const char* const kPathSeparator = "\\/";
#endif

#ifdef _WIN32
#include "uv.h"
#else
#include <unistd.h>
#endif

// The access modes can be any of F_OK, R_OK, W_OK or X_OK. Some might not be
// available on specific systems. They can be used in combination as well
// (F_OK | R_OK | W_OK | X_OK).
Expand Down Expand Up @@ -872,41 +879,39 @@ void FromNamespacedPath(std::string* path) {
#endif
}

static inline int GetValidMode(Environment* env,
Local<Value> mode_v,
std::string_view type) {
static inline Maybe<int> GetValidMode(Environment* env,
Local<Value> mode_v,
uv_fs_type type) {
if (!mode_v->IsInt32() && !mode_v->IsNullOrUndefined()) {
THROW_ERR_INVALID_ARG_TYPE(env, "mode must be int32 or null/undefined");
return -1;
return Nothing<int>();
}

int min = kMinimumAccessMode;
int max = kMaximumAccessMode;
int def = F_OK;

if (type == "copyFile") {
CHECK(type == UV_FS_ACCESS || type == UV_FS_COPYFILE);

if (type == UV_FS_COPYFILE) {
min = kMinimumCopyMode;
max = kMaximumCopyMode;
def = mode_v->IsNullOrUndefined() ? kDefaultCopyMode
: mode_v.As<Int32>()->Value();
} else if (type != "access") {
THROW_ERR_INVALID_ARG_TYPE(
env, "type must be equal to \"copyFile\" or \"access\"");
return -1;
}

if (mode_v->IsNullOrUndefined()) {
return def;
return Just(def);
}

const int mode = mode_v.As<Int32>()->Value();
if (mode < min || mode > max) {
THROW_ERR_OUT_OF_RANGE(
env, "mode is out of range: >= %d && <= %d", min, max);
return -1;
return Nothing<int>();
}

return mode;
return Just(mode);
}

void AfterMkdirp(uv_fs_t* req) {
Expand Down Expand Up @@ -1028,8 +1033,8 @@ void Access(const FunctionCallbackInfo<Value>& args) {
const int argc = args.Length();
CHECK_GE(argc, 2);

int mode = GetValidMode(env, args[1], "access");
if (mode == -1) return;
Maybe<int> mode = GetValidMode(env, args[1], UV_FS_ACCESS);
if (mode.IsNothing()) return;

BufferValue path(isolate, args[0]);
CHECK_NOT_NULL(*path);
Expand All @@ -1041,12 +1046,20 @@ void Access(const FunctionCallbackInfo<Value>& args) {
CHECK_NOT_NULL(req_wrap_async);
FS_ASYNC_TRACE_BEGIN1(
UV_FS_ACCESS, req_wrap_async, "path", TRACE_STR_COPY(*path))
AsyncCall(env, req_wrap_async, args, "access", UTF8, AfterNoArgs,
uv_fs_access, *path, mode);
AsyncCall(env,
req_wrap_async,
args,
"access",
UTF8,
AfterNoArgs,
uv_fs_access,
*path,
mode.FromJust());
} else { // access(path, mode)
FSReqWrapSync req_wrap_sync("access", *path);
FS_SYNC_TRACE_BEGIN(access);
SyncCallAndThrowOnError(env, &req_wrap_sync, uv_fs_access, *path, mode);
SyncCallAndThrowOnError(
env, &req_wrap_sync, uv_fs_access, *path, mode.FromJust());
FS_SYNC_TRACE_END(access);
}
}
Expand Down Expand Up @@ -2141,8 +2154,8 @@ static void CopyFile(const FunctionCallbackInfo<Value>& args) {
const int argc = args.Length();
CHECK_GE(argc, 3);

const int flags = GetValidMode(env, args[2], "copyFile");
if (flags == -1) return;
Maybe<int> flags = GetValidMode(env, args[2], UV_FS_COPYFILE);
if (flags.IsNothing()) return;

BufferValue src(isolate, args[0]);
CHECK_NOT_NULL(*src);
Expand All @@ -2162,14 +2175,23 @@ static void CopyFile(const FunctionCallbackInfo<Value>& args) {
TRACE_STR_COPY(*src),
"dest",
TRACE_STR_COPY(*dest))
AsyncDestCall(env, req_wrap_async, args, "copyfile",
*dest, dest.length(), UTF8, AfterNoArgs,
uv_fs_copyfile, *src, *dest, flags);
AsyncDestCall(env,
req_wrap_async,
args,
"copyfile",
*dest,
dest.length(),
UTF8,
AfterNoArgs,
uv_fs_copyfile,
*src,
*dest,
flags.FromJust());
} else { // copyFile(src, dest, flags)
FSReqWrapSync req_wrap_sync("copyfile", *src, *dest);
FS_SYNC_TRACE_BEGIN(copyfile);
SyncCallAndThrowOnError(
env, &req_wrap_sync, uv_fs_copyfile, *src, *dest, flags);
env, &req_wrap_sync, uv_fs_copyfile, *src, *dest, flags.FromJust());
FS_SYNC_TRACE_END(copyfile);
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/node_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ enum class FsStatFsOffset {
kFsStatFsFieldsNumber
};

enum class ModeOpType { access = 0, copyFile };

constexpr size_t kFsStatFsBufferLength =
static_cast<size_t>(FsStatFsOffset::kFsStatFsFieldsNumber);

Expand Down

0 comments on commit 1b6b918

Please sign in to comment.