profile
viewpoint
Vse Mozhet Byt vsemozhetbyt Kyiv, Ukraine

lingvoboard/nodereplacer 2

Tool for creating dictionaries

lingvoboard/AsyncLinesReader 1

Node.js script for reading text file line by line.

vsemozhetbyt/gls_sd_conv 1

Скрипт, конвертирующий исходные файлы .gls в словари StarDict и обратно.

vsemozhetbyt/vsemozhetbyt.github.io 1

Some vsemozhetbyt's varia

vsemozhetbyt/AsyncLinesReader 0

Node.js script for reading text file line by line.

vsemozhetbyt/eslint 0

A fully pluggable tool for identifying and reporting on patterns in JavaScript

vsemozhetbyt/javascript 0

JavaScript Style Guide

vsemozhetbyt/node 0

Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:

vsemozhetbyt/nodejs.org 0

The Node.js website.

vsemozhetbyt/ohm 0

A library and language for building parsers, interpreters, compilers, etc.

startedyahoo/serialize-javascript

started time in 5 days

delete branch vsemozhetbyt/node

delete branch : doc-stream-pipeline-signature

delete time in 5 days

startednemtsov/json-mask

started time in 6 days

issue commentpegjs/pegjs

Confusing error message for failed positive lookahead expression

Sorry, I am a bit clumsy, as I've just started to learn the PEG.

BTW, I've tried about dozen other parser generators as a newbie and this seems to be my favorite now)

vsemozhetbyt

comment created time in 8 days

issue commentpegjs/pegjs

Confusing error message for failed positive lookahead expression

I would say the message is confusing because Expected and Found is the same in this case, Maybe it would be useful to mention lookahead expressions if they are the cause of failure. Forbidden repetitions are just a case, compare this without a forbidden repetition.

const pegResult = require('pegjs/')
  .generate('root = ("a" / "b" !"a")+')
  .parse('aba');

console.log(pegResult);
peg$SyntaxError: Expected "a", "b", or end of input but "b" found.
vsemozhetbyt

comment created time in 8 days

issue commentpegjs/pegjs

Confusing error message for failed positive lookahead expression

I would rather say: "I have a rule where abcc is forbidden because c is disallowed as a lookahead in a rule about abc. When it complains, I'd prefer to hear about ccbut I only hear about c." Otherwise, the error message is not useful or clear: Expected "c" but "c" found.

vsemozhetbyt

comment created time in 8 days

issue openedpegjs/pegjs

Confusing error message for failed positive lookahead expression

Issue type

  • Bug Report: yes
  • Feature Request: maybe
  • Question: no
  • Not an issue: no

Prerequisites

  • Can you reproduce the issue?: yes
  • Did you search the repository issues?: yes
  • Did you check the forums?: no (cannot find the URL)
  • Did you perform a web search (google, yahoo, etc)?: no (seems unneeded)

Description

Error message for failed positive lookahead expression does not mention this expression

Steps to Reproduce

Consider a rule where double hyphens are not allowed:

const pegResult = require('pegjs/')
  .generate('root = ([^-] / "-" !"-")+')
  .parse('a-b--c');

console.log(pegResult);

Expected behavior:

Something like: peg$SyntaxError: Expected "-" !"-", [^\-], or end of input but "--" found.

Actual behavior:

peg$SyntaxError: Expected "-", [^\-], or end of input but "-" found.

Software

  • PEG.js: 0.11.0-master.b7b87ea
  • Node.js: 14.0.0-v8-canary202002123546737a75
  • NPM or Yarn: npm 6.13.7
  • Browser: -
  • OS: Windows 7 x64
  • Editor: -

created time in 9 days

issue commentpegjs/pegjs

Full Unicode support, namely for codepoints outside the BMP

It seems the . (dot character) expression also needs Unicode mode. Compare:

const string = '-🐎-👱-';

const symbols = (string.match(/./gu));
console.log(JSON.stringify(symbols, null, '  '));

const pegResult = require('pegjs/')
                 .generate('root = .+')
                 .parse(string);
console.log(JSON.stringify(pegResult, null, '  '));

Output:

[
  "-",
  "🐎",
  "-",
  "👱",
  "-"
]
[
  "-",
  "\ud83d",
  "\udc0e",
  "-",
  "\ud83d",
  "\udc71",
  "-"
]
doersino

comment created time in 9 days

startedharc/ohm

started time in 11 days

PR opened harc/ohm

Fix possible typos in doc/api-reference.md
+1 -1

0 comment

1 changed file

pr created time in 11 days

push eventvsemozhetbyt/ohm

Vse Mozhet Byt

commit sha 22c75822925ab45d1800f108f58ba2b1d20e1239

Fix possible typos in doc/api-reference.md

view details

push time in 11 days

PR opened harc/ohm

Fix possile typo in doc/syntax-reference.md
+1 -1

0 comment

1 changed file

pr created time in 11 days

push eventvsemozhetbyt/ohm

Vse Mozhet Byt

commit sha 2520a171dc2be9887712b7bb1fc546a0ed2e8073

Fix possile typo in doc/syntax-reference.md

view details

push time in 11 days

fork vsemozhetbyt/ohm

A library and language for building parsers, interpreters, compilers, etc.

fork in 11 days

delete branch vsemozhetbyt/apg-js2

delete branch : patch-1

delete time in 12 days

startedDmitrySoshnikov/syntax

started time in 12 days

startedgajus/scalpel

started time in 12 days

pull request commentnodejs/node

doc: update stream.pipeline() signature

Sorry, I did not even consider ... may mean an empty list. So maybe there are some more readers like me)

vsemozhetbyt

comment created time in 13 days

PR opened nodejs/node

doc: update stream.pipeline() signature
Checklist
  • [x] make -j4 test (UNIX), or vcbuild test (Windows) passes
  • [x] documentation is changed or added
  • [x] commit message follows commit guidelines

The ...transforms parameter seems optional.

Refs: https://github.com/nodejs/node/blob/087583741716969edf12874d4f1f1774de581f50/lib/internal/streams/pipeline.js#L130-L132

Refs: https://github.com/nodejs/node/blob/e559842188f541b884abff2ffad4d2d3e1b841a6/doc/api/stream.md#streams-compatibility-with-async-generators-and-async-iterators (see the last example)

+1 -1

0 comment

1 changed file

pr created time in 13 days

create barnchvsemozhetbyt/node

branch : doc-stream-pipeline-signature

created branch time in 13 days

fork vsemozhetbyt/node

Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:

https://nodejs.org/

fork in 13 days

delete branch vsemozhetbyt/regexp-to-ast

delete branch : patch-1

delete time in 13 days

fork vsemozhetbyt/node-1

Node.js JavaScript runtime :sparkles::turtle::rocket::sparkles:

https://nodejs.org/

fork in 13 days

startedlirantal/nodejs-cli-apps-best-practices

started time in 14 days

startedno-context/moo

started time in 14 days

startedkach/nearley

started time in 14 days

issue closednodejs/node-v8

last node-v8 REPL issue

  • Version: v14.0.0-v8-canary2020011995087de57b
  • Platform: Windows 7 x64
  • Subsystem: REPL

This is OK in 13.6.0 and v14.0.0-nightly20200119b318926634, but throws in v14.0.0-v8-canary2020011995087de57b:

> const foo = 1;
Uncaught SyntaxError: Identifier 'foo' has already been declared

It seems all the intermediate evaluations are saved in the context. See:

> let abc
Uncaught SyntaxError: Identifier 'abc' has already been declared
> z
Uncaught ReferenceError: z is not defined
> a
undefined
> ab
undefined
> abc
undefined
>

closed time in 14 days

vsemozhetbyt

issue commentnodejs/node-v8

last node-v8 REPL issue

Seems fixed in 14.0.0-v8-canary202002123546737a75. Thank you.

vsemozhetbyt

comment created time in 14 days

PR opened bd82/regexp-to-ast

Update examples that seem outdated
+2 -2

0 comment

1 changed file

pr created time in 15 days

push eventvsemozhetbyt/regexp-to-ast

Vse Mozhet Byt

commit sha 6c9896164af65f798bdf1159e780bf4da3955718

Update examples that seem outdated

view details

push time in 15 days

PR opened ldthomas/apg-js2

Fix outdated URL

Refs: https://github.com/ldthomas/apg-js2/commit/c3bcea172e94dced616279c8bdbdad41e54a0464 Refs: https://github.com/ldthomas/apg-js2-api/commit/9333c822c6b89be83bf0d210c5004baa1ed82098

+1 -1

0 comment

1 changed file

pr created time in 16 days

push eventvsemozhetbyt/apg-js2

Vse Mozhet Byt

commit sha 27e4fb745e1857b11cf5781a5fe5b034dadfa675

Fix outdated URL Refs: https://github.com/ldthomas/apg-js2/commit/c3bcea172e94dced616279c8bdbdad41e54a0464 Refs: https://github.com/ldthomas/apg-js2-api/commit/9333c822c6b89be83bf0d210c5004baa1ed82098

view details

push time in 16 days

fork vsemozhetbyt/apg-js2

JavaScript APG Version 2.0. APG is an ABNF Parser Generator. It generates recursive-descent parsers from a superset of ABNF grammars.

fork in 16 days

PR opened lezer-parser/website

Update tree.iterate() examples accordin last API

See https://lezer.codemirror.net/docs/ref/#tree.Subtree.iterate

+5 -5

0 comment

1 changed file

pr created time in 16 days

push eventvsemozhetbyt/website

Vse Mozhet Byt

commit sha a527d5a272976dbd42d7f7d54287183ad2d4da8a

Update tree.iterate() examples accordin last API See https://lezer.codemirror.net/docs/ref/#tree.Subtree.iterate

view details

push time in 16 days

fork vsemozhetbyt/website

Sources for https://lezer.codemirror.net

fork in 16 days

startedmgechev/tiny-compiler

started time in 17 days

startedmgechev/javascript-algorithms

started time in 17 days

startedCuadrix/puppeteer-page-proxy

started time in 18 days

startedjcoglan/canopy

started time in 18 days

startedaaditmshah/lexer

started time in 18 days

starteddchester/jsonpath

started time in 19 days

startedtc39/proposal-logical-assignment

started time in 20 days

issue closednongeneric/lsd2dsl

some issues in lsd2dsl-0.5.0

Sorry, not sure if the same issues present in the previous versions.

  1. Source files get .dsl. added before their extensions: dictionary.dsl.ann, dictionary.dsl.bmp, dictionary.dsl.dsl.

  2. If a dictionary has assets (images), they are extracted to the folder of the lsd2dsl-qtgui.exe, not to the selected folder for other source files.

Thank you for the great tool!

closed time in a month

vsemozhetbyt

issue commentnongeneric/lsd2dsl

some issues in lsd2dsl-0.5.0

Thank you!

vsemozhetbyt

comment created time in a month

issue openednongeneric/lsd2dsl

some issues in lsd2dsl-0.5.0

Sorry, not sure if the same issues present in the previous versions.

  1. Source files get .dsl. added before their extensions: dictionary.dsl.ann, dictionary, dictionary.dsl.bmp, dictionary..dsl.dsl.

  2. If a dictionary has assets (images), they are extracted to the folder of the lsd2dsl-qtgui.exe, not to the selected folder for other source files.

Thank you for the great tool!

created time in a month

startedgajus/puppeteer-proxy

started time in a month

startedmicrosoft/playwright

started time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

In Chrome, this seems fixed at least since V8 8.1.281.

vsemozhetbyt

comment created time in a month

fork vsemozhetbyt/goldendict

A feature-rich dictionary lookup program, supporting multiple dictionary formats (StarDict/Babylon/Lingvo/Dictd) and online dictionaries, featuring perfect article rendering with the complete markup, illustrations and other content retained, and allowing you to type in words without any accents or correct case.

http://goldendict.org/

fork in a month

startedilinsky/xpath.js

started time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

Is this the same issue? https://bugs.chromium.org/p/chromium/issues/detail?id=1043151

vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

Also notable: Google Chrome 81.0.4029.3 Dev with V8 8.1.187:

foo
VM46:1 Uncaught ReferenceError: foo is not defined
    at <anonymous>:1:1
(anonymous) @ VM46:1
const foo = 1
undefined 

Google Chrome 81.0.4031.0 canary with V8 8.1.218:

foo
VM36:1 Uncaught ReferenceError: foo is not defined
    at <anonymous>:1:1
(anonymous) @ VM36:1
const foo = 1
VM68:1 Uncaught SyntaxError: Identifier 'foo' has already been declared 

It seems something happens between V8 8.1.187 and V8 8.1.218 (the last node-v8 canary has 8.1.222).

vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

Welcome to Node.js v14.0.0-v8-canary2020011995087de57b.
Type ".help" for more information.
> bar
Uncaught ReferenceError: bar is not defined
> const bar = 1
Uncaught SyntaxError: Identifier 'bar' has already been declared
>
vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

The same in 13.6.0 and v14.0.0-nightly20200119b318926634:

Welcome to Node.js v13.6.0.
Type ".help" for more information.
> foo
Uncaught ReferenceError: foo is not defined
> const foo = 1
undefined
>
Welcome to Node.js v14.0.0-nightly20200119b318926634.
Type ".help" for more information.
> foo
Uncaught ReferenceError: foo is not defined
> const foo = 1
undefined
>
vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

But i do not redefine the const:

Welcome to Node.js v14.0.0-v8-canary2020011995087de57b.
Type ".help" for more information.
> foo
Uncaught ReferenceError: foo is not defined
> const foo = 1
Uncaught SyntaxError: Identifier 'foo' has already been declared
vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

No:

Welcome to Node.js v14.0.0-v8-canary2020011995087de57b.
Type ".help" for more information.
> foo
Uncaught ReferenceError: foo is not defined
>
vsemozhetbyt

comment created time in a month

issue commentnodejs/node-v8

last node-v8 REPL issue

> const foo = 1;
Uncaught SyntaxError: Identifier 'foo' has already been declared
> foo
1
>
vsemozhetbyt

comment created time in a month

issue openednodejs/node-v8

last node-v8 REPL issue

  • Version: v14.0.0-v8-canary2020011995087de57b
  • Platform: Windows 7 x64
  • Subsystem: REPL

This is OK in 13.6.0 and v14.0.0-nightly20200119b318926634, but throws in v14.0.0-v8-canary2020011995087de57b:

> const foo = 1;
Uncaught SyntaxError: Identifier 'foo' has already been declared

It seems all the intermediate evaluations are saved in the context. See:

> let abc
Uncaught SyntaxError: Identifier 'abc' has already been declared
> z
Uncaught ReferenceError: z is not defined
> a
undefined
> ab
undefined
> abc
undefined
>

created time in a month

startedprzemyslawpluta/node-youtube-dl

started time in a month

startedSAP/chevrotain

started time in 2 months

startedclsid2/mpc-hc

started time in 2 months

startedoguzhaninan/Buka

started time in 2 months

issue opened30-seconds/30-seconds-web

Order for cards

Previously, in GitHub README.md or in the site, the snippets were sorted alphabetically. That was handy for casual consecutive reading. Currently, we have only the site with cards in a hardly understandable order. Can the alphabetical order be restored?

created time in 2 months

issue commentpuppeteer/puppeteer

Page.Content freezes without error after running 101 times

@Mahanchello Try this:

await page.evaluate(selector =>
  Boolean(document.querySelector(selector)),
  sel.sub.confirmBtn
);
rainbowhat

comment created time in 2 months

issue opened30-seconds/30-seconds-of-code

Order for cards

Previously, in GitHub README.md or in the site, the snippets were sorted alphabetically. That as handy for casual consecutive reading. Currently, we have only the site with cards in a hardly understandable order. Can the alphabetical order be restored?

created time in 2 months

startedJordanirabor/nlp-node-natural-article

started time in 3 months

issue commentpuppeteer/puppeteer

How can I get element attribute without evaluate function

forEach() is not async, it runs all the functions at once and does not wait for them. Try for...of loop for the same.

JaLe29

comment created time in 3 months

issue commentpuppeteer/puppeteer

cannot access window.document on exposed Function

@adamchenwei Sorry, I do not know. page.evaluate() seems for me to be the simplest way, jsHandle API is more complicated.

perrefe

comment created time in 3 months

Pull request review commentnodejs/node

src,doc: add C++ internals documentation

+# Node.js C++ codebase++Hi! 👋 You’ve found the C++ code backing Node.js. This README aims to help you+get started working on it and document some idioms you may encounter while+doing so.++## Coding style++Node.js has a document detailing its [C++ coding style][]+that can be helpful as a reference for stylistic issues.++## V8 API documentation++A lot of the Node.js codebase is around what the underlying JavaScript engine,+V8, provides through its API for embedders. Knowledge of this API can also be+useful when working with native addons for Node.js written in C++, although for+new projects [N-API][] is typically the better alternative.++V8 does not provide much public API documentation beyond what is+available in its C++ header files, most importantly `v8.h`, which can be+accessed online in the following locations:++* On GitHub: [`v8.h` in Node.js master][]+* On GitHub: [`v8.h` in V8 master][]+* On the Chromium project’s Code Search application: [`v8.h` in Code Search][]++V8 also provides an [introduction for V8 embedders][],+which can be useful for understanding some of the concepts it uses in its+embedder API.++Important concepts when using V8 are the ones of [`Isolate`][]s and+[JavaScript value handles][].++## libuv API documentation++The other major dependency of Node.js is [libuv][], providing+the [event loop][] and other operation system abstractions to Node.js.++There is a [reference documentation for the libuv API][].++## Helpful concepts++A number of concepts are involved in putting together Node.js on top of V8 and+libuv. This section aims to explain some of them and how they work together.++<a id="isolate"></a>+### `Isolate`++The `v8::Isolate` class represents a single JavaScript engine instance, in+particular a set of JavaScript objects that can refer to each other+(the “heap”).++The `v8::Isolate` is often passed to other V8 API functions, and provides some+APIs for managing the behaviour of the JavaScript engine or querying about its+current state or statistics such as memory usage.++V8 APIs are not thread-safe unless explicitly specified. In a typical Node.js+application, the main thread and any `Worker` threads each have one `Isolate`,+and JavaScript objects from one `Isolate` cannot refer to objects from+another `Isolate`.++Garbage collection, as well as other operations that affect the entire heap,+happen on a per-`Isolate` basis.++Typical ways of accessing the current `Isolate` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `args.GetIsolate()`.+* Given a [`Context`][], using `context->GetIsolate()`.+* Given a [`Environment`][], using `env->isolate()`.++### V8 JavaScript values++V8 provides classes that mostly correspond to JavaScript types; for example,+`v8::Value` is a class representing any kind of JavaScript type, with+subclasses such as `v8::Number` (which in turn has subclasses like `v8::Int32`),+`v8::Boolean` or `v8::Object`. Most types are represented by subclasses+of `v8::Object`, e.g. `v8::Uint8Array` or `v8::Date`.++<a id="internal-fields"></a>+### Internal fields++V8 provides the ability to store data in so-called “internal fields” inside+`v8::Object`s that were created as instances of C++-backed classes. The number+of fields needs to be defined when creating that class.++Both JavaScript values and `void*` pointers may be stored in such fields.+In most native Node.js objects, the first internal field is used to store a+pointer to a [`BaseObject`][] subclass, which then contains all relevant+information associated with the JavaScript object.++The most typical way of working internal fields are:++* `obj->InternalFieldCount()` to look up the number of internal fields for an+  object (`0` for regular JavaScript objects).+* `obj->GetInternalField(i)` to get a JavaScript value from an internal field.+* `obj->SetInternalField(i, v)` to store a JavaScript value in an+  internal field.+* `obj->GetAlignedPointerFromInternalField(i)` to get a `void*` pointer from an+  internal field.+* `obj->SetAlignedPointerInInternalField(i, p)` to store a `void*` pointer in an+  internal field.++[`Context`][]s provide the same feature under the name “embedder data”.++<a id="js-handles"></a>+### JavaScript value handles++All JavaScript values are accessed through the V8 API through so-called handles,+of which there are two types: [`Local`][]s and [`Global`][]s.++<a id="local-handles"></a>+#### `Local` handles++A `v8::Local` handle is a temporary pointer to a JavaScript object, where+“temporary” usually means that is no longer needed after the current function+is done executing. `Local` handles can only be allocated on the C++ stack.++Most of the V8 API uses `Local` handles to work with JavaScript values or return+them from functions.++Whenever a `Local` handle is created, a `v8::HandleScope` or+`v8::EscapableHandleScope` object must exist on the stack. The `Local` is then+added to that scope and deleted along with it.++When inside a [binding function][], a `HandleScope` already exists outside of+it, so there is no need to explicitly create one.++`EscapableHandleScope`s can be used to allow a single `Local` handle to be+passed to the outer scope. This is useful when a function returns a `Local`.++The following JavaScript and C++ functions are mostly equivalent:++```js+function getFoo(obj) {+  return obj.foo;+}+```++```c+++v8::Local<v8::Value> GetFoo(v8::Local<v8::Context> context,+                            v8::Local<v8::Object> obj) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::EscapableHandleScope handle_scope(isolate);++  // The 'foo_string' handle cannot be returned from this function because+  // it is not “escaped” with `.Escape()`.+  v8::Local<v8::String> foo_string =+      v8::String::NewFromUtf8(isolate,+                              "foo",+                              v8::NewStringType::kNormal).ToLocalChecked();++  v8::Local<v8::Value> return_value;+  if (obj->Get(context, foo_string).ToLocal(&return_value)) {+    return handle_scope.Escape(return_value);+  } else {+    // There was a JS exception! Handle it somehow.+    return v8::Local<v8::Value>();+  }+}+```++See [exception handling][] for more information about the usage of `.To()`,+`.ToLocalChecked()`, `v8::Maybe` and `v8::MaybeLocal` usage.++##### Casting local handles++If it is known that a `Local<Value>` refers to a more specific type, it can+be cast to that type using `.As<...>()`:++```c+++v8::Local<v8::Value> some_value;+// CHECK() is a Node.js utilitity that works similar to assert().+CHECK(some_value->IsUint8Array());+v8::Local<v8::Uint8Array> as_uint8 = some_value.As<v8::Uint8Array>();+```++Generally, using `val.As<v8::X>()` is only valid if `val->IsX()` is true, and+failing to follow that rule may lead to crashes.++##### Detecting handle leaks++If it is expected that no `Local` handles should be created within a given+scope unless explicitly within a `HandleScope`, a `SealHandleScope` can be used.++For example, there is a `SealHandleScope` around the event loop, forcing+any functions that are called from the event loop and want to run or access+JavaScript code to create `HandleScope`s.++<a id="global-handles"></a>+#### `Global` handles++A `v8::Global` handle (sometimes also referred to by the name of its parent+class `Persistent`, although use of that is discouraged in Node.js) is a+reference to a JavaScript object that can remain active as long as the engine+instance is active.++Global handles can be either strong or weak. Strong global handles are so-called+“GC roots”, meaning that they will keep the JavaScript object they refer to+alive even if no other objects refer to them. Weak global handles do not do+that, and instead optionally call a callback when the object they refer to+is garbage-collected.++```c+++v8::Global<v8::Object> reference;++void StoreReference(v8::Isolate* isolate, v8::Local<v8::Object> obj) {+  // Create a strong reference to `obj`.+  reference.Reset(isolate, obj);+}++// Must be called with a HandleScope around it.+v8::Local<v8::Object> LoadReference(v8::Isolate* isolate) {+  return reference.Get(isolate);+}+```++##### `Eternal` handles++`v8::Eternal` handles are a special kind of handles similar to `v8::Global`+handles, with the exception that the values they point to are never+garbage-collected while the JavaScript Engine instance is alive, even if+the `v8::Eternal` itself is destroyed at some point. This type of handle+is rarely used.++<a id="context"></a>+### `Context`++JavaScript allows multiple global objects and sets of built-in JavaScript+objects (like the `Object` or `Array` functions) to coexist inside the same+heap. Node.js exposes this ability through the [`vm` module][].++V8 refers to each of these global objects and their associated builtins as a+`Context`.++Currently, in Node.js there is one main `Context` associated with an+[`Environment`][] instance, and most Node.js features will only work inside+that context. (The only exception at the time of writing are+[`MessagePort`][] objects.) This restriction is not inherent to the design of+Node.js, and a sufficiently committed person could restructure Node.js to+provide built-in modules inside of `vm.Context`s.++Often, the `Context` is passed around for [exception handling][].+Typical ways of accessing the current `Environment` in the Node.js code are:++* Given an [`Isolate`][], using `isolate->GetCurrentContext()`.+* Given an [`Environment`][], using `env->context()` to get the `Environment`’s+  main context.++<a id="event-loop"></a>+### Event loop++The main abstraction for an event loop inside Node.js is the `uv_loop_t` struct.+Typically, there is one event loop per thread. This includes not only the main+thread and Workers, but also helper threads that may occasionally be spawned+in the course of running a Node.js program.++The current event loop can be accessed using `env->event_loop()` given an+[`Environment`][] instance. The restriction of using a single event loop+is not inherent to the design of Node.js, and a sufficiently committed person+could restructure Node.js to provide e.g. the ability to run parts of Node.js+inside an event loop separate from the active thread’s event loop.++<a id="environment"></a>+### `Environment`++Node.js instances are represented by the `Environment` class.++Currently, every `Environment` class is associated with:++* One [event loop][]+* One [`Isolate`][]+* One main [`Context`][]++The `Environment` class contains a large number of different fields for+different Node.js modules, for example a libuv timer for `setTimeout()` or+the memory for a `Float64Array` that the `fs` module uses for storing data+returned from a `fs.stat()` call.++It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]+instances.++Typical ways of accessing the current `Environment` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `Environment::GetCurrent(args)`.+* Given a [`BaseObject`][], using `env()` or `self->env()`.+* Given a [`Context`][], using `Environment::GetCurrent(context)`.+  This requires that `context` has been associated with the `Environment`+  instance, e.g. is the main `Context` for the `Environment` or one of its+  `vm.Context`s.+* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks+  up the current [`Context`][] and then uses that.++<a id="isolate-data"></a>+### `IsolateData`++Every Node.js instance ([`Environment`][]) is associated with one `IsolateData`+instance that contains information about or associated with a given+[`Isolate`][].++#### String table++`IsolateData` contains a list of strings that can be quickly accessed+inside Node.js code, e.g. given an `Environment` instance `env` the JavaScript+string “name” can be accessed through `env->name_string()` without actually+creating a new JavaScript string.++### Platform++Every process that uses V8 has a `v8::Platform` instance that provides some+functionalities to V8, most importantly the ability to schedule work on+background threads.++Node.js provides a `NodePlatform` class that implements the `v8::Platform`+interface and uses libuv for providing background threading abilities.++The platform can be accessed through `isolate_data->platform()` given an+[`IsolateData`][] instance, although that only works when:++* The current Node.js instance was not started by an embedder; or+* The current Node.js instance was started by an embedder whose `v8::Platform`+  implementation also implement’s the `node::MultiIsolatePlatform` interface+  and who passed this to Node.js.++<a id="binding-functions"></a>+### Binding functions++C++ functions exposed to JS follow a specific signature. The following example+is from `node_util.cc`:++```c+++void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {+  CHECK(args[0]->IsArrayBufferView());+  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());+}+```++(Namespaces are usually omitted through the use of `using` statements in the+Node.js source code.)++`args[n]` is a `Local<Value>` that represents the n-th argument passed to the+function. `args.This()` is the `this` value inside this function call.+`args.Holder()` is equivalent to `args.This()` in all use cases inside of+Node.js.++`args.GetReturnValue()` is a placeholder for the return value of the function,+and provides a `.Set()` method that can be called with a boolean, integer,+floating-point number or a `Local<Value>` to set the return value.++Node.js provides various helpers for building JS classes in C++ and/or attaching+C++ functions to the exports of a built-in module:++```c+++void Initialize(Local<Object> target,+                Local<Value> unused,+                Local<Context> context,+                void* priv) {+  Environment* env = Environment::GetCurrent(context);++  env->SetMethod(target, "getaddrinfo", GetAddrInfo);+  env->SetMethod(target, "getnameinfo", GetNameInfo);++  // 'SetMethodNoSideEffect' means that debuggers can safely execute this+  // function for e.g. previews.+  env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP);++  // ... more code ...++  // Building the `ChannelWrap` class for JS:+  Local<FunctionTemplate> channel_wrap =+      env->NewFunctionTemplate(ChannelWrap::New);+  // Allow for 1 internal field, see `BaseObject` for details on this:+  channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);+  channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));++  // Set various methods on the class (i.e. on the prototype):+  env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);+  env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);+  // ...+  env->SetProtoMethod(channel_wrap, "querySoa", Query<QuerySoaWrap>);+  env->SetProtoMethod(channel_wrap, "getHostByAddr", Query<GetHostByAddrWrap>);++  env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers);++  Local<String> channel_wrap_string =+      FIXED_ONE_BYTE_STRING(env->isolate(), "ChannelWrap");+  channel_wrap->SetClassName(channel_wrap_string);+  target->Set(env->context(), channel_wrap_string,+              channel_wrap->GetFunction(context).ToLocalChecked()).Check();+}++// Run the `Initialize` function when loading this module through+// `internalBinding('cares_wrap')` in Node.js’s built-in JavaScript code:+NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, Initialize)+```++<a id="exception-handling"></a>+### Exception handling++The V8 engine provides multiple features to work with JavaScript exceptions,+as C++ exceptions are disabled inside of Node.js:++#### Maybe types++V8 provides the `v8::Maybe<T>` and `v8::MaybeLocal<T>` types, typically used+as return values from API functions that can run JavaScript code and therefore+can throw exceptions.++Conceptually, the idea is that every `v8::Maybe<T>` is either empty (checked+through `.IsNothing()`) or holds a value of type `T` (checked through+`.IsJust()`). If the `Maybe` is empty, then a JavaScript exception is pending.+A typical way of accessing the value is using the `.To()` function, which+returns a boolean indicating success of the operation (i.e. the `Maybe` not+being empty) and taking a pointer to a `T` to store the value if there is one.++##### Checked conversion++`maybe.Check()` can be used to assert that the maybe is not empty, i.e. crash+the process otherwise. `maybe.FromJust()` (aka `maybe.ToChecked()`) can be used+to access the value and crash the process if it is not set.++This should only be performed if it is actually sure that the operation has+not failed. A lot of Node.js’s source code does **not** follow this rule, and+can be brought to crash through this.++##### MaybeLocal++`v8::MaybeLocal<T>` is a variant of `v8::Maybe<T>` that is either empty or+holds a value of type `Local<T>`. It has methods that perform the same+operations as the methods of `v8::Maybe`, but with different names:++| `Maybe`                | `MaybeLocal`                    |+| ---------------------- | ------------------------------- |+| `maybe.IsNothing()`    | `maybe_local.IsEmpty()`         |+| `maybe.IsJust()`       | –                               |+| `maybe.To(&value)`     | `maybe_local.ToLocal(&local)`   |+| `maybe.ToChecked()`    | `maybe_local.ToLocalChecked()`  |+| `maybe.FromJust()`     | `maybe_local.ToLocalChecked()`  |+| `maybe.Check()`        | –                               |+| `v8::Nothing<T>()`     | `v8::MaybeLocal<T>()`           |+| `v8::Just<T>(value)`   | `v8::MaybeLocal<T>(value)`      |++##### Handling empty `Maybe`s++Usually, the best approach to encountering an empty `Maybe` is to just return+from the current function as soon as possible, and let execution in JavaScript+land resume. If the empty `Maybe` is encountered inside a nested function,+is may be a good idea to use a `Maybe` or `MaybeLocal` for the return type+of that function and pass information about pending JavaScript exceptions along+that way.++Generally, when an empty `Maybe` is encountered, it is not valid to attempt+to perform further calls to APIs that return `Maybe`s.++A typical pattern for dealing with APIs that return `Maybe` and `MaybeLocal` is+using `.ToLocal()` and `.To()` and returning early in case there is an error:++```c+++// This could also return a v8::MaybeLocal<v8::Number>, for example.+v8::Maybe<double> SumNumbers(v8::Local<v8::Context> context,+                             v8::Local<v8::Array> array_of_integers) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::HandleScope handle_scope(isolate);++  double sum = 0;++  for (uint32_t i = 0; i < array_of_integers->Length(); i++) {+    v8::Local<v8::Value> entry;+    if (array_of_integers->Get(context, i).ToLocal(&entry)) {+      // Oops, we might have hit a getter that throws an exception!+      // It’s better to not continue return an empty (“nothing”) Maybe.+      return v8::Nothing<double>();+    }++    if (!entry->IsNumber()) {+      // Let’s just skip any non-numbers. It would also be reasonable to throw+      // an exception here, e.g. using the error system in src/node_errors.h,+      // and then to return an empty Maybe again.+      continue;+    }++    // This cast is valid, because we’ve made sure it’s really a number.+    v8::Local<v8::Number> entry_as_number = entry.As<v8::Number>();++    sum += entry_as_number->Value();+  }++  return v8::Just(sum);+}++// Function that is exposed to JS:+void SumNumbers(const v8::FunctionCallbackInfo<v8::Value>& args) {+  // This will crash if the first argument is not an array. Let’s assume we+  // have performed type checking in a JavaScript wrapper function.+  CHECK(args[0]->IsArray());++  double sum;+  if (!SumNumbers(args.GetIsolate()->GetCurrentContext(),+                  args[0].As<v8::Array>()).To(&sum)) {+    // Nothing to do, we can just return directly to JavaScript.+    return;+  }++  args.GetReturnValue().Set(sum);+}+```++#### TryCatch++If there is a need to catch JavaScript exceptions in C++, V8 provides the+`v8::TryCatch` type for doing so, which we wrap into our own+`node::errors::TryCatchScope` in Node.js. The latter has the additional feature+of providing the ability to shut down the program in the typical Node.js way+(printing the exception + stack trace) if an exception is caught.++<a id="libuv-handles-and-requests"></a>+### libuv handles and requests++Two central concepts when working with libuv are handles and requests.++Handles are subclasses of the `uv_handle_t` “class”, and generally refer to+long-lived objects that can emit events multiple times, such as network sockets+or file system watchers.++In Node.js, handles are often managed through a [`HandleWrap`][] subclass.++Requests are one-time asynchronous function calls on the event loop, such as+file system requests or network write operations, that either succeed or fail.++In Node.js, requests are often managed through a [`ReqWrap`][] subclass.++### Environment cleanup++When a Node.js [`Environment`][] is destroyed, it generally needs to clean up+any resources owned by it, e.g. memory or libuv requests/handles.++<a id="cleanup-hooks"></a>+#### Cleanup hooks++Cleanup hooks are provided that run before the [`Environment`][]+is destroyed. They can be added and removed through by using+`env->AddCleanupHook(callback, hint);` and+`env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint`+argument.++Inside these cleanup hooks, new asynchronous operations *may* be started on the+event loop, although ideally that is avoided as much as possible.++Every [`BaseObject`][] has its own cleanup hook that deletes it. For+[`ReqWrap`][] and [`HandleWrap`][] instances, cleanup of the associated libuv+objects is performed automatically, i.e. handles are closed and requests+are cancelled if possible.++#### Closing libuv handles++If a libuv handle is not managed through a [`HandleWrap`][] instance,+it needs to be closed explicitly. Do not use `uv_close()` for that, but rather+`env->CloseHandle()`, which works the same way but keeps track of the number+of handles that are still closing.++#### Closing libuv requests++There is no way to abort libuv requests in general. If a libuv request is not+managed through a [`ReqWrap`][] instance, the+`env->IncreaseWaitingRequestCounter()` and+`env->DecreaseWaitingRequestCounter()` functions need to be used to keep track+of the number of active libuv requests.++#### Calling into JavaScript++Calling into JavaScript is not allowed during cleanup. Worker threads explicitly+forbid this during their shutdown sequence, but the main thread does not for+backwards compatibility reasons.++When calling into JavaScript without using [`MakeCallback()`][], check the+`env->can_call_into_js()` flag and do not proceed if it is set to `false`.++## Classes associated with JavaScript objects++### `MemoryRetainer`++A large number of classes in the Node.js C++ codebase refer to other objects.+The `MemoryRetainer` class is a helper for annotating C++ classes with+information that can be used by the heap snapshot builder in V8, so that+memory retained by C++ can be tracked in V8 heap snapshots captured in+Node.js applications.++Inheriting from the `MemoryRetainer` class enables objects (both from JavaScript+and C++) to refer to instances of that class, and in turn enables that class+to point to other objects as well, including native C++ types+such as `std::string` and track their memory usage.++This can be useful for debugging memory leaks.++The [`memory_retainer.h`][] header file explains how to use this class.++<a id="baseobject"></a>+### `BaseObject`++A frequently recurring situation is that a JavaScript object and a C++ object+need to be tied together. `BaseObject` is the main abstraction for that in+Node.js, and most classes that are associated with JavaScript objects are+subclasses of it. It is defined in [`base_object.h`][].++Every `BaseObject` is associated with one [`Environment`][] and one+`v8::Object`. The `v8::Object` needs to have at least one [internal field][]+that is used for storing the pointer to the C++ object. In order to ensure this,+the V8 `SetInternalFieldCount()` function is usually used when setting up the+class from C++.++The JavaScript object can be accessed as a `v8::Local<v8::Object>` by using+`self->object()`, given a `BaseObject` named `self`.++Accessing a `BaseObject` from a `v8::Local<v8::Object>` (frequently that is+`args.This()` or `args.Holder()` in a [binding function][]) can be done using+the `Unwrap<T>(obj)` function, where `T` is a subclass of `BaseObject`.+A helper for this is the `ASSIGN_OR_RETURN_UNWRAP` macro that returns from the+current function if unwrapping fails (typically that means that the `BaseObject`+has been deleted earlier).++```c+++void Http2Session::Request(const FunctionCallbackInfo<Value>& args) {+  Http2Session* session;+  ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());+  Environment* env = session->env();+  Local<Context> context = env->context();+  Isolate* isolate = env->isolate();++  // ...+  // The actual function body, which can now use the `session` object.+  // ...+}+```++#### Lifetime management++The `BaseObject` class comes with a set of features that allow managing the+lifetime of its instances, either associating it with the lifetime of the+corresponding JavaScript object or untying the two.++The `BaseObject::MakeWeak()` method turns the underlying [`Global`][] handle+into a weak one, and makes it so that the `BaseObject::OnGCCollect()` virtual+method is called when the JavaScript object is garbage collected. By default,+that methods deletes the `BaseObject` instance.++`BaseObject::ClearWeak()` undoes this effect.++It generally makes sense to call `MakeWeak()` in the constructor of a+`BaseObject` subclass, unless that subclass is referred to by e.g. the event+loop, as is the case for the [`HandleWrap`][] and [`ReqWrap`][] classes.++In addition, there are two kinds of smart pointers that can be used to refer+to `BaseObject`s.++`BaseObjectWeakPtr<T>` is similar to `std::weak_ptr<T>`, but holds on to+an object of a `BaseObject` subclass `T` and integrates with the lifetime+management of the former. When the `BaseObject` no longer exists, e.g. when+it was garbage collected, accessing it through `weak_ptr.get()` will return+`nullptr`.++`BaseObjectPtr<T>` is similar to `std::shared_ptr<T>`, but also holds on to+objects of a `BaseObject` subclass `T`. While there are `BaseObjectPtr`s+pointing to a given object, the `BaseObject` will always maintain a strong+reference to its associated JavaScript object. This can be useful when one+`BaseObject` refers to another `BaseObject` and wants to make sure it stays+alive during the lifetime of that reference.++A `BaseObject` can be “detached” throught the `BaseObject::Detach()` method.+In this case, it will be deleted once the last `BaseObjectPtr` referring to+it is destroyed. There must be at least one such pointer when `Detach()` is+called. This can be useful when one `BaseObject` fully owns another+`BaseObject`.++<a id="asyncwrap"></a>+### `AsyncWrap`++`AsyncWrap` is a subclass of `BaseObject` that additionally provides tracking+functions for asynchronous calls. It is commonly used for classes whose methods+make calls into JavaScript without any JavaScript stack below, i.e. more or less+directly from the event loop. It is defined in [`async_wrap.h`][].++Every `AsyncWrap` subclass has a “provider type”. A list of provider types is+maintained in `src/async_wrap.h`.++Every `AsyncWrap` instance is associated with two numbers, the “async id”+and the “async trigger id”. The “async id” is generally unique per `AsyncWrap`+instance, and only changes when the object is re-used in some way.++See the [`async_hooks` module][] documentation for more information about how+this information is provided to async tracking tools.++<a id="makecallback"></a>+#### `MakeCallback`++The `AsyncWrap` class has a set of methods called `MakeCallback()`, with the+intention of the naming being that it is used to “make calls back into+JavaScript” from the event loop, rather than making callbacks in some way.+(As the naming has made its way into Node.js’s public API, it’s not worth+the breakage of fixing it).++`MakeCallback()` generally calls a method on the JavaScript object associated+with the current `AsyncWrap`, and informs async tracking code about these calls+as well as takes care of running the `process.nextTick()` and `Promise` task+queues once it returns.++Before calling `MakeCallback()`, it is typically necessary to enter both a+`HandleScope` and a `Context::Scope`.++```c+++void StatWatcher::Callback(uv_fs_poll_t* handle,+                           int status,+                           const uv_stat_t* prev,+                           const uv_stat_t* curr) {+  // Get the StatWatcher instance associated with this call from libuv,+  // StatWatcher is a subclass of AsyncWrap.+  StatWatcher* wrap = ContainerOf(&StatWatcher::watcher_, handle);+  Environment* env = wrap->env();+  HandleScope handle_scope(env->isolate());+  Context::Scope context_scope(env->context());++  // Transform 'prev' and 'curr' into an array:+  Local<Value> arr = ...;++  Local<Value> argv[] = { Integer::New(env->isolate(), status), arr };+  wrap->MakeCallback(env->onchange_string(), arraysize(argv), argv);+}+```++See [Callback scopes][] for more information.++<a id="handlewrap"></a>+### `HandleWrap`++`HandleWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv handles][] easier. It provides the `.ref()`, `.unref()` and+`.hasRef()` methods as well as `.close()` to enable easier lifetime management+from JavaScript. It is defined in [`handle_wrap.h`][].++`HandleWrap` instances are [cleaned up][cleanup hooks] automatically when the+current Node.js [`Environment`][] is destroyed, e.g. when a Worker thread stops.++`HandleWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="reqwrap"></a>+### `ReqWrap`++`ReqWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv requests][] easier. It is defined in [`req_wrap.h`][].++In particular, its `Dispatch()` method is designed to avoid the need to keep+track of the current count of active libuv requests.++`ReqWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="callback-scopes"></a>+### Callback scopes++The public `CallbackScope` and the internally used `InternalCallbackScope`+classes provide the same facilities as [`MakeCallback()`][], namely:++* Emitting the `'before'` event for async tracking when entering the scope+* Setting the current async IDs to the ones passed to the constructor+* Emitting the `'after'` event for async tracking when leaving the scope+* Running the `process.nextTick()` queue+* Running microtasks, in particular `Promise` callbacks and async/await+  functions++Usually, using `AsyncWrap::MakeCallback()` or using the constructor taking+an `AsyncWrap*` argument (i.e. used as+`InternalCallbackScope callback_scope(this);`) suffices inside of Node.js’s+C++ codebase.++## C++ utilities++Node.js uses a few custom C++ utilities, mostly defined in [`util.h`][].++### Memory allocation++Node.js provides `Malloc()`, `Realloc()` and `Calloc()` functions that work+like their C stdlib counterparts, but crash if memory cannot be allocated.+(As V8 does not handle out-of-memory situations gracefully, it does not make+sense for Node.js to attempt to do so in all cases.)++The `UncheckedMalloc()`, `UncheckedRealloc()` and `UncheckedCalloc()` functions+return `nullptr` in these cases (or when `size == 0`).++#### Optional stack-based memory allocation++The `MaybeStackBuffer` class provides a way to allocate memory on the stack+if it is smaller than a given limit, and falls back to allocating it on the+heap if it is larger. This can be useful for performantly allocating temporary+data if it is typically expected to be small (e.g. file paths).++The `Utf8Value`, `TwoByteValue` (i.e. UTF-16 value) and `BufferValue`+(`Utf8Value` but copy data from a `Buffer` is that is passed) helpers

Is there a typo here?

addaleax

comment created time in 3 months

Pull request review commentnodejs/node

src,doc: add C++ internals documentation

+# Node.js C++ codebase++Hi! 👋 You’ve found the C++ code backing Node.js. This README aims to help you+get started working on it and document some idioms you may encounter while+doing so.++## Coding style++Node.js has a document detailing its [C++ coding style][]+that can be helpful as a reference for stylistic issues.++## V8 API documentation++A lot of the Node.js codebase is around what the underlying JavaScript engine,+V8, provides through its API for embedders. Knowledge of this API can also be+useful when working with native addons for Node.js written in C++, although for+new projects [N-API][] is typically the better alternative.++V8 does not provide much public API documentation beyond what is+available in its C++ header files, most importantly `v8.h`, which can be+accessed online in the following locations:++* On GitHub: [`v8.h` in Node.js master][]+* On GitHub: [`v8.h` in V8 master][]+* On the Chromium project’s Code Search application: [`v8.h` in Code Search][]++V8 also provides an [introduction for V8 embedders][],+which can be useful for understanding some of the concepts it uses in its+embedder API.++Important concepts when using V8 are the ones of [`Isolate`][]s and+[JavaScript value handles][].++## libuv API documentation++The other major dependency of Node.js is [libuv][], providing+the [event loop][] and other operation system abstractions to Node.js.++There is a [reference documentation for the libuv API][].++## Helpful concepts++A number of concepts are involved in putting together Node.js on top of V8 and+libuv. This section aims to explain some of them and how they work together.++<a id="isolate"></a>+### `Isolate`++The `v8::Isolate` class represents a single JavaScript engine instance, in+particular a set of JavaScript objects that can refer to each other+(the “heap”).++The `v8::Isolate` is often passed to other V8 API functions, and provides some+APIs for managing the behaviour of the JavaScript engine or querying about its+current state or statistics such as memory usage.++V8 APIs are not thread-safe unless explicitly specified. In a typical Node.js+application, the main thread and any `Worker` threads each have one `Isolate`,+and JavaScript objects from one `Isolate` cannot refer to objects from+another `Isolate`.++Garbage collection, as well as other operations that affect the entire heap,+happen on a per-`Isolate` basis.++Typical ways of accessing the current `Isolate` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `args.GetIsolate()`.+* Given a [`Context`][], using `context->GetIsolate()`.+* Given a [`Environment`][], using `env->isolate()`.++### V8 JavaScript values++V8 provides classes that mostly correspond to JavaScript types; for example,+`v8::Value` is a class representing any kind of JavaScript type, with+subclasses such as `v8::Number` (which in turn has subclasses like `v8::Int32`),+`v8::Boolean` or `v8::Object`. Most types are represented by subclasses+of `v8::Object`, e.g. `v8::Uint8Array` or `v8::Date`.++<a id="internal-fields"></a>+### Internal fields++V8 provides the ability to store data in so-called “internal fields” inside+`v8::Object`s that were created as instances of C++-backed classes. The number+of fields needs to be defined when creating that class.++Both JavaScript values and `void*` pointers may be stored in such fields.+In most native Node.js objects, the first internal field is used to store a+pointer to a [`BaseObject`][] subclass, which then contains all relevant+information associated with the JavaScript object.++The most typical way of working internal fields are:++* `obj->InternalFieldCount()` to look up the number of internal fields for an+  object (`0` for regular JavaScript objects).+* `obj->GetInternalField(i)` to get a JavaScript value from an internal field.+* `obj->SetInternalField(i, v)` to store a JavaScript value in an+  internal field.+* `obj->GetAlignedPointerFromInternalField(i)` to get a `void*` pointer from an+  internal field.+* `obj->SetAlignedPointerInInternalField(i, p)` to store a `void*` pointer in an+  internal field.++[`Context`][]s provide the same feature under the name “embedder data”.++<a id="js-handles"></a>+### JavaScript value handles++All JavaScript values are accessed through the V8 API through so-called handles,+of which there are two types: [`Local`][]s and [`Global`][]s.++<a id="local-handles"></a>+#### `Local` handles++A `v8::Local` handle is a temporary pointer to a JavaScript object, where+“temporary” usually means that is no longer needed after the current function+is done executing. `Local` handles can only be allocated on the C++ stack.++Most of the V8 API uses `Local` handles to work with JavaScript values or return+them from functions.++Whenever a `Local` handle is created, a `v8::HandleScope` or+`v8::EscapableHandleScope` object must exist on the stack. The `Local` is then+added to that scope and deleted along with it.++When inside a [binding function][], a `HandleScope` already exists outside of+it, so there is no need to explicitly create one.++`EscapableHandleScope`s can be used to allow a single `Local` handle to be+passed to the outer scope. This is useful when a function returns a `Local`.++The following JavaScript and C++ functions are mostly equivalent:++```js+function getFoo(obj) {+  return obj.foo;+}+```++```c+++v8::Local<v8::Value> GetFoo(v8::Local<v8::Context> context,+                            v8::Local<v8::Object> obj) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::EscapableHandleScope handle_scope(isolate);++  // The 'foo_string' handle cannot be returned from this function because+  // it is not “escaped” with `.Escape()`.+  v8::Local<v8::String> foo_string =+      v8::String::NewFromUtf8(isolate,+                              "foo",+                              v8::NewStringType::kNormal).ToLocalChecked();++  v8::Local<v8::Value> return_value;+  if (obj->Get(context, foo_string).ToLocal(&return_value)) {+    return handle_scope.Escape(return_value);+  } else {+    // There was a JS exception! Handle it somehow.+    return v8::Local<v8::Value>();+  }+}+```++See [exception handling][] for more information about the usage of `.To()`,+`.ToLocalChecked()`, `v8::Maybe` and `v8::MaybeLocal` usage.++##### Casting local handles++If it is known that a `Local<Value>` refers to a more specific type, it can+be cast to that type using `.As<...>()`:++```c+++v8::Local<v8::Value> some_value;+// CHECK() is a Node.js utilitity that works similar to assert().+CHECK(some_value->IsUint8Array());+v8::Local<v8::Uint8Array> as_uint8 = some_value.As<v8::Uint8Array>();+```++Generally, using `val.As<v8::X>()` is only valid if `val->IsX()` is true, and+failing to follow that rule may lead to crashes.++##### Detecting handle leaks++If it is expected that no `Local` handles should be created within a given+scope unless explicitly within a `HandleScope`, a `SealHandleScope` can be used.++For example, there is a `SealHandleScope` around the event loop, forcing+any functions that are called from the event loop and want to run or access+JavaScript code to create `HandleScope`s.++<a id="global-handles"></a>+#### `Global` handles++A `v8::Global` handle (sometimes also referred to by the name of its parent+class `Persistent`, although use of that is discouraged in Node.js) is a+reference to a JavaScript object that can remain active as long as the engine+instance is active.++Global handles can be either strong or weak. Strong global handles are so-called+“GC roots”, meaning that they will keep the JavaScript object they refer to+alive even if no other objects refer to them. Weak global handles do not do+that, and instead optionally call a callback when the object they refer to+is garbage-collected.++```c+++v8::Global<v8::Object> reference;++void StoreReference(v8::Isolate* isolate, v8::Local<v8::Object> obj) {+  // Create a strong reference to `obj`.+  reference.Reset(isolate, obj);+}++// Must be called with a HandleScope around it.+v8::Local<v8::Object> LoadReference(v8::Isolate* isolate) {+  return reference.Get(isolate);+}+```++##### `Eternal` handles++`v8::Eternal` handles are a special kind of handles similar to `v8::Global`+handles, with the exception that the values they point to are never+garbage-collected while the JavaScript Engine instance is alive, even if+the `v8::Eternal` itself is destroyed at some point. This type of handle+is rarely used.++<a id="context"></a>+### `Context`++JavaScript allows multiple global objects and sets of built-in JavaScript+objects (like the `Object` or `Array` functions) to coexist inside the same+heap. Node.js exposes this ability through the [`vm` module][].++V8 refers to each of these global objects and their associated builtins as a+`Context`.++Currently, in Node.js there is one main `Context` associated with an+[`Environment`][] instance, and most Node.js features will only work inside+that context. (The only exception at the time of writing are+[`MessagePort`][] objects.) This restriction is not inherent to the design of+Node.js, and a sufficiently committed person could restructure Node.js to+provide built-in modules inside of `vm.Context`s.++Often, the `Context` is passed around for [exception handling][].+Typical ways of accessing the current `Environment` in the Node.js code are:++* Given an [`Isolate`][], using `isolate->GetCurrentContext()`.+* Given an [`Environment`][], using `env->context()` to get the `Environment`’s+  main context.++<a id="event-loop"></a>+### Event loop++The main abstraction for an event loop inside Node.js is the `uv_loop_t` struct.+Typically, there is one event loop per thread. This includes not only the main+thread and Workers, but also helper threads that may occasionally be spawned+in the course of running a Node.js program.++The current event loop can be accessed using `env->event_loop()` given an+[`Environment`][] instance. The restriction of using a single event loop+is not inherent to the design of Node.js, and a sufficiently committed person+could restructure Node.js to provide e.g. the ability to run parts of Node.js+inside an event loop separate from the active thread’s event loop.++<a id="environment"></a>+### `Environment`++Node.js instances are represented by the `Environment` class.++Currently, every `Environment` class is associated with:++* One [event loop][]+* One [`Isolate`][]+* One main [`Context`][]++The `Environment` class contains a large number of different fields for+different Node.js modules, for example a libuv timer for `setTimeout()` or+the memory for a `Float64Array` that the `fs` module uses for storing data+returned from a `fs.stat()` call.++It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]+instances.++Typical ways of accessing the current `Environment` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `Environment::GetCurrent(args)`.+* Given a [`BaseObject`][], using `env()` or `self->env()`.+* Given a [`Context`][], using `Environment::GetCurrent(context)`.+  This requires that `context` has been associated with the `Environment`+  instance, e.g. is the main `Context` for the `Environment` or one of its+  `vm.Context`s.+* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks+  up the current [`Context`][] and then uses that.++<a id="isolate-data"></a>+### `IsolateData`++Every Node.js instance ([`Environment`][]) is associated with one `IsolateData`+instance that contains information about or associated with a given+[`Isolate`][].++#### String table++`IsolateData` contains a list of strings that can be quickly accessed+inside Node.js code, e.g. given an `Environment` instance `env` the JavaScript+string “name” can be accessed through `env->name_string()` without actually+creating a new JavaScript string.++### Platform++Every process that uses V8 has a `v8::Platform` instance that provides some+functionalities to V8, most importantly the ability to schedule work on+background threads.++Node.js provides a `NodePlatform` class that implements the `v8::Platform`+interface and uses libuv for providing background threading abilities.++The platform can be accessed through `isolate_data->platform()` given an+[`IsolateData`][] instance, although that only works when:++* The current Node.js instance was not started by an embedder; or+* The current Node.js instance was started by an embedder whose `v8::Platform`+  implementation also implement’s the `node::MultiIsolatePlatform` interface+  and who passed this to Node.js.++<a id="binding-functions"></a>+### Binding functions++C++ functions exposed to JS follow a specific signature. The following example+is from `node_util.cc`:++```c+++void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {+  CHECK(args[0]->IsArrayBufferView());+  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());+}+```++(Namespaces are usually omitted through the use of `using` statements in the+Node.js source code.)++`args[n]` is a `Local<Value>` that represents the n-th argument passed to the+function. `args.This()` is the `this` value inside this function call.+`args.Holder()` is equivalent to `args.This()` in all use cases inside of+Node.js.++`args.GetReturnValue()` is a placeholder for the return value of the function,+and provides a `.Set()` method that can be called with a boolean, integer,+floating-point number or a `Local<Value>` to set the return value.++Node.js provides various helpers for building JS classes in C++ and/or attaching+C++ functions to the exports of a built-in module:++```c+++void Initialize(Local<Object> target,+                Local<Value> unused,+                Local<Context> context,+                void* priv) {+  Environment* env = Environment::GetCurrent(context);++  env->SetMethod(target, "getaddrinfo", GetAddrInfo);+  env->SetMethod(target, "getnameinfo", GetNameInfo);++  // 'SetMethodNoSideEffect' means that debuggers can safely execute this+  // function for e.g. previews.+  env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP);++  // ... more code ...++  // Building the `ChannelWrap` class for JS:+  Local<FunctionTemplate> channel_wrap =+      env->NewFunctionTemplate(ChannelWrap::New);+  // Allow for 1 internal field, see `BaseObject` for details on this:+  channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);+  channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));++  // Set various methods on the class (i.e. on the prototype):+  env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);+  env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);+  // ...+  env->SetProtoMethod(channel_wrap, "querySoa", Query<QuerySoaWrap>);+  env->SetProtoMethod(channel_wrap, "getHostByAddr", Query<GetHostByAddrWrap>);++  env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers);++  Local<String> channel_wrap_string =+      FIXED_ONE_BYTE_STRING(env->isolate(), "ChannelWrap");+  channel_wrap->SetClassName(channel_wrap_string);+  target->Set(env->context(), channel_wrap_string,+              channel_wrap->GetFunction(context).ToLocalChecked()).Check();+}++// Run the `Initialize` function when loading this module through+// `internalBinding('cares_wrap')` in Node.js’s built-in JavaScript code:+NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, Initialize)+```++<a id="exception-handling"></a>+### Exception handling++The V8 engine provides multiple features to work with JavaScript exceptions,+as C++ exceptions are disabled inside of Node.js:++#### Maybe types++V8 provides the `v8::Maybe<T>` and `v8::MaybeLocal<T>` types, typically used+as return values from API functions that can run JavaScript code and therefore+can throw exceptions.++Conceptually, the idea is that every `v8::Maybe<T>` is either empty (checked+through `.IsNothing()`) or holds a value of type `T` (checked through+`.IsJust()`). If the `Maybe` is empty, then a JavaScript exception is pending.+A typical way of accessing the value is using the `.To()` function, which+returns a boolean indicating success of the operation (i.e. the `Maybe` not+being empty) and taking a pointer to a `T` to store the value if there is one.++##### Checked conversion++`maybe.Check()` can be used to assert that the maybe is not empty, i.e. crash+the process otherwise. `maybe.FromJust()` (aka `maybe.ToChecked()`) can be used+to access the value and crash the process if it is not set.++This should only be performed if it is actually sure that the operation has+not failed. A lot of Node.js’s source code does **not** follow this rule, and+can be brought to crash through this.++##### MaybeLocal++`v8::MaybeLocal<T>` is a variant of `v8::Maybe<T>` that is either empty or+holds a value of type `Local<T>`. It has methods that perform the same+operations as the methods of `v8::Maybe`, but with different names:++| `Maybe`                | `MaybeLocal`                    |+| ---------------------- | ------------------------------- |+| `maybe.IsNothing()`    | `maybe_local.IsEmpty()`         |+| `maybe.IsJust()`       | –                               |+| `maybe.To(&value)`     | `maybe_local.ToLocal(&local)`   |+| `maybe.ToChecked()`    | `maybe_local.ToLocalChecked()`  |+| `maybe.FromJust()`     | `maybe_local.ToLocalChecked()`  |+| `maybe.Check()`        | –                               |+| `v8::Nothing<T>()`     | `v8::MaybeLocal<T>()`           |+| `v8::Just<T>(value)`   | `v8::MaybeLocal<T>(value)`      |++##### Handling empty `Maybe`s++Usually, the best approach to encountering an empty `Maybe` is to just return+from the current function as soon as possible, and let execution in JavaScript+land resume. If the empty `Maybe` is encountered inside a nested function,+is may be a good idea to use a `Maybe` or `MaybeLocal` for the return type+of that function and pass information about pending JavaScript exceptions along+that way.++Generally, when an empty `Maybe` is encountered, it is not valid to attempt+to perform further calls to APIs that return `Maybe`s.++A typical pattern for dealing with APIs that return `Maybe` and `MaybeLocal` is+using `.ToLocal()` and `.To()` and returning early in case there is an error:++```c+++// This could also return a v8::MaybeLocal<v8::Number>, for example.+v8::Maybe<double> SumNumbers(v8::Local<v8::Context> context,+                             v8::Local<v8::Array> array_of_integers) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::HandleScope handle_scope(isolate);++  double sum = 0;++  for (uint32_t i = 0; i < array_of_integers->Length(); i++) {+    v8::Local<v8::Value> entry;+    if (array_of_integers->Get(context, i).ToLocal(&entry)) {+      // Oops, we might have hit a getter that throws an exception!+      // It’s better to not continue return an empty (“nothing”) Maybe.+      return v8::Nothing<double>();+    }++    if (!entry->IsNumber()) {+      // Let’s just skip any non-numbers. It would also be reasonable to throw+      // an exception here, e.g. using the error system in src/node_errors.h,+      // and then to return an empty Maybe again.+      continue;+    }++    // This cast is valid, because we’ve made sure it’s really a number.+    v8::Local<v8::Number> entry_as_number = entry.As<v8::Number>();++    sum += entry_as_number->Value();+  }++  return v8::Just(sum);+}++// Function that is exposed to JS:+void SumNumbers(const v8::FunctionCallbackInfo<v8::Value>& args) {+  // This will crash if the first argument is not an array. Let’s assume we+  // have performed type checking in a JavaScript wrapper function.+  CHECK(args[0]->IsArray());++  double sum;+  if (!SumNumbers(args.GetIsolate()->GetCurrentContext(),+                  args[0].As<v8::Array>()).To(&sum)) {+    // Nothing to do, we can just return directly to JavaScript.+    return;+  }++  args.GetReturnValue().Set(sum);+}+```++#### TryCatch++If there is a need to catch JavaScript exceptions in C++, V8 provides the+`v8::TryCatch` type for doing so, which we wrap into our own+`node::errors::TryCatchScope` in Node.js. The latter has the additional feature+of providing the ability to shut down the program in the typical Node.js way+(printing the exception + stack trace) if an exception is caught.++<a id="libuv-handles-and-requests"></a>+### libuv handles and requests++Two central concepts when working with libuv are handles and requests.++Handles are subclasses of the `uv_handle_t` “class”, and generally refer to+long-lived objects that can emit events multiple times, such as network sockets+or file system watchers.++In Node.js, handles are often managed through a [`HandleWrap`][] subclass.++Requests are one-time asynchronous function calls on the event loop, such as+file system requests or network write operations, that either succeed or fail.++In Node.js, requests are often managed through a [`ReqWrap`][] subclass.++### Environment cleanup++When a Node.js [`Environment`][] is destroyed, it generally needs to clean up+any resources owned by it, e.g. memory or libuv requests/handles.++<a id="cleanup-hooks"></a>+#### Cleanup hooks++Cleanup hooks are provided that run before the [`Environment`][]+is destroyed. They can be added and removed through by using+`env->AddCleanupHook(callback, hint);` and+`env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint`+argument.++Inside these cleanup hooks, new asynchronous operations *may* be started on the+event loop, although ideally that is avoided as much as possible.++Every [`BaseObject`][] has its own cleanup hook that deletes it. For+[`ReqWrap`][] and [`HandleWrap`][] instances, cleanup of the associated libuv+objects is performed automatically, i.e. handles are closed and requests+are cancelled if possible.++#### Closing libuv handles++If a libuv handle is not managed through a [`HandleWrap`][] instance,+it needs to be closed explicitly. Do not use `uv_close()` for that, but rather+`env->CloseHandle()`, which works the same way but keeps track of the number+of handles that are still closing.++#### Closing libuv requests++There is no way to abort libuv requests in general. If a libuv request is not+managed through a [`ReqWrap`][] instance, the+`env->IncreaseWaitingRequestCounter()` and+`env->DecreaseWaitingRequestCounter()` functions need to be used to keep track+of the number of active libuv requests.++#### Calling into JavaScript++Calling into JavaScript is not allowed during cleanup. Worker threads explicitly+forbid this during their shutdown sequence, but the main thread does not for+backwards compatibility reasons.++When calling into JavaScript without using [`MakeCallback()`][], check the+`env->can_call_into_js()` flag and do not proceed if it is set to `false`.++## Classes associated with JavaScript objects++### `MemoryRetainer`++A large number of classes in the Node.js C++ codebase refer to other objects.+The `MemoryRetainer` class is a helper for annotating C++ classes with+information that can be used by the heap snapshot builder in V8, so that+memory retained by C++ can be tracked in V8 heap snapshots captured in+Node.js applications.++Inheriting from the `MemoryRetainer` class enables objects (both from JavaScript+and C++) to refer to instances of that class, and in turn enables that class+to point to other objects as well, including native C++ types+such as `std::string` and track their memory usage.++This can be useful for debugging memory leaks.++The [`memory_retainer.h`][] header file explains how to use this class.++<a id="baseobject"></a>+### `BaseObject`++A frequently recurring situation is that a JavaScript object and a C++ object+need to be tied together. `BaseObject` is the main abstraction for that in+Node.js, and most classes that are associated with JavaScript objects are+subclasses of it. It is defined in [`base_object.h`][].++Every `BaseObject` is associated with one [`Environment`][] and one+`v8::Object`. The `v8::Object` needs to have at least one [internal field][]+that is used for storing the pointer to the C++ object. In order to ensure this,+the V8 `SetInternalFieldCount()` function is usually used when setting up the+class from C++.++The JavaScript object can be accessed as a `v8::Local<v8::Object>` by using+`self->object()`, given a `BaseObject` named `self`.++Accessing a `BaseObject` from a `v8::Local<v8::Object>` (frequently that is+`args.This()` or `args.Holder()` in a [binding function][]) can be done using+the `Unwrap<T>(obj)` function, where `T` is a subclass of `BaseObject`.+A helper for this is the `ASSIGN_OR_RETURN_UNWRAP` macro that returns from the+current function if unwrapping fails (typically that means that the `BaseObject`+has been deleted earlier).++```c+++void Http2Session::Request(const FunctionCallbackInfo<Value>& args) {+  Http2Session* session;+  ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());+  Environment* env = session->env();+  Local<Context> context = env->context();+  Isolate* isolate = env->isolate();++  // ...+  // The actual function body, which can now use the `session` object.+  // ...+}+```++#### Lifetime management++The `BaseObject` class comes with a set of features that allow managing the+lifetime of its instances, either associating it with the lifetime of the+corresponding JavaScript object or untying the two.++The `BaseObject::MakeWeak()` method turns the underlying [`Global`][] handle+into a weak one, and makes it so that the `BaseObject::OnGCCollect()` virtual+method is called when the JavaScript object is garbage collected. By default,+that methods deletes the `BaseObject` instance.++`BaseObject::ClearWeak()` undoes this effect.++It generally makes sense to call `MakeWeak()` in the constructor of a+`BaseObject` subclass, unless that subclass is referred to by e.g. the event+loop, as is the case for the [`HandleWrap`][] and [`ReqWrap`][] classes.++In addition, there are two kinds of smart pointers that can be used to refer+to `BaseObject`s.++`BaseObjectWeakPtr<T>` is similar to `std::weak_ptr<T>`, but holds on to+an object of a `BaseObject` subclass `T` and integrates with the lifetime+management of the former. When the `BaseObject` no longer exists, e.g. when+it was garbage collected, accessing it through `weak_ptr.get()` will return+`nullptr`.++`BaseObjectPtr<T>` is similar to `std::shared_ptr<T>`, but also holds on to+objects of a `BaseObject` subclass `T`. While there are `BaseObjectPtr`s+pointing to a given object, the `BaseObject` will always maintain a strong+reference to its associated JavaScript object. This can be useful when one+`BaseObject` refers to another `BaseObject` and wants to make sure it stays+alive during the lifetime of that reference.++A `BaseObject` can be “detached” throught the `BaseObject::Detach()` method.+In this case, it will be deleted once the last `BaseObjectPtr` referring to+it is destroyed. There must be at least one such pointer when `Detach()` is+called. This can be useful when one `BaseObject` fully owns another+`BaseObject`.++<a id="asyncwrap"></a>+### `AsyncWrap`++`AsyncWrap` is a subclass of `BaseObject` that additionally provides tracking+functions for asynchronous calls. It is commonly used for classes whose methods+make calls into JavaScript without any JavaScript stack below, i.e. more or less+directly from the event loop. It is defined in [`async_wrap.h`][].++Every `AsyncWrap` subclass has a “provider type”. A list of provider types is+maintained in `src/async_wrap.h`.++Every `AsyncWrap` instance is associated with two numbers, the “async id”+and the “async trigger id”. The “async id” is generally unique per `AsyncWrap`+instance, and only changes when the object is re-used in some way.++See the [`async_hooks` module][] documentation for more information about how+this information is provided to async tracking tools.++<a id="makecallback"></a>+#### `MakeCallback`++The `AsyncWrap` class has a set of methods called `MakeCallback()`, with the+intention of the naming being that it is used to “make calls back into+JavaScript” from the event loop, rather than making callbacks in some way.+(As the naming has made its way into Node.js’s public API, it’s not worth+the breakage of fixing it).++`MakeCallback()` generally calls a method on the JavaScript object associated+with the current `AsyncWrap`, and informs async tracking code about these calls+as well as takes care of running the `process.nextTick()` and `Promise` task+queues once it returns.++Before calling `MakeCallback()`, it is typically necessary to enter both a+`HandleScope` and a `Context::Scope`.++```c+++void StatWatcher::Callback(uv_fs_poll_t* handle,+                           int status,+                           const uv_stat_t* prev,+                           const uv_stat_t* curr) {+  // Get the StatWatcher instance associated with this call from libuv,+  // StatWatcher is a subclass of AsyncWrap.+  StatWatcher* wrap = ContainerOf(&StatWatcher::watcher_, handle);+  Environment* env = wrap->env();+  HandleScope handle_scope(env->isolate());+  Context::Scope context_scope(env->context());++  // Transform 'prev' and 'curr' into an array:+  Local<Value> arr = ...;++  Local<Value> argv[] = { Integer::New(env->isolate(), status), arr };+  wrap->MakeCallback(env->onchange_string(), arraysize(argv), argv);+}+```++See [Callback scopes][] for more information.++<a id="handlewrap"></a>+### `HandleWrap`++`HandleWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv handles][] easier. It provides the `.ref()`, `.unref()` and+`.hasRef()` methods as well as `.close()` to enable easier lifetime management+from JavaScript. It is defined in [`handle_wrap.h`][].++`HandleWrap` instances are [cleaned up][cleanup hooks] automatically when the+current Node.js [`Environment`][] is destroyed, e.g. when a Worker thread stops.++`HandleWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="reqwrap"></a>+### `ReqWrap`++`ReqWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv requests][] easier. It is defined in [`req_wrap.h`][].++In particular, its `Dispatch()` method is designed to avoid the need to keep+track of the current count of active libuv requests.++`ReqWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="callback-scopes"></a>+### Callback scopes++The public `CallbackScope` and the internally used `InternalCallbackScope`+classes provide the same facilities as [`MakeCallback()`][], namely:++* Emitting the `'before'` event for async tracking when entering the scope+* Setting the current async IDs to the ones passed to the constructor+* Emitting the `'after'` event for async tracking when leaving the scope+* Running the `process.nextTick()` queue+* Running microtasks, in particular `Promise` callbacks and async/await+  functions++Usually, using `AsyncWrap::MakeCallback()` or using the constructor taking+an `AsyncWrap*` argument (i.e. used as+`InternalCallbackScope callback_scope(this);`) suffices inside of Node.js’s+C++ codebase.++## C++ utilities++Node.js uses a few custom C++ utilities, mostly defined in [`util.h`][].++### Memory allocation++Node.js provides `Malloc()`, `Realloc()` and `Calloc()` functions that work+like their C stdlib counterparts, but crash if memory cannot be allocated.+(As V8 does not handle out-of-memory situations gracefully, it does not make+sense for Node.js to attempt to do so in all cases.)++The `UncheckedMalloc()`, `UncheckedRealloc()` and `UncheckedCalloc()` functions+return `nullptr` in these cases (or when `size == 0`).++#### Optional stack-based memory allocation++The `MaybeStackBuffer` class provides a way to allocate memory on the stack+if it is smaller than a given limit, and falls back to allocating it on the+heap if it is larger. This can be useful for performantly allocating temporary+data if it is typically expected to be small (e.g. file paths).++The `Utf8Value`, `TwoByteValue` (i.e. UTF-16 value) and `BufferValue`+(`Utf8Value` but copy data from a `Buffer` is that is passed) helpers+inherit from this class and allow accessing the characters in a JavaScript+string this way.++```c+++static void Chdir(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  // ...+  CHECK(args[0]->IsString());+  Utf8Value path(env->isolate(), args[0]);+  int err = uv_chdir(*path);+  if (err) {+    // ... error handling ...+  }+}+```++### Assertions++Node.js provides a few macros that behave similar to `assert()`:++* `CHECK(expression)` aborts the process with a stack trace+  if `expression` is false.+* `CHECK_EQ(a, b)` checks for `a == b`+* `CHECK_GE(a, b)` checks for `a >= b`+* `CHECK_GT(a, b)` checks for `a > b`+* `CHECK_LE(a, b)` checks for `a <= b`+* `CHECK_LT(a, b)` checks for `a < b`+* `CHECK_NE(a, b)` checks for `a != b`+* `CHECK_NULL(val)` checks for `a == nullptr`+* `CHECK_NOT_NULL(val)` checks for `a != nullptr`+* `CHECK_IMPLIES(a, b)` checks that `b` is true if `a` is true.+* `UNREACHABLE([message])` aborts the process if it is reached.++`CHECK`s are always enabled. For checks that should only run in debug mode, use+`DCHECK()`, `DCHECK_EQ()`, etc.++### Scope-based cleanup++The `OnScopeLeave()` function can be used to run a piece of code when leaving+the current C++ scope.++```c+++static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  uv_passwd_t pwd;+  // ...++  const int err = uv_os_get_passwd(&pwd);++  if (err) {+    // ... error handling, return early ...+  }++  auto free_passwd = OnScopeLeave([&]() { uv_os_free_passwd(&pwd); });++  // ...+  // Turn `pwd` into a JavaScript object now; whenever we return from this+  // function, `uv_os_free_passwd()` will be called.+  // ...+}+```++[`BaseObject`]: #baseobject+[`Context`]: #context+[`Environment`]: #environment+[`Global`]: #global-handles+[`HandleWrap`]: #handlewrap+[`IsolateData`]: #isolate-data+[`Isolate`]: #isolate+[`Local`]: #local-handles+[`MakeCallback()`]: #makecallback+[`MessagePort`]: https://nodejs.org/api/worker_threads.html#worker_threads_class_messageport+[`ReqWrap`]: #reqwrap+[`async_hooks` module]: https://nodejs.org/api/async_hooks.html+[`async_wrap.h`]: async_wrap.h+[`base_object.h`]: base_object.h+[`handle_wrap.h`]: handle_wrap.h+[`memory_retainer.h`]: memory_retainer.h+[`req_wrap.h`]: req_wrap.h+[`util.h`]: util.h+[`v8.h` in Code Search]: https://cs.chromium.org/chromium/src/v8/include/v8.h+[`v8.h` in Node.js master]: https://github.com/nodejs/node/blob/master/deps/v8/include/v8.h+[`v8.h` in V8 master]: https://github.com/v8/v8/blob/master/include/v8.h+[`vm` module]: https://nodejs.org/api/vm.html+[C++ coding style]: ../CPP_STYLE_GUIDE.md+[Callback scopes]: #callback-scopes+[JavaScript value handles]: #js-handles+[N-API]: https://nodejs.org/api/n-api.html+[binding function]: #binding-functions+[cleanup hooks]: #cleanup-hooks+[event loop]: #event-loop+[exception handling]: #exception-handling+[internal field]: #internal-field
- [internal field]: #internal-field
+ [internal field]: #internal-fields
addaleax

comment created time in 3 months

Pull request review commentnodejs/node

src,doc: add C++ internals documentation

+# Node.js C++ codebase++Hi! 👋 You’ve found the C++ code backing Node.js. This README aims to help you+get started working on it and document some idioms you may encounter while+doing so.++## Coding style++Node.js has a document detailing its [C++ coding style][]+that can be helpful as a reference for stylistic issues.++## V8 API documentation++A lot of the Node.js codebase is around what the underlying JavaScript engine,+V8, provides through its API for embedders. Knowledge of this API can also be+useful when working with native addons for Node.js written in C++, although for+new projects [N-API][] is typically the better alternative.++V8 does not provide much public API documentation beyond what is+available in its C++ header files, most importantly `v8.h`, which can be+accessed online in the following locations:++* On GitHub: [`v8.h` in Node.js master][]+* On GitHub: [`v8.h` in V8 master][]+* On the Chromium project’s Code Search application: [`v8.h` in Code Search][]++V8 also provides an [introduction for V8 embedders][],+which can be useful for understanding some of the concepts it uses in its+embedder API.++Important concepts when using V8 are the ones of [`Isolate`][]s and+[JavaScript value handles][].++## libuv API documentation++The other major dependency of Node.js is [libuv][], providing+the [event loop][] and other operation system abstractions to Node.js.++There is a [reference documentation for the libuv API][].++## Helpful concepts++A number of concepts are involved in putting together Node.js on top of V8 and+libuv. This section aims to explain some of them and how they work together.++<a id="isolate"></a>+### `Isolate`++The `v8::Isolate` class represents a single JavaScript engine instance, in+particular a set of JavaScript objects that can refer to each other+(the “heap”).++The `v8::Isolate` is often passed to other V8 API functions, and provides some+APIs for managing the behaviour of the JavaScript engine or querying about its+current state or statistics such as memory usage.++V8 APIs are not thread-safe unless explicitly specified. In a typical Node.js+application, the main thread and any `Worker` threads each have one `Isolate`,+and JavaScript objects from one `Isolate` cannot refer to objects from+another `Isolate`.++Garbage collection, as well as other operations that affect the entire heap,+happen on a per-`Isolate` basis.++Typical ways of accessing the current `Isolate` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `args.GetIsolate()`.+* Given a [`Context`][], using `context->GetIsolate()`.+* Given a [`Environment`][], using `env->isolate()`.++### V8 JavaScript values++V8 provides classes that mostly correspond to JavaScript types; for example,+`v8::Value` is a class representing any kind of JavaScript type, with+subclasses such as `v8::Number` (which in turn has subclasses like `v8::Int32`),+`v8::Boolean` or `v8::Object`. Most types are represented by subclasses+of `v8::Object`, e.g. `v8::Uint8Array` or `v8::Date`.++<a id="internal-fields"></a>+### Internal fields++V8 provides the ability to store data in so-called “internal fields” inside+`v8::Object`s that were created as instances of C++-backed classes. The number+of fields needs to be defined when creating that class.++Both JavaScript values and `void*` pointers may be stored in such fields.+In most native Node.js objects, the first internal field is used to store a+pointer to a [`BaseObject`][] subclass, which then contains all relevant+information associated with the JavaScript object.++The most typical way of working internal fields are:++* `obj->InternalFieldCount()` to look up the number of internal fields for an+  object (`0` for regular JavaScript objects).+* `obj->GetInternalField(i)` to get a JavaScript value from an internal field.+* `obj->SetInternalField(i, v)` to store a JavaScript value in an+  internal field.+* `obj->GetAlignedPointerFromInternalField(i)` to get a `void*` pointer from an+  internal field.+* `obj->SetAlignedPointerInInternalField(i, p)` to store a `void*` pointer in an+  internal field.++[`Context`][]s provide the same feature under the name “embedder data”.++<a id="js-handles"></a>+### JavaScript value handles++All JavaScript values are accessed through the V8 API through so-called handles,+of which there are two types: [`Local`][]s and [`Global`][]s.++<a id="local-handles"></a>+#### `Local` handles++A `v8::Local` handle is a temporary pointer to a JavaScript object, where+“temporary” usually means that is no longer needed after the current function+is done executing. `Local` handles can only be allocated on the C++ stack.++Most of the V8 API uses `Local` handles to work with JavaScript values or return+them from functions.++Whenever a `Local` handle is created, a `v8::HandleScope` or+`v8::EscapableHandleScope` object must exist on the stack. The `Local` is then+added to that scope and deleted along with it.++When inside a [binding function][], a `HandleScope` already exists outside of+it, so there is no need to explicitly create one.++`EscapableHandleScope`s can be used to allow a single `Local` handle to be+passed to the outer scope. This is useful when a function returns a `Local`.++The following JavaScript and C++ functions are mostly equivalent:++```js+function getFoo(obj) {+  return obj.foo;+}+```++```c+++v8::Local<v8::Value> GetFoo(v8::Local<v8::Context> context,+                            v8::Local<v8::Object> obj) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::EscapableHandleScope handle_scope(isolate);++  // The 'foo_string' handle cannot be returned from this function because+  // it is not “escaped” with `.Escape()`.+  v8::Local<v8::String> foo_string =+      v8::String::NewFromUtf8(isolate,+                              "foo",+                              v8::NewStringType::kNormal).ToLocalChecked();++  v8::Local<v8::Value> return_value;+  if (obj->Get(context, foo_string).ToLocal(&return_value)) {+    return handle_scope.Escape(return_value);+  } else {+    // There was a JS exception! Handle it somehow.+    return v8::Local<v8::Value>();+  }+}+```++See [exception handling][] for more information about the usage of `.To()`,+`.ToLocalChecked()`, `v8::Maybe` and `v8::MaybeLocal` usage.++##### Casting local handles++If it is known that a `Local<Value>` refers to a more specific type, it can+be cast to that type using `.As<...>()`:++```c+++v8::Local<v8::Value> some_value;+// CHECK() is a Node.js utilitity that works similar to assert().+CHECK(some_value->IsUint8Array());+v8::Local<v8::Uint8Array> as_uint8 = some_value.As<v8::Uint8Array>();+```++Generally, using `val.As<v8::X>()` is only valid if `val->IsX()` is true, and+failing to follow that rule may lead to crashes.++##### Detecting handle leaks++If it is expected that no `Local` handles should be created within a given+scope unless explicitly within a `HandleScope`, a `SealHandleScope` can be used.++For example, there is a `SealHandleScope` around the event loop, forcing+any functions that are called from the event loop and want to run or access+JavaScript code to create `HandleScope`s.++<a id="global-handles"></a>+#### `Global` handles++A `v8::Global` handle (sometimes also referred to by the name of its parent+class `Persistent`, although use of that is discouraged in Node.js) is a+reference to a JavaScript object that can remain active as long as the engine+instance is active.++Global handles can be either strong or weak. Strong global handles are so-called+“GC roots”, meaning that they will keep the JavaScript object they refer to+alive even if no other objects refer to them. Weak global handles do not do+that, and instead optionally call a callback when the object they refer to+is garbage-collected.++```c+++v8::Global<v8::Object> reference;++void StoreReference(v8::Isolate* isolate, v8::Local<v8::Object> obj) {+  // Create a strong reference to `obj`.+  reference.Reset(isolate, obj);+}++// Must be called with a HandleScope around it.+v8::Local<v8::Object> LoadReference(v8::Isolate* isolate) {+  return reference.Get(isolate);+}+```++##### `Eternal` handles++`v8::Eternal` handles are a special kind of handles similar to `v8::Global`+handles, with the exception that the values they point to are never+garbage-collected while the JavaScript Engine instance is alive, even if+the `v8::Eternal` itself is destroyed at some point. This type of handle+is rarely used.++<a id="context"></a>+### `Context`++JavaScript allows multiple global objects and sets of built-in JavaScript+objects (like the `Object` or `Array` functions) to coexist inside the same+heap. Node.js exposes this ability through the [`vm` module][].++V8 refers to each of these global objects and their associated builtins as a+`Context`.++Currently, in Node.js there is one main `Context` associated with an+[`Environment`][] instance, and most Node.js features will only work inside+that context. (The only exception at the time of writing are+[`MessagePort`][] objects.) This restriction is not inherent to the design of+Node.js, and a sufficiently committed person could restructure Node.js to+provide built-in modules inside of `vm.Context`s.++Often, the `Context` is passed around for [exception handling][].+Typical ways of accessing the current `Environment` in the Node.js code are:++* Given an [`Isolate`][], using `isolate->GetCurrentContext()`.+* Given an [`Environment`][], using `env->context()` to get the `Environment`’s+  main context.++<a id="event-loop"></a>+### Event loop++The main abstraction for an event loop inside Node.js is the `uv_loop_t` struct.+Typically, there is one event loop per thread. This includes not only the main+thread and Workers, but also helper threads that may occasionally be spawned+in the course of running a Node.js program.++The current event loop can be accessed using `env->event_loop()` given an+[`Environment`][] instance. The restriction of using a single event loop+is not inherent to the design of Node.js, and a sufficiently committed person+could restructure Node.js to provide e.g. the ability to run parts of Node.js+inside an event loop separate from the active thread’s event loop.++<a id="environment"></a>+### `Environment`++Node.js instances are represented by the `Environment` class.++Currently, every `Environment` class is associated with:++* One [event loop][]+* One [`Isolate`][]+* One main [`Context`][]++The `Environment` class contains a large number of different fields for+different Node.js modules, for example a libuv timer for `setTimeout()` or+the memory for a `Float64Array` that the `fs` module uses for storing data+returned from a `fs.stat()` call.++It also provides [cleanup hooks][] and maintains a list of [`BaseObject`][]+instances.++Typical ways of accessing the current `Environment` in the Node.js code are:++* Given a `FunctionCallbackInfo` for a [binding function][],+  using `Environment::GetCurrent(args)`.+* Given a [`BaseObject`][], using `env()` or `self->env()`.+* Given a [`Context`][], using `Environment::GetCurrent(context)`.+  This requires that `context` has been associated with the `Environment`+  instance, e.g. is the main `Context` for the `Environment` or one of its+  `vm.Context`s.+* Given an [`Isolate`][], using `Environment::GetCurrent(isolate)`. This looks+  up the current [`Context`][] and then uses that.++<a id="isolate-data"></a>+### `IsolateData`++Every Node.js instance ([`Environment`][]) is associated with one `IsolateData`+instance that contains information about or associated with a given+[`Isolate`][].++#### String table++`IsolateData` contains a list of strings that can be quickly accessed+inside Node.js code, e.g. given an `Environment` instance `env` the JavaScript+string “name” can be accessed through `env->name_string()` without actually+creating a new JavaScript string.++### Platform++Every process that uses V8 has a `v8::Platform` instance that provides some+functionalities to V8, most importantly the ability to schedule work on+background threads.++Node.js provides a `NodePlatform` class that implements the `v8::Platform`+interface and uses libuv for providing background threading abilities.++The platform can be accessed through `isolate_data->platform()` given an+[`IsolateData`][] instance, although that only works when:++* The current Node.js instance was not started by an embedder; or+* The current Node.js instance was started by an embedder whose `v8::Platform`+  implementation also implement’s the `node::MultiIsolatePlatform` interface+  and who passed this to Node.js.++<a id="binding-functions"></a>+### Binding functions++C++ functions exposed to JS follow a specific signature. The following example+is from `node_util.cc`:++```c+++void ArrayBufferViewHasBuffer(const FunctionCallbackInfo<Value>& args) {+  CHECK(args[0]->IsArrayBufferView());+  args.GetReturnValue().Set(args[0].As<ArrayBufferView>()->HasBuffer());+}+```++(Namespaces are usually omitted through the use of `using` statements in the+Node.js source code.)++`args[n]` is a `Local<Value>` that represents the n-th argument passed to the+function. `args.This()` is the `this` value inside this function call.+`args.Holder()` is equivalent to `args.This()` in all use cases inside of+Node.js.++`args.GetReturnValue()` is a placeholder for the return value of the function,+and provides a `.Set()` method that can be called with a boolean, integer,+floating-point number or a `Local<Value>` to set the return value.++Node.js provides various helpers for building JS classes in C++ and/or attaching+C++ functions to the exports of a built-in module:++```c+++void Initialize(Local<Object> target,+                Local<Value> unused,+                Local<Context> context,+                void* priv) {+  Environment* env = Environment::GetCurrent(context);++  env->SetMethod(target, "getaddrinfo", GetAddrInfo);+  env->SetMethod(target, "getnameinfo", GetNameInfo);++  // 'SetMethodNoSideEffect' means that debuggers can safely execute this+  // function for e.g. previews.+  env->SetMethodNoSideEffect(target, "canonicalizeIP", CanonicalizeIP);++  // ... more code ...++  // Building the `ChannelWrap` class for JS:+  Local<FunctionTemplate> channel_wrap =+      env->NewFunctionTemplate(ChannelWrap::New);+  // Allow for 1 internal field, see `BaseObject` for details on this:+  channel_wrap->InstanceTemplate()->SetInternalFieldCount(1);+  channel_wrap->Inherit(AsyncWrap::GetConstructorTemplate(env));++  // Set various methods on the class (i.e. on the prototype):+  env->SetProtoMethod(channel_wrap, "queryAny", Query<QueryAnyWrap>);+  env->SetProtoMethod(channel_wrap, "queryA", Query<QueryAWrap>);+  // ...+  env->SetProtoMethod(channel_wrap, "querySoa", Query<QuerySoaWrap>);+  env->SetProtoMethod(channel_wrap, "getHostByAddr", Query<GetHostByAddrWrap>);++  env->SetProtoMethodNoSideEffect(channel_wrap, "getServers", GetServers);++  Local<String> channel_wrap_string =+      FIXED_ONE_BYTE_STRING(env->isolate(), "ChannelWrap");+  channel_wrap->SetClassName(channel_wrap_string);+  target->Set(env->context(), channel_wrap_string,+              channel_wrap->GetFunction(context).ToLocalChecked()).Check();+}++// Run the `Initialize` function when loading this module through+// `internalBinding('cares_wrap')` in Node.js’s built-in JavaScript code:+NODE_MODULE_CONTEXT_AWARE_INTERNAL(cares_wrap, Initialize)+```++<a id="exception-handling"></a>+### Exception handling++The V8 engine provides multiple features to work with JavaScript exceptions,+as C++ exceptions are disabled inside of Node.js:++#### Maybe types++V8 provides the `v8::Maybe<T>` and `v8::MaybeLocal<T>` types, typically used+as return values from API functions that can run JavaScript code and therefore+can throw exceptions.++Conceptually, the idea is that every `v8::Maybe<T>` is either empty (checked+through `.IsNothing()`) or holds a value of type `T` (checked through+`.IsJust()`). If the `Maybe` is empty, then a JavaScript exception is pending.+A typical way of accessing the value is using the `.To()` function, which+returns a boolean indicating success of the operation (i.e. the `Maybe` not+being empty) and taking a pointer to a `T` to store the value if there is one.++##### Checked conversion++`maybe.Check()` can be used to assert that the maybe is not empty, i.e. crash+the process otherwise. `maybe.FromJust()` (aka `maybe.ToChecked()`) can be used+to access the value and crash the process if it is not set.++This should only be performed if it is actually sure that the operation has+not failed. A lot of Node.js’s source code does **not** follow this rule, and+can be brought to crash through this.++##### MaybeLocal++`v8::MaybeLocal<T>` is a variant of `v8::Maybe<T>` that is either empty or+holds a value of type `Local<T>`. It has methods that perform the same+operations as the methods of `v8::Maybe`, but with different names:++| `Maybe`                | `MaybeLocal`                    |+| ---------------------- | ------------------------------- |+| `maybe.IsNothing()`    | `maybe_local.IsEmpty()`         |+| `maybe.IsJust()`       | –                               |+| `maybe.To(&value)`     | `maybe_local.ToLocal(&local)`   |+| `maybe.ToChecked()`    | `maybe_local.ToLocalChecked()`  |+| `maybe.FromJust()`     | `maybe_local.ToLocalChecked()`  |+| `maybe.Check()`        | –                               |+| `v8::Nothing<T>()`     | `v8::MaybeLocal<T>()`           |+| `v8::Just<T>(value)`   | `v8::MaybeLocal<T>(value)`      |++##### Handling empty `Maybe`s++Usually, the best approach to encountering an empty `Maybe` is to just return+from the current function as soon as possible, and let execution in JavaScript+land resume. If the empty `Maybe` is encountered inside a nested function,+is may be a good idea to use a `Maybe` or `MaybeLocal` for the return type+of that function and pass information about pending JavaScript exceptions along+that way.++Generally, when an empty `Maybe` is encountered, it is not valid to attempt+to perform further calls to APIs that return `Maybe`s.++A typical pattern for dealing with APIs that return `Maybe` and `MaybeLocal` is+using `.ToLocal()` and `.To()` and returning early in case there is an error:++```c+++// This could also return a v8::MaybeLocal<v8::Number>, for example.+v8::Maybe<double> SumNumbers(v8::Local<v8::Context> context,+                             v8::Local<v8::Array> array_of_integers) {+  v8::Isolate* isolate = context->GetIsolate();+  v8::HandleScope handle_scope(isolate);++  double sum = 0;++  for (uint32_t i = 0; i < array_of_integers->Length(); i++) {+    v8::Local<v8::Value> entry;+    if (array_of_integers->Get(context, i).ToLocal(&entry)) {+      // Oops, we might have hit a getter that throws an exception!+      // It’s better to not continue return an empty (“nothing”) Maybe.+      return v8::Nothing<double>();+    }++    if (!entry->IsNumber()) {+      // Let’s just skip any non-numbers. It would also be reasonable to throw+      // an exception here, e.g. using the error system in src/node_errors.h,+      // and then to return an empty Maybe again.+      continue;+    }++    // This cast is valid, because we’ve made sure it’s really a number.+    v8::Local<v8::Number> entry_as_number = entry.As<v8::Number>();++    sum += entry_as_number->Value();+  }++  return v8::Just(sum);+}++// Function that is exposed to JS:+void SumNumbers(const v8::FunctionCallbackInfo<v8::Value>& args) {+  // This will crash if the first argument is not an array. Let’s assume we+  // have performed type checking in a JavaScript wrapper function.+  CHECK(args[0]->IsArray());++  double sum;+  if (!SumNumbers(args.GetIsolate()->GetCurrentContext(),+                  args[0].As<v8::Array>()).To(&sum)) {+    // Nothing to do, we can just return directly to JavaScript.+    return;+  }++  args.GetReturnValue().Set(sum);+}+```++#### TryCatch++If there is a need to catch JavaScript exceptions in C++, V8 provides the+`v8::TryCatch` type for doing so, which we wrap into our own+`node::errors::TryCatchScope` in Node.js. The latter has the additional feature+of providing the ability to shut down the program in the typical Node.js way+(printing the exception + stack trace) if an exception is caught.++<a id="libuv-handles-and-requests"></a>+### libuv handles and requests++Two central concepts when working with libuv are handles and requests.++Handles are subclasses of the `uv_handle_t` “class”, and generally refer to+long-lived objects that can emit events multiple times, such as network sockets+or file system watchers.++In Node.js, handles are often managed through a [`HandleWrap`][] subclass.++Requests are one-time asynchronous function calls on the event loop, such as+file system requests or network write operations, that either succeed or fail.++In Node.js, requests are often managed through a [`ReqWrap`][] subclass.++### Environment cleanup++When a Node.js [`Environment`][] is destroyed, it generally needs to clean up+any resources owned by it, e.g. memory or libuv requests/handles.++<a id="cleanup-hooks"></a>+#### Cleanup hooks++Cleanup hooks are provided that run before the [`Environment`][]+is destroyed. They can be added and removed through by using+`env->AddCleanupHook(callback, hint);` and+`env->RemoveCleanupHook(callback, hint);`, where callback takes a `void* hint`+argument.++Inside these cleanup hooks, new asynchronous operations *may* be started on the+event loop, although ideally that is avoided as much as possible.++Every [`BaseObject`][] has its own cleanup hook that deletes it. For+[`ReqWrap`][] and [`HandleWrap`][] instances, cleanup of the associated libuv+objects is performed automatically, i.e. handles are closed and requests+are cancelled if possible.++#### Closing libuv handles++If a libuv handle is not managed through a [`HandleWrap`][] instance,+it needs to be closed explicitly. Do not use `uv_close()` for that, but rather+`env->CloseHandle()`, which works the same way but keeps track of the number+of handles that are still closing.++#### Closing libuv requests++There is no way to abort libuv requests in general. If a libuv request is not+managed through a [`ReqWrap`][] instance, the+`env->IncreaseWaitingRequestCounter()` and+`env->DecreaseWaitingRequestCounter()` functions need to be used to keep track+of the number of active libuv requests.++#### Calling into JavaScript++Calling into JavaScript is not allowed during cleanup. Worker threads explicitly+forbid this during their shutdown sequence, but the main thread does not for+backwards compatibility reasons.++When calling into JavaScript without using [`MakeCallback()`][], check the+`env->can_call_into_js()` flag and do not proceed if it is set to `false`.++## Classes associated with JavaScript objects++### `MemoryRetainer`++A large number of classes in the Node.js C++ codebase refer to other objects.+The `MemoryRetainer` class is a helper for annotating C++ classes with+information that can be used by the heap snapshot builder in V8, so that+memory retained by C++ can be tracked in V8 heap snapshots captured in+Node.js applications.++Inheriting from the `MemoryRetainer` class enables objects (both from JavaScript+and C++) to refer to instances of that class, and in turn enables that class+to point to other objects as well, including native C++ types+such as `std::string` and track their memory usage.++This can be useful for debugging memory leaks.++The [`memory_retainer.h`][] header file explains how to use this class.++<a id="baseobject"></a>+### `BaseObject`++A frequently recurring situation is that a JavaScript object and a C++ object+need to be tied together. `BaseObject` is the main abstraction for that in+Node.js, and most classes that are associated with JavaScript objects are+subclasses of it. It is defined in [`base_object.h`][].++Every `BaseObject` is associated with one [`Environment`][] and one+`v8::Object`. The `v8::Object` needs to have at least one [internal field][]+that is used for storing the pointer to the C++ object. In order to ensure this,+the V8 `SetInternalFieldCount()` function is usually used when setting up the+class from C++.++The JavaScript object can be accessed as a `v8::Local<v8::Object>` by using+`self->object()`, given a `BaseObject` named `self`.++Accessing a `BaseObject` from a `v8::Local<v8::Object>` (frequently that is+`args.This()` or `args.Holder()` in a [binding function][]) can be done using+the `Unwrap<T>(obj)` function, where `T` is a subclass of `BaseObject`.+A helper for this is the `ASSIGN_OR_RETURN_UNWRAP` macro that returns from the+current function if unwrapping fails (typically that means that the `BaseObject`+has been deleted earlier).++```c+++void Http2Session::Request(const FunctionCallbackInfo<Value>& args) {+  Http2Session* session;+  ASSIGN_OR_RETURN_UNWRAP(&session, args.Holder());+  Environment* env = session->env();+  Local<Context> context = env->context();+  Isolate* isolate = env->isolate();++  // ...+  // The actual function body, which can now use the `session` object.+  // ...+}+```++#### Lifetime management++The `BaseObject` class comes with a set of features that allow managing the+lifetime of its instances, either associating it with the lifetime of the+corresponding JavaScript object or untying the two.++The `BaseObject::MakeWeak()` method turns the underlying [`Global`][] handle+into a weak one, and makes it so that the `BaseObject::OnGCCollect()` virtual+method is called when the JavaScript object is garbage collected. By default,+that methods deletes the `BaseObject` instance.++`BaseObject::ClearWeak()` undoes this effect.++It generally makes sense to call `MakeWeak()` in the constructor of a+`BaseObject` subclass, unless that subclass is referred to by e.g. the event+loop, as is the case for the [`HandleWrap`][] and [`ReqWrap`][] classes.++In addition, there are two kinds of smart pointers that can be used to refer+to `BaseObject`s.++`BaseObjectWeakPtr<T>` is similar to `std::weak_ptr<T>`, but holds on to+an object of a `BaseObject` subclass `T` and integrates with the lifetime+management of the former. When the `BaseObject` no longer exists, e.g. when+it was garbage collected, accessing it through `weak_ptr.get()` will return+`nullptr`.++`BaseObjectPtr<T>` is similar to `std::shared_ptr<T>`, but also holds on to+objects of a `BaseObject` subclass `T`. While there are `BaseObjectPtr`s+pointing to a given object, the `BaseObject` will always maintain a strong+reference to its associated JavaScript object. This can be useful when one+`BaseObject` refers to another `BaseObject` and wants to make sure it stays+alive during the lifetime of that reference.++A `BaseObject` can be “detached” throught the `BaseObject::Detach()` method.+In this case, it will be deleted once the last `BaseObjectPtr` referring to+it is destroyed. There must be at least one such pointer when `Detach()` is+called. This can be useful when one `BaseObject` fully owns another+`BaseObject`.++<a id="asyncwrap"></a>+### `AsyncWrap`++`AsyncWrap` is a subclass of `BaseObject` that additionally provides tracking+functions for asynchronous calls. It is commonly used for classes whose methods+make calls into JavaScript without any JavaScript stack below, i.e. more or less+directly from the event loop. It is defined in [`async_wrap.h`][].++Every `AsyncWrap` subclass has a “provider type”. A list of provider types is+maintained in `src/async_wrap.h`.++Every `AsyncWrap` instance is associated with two numbers, the “async id”+and the “async trigger id”. The “async id” is generally unique per `AsyncWrap`+instance, and only changes when the object is re-used in some way.++See the [`async_hooks` module][] documentation for more information about how+this information is provided to async tracking tools.++<a id="makecallback"></a>+#### `MakeCallback`++The `AsyncWrap` class has a set of methods called `MakeCallback()`, with the+intention of the naming being that it is used to “make calls back into+JavaScript” from the event loop, rather than making callbacks in some way.+(As the naming has made its way into Node.js’s public API, it’s not worth+the breakage of fixing it).++`MakeCallback()` generally calls a method on the JavaScript object associated+with the current `AsyncWrap`, and informs async tracking code about these calls+as well as takes care of running the `process.nextTick()` and `Promise` task+queues once it returns.++Before calling `MakeCallback()`, it is typically necessary to enter both a+`HandleScope` and a `Context::Scope`.++```c+++void StatWatcher::Callback(uv_fs_poll_t* handle,+                           int status,+                           const uv_stat_t* prev,+                           const uv_stat_t* curr) {+  // Get the StatWatcher instance associated with this call from libuv,+  // StatWatcher is a subclass of AsyncWrap.+  StatWatcher* wrap = ContainerOf(&StatWatcher::watcher_, handle);+  Environment* env = wrap->env();+  HandleScope handle_scope(env->isolate());+  Context::Scope context_scope(env->context());++  // Transform 'prev' and 'curr' into an array:+  Local<Value> arr = ...;++  Local<Value> argv[] = { Integer::New(env->isolate(), status), arr };+  wrap->MakeCallback(env->onchange_string(), arraysize(argv), argv);+}+```++See [Callback scopes][] for more information.++<a id="handlewrap"></a>+### `HandleWrap`++`HandleWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv handles][] easier. It provides the `.ref()`, `.unref()` and+`.hasRef()` methods as well as `.close()` to enable easier lifetime management+from JavaScript. It is defined in [`handle_wrap.h`][].++`HandleWrap` instances are [cleaned up][cleanup hooks] automatically when the+current Node.js [`Environment`][] is destroyed, e.g. when a Worker thread stops.++`HandleWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="reqwrap"></a>+### `ReqWrap`++`ReqWrap` is a subclass of `AsyncWrap` specifically designed to make working+with [libuv requests][] easier. It is defined in [`req_wrap.h`][].++In particular, its `Dispatch()` method is designed to avoid the need to keep+track of the current count of active libuv requests.++`ReqWrap` also provides facilities for diagnostic tooling to get an+overview over libuv handles managed by Node.js.++<a id="callback-scopes"></a>+### Callback scopes++The public `CallbackScope` and the internally used `InternalCallbackScope`+classes provide the same facilities as [`MakeCallback()`][], namely:++* Emitting the `'before'` event for async tracking when entering the scope+* Setting the current async IDs to the ones passed to the constructor+* Emitting the `'after'` event for async tracking when leaving the scope+* Running the `process.nextTick()` queue+* Running microtasks, in particular `Promise` callbacks and async/await+  functions++Usually, using `AsyncWrap::MakeCallback()` or using the constructor taking+an `AsyncWrap*` argument (i.e. used as+`InternalCallbackScope callback_scope(this);`) suffices inside of Node.js’s+C++ codebase.++## C++ utilities++Node.js uses a few custom C++ utilities, mostly defined in [`util.h`][].++### Memory allocation++Node.js provides `Malloc()`, `Realloc()` and `Calloc()` functions that work+like their C stdlib counterparts, but crash if memory cannot be allocated.+(As V8 does not handle out-of-memory situations gracefully, it does not make+sense for Node.js to attempt to do so in all cases.)++The `UncheckedMalloc()`, `UncheckedRealloc()` and `UncheckedCalloc()` functions+return `nullptr` in these cases (or when `size == 0`).++#### Optional stack-based memory allocation++The `MaybeStackBuffer` class provides a way to allocate memory on the stack+if it is smaller than a given limit, and falls back to allocating it on the+heap if it is larger. This can be useful for performantly allocating temporary+data if it is typically expected to be small (e.g. file paths).++The `Utf8Value`, `TwoByteValue` (i.e. UTF-16 value) and `BufferValue`+(`Utf8Value` but copy data from a `Buffer` is that is passed) helpers+inherit from this class and allow accessing the characters in a JavaScript+string this way.++```c+++static void Chdir(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  // ...+  CHECK(args[0]->IsString());+  Utf8Value path(env->isolate(), args[0]);+  int err = uv_chdir(*path);+  if (err) {+    // ... error handling ...+  }+}+```++### Assertions++Node.js provides a few macros that behave similar to `assert()`:++* `CHECK(expression)` aborts the process with a stack trace+  if `expression` is false.+* `CHECK_EQ(a, b)` checks for `a == b`+* `CHECK_GE(a, b)` checks for `a >= b`+* `CHECK_GT(a, b)` checks for `a > b`+* `CHECK_LE(a, b)` checks for `a <= b`+* `CHECK_LT(a, b)` checks for `a < b`+* `CHECK_NE(a, b)` checks for `a != b`+* `CHECK_NULL(val)` checks for `a == nullptr`+* `CHECK_NOT_NULL(val)` checks for `a != nullptr`+* `CHECK_IMPLIES(a, b)` checks that `b` is true if `a` is true.+* `UNREACHABLE([message])` aborts the process if it is reached.++`CHECK`s are always enabled. For checks that should only run in debug mode, use+`DCHECK()`, `DCHECK_EQ()`, etc.++### Scope-based cleanup++The `OnScopeLeave()` function can be used to run a piece of code when leaving+the current C++ scope.++```c+++static void GetUserInfo(const FunctionCallbackInfo<Value>& args) {+  Environment* env = Environment::GetCurrent(args);+  uv_passwd_t pwd;+  // ...++  const int err = uv_os_get_passwd(&pwd);++  if (err) {+    // ... error handling, return early ...+  }++  auto free_passwd = OnScopeLeave([&]() { uv_os_free_passwd(&pwd); });++  // ...+  // Turn `pwd` into a JavaScript object now; whenever we return from this+  // function, `uv_os_free_passwd()` will be called.+  // ...+}+```++[`BaseObject`]: #baseobject+[`Context`]: #context+[`Environment`]: #environment+[`Global`]: #global-handles+[`HandleWrap`]: #handlewrap+[`IsolateData`]: #isolate-data+[`Isolate`]: #isolate+[`Local`]: #local-handles+[`MakeCallback()`]: #makecallback+[`MessagePort`]: https://nodejs.org/api/worker_threads.html#worker_threads_class_messageport+[`ReqWrap`]: #reqwrap+[`async_hooks` module]: https://nodejs.org/api/async_hooks.html+[`async_wrap.h`]: async_wrap.h+[`base_object.h`]: base_object.h+[`handle_wrap.h`]: handle_wrap.h+[`memory_retainer.h`]: memory_retainer.h

Sorry to be late. This link seems 404 now.

addaleax

comment created time in 3 months

push eventvsemozhetbyt/node

Vladislav Botvin

commit sha 615ec972de176f7d14124e96f57595c2e3c05ad1

buffer: change var to let PR-URL: https://github.com/nodejs/node/pull/30292 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Ilia Safronov

commit sha 7f50839f7de0fc5ff86093f56bebcc44ad5a3ac5

lib: change var to let in lib/_stream_duplex.js PR-URL: https://github.com/nodejs/node/pull/30297 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Dmitriy Kikinskiy

commit sha bbfa2e9cb13334032ad8704db7e5cdc6c457305c

dns: switch var to const/let Simple exchange var to const/let. PR-URL: https://github.com/nodejs/node/pull/30302 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Nolik

commit sha eb773217ae6f4b4ea0e906ff1cc492502c32a006

process: add coverage tests for sourceMapFromDataUrl method PR-URL: https://github.com/nodejs/node/pull/30319 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Ben Coe <bencoe@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Masashi Hirano <shisama07@gmail.com>

view details

peze

commit sha 896b75a4da58a7283d551c4595e0aa454baca3e0

path: replace var with let in lib/path.js PR-URL: https://github.com/nodejs/node/pull/30260 Refs: https://github.com/nodejs/code-and-learn/issues/97 Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com>

view details

Rich Trott

commit sha acd35d92750840f76a6c8bb4574a7b9fa3ca6b57

test: fix test-benchmark-cluster test-benchmark-cluster needs to account for an option added in 973f324. PR-URL: https://github.com/nodejs/node/pull/30342 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Rich Trott

commit sha 5f9794ea9aaaf5597974a65460e1f3069f68475f

doc,meta: remove wait period for npm pull requests Treat npm pull requests like all other pull requests. Remove special extended wait period for landing. PR-URL: https://github.com/nodejs/node/pull/30329 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Ruy Adorno

commit sha 4b97c3addb246274cd7e8432edd537e0bdf60b63

deps: update npm to 6.13.0 PR-URL: https://github.com/nodejs/node/pull/30271 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>

view details

Rich Trott

commit sha e44d73f0117b9a1f7e5f9af759871b24638331a6

doc,meta: allow Travis results for doc/comment changes Permit the use of Travis CI results for pull requests that only change documentation or comments. This also removes node-test-pull-request-lite-pipeline from the documentation. Efforts to move all CI jobs to pipelines have stalled and it's not clear that our current Jenkins admins are enthusiastic about pipelines. PR-URL: https://github.com/nodejs/node/pull/30330 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

AshCripps

commit sha 8ac771b8093f26ede5426a10ca243eed0d2af2ef

test: mark test-http-dump-req-when-res-ends as flaky on windows PR-URL: https://github.com/nodejs/node/pull/30316 Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

cclauss

commit sha e6a58a89cb01aaac668aabf4cab737c6503a27a1

test: fix Python unittests in ./test and ./tools Co-authored-by: @patrickhousley Fixes to Python tests to ensure that the following all pass: 1. __python2 -m pytest ./test ./tools__ # 30 tests pass 2. __python3 -m pytest ./test ./tools__ # 30 tests pass 3. __python2 -m unittest discover -s ./test/tools__ # 1 test passes 4. __python3 -m unittest discover -s ./test/tools__ # 1 test passes 5. __PYTHON=python2 make tooltest__ # 1 test passes 6. __PYTHON=python3 make tooltest__ # 1 test passes This is a subset of #30033 PR-URL: https://github.com/nodejs/node/pull/30340 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: David Carlier <devnexen@gmail.com>

view details

Kamat, Trivikram

commit sha e55d65384d3feb3dd1bb7341a23766663fbcdba6

doc: add link to node-code-ide-configs in testing Refs: https://github.com/orgs/nodejs/teams/collaborators/discussions/58 This config will help contributors to run/debug tests on VSCode PR-URL: https://github.com/nodejs/node/pull/24012 Reviewed-By: James M Snell <jasnell@gmail.com>

view details

Robert Nagy

commit sha f8c069f5b88a25304ee2fc638c51464b4df196dd

stream: increase MAX_HWM MAX_HWM was added in 9208c89 where the highwatermark was changed to always increase in steps of highest power of 2 to prevent increasing hwm excessivly in tiny amounts. Why a limit was added on the highwatermark is unclear but breaks existing usage where a larger read size is used. The invariant for read(n) is that a buffer of size n is always returned. Considering a maximum ceiling on the buffer size breaks this invariant. This PR significantly increases the limit to make it less likely to break the previous invariant and also documents the limit. Fixes: https://github.com/nodejs/node/issues/29933 PR-URL: https://github.com/nodejs/node/pull/29938 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>

view details

Anna Henningsen

commit sha e66a2acc4cb9fc09fc32d1833b89ae56468a0931

src: migrate off ArrayBuffer::GetContents V8 deprecates `GetContents()` in favour of `GetBackingStore()`. Update our code to reflect that. V8 also deprecates `Externalize()` and `IsExternal()`; we should be able to remove all usage of this once V8 8.0 is there. PR-URL: https://github.com/nodejs/node/pull/30339 Refs: https://github.com/v8/v8/commit/bfe3d6bce734e596e312465e207bcfd55a59fe34 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com>

view details

telenord

commit sha c396f87efcb4f5f83592943b11e328e9106e286b

http: http_incoming rename var to let and const PR-URL: https://github.com/nodejs/node/pull/30285 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

alexahdp

commit sha 73780e33e3424c040f42eed7ac3999cdf36bbaa4

net: replaced vars to lets and consts PR-URL: https://github.com/nodejs/node/pull/30287 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

telenord

commit sha cd696959d9a9a18b4a68c3b2a142a9b3fedae702

http: http_common rename var to let and const PR-URL: https://github.com/nodejs/node/pull/30288 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>

view details

Vadim Gorbachev

commit sha f372867a40604878074049ef46303640b43079b9

lib: replaced var to let in lib/v8.js PR-URL: https://github.com/nodejs/node/pull/30305 Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>

view details

Daniil Pletnev

commit sha cc6f99de449beb0993db3647de4ef979bead804d

tls: replace var with let PR-URL: https://github.com/nodejs/node/pull/30308 Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>

view details

Guy Bedford

commit sha 796f3d0af49164314868c4778af90eca356f1fef

esm: unflag --experimental-modules PR-URL: https://github.com/nodejs/node/pull/29866 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>

view details

push time in 3 months

Pull request review commentnodejs/node

doc,deps: document how to maintain ICU in Node.js

+# Maintaining ICU in Node.js++## Background++International Components for Unicode ([ICU4C][ICU]) is used both by V8+and also by Node.js directly to provide internationalization+functionality. To quote from icu-project.org:++> ICU is a mature, widely used set of C/C++ and Java libraries providing+> Unicode and Globalization support for software applications. ICU is+> widely portable and gives applications the same results on all platforms+> and between C/C++ and Java software.++## Data dependencies++ICU consumes and includes:++* Extracted locale data from [CLDR][]+* Extracted [Unicode][] data.+* Time zone ([tz][]) data++The current versions of these items can be viewed for node with `node -p process.versions`:++```shell+$ node -p process.versions++{+  …+  cldr: '35.1',+  icu: '64.2',+  tz: '2019a',+  unicode: '12.1'+}+```++## Release Schedule++ICU typically has >1 release a year, particularly coinciding with a major+release of [Unicode][]. The current release schedule is available on the [ICU][]+website on the left sidebar.++### V8 depends on ICU++V8 will aggressively upgrade to a new ICU version, due to requirements for+features/bugfixes needed for [Ecma402][] support. The minimum required version+of ICU is specified within the V8 source tree. If the ICU version is too old,+V8 will not compile.++```c+// deps/v8/src/objects/intl-objects.h+#define V8_MINIMUM_ICU_VERSION 64+```++V8 in Node.js depends on the ICU version supplied by Node.js.++The file `tools/icu/icu_versions.json` contains the current minimum+version of ICU that Node.js is known to work with. This should be+_at least_ the same version as V8. When V8 is updated, please+bump this number as well so that users will find out earlier that+their ICU is too old.++## How to upgrade ICU++* Make sure your Node.js workspace is clean (clean `git status`) should be+  sufficient.+* Configure Node.js with the specific [ICU version](http://icu-project.org/download)+  you want to upgrade to, for example:++```shell+./configure \+    --with-intl=full-icu \+    --with-icu-source=http://download.icu-project.org/files/icu4c/58.1/icu4c-58_1-src.tgz+make+```++> _Note_ in theory, the equivalent `vcbuild.bat` commands should work also,+> but the commands below are makefile-centric.++* If there are ICU version-specific changes needed, you may need to make changes+  in `tools/icu/icu-generic.gyp` or add patch files to `tools/icu/patches`.+  * Specifically, look for the lists in `sources!` in the `tools/icu/icu-generic.gyp` for+  files to exclude.++* Verify the Node.js build works:++```shell+make test-ci+```++Also running++<!-- eslint-disable strict -->++```js+new Intl.DateTimeFormat('es', {month: 'long'}).format(new Date(9E8));+```++…Should return `enero` not `January`.++* Now, copy `deps/icu` over to `deps/icu-small`++> :warning: Do not modify any source code in `deps/icu-small` !+> See section below about floating patches to ICU.++```shell+python tools/icu/shrink-icu-src.py+```++* Now, do a clean rebuild of Node.js to test:++```shell+make -k distclean+./configure+make+```++* Test this newly default-generated Node.js++<!-- eslint-disable strict -->++```js+process.versions.icu;+new Intl.DateTimeFormat('es', {month: 'long'}).format(new Date(9E8));+```++(This should print your updated ICU version number, and also `January` again.)++You are ready to check in the updated `deps/icu-small`. This is a big commit,+so make this a separate commit from the smaller changes.++> :warning: Do not modify any source code in `deps/icu-small` !+> See section below about floating patches to ICU.++* Now, rebuild the Node.js license.++```shell+# clean up - remove deps/icu+make clean+tools/license-builder.sh+```++* Update the URL and hash for the full ICU file in `tools/icu/current_ver.dep`.+It should match the ICU URL used in the first step.  When this is done, the+following should build with small ICU.++```shell+# clean up+rm -rf out deps/icu deps/icu4c*+./configure --with-intl=small-icu --download=all+make+make test-ci+```++* commit the change to `tools/icu/current_ver.dep` and `LICENSE` files.++  * Note: To simplify review, I often will “pre-land” this patch, meaning that+  I run the patch through `curl -L https://github.com/nodejs/node/pull/xxx.patch+  | git am -3 --whitespace=fix` per the collaborator’s guide… and then push that+  patched branch into my PR's branch. This reduces the whitespace changes that+  show up in the PR, since the final land will eliminate those anyway.++## Floating patches to ICU++Floating patches are applied at `configure` time. The "patch" files+are used instead of the original source files. The patch files are+complete `.cpp` files replacing the original contents.++Patches are tied to a specific ICU version. They won’t apply to a+future ICU version.  We assume that you filed a bug against [ICU][] and+upstreamed the fix, so the patch won’t be needed in a later ICU+version.++### Example++For example, to patch `source/tools/toolutil/pkg_genc.cpp` for+ICU version 63:++```shell+# go to your Node directory

Maybe Node.js or node?

srl295

comment created time in 3 months

Pull request review commentnodejs/node

doc,deps: document how to maintain ICU in Node.js

+# Maintaining ICU in Node.js++## Background++International Components for Unicode ([ICU4C][ICU]) is used both by V8+and also by Node.js directly to provide internationalization+functionality. To quote from icu-project.org:++> ICU is a mature, widely used set of C/C++ and Java libraries providing+> Unicode and Globalization support for software applications. ICU is+> widely portable and gives applications the same results on all platforms+> and between C/C++ and Java software.++## Data dependencies++ICU consumes and includes:++* Extracted locale data from [CLDR][]+* Extracted [Unicode][] data.+* Time zone ([tz][]) data++The current versions of these items can be viewed for node with `node -p process.versions`:++```shell+$ node -p process.versions++{+  …+  cldr: '35.1',+  icu: '64.2',+  tz: '2019a',+  unicode: '12.1'+}+```++## Release Schedule++ICU typically has >1 release a year, particularly coinciding with a major+release of [Unicode][]. The current release schedule is available on the [ICU][]+website on the left sidebar.++### V8 depends on ICU++V8 will aggressively upgrade to a new ICU version, due to requirements for+features/bugfixes needed for [Ecma402][] support. The minimum required version+of ICU is specified within the V8 source tree. If the ICU version is too old,+V8 will not compile.++```c+// deps/v8/src/objects/intl-objects.h+#define V8_MINIMUM_ICU_VERSION 64+```++V8 in Node.js depends on the ICU version supplied by Node.js.++The file `tools/icu/icu_versions.json` contains the current minimum+version of ICU that Node.js is known to work with. This should be+_at least_ the same version as V8. When V8 is updated, please+bump this number as well so that users will find out earlier that+their ICU is too old.++## How to upgrade ICU++* Make sure your Node.js workspace is clean (clean `git status`) should be

Maybe parentheses nit:

* Make sure your Node.js workspace is clean (clean `git status` should be
  sufficient).
srl295

comment created time in 3 months

Pull request review commentnodejs/node

doc,deps: document how to maintain ICU in Node.js

 internationalization functionality. * `README.md` — you are here * `shrink-icu-src.py` — this is used during upgrade (see guide below) -## How to upgrade ICU+Note:+> The files in this directory were written for the Node.js v0.12 effort.+> The original intent was to merge the tools such as `icutrim.py` and `iculslocs.cc`+> back into ICU. ICU has gained its own “data slicer” tool.+> There is an issue open, https://github.com/nodejs/node/issues/25136+> for replacing `icutrim.py` with the [ICU data slicer][]. -* Make sure your Node.js workspace is clean (clean `git status`) should be-  sufficient.-* Configure Node.js with the specific [ICU version](http://icu-project.org/download)-  you want to upgrade to, for example:+## See Also -```shell-./configure \-    --with-intl=full-icu \-    --with-icu-source=http://download.icu-project.org/files/icu4c/58.1/icu4c-58_1-src.tgz-make-```+* [docs/guides/maintaining-icu.md](../../doc/guides/maintaining-icu.md) for+information on maintaining ICU in Node.js -> _Note_ in theory, the equivalent `vcbuild.bat` commands should work also,-> but the commands below are makefile-centric.+* [docs/api/intl.md](../../doc/api/intl.md) for information on the+internationalization-related APIs in Node.js+* [The ICU Homepage][ICU] -* If there are ICU version-specific changes needed, you may need to make changes-  in `icu-generic.gyp` or add patch files to `tools/icu/patches`.-  * Specifically, look for the lists in `sources!` in the `icu-generic.gyp` for-  files to exclude.--* Verify the Node.js build works:--```shell-make test-ci-```--Also running--<!-- eslint-disable strict -->--```js-new Intl.DateTimeFormat('es', {month: 'long'}).format(new Date(9E8));-```--…Should return `enero` not `January`.--* Now, copy `deps/icu` over to `deps/icu-small`--```shell-python tools/icu/shrink-icu-src.py-```--* Now, do a clean rebuild of Node.js to test:--```shell-make -k distclean-./configure-make-```--* Test this newly default-generated Node.js--<!-- eslint-disable strict -->--```js-process.versions.icu;-new Intl.DateTimeFormat('es', {month: 'long'}).format(new Date(9E8));-```--(This should print your updated ICU version number, and also `January` again.)--You are ready to check in the updated `deps/small-icu`. This is a big commit,-so make this a separate commit from the smaller changes.--* Now, rebuild the Node.js license.--```shell-# clean up - remove deps/icu-make clean-tools/license-builder.sh-```--* Update the URL and hash for the full ICU file in `tools/icu/current_ver.dep`.-It should match the ICU URL used in the first step.  When this is done, the-following should build with small ICU.--```shell-# clean up-rm -rf out deps/icu deps/icu4c*-./configure --with-intl=small-icu --download=all-make-make test-ci-```--* commit the change to `tools/icu/current_ver.dep` and `LICENSE` files.--  * Note: To simplify review, I often will “pre-land” this patch, meaning that-  I run the patch through `curl -L https://github.com/nodejs/node/pull/xxx.patch-  | git am -3 --whitespace=fix` per the collaborator’s guide… and then push that-  patched branch into my PR's branch. This reduces the whitespace changes that-  show up in the PR, since the final land will eliminate those anyway.---------## Postscript about the tools--The files in this directory were written for the Node.js effort.-It was the intent of their author (Steven R. Loomis / srl295) to-merge them upstream into ICU, pending much discussion within the-ICU-TC.--`icu_small.json` is somewhat node-specific as it specifies a "small ICU"-configuration file for the `icutrim.py` script. `icutrim.py` and-`iculslocs.cpp` may themselves be superseded by components built into-ICU in the future. As of this writing, however, the tools are separate-entities within Node.js, although theyare being scrutinized by interested-members of the ICU-TC. The “upstream” ICU bugs are given below.--* [#10919](http://bugs.icu-project.org/trac/ticket/10919)-  (experimental branch - may copy any source patches here)-* [#10922](http://bugs.icu-project.org/trac/ticket/10922)-  (data packaging improvements)-* [#10923](http://bugs.icu-project.org/trac/ticket/10923)-  (rewrite data building in python)+[ICU data slicer]: https://github.com/unicode-org/icu/blob/master/docs/userguide/icu_data/buildtool.md+[ICU]: http//icu-project.org
[ICU]: http://icu-project.org
srl295

comment created time in 3 months

Pull request review commentnodejs/node

http: llhttp opt-in insecure HTTP header parsing

 added: v9.0.0 Specify the `module` of a custom [experimental ECMAScript Module loader][]. `module` may be either a path to a file, or an ECMAScript Module name. +### `--insecure-http`+<!-- YAML+added: FIXME

Nit: according to docs and release automation, this needs to be

added: REPLACEME
sam-github

comment created time in 3 months

Pull request review commentnodejs/node

http2: make maximum invalid frames and maximum rejected streams configurable

 server.listen(80); <!-- YAML added: v8.4.0 changes:+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionRejectedStreams option with a default of 100.+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionInvalidFrames option with a default of 1000.
    description: Added `maxSessionInvalidFrames` option with a default of
                 `1000`.
lundibundi

comment created time in 3 months

Pull request review commentnodejs/node

http2: make maximum invalid frames and maximum rejected streams configurable

 error will be thrown. <!-- YAML added: v8.4.0 changes:+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionRejectedStreams option with a default of 100.
    description: Added `maxSessionRejectedStreams` option with a default of
                 `100`.
lundibundi

comment created time in 3 months

Pull request review commentnodejs/node

http2: make maximum invalid frames and maximum rejected streams configurable

 server.listen(80); <!-- YAML added: v8.4.0 changes:+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionRejectedStreams option with a default of 100.
    description: Added `maxSessionRejectedStreams` option with a default of
                 `100`.
lundibundi

comment created time in 3 months

Pull request review commentnodejs/node

http2: make maximum invalid frames and maximum rejected streams configurable

 error will be thrown. <!-- YAML added: v8.4.0 changes:+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionRejectedStreams option with a default of 100.+  - version: REPLACEME+    pr-url: https://github.com/nodejs/node/pull/30534+    description: Added maxSessionInvalidFrames option with a default of 1000.
    description: Added `maxSessionInvalidFrames` option with a default of
                 `1000`.
lundibundi

comment created time in 3 months

pull request commentnodejs/node

cli: add --trace-exit cli option

It seems doc/node.1 also needs updating.

legendecas

comment created time in 3 months

Pull request review commentnodejs/node

doc: adds NO_COLOR to assert doc page

 assert.deepEqual([[[1, 2, 3]], 4, 5], [[[1, 2, '3']], 4, 5]); //   ] ``` -To deactivate the colors, use the `NODE_DISABLE_COLORS` environment variable.+To deactivate the colors, use the `NO_COLOR` or+`NODE_DISABLE_COLORS` environment variable. This will also deactivate the colors in the REPL. +For more on the color support in terminal environments, read+the tty [getColorDepth](tty.html#tty_writestream_getcolordepth_env) doc.

Nit:

the tty [getColorDepth()](tty.html#tty_writestream_getcolordepth_env) doc.
shobhitchittora

comment created time in 3 months

issue commentGoogleChrome/puppeteer

how to check if selector exists or is present ?

Maybe if you provide a small but complete script example, somebody will be able to help.

fran0254

comment created time in 3 months

pull request commentnodejs/node

deps: ICU time zone data documentation

It seems we have some linter issues (line length and list markers).

apaprocki

comment created time in 3 months

Pull request review commentnodejs/node

deps: ICU time zone data documentation

+# ICU Time Zone Data++Time zone data files are updated independently of ICU CLDR data.  ICU and its main data files do not need to be upgraded in order to apply time zone data file fixes.++The [IANA tzdata](https://www.iana.org/time-zones) project releases new versions and announces them on the [`tz-announce`](http://mm.icann.org/pipermail/tz-announce/) mailing list.++The Unicode project takes new releases and publishes [updated time zone data files](https://github.com/unicode-org/icu-data/tree/master/tzdata/icunew) in the icu/icu-data repository.++All modern versions of Node use the version 44 ABI of the time zone data files.++## Updating the `icu-small` ICU `.dat` File++- Decompress `deps/icu-small/source/data/in/icudt##l.dat.bz2`, where `##` is the ICU major version number.+- Clone the icu/icu-data repository and copy the latest `tzdata` release `le` files into the `source/data/in` directory.+- Follow the upstream [ICU instructions](http://userguide.icu-project.org/datetime/timezone) to patch the ICU `.dat` file:+  > `for i in zoneinfo64.res windowsZones.res timezoneTypes.res metaZones.res; do icupkg -a $i icudt*l.dat`+- Optionally, verify that there is only one of the above files listed when using `icupkg -l`.+- Optionally, extract each file using `icupkg -x` and verify the `shasum` matches the desired value.+- Compress the `.dat` file as the same filename in the first step.

Not sure but maybe:

- Compress the `.dat` file with the same filename as in the first step.
apaprocki

comment created time in 3 months

Pull request review commentnodejs/node

deps: ICU time zone data documentation

+# ICU Time Zone Data++Time zone data files are updated independently of ICU CLDR data.  ICU and its main data files do not need to be upgraded in order to apply time zone data file fixes.++The [IANA tzdata](https://www.iana.org/time-zones) project releases new versions and announces them on the [`tz-announce`](http://mm.icann.org/pipermail/tz-announce/) mailing list.++The Unicode project takes new releases and publishes [updated time zone data files](https://github.com/unicode-org/icu-data/tree/master/tzdata/icunew) in the icu/icu-data repository.++All modern versions of Node use the version 44 ABI of the time zone data files.

Nit:

All modern versions of Node.js use the version 44 ABI of the time zone data files.
apaprocki

comment created time in 3 months

issue commentGoogleChrome/puppeteer

how to check if selector exists or is present ?

Do you wait for the default timeout (30 sec)?

fran0254

comment created time in 3 months

Pull request review commentnodejs/node

doc: esm: improve dual package hazard docs

 This approach is appropriate for any of the following use cases: * The package stores internal state, and the package author would prefer not to   refactor the package to isolate its state management. See the next section. -A variant of this approach would add an export, e.g. `"./module"`, to point to-an all-ES module-syntax version the package. This could be used via `import+A variant of this approach not requiring `--experimental-conditional-exports`+for consumers could be to add an export, e.g. `"./module"`, to point to an+all-ES module-syntax version the package. This could be used via `import

Not sure, but maybe:

all-ES module-syntax version of the package. This could be used via `import
GeoffreyBooth

comment created time in 3 months

Pull request review commentnodejs/node

doc: esm: improve dual package hazard docs

 This approach is appropriate for any of the following use cases: Even with isolated state, there is still the cost of possible extra code execution between the CommonJS and ES module versions of a package. +As with the previous approach, a variant of this approach not requiring+`--experimental-conditional-exports` for consumers could be to add an export,+e.g. `"./module"`, to point to an all-ES module-syntax version the package:

Not sure, but maybe:

e.g. `"./module"`, to point to an all-ES module-syntax version of the package:
GeoffreyBooth

comment created time in 3 months

issue commentGoogleChrome/puppeteer

how to check if selector exists or is present ?

Try this:

  try {
    await page.waitForSelector('img');
    console.log('found');
  } catch {
    console.log('not found');
  }
fran0254

comment created time in 3 months

issue commentGoogleChrome/puppeteer

how to check if selector exists or is present ?

It seems the way is the same: use page.waitForSelector() to wait for the element, timeout means failed log-in.

fran0254

comment created time in 3 months

delete branch vsemozhetbyt/node

delete branch : doc-nits-09.11.2019

delete time in 3 months

startedpvdz/tenko

started time in 4 months

PR opened nodejs/node

doc: fix some recent doc nits
Checklist
  • [x] make -j4 test (UNIX), or vcbuild test (Windows) passes
  • [x] documentation is changed or added
  • [x] commit message follows commit guidelines
  • Fix formatting.
  • Fix list numbering.
  • Unify abbreviation casing.
  • Use an uppercased constructor in a hypothetic code example.
  • Fix typos.
  • Fix sorting in sections and references.
+19 -19

0 comment

4 changed files

pr created time in 4 months

create barnchvsemozhetbyt/node

branch : doc-nits-09.11.2019

created branch time in 4 months

push eventvsemozhetbyt/node

Michaël Zasso

commit sha a4e075f66833d08fc426c9406eb3894ec56326c1

test: fix test runner for Python 3 on Windows Explicitly open files with utf8 encoding, otherwise the system could use another encoding such as latin1 by default. PR-URL: https://github.com/nodejs/node/pull/30023 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Christian Clauss <cclauss@me.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Michaël Zasso

commit sha b554214249b4d03ca68f98f2a2715511a7049397

build: default Windows build to Visual Studio 2019 Building and testing Node.js with Visual Studio 2019 is now working as expected. Fallback to VS 2017 if VS 2019 was not found. Fixes: https://github.com/nodejs/node/issues/27214 PR-URL: https://github.com/nodejs/node/pull/30022 Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Beth Griggs <Bethany.Griggs@uk.ibm.com>

view details

Michaël Zasso

commit sha 0822bfaa9f52aea289abd0e15a90b0df2e12f7e1

build: make configure --without-snapshot a no-op From V8 7.9, the option will no longer exist upstream. Refs: https://chromium-review.googlesource.com/c/chromium/src/+/1796325 PR-URL: https://github.com/nodejs/node/pull/30021 Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

cjihrig

commit sha 7d433a936bce26707f7a10bb56b121fe0dfb0a66

deps: upgrade to libuv 1.33.1 Notable changes: - uv_random() has been added. - More work to read those pesky Windows environment variables. - Several build fixes for Tier 3 platforms (Android, NetBSD, OpenBSD, Haiku). - Stop using fsevents to watch files (using kqueue again). PR-URL: https://github.com/nodejs/node/pull/29996 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Daniel Bevenius

commit sha a5bab214589b881b6714b43136e48936652153a2

src: remove unused iomanip include This commit removes the include of the IO manipulators header as I can't find that it is used anywhere. PR-URL: https://github.com/nodejs/node/pull/30004 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Michaël Zasso

commit sha 701933ca8f943604af245c4e066cf6f3d4ecbcc2

2019-10-21, Version 12.13.0 'Erbium' (LTS) This release marks the transition of Node.js 12.x into Long Term Support (LTS) with the codename 'Erbium'. The 12.x release line now moves into "Active LTS" and will remain so until October 2020. After that time, it will move into "Maintenance" until end of life in April 2022. Notable changes: npm was updated to 6.12.0. It now includes a version of `node-gyp` that supports Python 3 for building native modules. PR-URL: https://github.com/nodejs/node/pull/29981

view details

Shelley Vohr

commit sha 71b342f93725a9bba5fa1f83a9f0fa88a482d759

src: fewer uses of NODE_USE_V8_PLATFORM PR-URL: https://github.com/nodejs/node/pull/30029 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>

view details

Anna Henningsen

commit sha 31217a8e88d7414579284267f8715112bf8a0fc6

cli: add --trace-uncaught flag Add a flag that makes Node.js print the stack trace at the time of *throwing* uncaught exceptions, rather than at the creation of the `Error` object, if there is any. This is disabled by default because it affects GC behavior. PR-URL: https://github.com/nodejs/node/pull/30025 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Beth Griggs

commit sha 42bf0c8df2094813e0d86af9eddf374fc9bdadc4

2019-10-22, Version 13.0.0 (Current) Notable changes: * assert: * If the validation function passed to `assert.throws()` or `assert.rejects()` returns a value other than `true`, an assertion error will be thrown instead of the original error to highlight the programming mistake (Ruben Bridgewater). https://github.com/nodejs/node/pull/28263 * If a constructor function is passed to validate the instance of errors thrown in `assert.throws()` or `assert.reject()`, an assertion error will be thrown instead of the original error (Ruben Bridgewater). https://github.com/nodejs/node/pull/28263 * build: * Node.js releases are now built with default full-icu support. This means that all locales supported by ICU are now included and Intl-related APIs may return different values than before (Richard Lau). https://github.com/nodejs/node/pull/29887 * The minimum Xcode version supported for macOS was increased to 10. It is still possible to build Node.js with Xcode 8 but this may no longer be the case in a future v13.x release (Michael Dawson). https://github.com/nodejs/node/pull/29622 * child_process: * `ChildProcess._channel` (DEP0129) is now a Runtime deprecation (cjihrig). https://github.com/nodejs/node/pull/27949 * console: * The output `console.timeEnd()` and `console.timeLog()` will now automatically select a suitable time unit instead of always using milliseconds (Xavier Stouder). https://github.com/nodejs/node/pull/29251 * deps: * The V8 engine was updated to version 7.8. This includes performance improvements to object destructuring, memory usage and WebAssembly startup time (Myles Borins). https://github.com/nodejs/node/pull/29694) * domain: * The domain's error handler is now executed with the active domain set to the domain's parent to prevent inner recursion (Julien Gilli). https://github.com/nodejs/node/pull/26211 * fs: * The undocumented method `FSWatcher.prototype.start()` was removed (Lucas Holmquist). https://github.com/nodejs/node/pull/29905 * Calling the `open()` method on a `ReadStream` or `WriteStream` now emits a runtime deprecation warning. The methods are supposed to be internal and should not be called by user code (Robert Nagy). https://github.com/nodejs/node/pull/29061 * `fs.read/write`, `fs.readSync/writeSync` and `fd.read/write` now accept any safe integer as their `offset` parameter. The value of `offset` is also no longer coerced, so a valid type must be passed to the functions (Zach Bjornson). https://github.com/nodejs/node/pull/26572 * http: * Aborted requests no longer emit the `end` or `error` events after `aborted` (Robert Nagy). https://github.com/nodejs/node/pull/27984 https://github.com/nodejs/node/pull/20077 * Data will no longer be emitted after a socket error (Robert Nagy). https://github.com/nodejs/node/pull/28711 * The legacy HTTP parser (previously available under the `--http-parser=legacy` flag) was removed (Anna Henningsen). https://github.com/nodejs/node/pull/29589 * The `host` option for HTTP requests is now validated to be a string value (Giorgos Ntemiris). https://github.com/nodejs/node/pull/29568 * The `request.connection` and `response.connection` properties are now runtime deprecated. The equivalent `request.socket` and `response.socket` should be used instead (Robert Nagy). https://github.com/nodejs/node/pull/29015 * http, http2: * The default server timeout was removed (Ali Ijaz Sheikh). https://github.com/nodejs/node/pull/27558 * Brought 425 status code name into accordance with RFC 8470. The name changed from "Unordered Collection" to "Too Early" (Sergei Osipov). https://github.com/nodejs/node/pull/29880 * lib: * The `error.errno` property will now always be a number. To get the string value, use `error.code` instead (Joyee Cheung). https://github.com/nodejs/node/pull/28140 * module: * `module.createRequireFromPath()` is deprecated. Use `module.createRequire()` instead (cjihrig). https://github.com/nodejs/node/pull/27951 * src: * Changing the value of `process.env.TZ` will now clear the tz cache. This affects the default time zone used by methods such as `Date.prototype.toString` (Ben Noordhuis). https://github.com/nodejs/node/pull/20026 * stream: * The timing and behavior of streams was consolidated for a number of edge cases. Please look at the individual commits below for more information. PR-URL: https://github.com/nodejs/node/pull/29504

view details

Anna Henningsen

commit sha 4201cdde89af76d80ec794e82ee0b1c47c107299

test: expand Worker test for non-shared ArrayBuffer This test would be broken by V8 7.9 due to the changed `ArrayBuffer` backing store management (the same way that V8 7.8 broke this for `SharedArrayBuffer`s). While working on a solution, it would be good to already have this test in Node.js to avoid unnecessary accidental breakage. Refs: https://github.com/nodejs/node-v8/issues/115 PR-URL: https://github.com/nodejs/node/pull/30044 Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Luigi Pinca

commit sha 94230d15bdbfe229901b221feb5814b60f8eeedb

stream: remove dead code `String.prototype.split()` returns an array of strings so the branch is never taken. Fixes: https://github.com/nodejs/node/issues/30040 PR-URL: https://github.com/nodejs/node/pull/30041 Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>

view details

Luigi Pinca

commit sha 1070153cf6da6eb95644799008240825432b07e3

stream: simplify uint8ArrayToBuffer helper The fallback code is no longer used when exporting to readable-stream. Refs: https://github.com/nodejs/node/pull/29514 PR-URL: https://github.com/nodejs/node/pull/30041 Fixes: https://github.com/nodejs/node/issues/30040 Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>

view details

Vse Mozhet Byt

commit sha 0ecd3c68452ff9b9709cdaf5b11b48e36c685a8e

doc: join parts of disrupt section in cli.md Also eliminate some redundancy. PR-URL: https://github.com/nodejs/node/pull/30038 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Yongsheng Zhang <zyszys98@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

view details

Richard Lau

commit sha 639085e410e805303b4511edee4c2a315006a7f8

build: log the found compiler version if too old `configure` will log a warning if the detected compiler is not new enough. Take some of the guesswork out of it by also logging the version of the compiler that was detected. PR-URL: https://github.com/nodejs/node/pull/30028 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Jiawen Geng <technicalcute@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com>

view details

legendecas

commit sha 45efe67a84d382fed3c86d56f56beffc6bb0a136

src: expose ListNode<T>::prev_ on postmortem metadata Make ListNode<T> postmortem easier to find last items in the queue. PR-URL: https://github.com/nodejs/node/pull/30027 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: David Carlier <devnexen@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>

view details

Anna Henningsen

commit sha 2dc70657a33d19e67fb8db4de4169a11371c5763

src: make implementing CancelPendingDelayedTasks for platform optional Fold `CancelPendingDelayedTasks()` into `UnregisterIsolate()` and make implementing it optional. It makes sense for these two operations to happen at the same time, so it is sufficient to provide a single operation instead of two separate ones. PR-URL: https://github.com/nodejs/node/pull/30034 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Shelley Vohr <codebytere@gmail.com>

view details

Richard Lau

commit sha b5b7e585f07c962a8329e021e9a9c56ce8a71420

build: make linter failures fail `test-doc` target Linter failures in the `test-doc` make target were not failing the build if the subsequent `doctools` test passed as its exit code wasn't being preserved. Make the `lint` target a dependency of `test-doc` so that it is outside of the `node_use_openssl` guard -- its own dependencies have their own guards where necessary and the targets that don't require an available node (e.g. the C++ linters) will be allowed to run. PR-URL: https://github.com/nodejs/node/pull/30012 Reviewed-By: Sam Roberts <vieuxtech@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: Daniel Bevenius <daniel.bevenius@gmail.com> Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>

view details

Beth Griggs

commit sha afbbcb050e0c1db9c6fc17fb0140680ac00f37e8

2019-10-22, Version 10.17.0 'Dubnium' (LTS) Notable changes: * crypto: * add support for chacha20-poly1305 for AEAD (chux0519) https://github.com/nodejs/node/pull/24081 * increase maxmem range from 32 to 53 bits (Tobias Nießen) https://github.com/nodejs/node/pull/28799 * deps: * update npm to 6.11.3 (claudiahdz) https://github.com/nodejs/node/pull/29430 * upgrade openssl sources to 1.1.1d (Sam Roberts) https://github.com/nodejs/node/pull/29921 * dns: * remove dns.promises experimental warning (cjihrig) https://github.com/nodejs/node/pull/26592 * fs: * remove experimental warning for fs.promises (Anna Henningsen) https://github.com/nodejs/node/pull/26581 * http: * makes response.writeHead return the response (Mark S. Everitt) https://github.com/nodejs/node/pull/25974 * http2: * makes response.writeHead return the response (Mark S. Everitt) https://github.com/nodejs/node/pull/25974 * n-api: * make func argument of napi\_create\_threadsafe\_function optional (legendecas) https://github.com/nodejs/node/pull/27791 * mark version 5 N-APIs as stable (Gabriel Schulhof) https://github.com/nodejs/node/pull/29401 * implement date object (Jarrod Connolly) https://github.com/nodejs/node/pull/25917 * process: * add --unhandled-rejections flag (Ruben Bridgewater) https://github.com/nodejs/node/pull/26599 * stream: * implement Readable.from async iterator utility (Guy Bedford) https://github.com/nodejs/node/pull/27660 * make Symbol.asyncIterator support stable (Matteo Collina) https://github.com/nodejs/node/pull/26989 PR-URL: https://github.com/nodejs/node/pull/29875

view details

Daniel Bevenius

commit sha 4187fcb2001581004280685e78ab0f249d8347e7

src: remove unnecessary std::endl usage This commit removes a few std::endl that could be replaced by '\n' as it does not look like the buffer needs to be flushed in these places. This is only done in error handling, and once when the report has been generated, so this is very minor but I thought I'd bring it up in case it was overlooked. PR-URL: https://github.com/nodejs/node/pull/30003 Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Tobias Nießen <tniessen@tnie.de>

view details

bcoe

commit sha b964e771171cdac3e2b86b8a68a153c9f6f42790

doc: --enable-source-maps and prepareStackTrace are incompatible document the fact that --enable-source-maps and prepareStackTrace are incompatible, see #29994 PR-URL: https://github.com/nodejs/node/pull/30046 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>

view details

push time in 4 months

more