Skip to content

Commit

Permalink
src: lazily load internalBinding('uv') and build the errmap lazily
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
joyeecheung committed Dec 28, 2018
1 parent 13ae538 commit c5d4f00
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 27 deletions.
29 changes: 21 additions & 8 deletions lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ const kInfo = Symbol('info');
const messages = new Map();
const codes = {};

const {
errmap,
UV_EAI_NODATA,
UV_EAI_NONAME
} = internalBinding('uv');
const { kMaxLength } = internalBinding('buffer');
const { defineProperty } = Object;

Expand Down Expand Up @@ -237,6 +232,24 @@ function getMessage(key, args) {
return util.format.apply(null, args);
}

let uvBinding;

function lazyUv() {
if (!uvBinding) {
uvBinding = internalBinding('uv');
}
return uvBinding;
}

function lazyErrmapGet(name) {
uvBinding = lazyUv();
if (!uvBinding.errmap) {
uvBinding.errmap = uvBinding.getErrorMap();
}
return uvBinding.errmap.get(name);
}


/**
* This creates an error compatible with errors produced in the C++
* function UVException using a context object with data assembled in C++.
Expand All @@ -247,7 +260,7 @@ function getMessage(key, args) {
* @returns {Error}
*/
function uvException(ctx) {
const [ code, uvmsg ] = errmap.get(ctx.errno);
const [ code, uvmsg ] = lazyErrmapGet(ctx.errno);
let message = `${code}: ${ctx.message || uvmsg}, ${ctx.syscall}`;

let path;
Expand Down Expand Up @@ -303,7 +316,7 @@ function uvException(ctx) {
* @returns {Error}
*/
function uvExceptionWithHostPort(err, syscall, address, port) {
const [ code, uvmsg ] = errmap.get(err);
const [ code, uvmsg ] = lazyErrmapGet(err);
const message = `${syscall} ${code}: ${uvmsg}`;
let details = '';

Expand Down Expand Up @@ -421,7 +434,7 @@ function dnsException(code, syscall, hostname) {
if (typeof code === 'number') {
// FIXME(bnoordhuis) Remove this backwards compatibility nonsense and pass
// the true error to the user. ENOTFOUND is not even a proper POSIX error!
if (code === UV_EAI_NODATA || code === UV_EAI_NONAME) {
if (code === lazyUv().UV_EAI_NODATA || code === lazyUv().UV_EAI_NONAME) {
code = 'ENOTFOUND'; // Fabricated error name.
} else {
code = lazyInternalUtil().getSystemErrorName(code);
Expand Down
15 changes: 12 additions & 3 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ const {
isNativeError
} = internalBinding('types');

const { errmap } = internalBinding('uv');

const noCrypto = !process.versions.openssl;

const experimentalWarnings = new Set();
Expand Down Expand Up @@ -250,8 +248,19 @@ function getConstructorOf(obj) {
return null;
}

let uvBinding;
function lazyErrmapGet(name) {
if (!uvBinding) {
uvBinding = internalBinding('uv');
}
if (!uvBinding.errmap) {
uvBinding.errmap = uvBinding.getErrorMap();
}
return uvBinding.errmap.get(name);
}

function getSystemErrorName(err) {
const entry = errmap.get(err);
const entry = lazyErrmapGet(err);
return entry ? entry[0] : `Unknown system error ${err}`;
}

Expand Down
39 changes: 23 additions & 16 deletions src/uv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,10 @@ void ErrName(const FunctionCallbackInfo<Value>& args) {
}


void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
void GetErrMap(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Isolate* isolate = env->isolate();
target->Set(env->context(),
FIXED_ONE_BYTE_STRING(isolate, "errname"),
env->NewFunctionTemplate(ErrName)
->GetFunction(env->context())
.ToLocalChecked()).FromJust();

#define V(name, _) NODE_DEFINE_CONSTANT(target, UV_##name);
UV_ERRNO_MAP(V)
#undef V
Local<Context> context = env->context();

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

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

target->Set(context, FIXED_ONE_BYTE_STRING(isolate, "errmap"),
err_map).FromJust();
args.GetReturnValue().Set(err_map);
}

void Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
Environment* env = Environment::GetCurrent(context);
Isolate* isolate = env->isolate();
target->Set(env->context(),
FIXED_ONE_BYTE_STRING(isolate, "errname"),
env->NewFunctionTemplate(ErrName)
->GetFunction(env->context())
.ToLocalChecked()).FromJust();

#define V(name, _) NODE_DEFINE_CONSTANT(target, UV_##name);
UV_ERRNO_MAP(V)
#undef V

env->SetMethod(target, "getErrorMap", GetErrMap);
}

} // anonymous namespace
Expand Down

0 comments on commit c5d4f00

Please sign in to comment.