Skip to content

Commit c5d4f00

Browse files
committed
src: lazily load internalBinding('uv') and build the errmap lazily
This removes the `internalBinding('uv')` call from the normal bootstrap for now, and avoids building `errmap` by default which expands to a lot of calls into V8.
1 parent 13ae538 commit c5d4f00

File tree

3 files changed

+56
-27
lines changed

3 files changed

+56
-27
lines changed

lib/internal/errors.js

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ const kInfo = Symbol('info');
1515
const messages = new Map();
1616
const codes = {};
1717

18-
const {
19-
errmap,
20-
UV_EAI_NODATA,
21-
UV_EAI_NONAME
22-
} = internalBinding('uv');
2318
const { kMaxLength } = internalBinding('buffer');
2419
const { defineProperty } = Object;
2520

@@ -237,6 +232,24 @@ function getMessage(key, args) {
237232
return util.format.apply(null, args);
238233
}
239234

235+
let uvBinding;
236+
237+
function lazyUv() {
238+
if (!uvBinding) {
239+
uvBinding = internalBinding('uv');
240+
}
241+
return uvBinding;
242+
}
243+
244+
function lazyErrmapGet(name) {
245+
uvBinding = lazyUv();
246+
if (!uvBinding.errmap) {
247+
uvBinding.errmap = uvBinding.getErrorMap();
248+
}
249+
return uvBinding.errmap.get(name);
250+
}
251+
252+
240253
/**
241254
* This creates an error compatible with errors produced in the C++
242255
* function UVException using a context object with data assembled in C++.
@@ -247,7 +260,7 @@ function getMessage(key, args) {
247260
* @returns {Error}
248261
*/
249262
function uvException(ctx) {
250-
const [ code, uvmsg ] = errmap.get(ctx.errno);
263+
const [ code, uvmsg ] = lazyErrmapGet(ctx.errno);
251264
let message = `${code}: ${ctx.message || uvmsg}, ${ctx.syscall}`;
252265

253266
let path;
@@ -303,7 +316,7 @@ function uvException(ctx) {
303316
* @returns {Error}
304317
*/
305318
function uvExceptionWithHostPort(err, syscall, address, port) {
306-
const [ code, uvmsg ] = errmap.get(err);
319+
const [ code, uvmsg ] = lazyErrmapGet(err);
307320
const message = `${syscall} ${code}: ${uvmsg}`;
308321
let details = '';
309322

@@ -421,7 +434,7 @@ function dnsException(code, syscall, hostname) {
421434
if (typeof code === 'number') {
422435
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
423436
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
424-
if (code === UV_EAI_NODATA || code === UV_EAI_NONAME) {
437+
if (code === lazyUv().UV_EAI_NODATA || code === lazyUv().UV_EAI_NONAME) {
425438
code = 'ENOTFOUND'; // Fabricated error name.
426439
} else {
427440
code = lazyInternalUtil().getSystemErrorName(code);

lib/internal/util.js

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ const {
1616
isNativeError
1717
} = internalBinding('types');
1818

19-
const { errmap } = internalBinding('uv');
20-
2119
const noCrypto = !process.versions.openssl;
2220

2321
const experimentalWarnings = new Set();
@@ -250,8 +248,19 @@ function getConstructorOf(obj) {
250248
return null;
251249
}
252250

251+
let uvBinding;
252+
function lazyErrmapGet(name) {
253+
if (!uvBinding) {
254+
uvBinding = internalBinding('uv');
255+
}
256+
if (!uvBinding.errmap) {
257+
uvBinding.errmap = uvBinding.getErrorMap();
258+
}
259+
return uvBinding.errmap.get(name);
260+
}
261+
253262
function getSystemErrorName(err) {
254-
const entry = errmap.get(err);
263+
const entry = lazyErrmapGet(err);
255264
return entry ? entry[0] : `Unknown system error ${err}`;
256265
}
257266

src/uv.cc

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -58,21 +58,10 @@ void ErrName(const FunctionCallbackInfo<Value>& args) {
5858
}
5959

6060

61-
void Initialize(Local<Object> target,
62-
Local<Value> unused,
63-
Local<Context> context,
64-
void* priv) {
65-
Environment* env = Environment::GetCurrent(context);
61+
void GetErrMap(const FunctionCallbackInfo<Value>& args) {
62+
Environment* env = Environment::GetCurrent(args);
6663
Isolate* isolate = env->isolate();
67-
target->Set(env->context(),
68-
FIXED_ONE_BYTE_STRING(isolate, "errname"),
69-
env->NewFunctionTemplate(ErrName)
70-
->GetFunction(env->context())
71-
.ToLocalChecked()).FromJust();
72-
73-
#define V(name, _) NODE_DEFINE_CONSTANT(target, UV_##name);
74-
UV_ERRNO_MAP(V)
75-
#undef V
64+
Local<Context> context = env->context();
7665

7766
Local<Map> err_map = Map::New(isolate);
7867

@@ -90,8 +79,26 @@ void Initialize(Local<Object> target,
9079
UV_ERRNO_MAP(V)
9180
#undef V
9281

93-
target->Set(context, FIXED_ONE_BYTE_STRING(isolate, "errmap"),
94-
err_map).FromJust();
82+
args.GetReturnValue().Set(err_map);
83+
}
84+
85+
void Initialize(Local<Object> target,
86+
Local<Value> unused,
87+
Local<Context> context,
88+
void* priv) {
89+
Environment* env = Environment::GetCurrent(context);
90+
Isolate* isolate = env->isolate();
91+
target->Set(env->context(),
92+
FIXED_ONE_BYTE_STRING(isolate, "errname"),
93+
env->NewFunctionTemplate(ErrName)
94+
->GetFunction(env->context())
95+
.ToLocalChecked()).FromJust();
96+
97+
#define V(name, _) NODE_DEFINE_CONSTANT(target, UV_##name);
98+
UV_ERRNO_MAP(V)
99+
#undef V
100+
101+
env->SetMethod(target, "getErrorMap", GetErrMap);
95102
}
96103

97104
} // anonymous namespace

0 commit comments

Comments
 (0)