Skip to content

Commit c4ca0d7

Browse files
aduh95RafaelGSS
authored andcommitted
esm: avoid import.meta setup costs for unused properties
PR-URL: #57286 Reviewed-By: Jacob Smith <jacob@frende.me> Reviewed-By: Edy Silva <edigleyssonsilva@gmail.com>
1 parent e61b38e commit c4ca0d7

File tree

3 files changed

+82
-7
lines changed

3 files changed

+82
-7
lines changed

lib/internal/modules/esm/initialize_import_meta.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ const {
55
} = primordials;
66

77
const { getOptionValue } = require('internal/options');
8-
const { fileURLToPath } = require('internal/url');
9-
const { dirname } = require('path');
8+
const {
9+
setLazyPathHelpers,
10+
} = internalBinding('modules');
11+
1012
const experimentalImportMetaResolve = getOptionValue('--experimental-import-meta-resolve');
1113

1214
/**
@@ -58,11 +60,9 @@ function initializeImportMeta(meta, context, loader) {
5860

5961
// Alphabetical
6062
if (StringPrototypeStartsWith(url, 'file:') === true) {
61-
// These only make sense for locally loaded modules,
62-
// i.e. network modules are not supported.
63-
const filePath = fileURLToPath(url);
64-
meta.dirname = dirname(filePath);
65-
meta.filename = filePath;
63+
// dirname
64+
// filename
65+
setLazyPathHelpers(meta, url);
6666
}
6767

6868
if (!loader || loader.allowImportMetaResolve) {

src/env_properties.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@
125125
V(destroyed_string, "destroyed") \
126126
V(detached_string, "detached") \
127127
V(dh_string, "DH") \
128+
V(dirname_string, "dirname") \
128129
V(divisor_length_string, "divisorLength") \
129130
V(dns_a_string, "A") \
130131
V(dns_aaaa_string, "AAAA") \
@@ -335,6 +336,7 @@
335336
"export * from 'original'; export { default } from 'original'; export " \
336337
"const __esModule = true;") \
337338
V(require_string, "require") \
339+
V(resolve_string, "resolve") \
338340
V(resource_string, "resource") \
339341
V(result_string, "result") \
340342
V(retry_string, "retry") \

src/node_modules.cc

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ using v8::Null;
3535
using v8::Object;
3636
using v8::ObjectTemplate;
3737
using v8::Primitive;
38+
using v8::PropertyCallbackInfo;
3839
using v8::String;
3940
using v8::Undefined;
4041
using v8::Value;
@@ -594,6 +595,76 @@ void GetCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
594595
isolate, v8::Null(isolate), names.data(), values.data(), names.size()));
595596
}
596597

598+
static void PathHelpersLazyGetter(Local<v8::Name> name,
599+
const PropertyCallbackInfo<Value>& info) {
600+
Isolate* isolate = info.GetIsolate();
601+
// This getter has no JavaScript function representation and is not
602+
// invoked in the creation context.
603+
// When this getter is invoked in a vm context, the `Realm::GetCurrent(info)`
604+
// returns a nullptr and retrieve the creation context via `this` object and
605+
// get the creation Realm.
606+
Local<Value> receiver_val = info.This();
607+
if (!receiver_val->IsObject()) {
608+
THROW_ERR_INVALID_INVOCATION(isolate);
609+
return;
610+
}
611+
Local<Object> receiver = receiver_val.As<Object>();
612+
Local<Context> context;
613+
if (!receiver->GetCreationContext().ToLocal(&context)) {
614+
THROW_ERR_INVALID_INVOCATION(isolate);
615+
return;
616+
}
617+
Environment* env = Environment::GetCurrent(context);
618+
619+
node::Utf8Value url(isolate, info.Data());
620+
auto file_url = ada::parse(url.ToStringView());
621+
CHECK(file_url);
622+
auto file_path = url::FileURLToPath(env, *file_url);
623+
CHECK(file_path.has_value());
624+
std::string_view ret_view = file_path.value();
625+
626+
node::Utf8Value utf8name(isolate, name);
627+
auto plain_name = utf8name.ToStringView();
628+
if (plain_name == "dirname") {
629+
#ifdef _WIN32
630+
#define PATH_SEPARATOR '\\'
631+
#else
632+
#define PATH_SEPARATOR '/'
633+
#endif
634+
auto index = ret_view.rfind(PATH_SEPARATOR);
635+
CHECK(index != std::string_view::npos);
636+
ret_view.remove_suffix(ret_view.size() - index);
637+
#undef PATH_SEPARATOR
638+
}
639+
Local<Value> ret;
640+
if (!ToV8Value(context, ret_view, isolate).ToLocal(&ret)) {
641+
return;
642+
}
643+
info.GetReturnValue().Set(ret);
644+
}
645+
void InitImportMetaPathHelpers(const FunctionCallbackInfo<Value>& args) {
646+
// target, url, shouldSetDirnameAndFilename, resolve
647+
CHECK_GE(args.Length(), 2);
648+
CHECK(args[0]->IsObject());
649+
CHECK(args[1]->IsString());
650+
651+
Isolate* isolate = args.GetIsolate();
652+
Local<Context> context = isolate->GetCurrentContext();
653+
Environment* env = Environment::GetCurrent(context);
654+
655+
auto target = args[0].As<Object>();
656+
657+
// N.B.: Order is important to keep keys in alphabetical order.
658+
if (target
659+
->SetLazyDataProperty(
660+
context, env->dirname_string(), PathHelpersLazyGetter, args[1])
661+
.IsNothing() ||
662+
target
663+
->SetLazyDataProperty(
664+
context, env->filename_string(), PathHelpersLazyGetter, args[1])
665+
.IsNothing())
666+
return;
667+
}
597668
void SaveCompileCacheEntry(const FunctionCallbackInfo<Value>& args) {
598669
Isolate* isolate = args.GetIsolate();
599670
Local<Context> context = isolate->GetCurrentContext();
@@ -627,6 +698,7 @@ void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data,
627698
SetMethod(isolate, target, "flushCompileCache", FlushCompileCache);
628699
SetMethod(isolate, target, "getCompileCacheEntry", GetCompileCacheEntry);
629700
SetMethod(isolate, target, "saveCompileCacheEntry", SaveCompileCacheEntry);
701+
SetMethod(isolate, target, "setLazyPathHelpers", InitImportMetaPathHelpers);
630702
}
631703

632704
void BindingData::CreatePerContextProperties(Local<Object> target,
@@ -682,6 +754,7 @@ void BindingData::RegisterExternalReferences(
682754
registry->Register(FlushCompileCache);
683755
registry->Register(GetCompileCacheEntry);
684756
registry->Register(SaveCompileCacheEntry);
757+
registry->Register(InitImportMetaPathHelpers);
685758
}
686759

687760
} // namespace modules

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy