src: disambiguate terms used to refer to builtins and addons

The term "native module" dates back to some of the oldest code
in the code base. Within the context of Node.js core it usually
refers to modules that are native to Node.js (e.g. fs, http),
but it can cause confusion for people who don't work on this
part of the code base, as "native module" can also refer to
native addons - which is even the case in some of the API
docs and error messages.

This patch tries to make the usage of these terms more consistent.
Now within the context of Node.js core:

- JavaScript scripts that are built-in to Node.js are now referred
  to as "built-in(s)". If they are available as modules,
  they can also be referred to as "built-in module(s)".
- Dynamically-linked shared objects that are loaded into
  the Node.js processes are referred to as "addons".

We will try to avoid using the term "native modules" because it could
be ambiguous.

Changes in this patch:

File names:
- node_native_module.h -> node_builtins.h,
- node_native_module.cc -> node_builtins.cc

C++ binding names:
- `native_module` -> `builtins`

`node::Environment`:
- `native_modules_without_cache` -> `builtins_without_cache`
- `native_modules_with_cache` -> `builtins_with_cache`
- `native_modules_in_snapshot` -> `builtins_in_cache`
- `native_module_require` -> `builtin_module_require`

`node::EnvSerializeInfo`:
- `native_modules` -> `builtins

`node::native_module::NativeModuleLoader`:
- `native_module` namespace -> `builtins` namespace
- `NativeModuleLoader` -> `BuiltinLoader`
- `NativeModuleRecordMap` -> `BuiltinSourceMap`
- `NativeModuleCacheMap` -> `BuiltinCodeCacheMap`
- `ModuleIds` -> `BuiltinIds`
- `ModuleCategories` -> `BuiltinCategories`
- `LoadBuiltinModuleSource` -> `LoadBuiltinSource`

`loader.js`:
- `NativeModule` -> `BuiltinModule` (the `NativeModule` name used in
  `process.moduleLoadList` is kept for compatibility)

And other clarifications in the documentation and comments.

PR-URL: https://github.com/nodejs/node/pull/44135
Fixes: https://github.com/nodejs/node/issues/44036
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
This commit is contained in:
Joyee Cheung 2022-08-05 02:32:06 +08:00 committed by legendecas
parent fa22337901
commit 472edc775d
No known key found for this signature in database
GPG Key ID: CB3C9EC2BC27057C
42 changed files with 308 additions and 340 deletions

2
.github/CODEOWNERS vendored
View File

@ -107,7 +107,7 @@
/benchmark/misc/startup.js @nodejs/startup
/src/node.cc @nodejs/startup
/src/node_native_module* @nodejs/startup
/src/node_builtins* @nodejs/startup
/src/node_snapshot* @nodejs/startup
/lib/internal/bootstrap/* @nodejs/startup
/tools/snapshot/* @nodejs/startup

View File

@ -1996,7 +1996,7 @@ changes:
Type: Compile-time
Certain versions of `node::MakeCallback` APIs available to native modules are
Certain versions of `node::MakeCallback` APIs available to native addons are
deprecated. Please use the versions of the API that accept an `async_context`
parameter.
@ -2746,7 +2746,7 @@ changes:
Type: Documentation-only
The `node:repl` module exports a `_builtinLibs` property that contains an array
with native modules. It was incomplete so far and instead it's better to rely
of built-in modules. It was incomplete so far and instead it's better to rely
upon `require('node:module').builtinModules`.
### DEP0143: `Transform._transformState`

View File

@ -707,8 +707,8 @@ This does not apply to [native addons][], for which reloading will result in an
error.
Adding or replacing entries is also possible. This cache is checked before
native modules and if a name matching a native module is added to the cache,
only `node:`-prefixed require calls are going to receive the native module.
built-in modules and if a name matching a built-in module is added to the cache,
only `node:`-prefixed require calls are going to receive the built-in module.
Use with care!
<!-- eslint-disable node-core/no-duplicate-requires -->

View File

@ -201,9 +201,9 @@ GitHub projects using CMake.js.
#### prebuildify
[prebuildify][] is a tool based on node-gyp. The advantage of prebuildify is
that the built binaries are bundled with the native module when it's
that the built binaries are bundled with the native addon when it's
uploaded to npm. The binaries are downloaded from npm and are immediately
available to the module user when the native module is installed.
available to the module user when the native addon is installed.
## Usage
@ -1384,7 +1384,7 @@ callback throws an exception with no way to recover.
### Fatal errors
In the event of an unrecoverable error in a native module, a fatal error can be
In the event of an unrecoverable error in a native addon, a fatal error can be
thrown to immediately terminate the process.
#### `napi_fatal_error`
@ -5724,7 +5724,7 @@ Returns `napi_ok` if the API succeeded.
This function gives V8 an indication of the amount of externally allocated
memory that is kept alive by JavaScript objects (i.e. a JavaScript object
that points to its own memory allocated by a native module). Registering
that points to its own memory allocated by a native addon). Registering
externally allocated memory will trigger global garbage collections more
often than it would otherwise.

View File

@ -1,6 +1,6 @@
# Contributing a new API to Node-API
Node-API is the next-generation ABI-stable API for native modules.
Node-API is the next-generation ABI-stable API for native addons.
While improving the API surface is encouraged and welcomed, the following are
a set of principles and guidelines to keep in mind while adding a new
Node-API.

View File

@ -65,7 +65,7 @@ const { openSync, closeSync, readSync } = require('fs');
const { inspect } = require('internal/util/inspect');
const { isPromise, isRegExp } = require('internal/util/types');
const { EOL } = require('internal/constants');
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const { isError } = require('internal/util');
const errorCache = new SafeMap();
@ -303,7 +303,7 @@ function getErrMessage(message, fn) {
// Skip Node.js modules!
if (StringPrototypeStartsWith(filename, 'node:') &&
NativeModule.exists(StringPrototypeSlice(filename, 5))) {
BuiltinModule.exists(StringPrototypeSlice(filename, 5))) {
errorCache.set(identifier, undefined);
return;
}

View File

@ -24,7 +24,7 @@
// and have their nm_flags set to NM_F_INTERNAL.
//
// Internal JavaScript module loader:
// - NativeModule: a minimal module system used to load the JavaScript core
// - BuiltinModule: a minimal module system used to load the JavaScript core
// modules found in lib/**/*.js and deps/**/*.js. All core modules are
// compiled into the node binary via node_javascript.cc generated by js2c.py,
// so they can be loaded faster without the cost of I/O. This class makes the
@ -180,9 +180,9 @@ let internalBinding;
const loaderId = 'internal/bootstrap/loaders';
const {
moduleIds,
builtinIds,
compileFunction
} = internalBinding('native_module');
} = internalBinding('builtins');
const getOwn = (target, property, receiver) => {
return ObjectPrototypeHasOwnProperty(target, property) ?
@ -195,13 +195,13 @@ const getOwn = (target, property, receiver) => {
* Be careful not to expose this to user land unless --expose-internals is
* used, in which case there is no compatibility guarantee about this class.
*/
class NativeModule {
class BuiltinModule {
/**
* A map from the module IDs to the module instances.
* @type {Map<string, NativeModule>}
* @type {Map<string, BuiltinModule>}
*/
static map = new SafeMap(
ArrayPrototypeMap(moduleIds, (id) => [id, new NativeModule(id)])
ArrayPrototypeMap(builtinIds, (id) => [id, new BuiltinModule(id)])
);
constructor(id) {
@ -216,7 +216,7 @@ class NativeModule {
this.loading = false;
// The following properties are used by the ESM implementation and only
// initialized when the native module is loaded by users.
// initialized when the built-in module is loaded by users.
/**
* The C++ ModuleWrap binding used to interface with the ESM implementation.
* @type {ModuleWrap|undefined}
@ -232,7 +232,7 @@ class NativeModule {
// To be called during pre-execution when --expose-internals is on.
// Enables the user-land module loader to access internal modules.
static exposeInternals() {
for (const { 0: id, 1: mod } of NativeModule.map) {
for (const { 0: id, 1: mod } of BuiltinModule.map) {
// Do not expose this to user land even with --expose-internals.
if (id !== loaderId) {
mod.canBeRequiredByUsers = true;
@ -241,11 +241,11 @@ class NativeModule {
}
static exists(id) {
return NativeModule.map.has(id);
return BuiltinModule.map.has(id);
}
static canBeRequiredByUsers(id) {
const mod = NativeModule.map.get(id);
const mod = BuiltinModule.map.get(id);
return mod && mod.canBeRequiredByUsers;
}
@ -327,7 +327,7 @@ class NativeModule {
const fn = compileFunction(id);
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// BuiltinLoader::LookupAndCompile().
fn(this.exports, requireFn, this, process, internalBinding, primordials);
this.loaded = true;
@ -335,6 +335,8 @@ class NativeModule {
this.loading = false;
}
// "NativeModule" is a legacy name of "BuiltinModule". We keep it
// here to avoid breaking users who parse process.moduleLoadList.
ArrayPrototypePush(moduleLoadList, `NativeModule ${id}`);
return this.exports;
}
@ -344,7 +346,7 @@ class NativeModule {
// written in CommonJS style.
const loaderExports = {
internalBinding,
NativeModule,
BuiltinModule,
require: nativeModuleRequire
};
@ -353,7 +355,7 @@ function nativeModuleRequire(id) {
return loaderExports;
}
const mod = NativeModule.map.get(id);
const mod = BuiltinModule.map.get(id);
// Can't load the internal errors module from here, have to use a raw error.
// eslint-disable-next-line no-restricted-syntax
if (!mod) throw new TypeError(`Missing internal module '${id}'`);
@ -363,7 +365,7 @@ function nativeModuleRequire(id) {
// Allow internal modules from dependencies to require
// other modules from dependencies by providing fallbacks.
function requireWithFallbackInDeps(request) {
if (!NativeModule.map.has(request)) {
if (!BuiltinModule.map.has(request)) {
request = `internal/deps/${request}`;
}
return nativeModuleRequire(request);

View File

@ -18,7 +18,7 @@
// modules to use.
// - `lib/internal/bootstrap/loaders.js`: to setup internal binding and
// module loaders, including `process.binding()`, `process._linkedBinding()`,
// `internalBinding()` and `NativeModule`.
// `internalBinding()` and `BuiltinModule`.
//
// This file is run to bootstrap both the main thread and the worker threads.
// After this file is run, certain properties are setup according to the
@ -89,7 +89,7 @@ process.domain = null;
process._exiting = false;
// process.config is serialized config.gypi
const nativeModule = internalBinding('native_module');
const nativeModule = internalBinding('builtins');
// TODO(@jasnell): Once this has gone through one full major
// release cycle, remove the Proxy and setter and update the

View File

@ -118,8 +118,8 @@ function extractFunctionName(description) {
}
const {
moduleIds: PUBLIC_BUILTINS,
} = internalBinding('native_module');
builtinIds: PUBLIC_BUILTINS,
} = internalBinding('builtins');
const NATIVES = internalBinding('natives');
function isNativeUrl(url) {
url = RegExpPrototypeSymbolReplace(/\.js$/, url, '');

View File

@ -7,7 +7,7 @@ const {
} = primordials;
const binding = internalBinding('mksnapshot');
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const {
compileSerializeMain,
} = binding;
@ -92,7 +92,7 @@ function supportedInUserSnapshot(id) {
}
function requireForUserSnapshot(id) {
if (!NativeModule.canBeRequiredByUsers(id)) {
if (!BuiltinModule.canBeRequiredByUsers(id)) {
// eslint-disable-next-line no-restricted-syntax
const err = new Error(
`Cannot find module '${id}'. `

View File

@ -17,7 +17,7 @@ const {
ERR_MANIFEST_DEPENDENCY_MISSING,
ERR_UNKNOWN_BUILTIN_MODULE
} = require('internal/errors').codes;
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const { validateString } = require('internal/validators');
const path = require('path');
@ -42,10 +42,10 @@ const cjsConditions = new SafeSet([
...userConditions,
]);
function loadNativeModule(filename, request) {
const mod = NativeModule.map.get(filename);
function loadBuiltinModule(filename, request) {
const mod = BuiltinModule.map.get(filename);
if (mod?.canBeRequiredByUsers) {
debug('load native module %s', request);
debug('load built-in module %s', request);
// compileForPublicLoader() throws if mod.canBeRequiredByUsers is false:
mod.compileForPublicLoader();
return mod;
@ -73,7 +73,7 @@ function makeRequireFunction(mod, redirects) {
const href = destination.href;
if (destination.protocol === 'node:') {
const specifier = destination.pathname;
const mod = loadNativeModule(specifier, href);
const mod = loadBuiltinModule(specifier, href);
if (mod && mod.canBeRequiredByUsers) {
return mod.exports;
}
@ -230,7 +230,7 @@ module.exports = {
addBuiltinLibsToObject,
cjsConditions,
hasEsmSyntax,
loadNativeModule,
loadBuiltinModule,
makeRequireFunction,
normalizeReferrerURL,
stripBOM,

View File

@ -74,7 +74,7 @@ module.exports = {
get hasLoadedAnyUserCJSModule() { return hasLoadedAnyUserCJSModule; }
};
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const {
maybeCacheSourceMap,
} = require('internal/source_map/source_map_cache');
@ -92,7 +92,7 @@ const { safeGetenv } = internalBinding('credentials');
const {
cjsConditions,
hasEsmSyntax,
loadNativeModule,
loadBuiltinModule,
makeRequireFunction,
normalizeReferrerURL,
stripBOM,
@ -181,9 +181,9 @@ function Module(id = '', parent) {
}
const builtinModules = [];
for (const { 0: id, 1: mod } of NativeModule.map) {
for (const { 0: id, 1: mod } of BuiltinModule.map) {
if (mod.canBeRequiredByUsers &&
NativeModule.canBeRequiredWithoutScheme(id)) {
BuiltinModule.canBeRequiredWithoutScheme(id)) {
ArrayPrototypePush(builtinModules, id);
}
}
@ -191,7 +191,7 @@ for (const { 0: id, 1: mod } of NativeModule.map) {
const allBuiltins = new SafeSet(
ArrayPrototypeFlatMap(builtinModules, (bm) => [bm, `node:${bm}`])
);
NativeModule.getSchemeOnlyModuleNames().forEach((builtin) => allBuiltins.add(`node:${builtin}`));
BuiltinModule.getSchemeOnlyModuleNames().forEach((builtin) => allBuiltins.add(`node:${builtin}`));
ObjectFreeze(builtinModules);
Module.builtinModules = builtinModules;
@ -254,7 +254,7 @@ ObjectDefineProperty(Module, 'wrapper', {
const isPreloadingDesc = { get() { return isPreloading; } };
ObjectDefineProperty(Module.prototype, 'isPreloading', isPreloadingDesc);
ObjectDefineProperty(NativeModule.prototype, 'isPreloading', isPreloadingDesc);
ObjectDefineProperty(BuiltinModule.prototype, 'isPreloading', isPreloadingDesc);
function getModuleParent() {
return moduleParentCache.get(this);
@ -675,8 +675,8 @@ if (isWindows) {
}
Module._resolveLookupPaths = function(request, parent) {
if (NativeModule.canBeRequiredByUsers(request) &&
NativeModule.canBeRequiredWithoutScheme(request)) {
if (BuiltinModule.canBeRequiredByUsers(request) &&
BuiltinModule.canBeRequiredWithoutScheme(request)) {
debug('looking for %j in []', request);
return null;
}
@ -763,7 +763,7 @@ function getExportsForCircularRequire(module) {
// Check the cache for the requested file.
// 1. If a module already exists in the cache: return its exports object.
// 2. If the module is native: call
// `NativeModule.prototype.compileForPublicLoader()` and return the exports.
// `BuiltinModule.prototype.compileForPublicLoader()` and return the exports.
// 3. Otherwise, create a new module for the file and save it to the cache.
// Then have it load the file contents before returning its exports
// object.
@ -792,7 +792,7 @@ Module._load = function(request, parent, isMain) {
// Slice 'node:' prefix
const id = StringPrototypeSlice(request, 5);
const module = loadNativeModule(id, request);
const module = loadBuiltinModule(id, request);
if (!module?.canBeRequiredByUsers) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(request);
}
@ -814,9 +814,9 @@ Module._load = function(request, parent, isMain) {
}
}
const mod = loadNativeModule(filename, request);
const mod = loadBuiltinModule(filename, request);
if (mod?.canBeRequiredByUsers &&
NativeModule.canBeRequiredWithoutScheme(filename)) {
BuiltinModule.canBeRequiredWithoutScheme(filename)) {
return mod.exports;
}
@ -865,10 +865,10 @@ Module._resolveFilename = function(request, parent, isMain, options) {
if (
(
StringPrototypeStartsWith(request, 'node:') &&
NativeModule.canBeRequiredByUsers(StringPrototypeSlice(request, 5))
BuiltinModule.canBeRequiredByUsers(StringPrototypeSlice(request, 5))
) || (
NativeModule.canBeRequiredByUsers(request) &&
NativeModule.canBeRequiredWithoutScheme(request)
BuiltinModule.canBeRequiredByUsers(request) &&
BuiltinModule.canBeRequiredWithoutScheme(request)
)
) {
return request;
@ -1298,9 +1298,9 @@ Module._preloadModules = function(requests) {
};
Module.syncBuiltinESMExports = function syncBuiltinESMExports() {
for (const mod of NativeModule.map.values()) {
for (const mod of BuiltinModule.map.values()) {
if (mod.canBeRequiredByUsers &&
NativeModule.canBeRequiredWithoutScheme(mod.id)) {
BuiltinModule.canBeRequiredWithoutScheme(mod.id)) {
mod.syncExports();
}
}

View File

@ -719,7 +719,7 @@ class ESMLoader {
filename: '<preload>',
}
);
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
// We only allow replacing the importMetaInitializer during preload,
// after preload is finished, we disable the ability to replace it
//
@ -737,8 +737,8 @@ class ESMLoader {
globalThis,
// Param getBuiltin
(builtinName) => {
if (NativeModule.canBeRequiredByUsers(builtinName) &&
NativeModule.canBeRequiredWithoutScheme(builtinName)) {
if (BuiltinModule.canBeRequiredByUsers(builtinName) &&
BuiltinModule.canBeRequiredWithoutScheme(builtinName)) {
return require(builtinName);
}
throw new ERR_INVALID_ARG_VALUE('builtinName', builtinName);

View File

@ -26,7 +26,7 @@ const {
StringPrototypeStartsWith,
} = primordials;
const internalFS = require('internal/fs/utils');
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const {
realpathSync,
statSync,
@ -752,8 +752,8 @@ function parsePackageName(specifier, base) {
* @returns {resolved: URL, format? : string}
*/
function packageResolve(specifier, base, conditions) {
if (NativeModule.canBeRequiredByUsers(specifier) &&
NativeModule.canBeRequiredWithoutScheme(specifier)) {
if (BuiltinModule.canBeRequiredByUsers(specifier) &&
BuiltinModule.canBeRequiredWithoutScheme(specifier)) {
return new URL('node:' + specifier);
}
@ -935,8 +935,8 @@ function checkIfDisallowedImport(specifier, parsed, parsedParentURL) {
return { url: parsed.href };
}
if (NativeModule.canBeRequiredByUsers(specifier) &&
NativeModule.canBeRequiredWithoutScheme(specifier)) {
if (BuiltinModule.canBeRequiredByUsers(specifier) &&
BuiltinModule.canBeRequiredWithoutScheme(specifier)) {
throw new ERR_NETWORK_IMPORT_DISALLOWED(
specifier,
parsedParentURL,

View File

@ -28,7 +28,7 @@ const { readFileSync } = require('fs');
const { extname, isAbsolute } = require('path');
const {
hasEsmSyntax,
loadNativeModule,
loadBuiltinModule,
stripBOM,
} = require('internal/modules/cjs/helpers');
const {
@ -254,7 +254,7 @@ translators.set('builtin', async function builtinStrategy(url) {
debug(`Translating BuiltinModule ${url}`);
// Slice 'node:' scheme
const id = StringPrototypeSlice(url, 5);
const module = loadNativeModule(id, url);
const module = loadBuiltinModule(id, url);
if (!StringPrototypeStartsWith(url, 'node:') || !module) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(url);
}

View File

@ -322,7 +322,7 @@ function initializeReport() {
function setupDebugEnv() {
require('internal/util/debuglog').initializeDebugEnv(process.env.NODE_DEBUG);
if (getOptionValue('--expose-internals')) {
require('internal/bootstrap/loaders').NativeModule.exposeInternals();
require('internal/bootstrap/loaders').BuiltinModule.exposeInternals();
}
}
@ -524,8 +524,8 @@ function initializePolicy() {
}
function initializeWASI() {
const { NativeModule } = require('internal/bootstrap/loaders');
const mod = NativeModule.map.get('wasi');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const mod = BuiltinModule.map.get('wasi');
mod.canBeRequiredByUsers =
getOptionValue('--experimental-wasi-unstable-preview1');
}

View File

@ -136,7 +136,7 @@ const {
const assert = require('internal/assert');
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const {
validateObject,
validateString,
@ -1375,7 +1375,7 @@ function formatError(err, constructor, tag, ctx, keys) {
let esmWorkingDirectory;
for (let line of lines) {
const core = line.match(coreModuleRegExp);
if (core !== null && NativeModule.exists(core[1])) {
if (core !== null && BuiltinModule.exists(core[1])) {
newStack += `\n${ctx.stylize(line, 'undefined')}`;
} else {
newStack += '\n';

View File

@ -1,4 +1,4 @@
'use strict';
// Re-export process as a native module
// Re-export process as a built-in module
module.exports = process;

View File

@ -99,7 +99,7 @@ const {
globalThis,
} = primordials;
const { NativeModule } = require('internal/bootstrap/loaders');
const { BuiltinModule } = require('internal/bootstrap/loaders');
const {
makeRequireFunction,
addBuiltinLibsToObject
@ -130,7 +130,7 @@ let _builtinLibs = ArrayPrototypeFilter(
const nodeSchemeBuiltinLibs = ArrayPrototypeMap(
_builtinLibs, (lib) => `node:${lib}`);
ArrayPrototypeForEach(
NativeModule.getSchemeOnlyModuleNames(),
BuiltinModule.getSchemeOnlyModuleNames(),
(lib) => ArrayPrototypePush(nodeSchemeBuiltinLibs, `node:${lib}`),
);
const domain = require('domain');

View File

@ -488,6 +488,7 @@
'src/node_binding.cc',
'src/node_blob.cc',
'src/node_buffer.cc',
'src/node_builtins.cc',
'src/node_config.cc',
'src/node_constants.cc',
'src/node_contextify.cc',
@ -503,7 +504,6 @@
'src/node_main_instance.cc',
'src/node_messaging.cc',
'src/node_metadata.cc',
'src/node_native_module.cc',
'src/node_options.cc',
'src/node_os.cc',
'src/node_perf.cc',
@ -588,6 +588,7 @@
'src/node_binding.h',
'src/node_blob.h',
'src/node_buffer.h',
'src/node_builtins.h',
'src/node_constants.h',
'src/node_context_data.h',
'src/node_contextify.h',
@ -608,7 +609,6 @@
'src/node_messaging.h',
'src/node_metadata.h',
'src/node_mutex.h',
'src/node_native_module.h',
'src/node_object_wrap.h',
'src/node_options.h',
'src/node_options-inl.h',

View File

@ -1,8 +1,8 @@
#include "node.h"
#include "node_builtins.h"
#include "node_context_data.h"
#include "node_errors.h"
#include "node_internals.h"
#include "node_native_module.h"
#include "node_options-inl.h"
#include "node_platform.h"
#include "node_shadow_realm.h"
@ -449,14 +449,13 @@ MaybeLocal<Value> LoadEnvironment(
// TODO(addaleax): Avoid having a global table for all scripts.
std::string name = "embedder_main_" + std::to_string(env->thread_id());
native_module::NativeModuleLoader::Add(
builtins::BuiltinLoader::Add(
name.c_str(), UnionBytes(**main_utf16, main_utf16->length()));
env->set_main_utf16(std::move(main_utf16));
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
std::vector<Local<Value>> args = {
env->process_object(),
env->native_module_require()};
// BuiltinLoader::LookupAndCompile().
std::vector<Local<Value>> args = {env->process_object(),
env->builtin_module_require()};
return ExecuteBootstrapper(env, name.c_str(), &args);
});
}
@ -698,11 +697,10 @@ Maybe<bool> InitializePrimordials(Local<Context> context) {
for (const char** module = context_files; *module != nullptr; module++) {
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// BuiltinLoader::LookupAndCompile().
Local<Value> arguments[] = {context->Global(), exports, primordials};
MaybeLocal<Function> maybe_fn =
native_module::NativeModuleLoader::LookupAndCompile(
context, *module, nullptr);
builtins::BuiltinLoader::LookupAndCompile(context, *module, nullptr);
Local<Function> fn;
if (!maybe_fn.ToLocal(&fn)) {
return Nothing<bool>();

View File

@ -1390,8 +1390,9 @@ BaseObjectPtr<BaseObject> NativeKeyObject::KeyObjectTransferData::Deserialize(
Local<Function> key_ctor;
Local<Value> arg = FIXED_ONE_BYTE_STRING(env->isolate(),
"internal/crypto/keys");
if (env->native_module_require()->
Call(context, Null(env->isolate()), 1, &arg).IsEmpty()) {
if (env->builtin_module_require()
->Call(context, Null(env->isolate()), 1, &arg)
.IsEmpty()) {
return {};
}
switch (data_->GetKeyType()) {

View File

@ -1597,11 +1597,11 @@ void Environment::PrintInfoForSnapshotIfDebug() {
fprintf(stderr, "BaseObjects at the exit of the Environment:\n");
PrintAllBaseObjects();
fprintf(stderr, "\nNative modules without cache:\n");
for (const auto& s : native_modules_without_cache) {
for (const auto& s : builtins_without_cache) {
fprintf(stderr, "%s\n", s.c_str());
}
fprintf(stderr, "\nNative modules with cache:\n");
for (const auto& s : native_modules_with_cache) {
for (const auto& s : builtins_with_cache) {
fprintf(stderr, "%s\n", s.c_str());
}
fprintf(stderr, "\nStatic bindings (need to be registered):\n");
@ -1657,8 +1657,8 @@ EnvSerializeInfo Environment::Serialize(SnapshotCreator* creator) {
SerializeBindingData(this, creator, &info);
// Currently all modules are compiled without cache in builtin snapshot
// builder.
info.native_modules = std::vector<std::string>(
native_modules_without_cache.begin(), native_modules_without_cache.end());
info.builtins = std::vector<std::string>(builtins_without_cache.begin(),
builtins_without_cache.end());
info.async_hooks = async_hooks_.Serialize(ctx, creator);
info.immediate_info = immediate_info_.Serialize(ctx, creator);
@ -1717,9 +1717,9 @@ std::ostream& operator<<(std::ostream& output, const EnvSerializeInfo& i) {
<< "// -- bindings begins --\n"
<< i.bindings << ",\n"
<< "// -- bindings ends --\n"
<< "// -- native_modules begins --\n"
<< i.native_modules << ",\n"
<< "// -- native_modules ends --\n"
<< "// -- builtins begins --\n"
<< i.builtins << ",\n"
<< "// -- builtins ends --\n"
<< "// -- async_hooks begins --\n"
<< i.async_hooks << ",\n"
<< "// -- async_hooks ends --\n"
@ -1767,7 +1767,7 @@ void Environment::DeserializeProperties(const EnvSerializeInfo* info) {
RunDeserializeRequests();
native_modules_in_snapshot = info->native_modules;
builtins_in_snapshot = info->builtins;
async_hooks_.Deserialize(ctx);
immediate_info_.Deserialize(ctx);
tick_info_.Deserialize(ctx);
@ -1988,9 +1988,8 @@ void Environment::MemoryInfo(MemoryTracker* tracker) const {
// Iteratable STLs have their own sizes subtracted from the parent
// by default.
tracker->TrackField("isolate_data", isolate_data_);
tracker->TrackField("native_modules_with_cache", native_modules_with_cache);
tracker->TrackField("native_modules_without_cache",
native_modules_without_cache);
tracker->TrackField("builtins_with_cache", builtins_with_cache);
tracker->TrackField("builtins_without_cache", builtins_without_cache);
tracker->TrackField("destroy_async_id_list", destroy_async_id_list_);
tracker->TrackField("exec_argv", exec_argv_);
tracker->TrackField("exiting", exiting_);

View File

@ -34,8 +34,8 @@
#include "handle_wrap.h"
#include "node.h"
#include "node_binding.h"
#include "node_builtins.h"
#include "node_main_instance.h"
#include "node_native_module.h"
#include "node_options.h"
#include "node_perf_common.h"
#include "node_snapshotable.h"
@ -548,7 +548,7 @@ class NoArrayBufferZeroFillScope {
V(maybe_cache_generated_source_map, v8::Function) \
V(messaging_deserialize_create_object, v8::Function) \
V(message_port, v8::Object) \
V(native_module_require, v8::Function) \
V(builtin_module_require, v8::Function) \
V(performance_entry_callback, v8::Function) \
V(performance_entry_template, v8::Function) \
V(prepare_stack_trace_callback, v8::Function) \
@ -969,7 +969,7 @@ struct DeserializeRequest {
struct EnvSerializeInfo {
std::vector<PropInfo> bindings;
std::vector<std::string> native_modules;
std::vector<std::string> builtins;
AsyncHooks::SerializeInfo async_hooks;
TickInfo::SerializeInfo tick_info;
ImmediateInfo::SerializeInfo immediate_info;
@ -1004,9 +1004,9 @@ struct SnapshotData {
// A vector of built-in ids and v8::ScriptCompiler::CachedData, this can be
// shared across Node.js instances because they are supposed to share the
// read only space. We use native_module::CodeCacheInfo because
// read only space. We use builtins::CodeCacheInfo because
// v8::ScriptCompiler::CachedData is not copyable.
std::vector<native_module::CodeCacheInfo> code_cache;
std::vector<builtins::CodeCacheInfo> code_cache;
void ToBlob(FILE* out) const;
static void FromBlob(SnapshotData* out, FILE* in);
@ -1206,11 +1206,11 @@ class Environment : public MemoryRetainer {
inline std::vector<double>* destroy_async_id_list();
std::set<struct node_module*> internal_bindings;
std::set<std::string> native_modules_with_cache;
std::set<std::string> native_modules_without_cache;
std::set<std::string> builtins_with_cache;
std::set<std::string> builtins_without_cache;
// This is only filled during deserialization. We use a vector since
// it's only used for tests.
std::vector<std::string> native_modules_in_snapshot;
std::vector<std::string> builtins_in_snapshot;
std::unordered_multimap<int, loader::ModuleWrap*> hash_to_module_map;
std::unordered_map<uint32_t, loader::ModuleWrap*> id_to_module_map;

View File

@ -28,11 +28,11 @@
#include "histogram-inl.h"
#include "memory_tracker-inl.h"
#include "node_binding.h"
#include "node_builtins.h"
#include "node_errors.h"
#include "node_internals.h"
#include "node_main_instance.h"
#include "node_metadata.h"
#include "node_native_module.h"
#include "node_options-inl.h"
#include "node_perf.h"
#include "node_process-inl.h"
@ -121,7 +121,7 @@
namespace node {
using native_module::NativeModuleLoader;
using builtins::BuiltinLoader;
using v8::EscapableHandleScope;
using v8::Function;
@ -172,7 +172,7 @@ MaybeLocal<Value> ExecuteBootstrapper(Environment* env,
std::vector<Local<Value>>* arguments) {
EscapableHandleScope scope(env->isolate());
MaybeLocal<Function> maybe_fn =
NativeModuleLoader::LookupAndCompile(env->context(), id, env);
BuiltinLoader::LookupAndCompile(env->context(), id, env);
Local<Function> fn;
if (!maybe_fn.ToLocal(&fn)) {
@ -292,7 +292,7 @@ MaybeLocal<Value> Environment::BootstrapInternalLoaders() {
EscapableHandleScope scope(isolate_);
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// BuiltinLoader::LookupAndCompile().
std::vector<Local<Value>> loaders_args = {
process_object(),
NewFunctionTemplate(isolate_, binding::GetLinkedBinding)
@ -319,7 +319,7 @@ MaybeLocal<Value> Environment::BootstrapInternalLoaders() {
Local<Value> require =
loader_exports_obj->Get(context(), require_string()).ToLocalChecked();
CHECK(require->IsFunction());
set_native_module_require(require.As<Function>());
set_builtin_module_require(require.As<Function>());
return scope.Escape(loader_exports);
}
@ -328,11 +328,10 @@ MaybeLocal<Value> Environment::BootstrapNode() {
EscapableHandleScope scope(isolate_);
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// BuiltinLoader::LookupAndCompile().
// process, require, internalBinding, primordials
std::vector<Local<Value>> node_args = {
process_object(),
native_module_require(),
std::vector<Local<Value>> node_args = {process_object(),
builtin_module_require(),
internal_binding_loader(),
primordials()};
@ -414,9 +413,9 @@ MaybeLocal<Value> StartExecution(Environment* env, const char* main_script_id) {
CHECK_NOT_NULL(main_script_id);
// Arguments must match the parameters specified in
// NativeModuleLoader::LookupAndCompile().
// BuiltinLoader::LookupAndCompile().
std::vector<Local<Value>> arguments = {env->process_object(),
env->native_module_require(),
env->builtin_module_require(),
env->internal_binding_loader(),
env->primordials()};
@ -438,7 +437,7 @@ MaybeLocal<Value> StartExecution(Environment* env, StartExecutionCallback cb) {
StartExecutionCallbackInfo info = {
env->process_object(),
env->native_module_require(),
env->builtin_module_require(),
};
return scope.EscapeMaybe(cb(info));
@ -975,7 +974,7 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
// We should set node_is_initialized here instead of in node::Start,
// otherwise embedders using node::Init to initialize everything will not be
// able to set it and native modules will not load for them.
// able to set it and native addons will not load for them.
node_is_initialized = true;
return 0;
}
@ -1265,7 +1264,7 @@ int LoadSnapshotDataAndRun(const SnapshotData** snapshot_data_ptr,
}
if ((*snapshot_data_ptr) != nullptr) {
NativeModuleLoader::RefreshCodeCache((*snapshot_data_ptr)->code_cache);
BuiltinLoader::RefreshCodeCache((*snapshot_data_ptr)->code_cache);
}
NodeMainInstance main_instance(*snapshot_data_ptr,
uv_default_loop(),

View File

@ -3,7 +3,7 @@
#ifdef BUILDING_NODE_EXTENSION
#ifdef _WIN32
// Building native module against node
// Building native addon against node
#define NAPI_EXTERN __declspec(dllimport)
#elif defined(__wasm32__)
#define NAPI_EXTERN __attribute__((__import_module__("napi")))

View File

@ -1,9 +1,9 @@
#include "node_binding.h"
#include <atomic>
#include "env-inl.h"
#include "node_builtins.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_native_module.h"
#include "util.h"
#include <string>
@ -37,6 +37,7 @@
V(blob) \
V(block_list) \
V(buffer) \
V(builtins) \
V(cares_wrap) \
V(config) \
V(contextify) \
@ -54,7 +55,6 @@
V(messaging) \
V(module_wrap) \
V(mksnapshot) \
V(native_module) \
V(options) \
V(os) \
V(performance) \
@ -591,15 +591,13 @@ void GetInternalBinding(const FunctionCallbackInfo<Value>& args) {
exports->SetPrototype(env->context(), Null(env->isolate())).FromJust());
DefineConstants(env->isolate(), exports);
} else if (!strcmp(*module_v, "natives")) {
exports =
native_module::NativeModuleLoader::GetSourceObject(env->context());
exports = builtins::BuiltinLoader::GetSourceObject(env->context());
// Legacy feature: process.binding('natives').config contains stringified
// config.gypi
CHECK(exports
->Set(env->context(),
env->config_string(),
native_module::NativeModuleLoader::GetConfigString(
env->isolate()))
builtins::BuiltinLoader::GetConfigString(env->isolate()))
.FromJust());
} else {
char errmsg[1024];

View File

@ -1,4 +1,4 @@
#include "node_native_module.h"
#include "node_builtins.h"
#include "debug_utils-inl.h"
#include "env-inl.h"
#include "node_external_reference.h"
@ -6,7 +6,7 @@
#include "util-inl.h"
namespace node {
namespace native_module {
namespace builtins {
using v8::Context;
using v8::DEFAULT;
@ -28,28 +28,27 @@ using v8::SideEffectType;
using v8::String;
using v8::Value;
NativeModuleLoader NativeModuleLoader::instance_;
BuiltinLoader BuiltinLoader::instance_;
NativeModuleLoader::NativeModuleLoader()
: config_(GetConfig()), has_code_cache_(false) {
BuiltinLoader::BuiltinLoader() : config_(GetConfig()), has_code_cache_(false) {
LoadJavaScriptSource();
}
NativeModuleLoader* NativeModuleLoader::GetInstance() {
BuiltinLoader* BuiltinLoader::GetInstance() {
return &instance_;
}
bool NativeModuleLoader::Exists(const char* id) {
bool BuiltinLoader::Exists(const char* id) {
auto& source = GetInstance()->source_;
return source.find(id) != source.end();
}
bool NativeModuleLoader::Add(const char* id, const UnionBytes& source) {
bool BuiltinLoader::Add(const char* id, const UnionBytes& source) {
auto result = GetInstance()->source_.emplace(id, source);
return result.second;
}
Local<Object> NativeModuleLoader::GetSourceObject(Local<Context> context) {
Local<Object> BuiltinLoader::GetSourceObject(Local<Context> context) {
Isolate* isolate = context->GetIsolate();
Local<Object> out = Object::New(isolate);
auto& source = GetInstance()->source_;
@ -60,11 +59,11 @@ Local<Object> NativeModuleLoader::GetSourceObject(Local<Context> context) {
return out;
}
Local<String> NativeModuleLoader::GetConfigString(Isolate* isolate) {
Local<String> BuiltinLoader::GetConfigString(Isolate* isolate) {
return GetInstance()->config_.ToStringChecked(isolate);
}
std::vector<std::string> NativeModuleLoader::GetModuleIds() {
std::vector<std::string> BuiltinLoader::GetBuiltinIds() {
std::vector<std::string> ids;
ids.reserve(source_.size());
for (auto const& x : source_) {
@ -73,9 +72,9 @@ std::vector<std::string> NativeModuleLoader::GetModuleIds() {
return ids;
}
void NativeModuleLoader::InitializeModuleCategories() {
if (module_categories_.is_initialized) {
DCHECK(!module_categories_.can_be_required.empty());
void BuiltinLoader::InitializeBuiltinCategories() {
if (builtin_categories_.is_initialized) {
DCHECK(!builtin_categories_.can_be_required.empty());
return;
}
@ -91,13 +90,12 @@ void NativeModuleLoader::InitializeModuleCategories() {
"internal/main/"
};
module_categories_.can_be_required.emplace(
builtin_categories_.can_be_required.emplace(
"internal/deps/cjs-module-lexer/lexer");
module_categories_.cannot_be_required = std::set<std::string> {
builtin_categories_.cannot_be_required = std::set<std::string> {
#if !HAVE_INSPECTOR
"inspector",
"internal/util/inspector",
"inspector", "internal/util/inspector",
#endif // !HAVE_INSPECTOR
#if !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT)
@ -105,26 +103,16 @@ void NativeModuleLoader::InitializeModuleCategories() {
#endif // !NODE_USE_V8_PLATFORM || !defined(NODE_HAVE_I18N_SUPPORT)
#if !HAVE_OPENSSL
"crypto",
"crypto/promises",
"https",
"http2",
"tls",
"_tls_common",
"_tls_wrap",
"internal/tls/secure-pair",
"internal/tls/parse-cert-string",
"internal/tls/secure-context",
"internal/http2/core",
"internal/http2/compat",
"internal/policy/manifest",
"internal/process/policy",
"crypto", "crypto/promises", "https", "http2", "tls", "_tls_common",
"_tls_wrap", "internal/tls/secure-pair",
"internal/tls/parse-cert-string", "internal/tls/secure-context",
"internal/http2/core", "internal/http2/compat",
"internal/policy/manifest", "internal/process/policy",
"internal/streams/lazy_transform",
#endif // !HAVE_OPENSSL
"sys", // Deprecated.
"wasi", // Experimental.
"internal/test/binding",
"internal/v8_prof_polyfill",
"internal/test/binding", "internal/v8_prof_polyfill",
"internal/v8_prof_processor",
};
@ -135,46 +123,45 @@ void NativeModuleLoader::InitializeModuleCategories() {
continue;
}
if (id.find(prefix) == 0 &&
module_categories_.can_be_required.count(id) == 0) {
module_categories_.cannot_be_required.emplace(id);
builtin_categories_.can_be_required.count(id) == 0) {
builtin_categories_.cannot_be_required.emplace(id);
}
}
}
for (auto const& x : source_) {
const std::string& id = x.first;
if (0 == module_categories_.cannot_be_required.count(id)) {
module_categories_.can_be_required.emplace(id);
if (0 == builtin_categories_.cannot_be_required.count(id)) {
builtin_categories_.can_be_required.emplace(id);
}
}
module_categories_.is_initialized = true;
builtin_categories_.is_initialized = true;
}
const std::set<std::string>& NativeModuleLoader::GetCannotBeRequired() {
InitializeModuleCategories();
return module_categories_.cannot_be_required;
const std::set<std::string>& BuiltinLoader::GetCannotBeRequired() {
InitializeBuiltinCategories();
return builtin_categories_.cannot_be_required;
}
const std::set<std::string>& NativeModuleLoader::GetCanBeRequired() {
InitializeModuleCategories();
return module_categories_.can_be_required;
const std::set<std::string>& BuiltinLoader::GetCanBeRequired() {
InitializeBuiltinCategories();
return builtin_categories_.can_be_required;
}
bool NativeModuleLoader::CanBeRequired(const char* id) {
bool BuiltinLoader::CanBeRequired(const char* id) {
return GetCanBeRequired().count(id) == 1;
}
bool NativeModuleLoader::CannotBeRequired(const char* id) {
bool BuiltinLoader::CannotBeRequired(const char* id) {
return GetCannotBeRequired().count(id) == 1;
}
NativeModuleCacheMap* NativeModuleLoader::code_cache() {
BuiltinCodeCacheMap* BuiltinLoader::code_cache() {
return &code_cache_;
}
ScriptCompiler::CachedData* NativeModuleLoader::GetCodeCache(
const char* id) const {
ScriptCompiler::CachedData* BuiltinLoader::GetCodeCache(const char* id) const {
Mutex::ScopedLock lock(code_cache_mutex_);
const auto it = code_cache_.find(id);
if (it == code_cache_.end()) {
@ -201,7 +188,7 @@ static std::string OnDiskFileName(const char* id) {
}
#endif // NODE_BUILTIN_MODULES_PATH
MaybeLocal<String> NativeModuleLoader::LoadBuiltinModuleSource(Isolate* isolate,
MaybeLocal<String> BuiltinLoader::LoadBuiltinSource(Isolate* isolate,
const char* id) {
#ifdef NODE_BUILTIN_MODULES_PATH
if (strncmp(id, "embedder_main_", strlen("embedder_main_")) == 0) {
@ -235,16 +222,16 @@ MaybeLocal<String> NativeModuleLoader::LoadBuiltinModuleSource(Isolate* isolate,
// Returns Local<Function> of the compiled module if return_code_cache
// is false (we are only compiling the function).
// Otherwise return a Local<Object> containing the cache.
MaybeLocal<Function> NativeModuleLoader::LookupAndCompileInternal(
MaybeLocal<Function> BuiltinLoader::LookupAndCompileInternal(
Local<Context> context,
const char* id,
std::vector<Local<String>>* parameters,
NativeModuleLoader::Result* result) {
BuiltinLoader::Result* result) {
Isolate* isolate = context->GetIsolate();
EscapableHandleScope scope(isolate);
Local<String> source;
if (!LoadBuiltinModuleSource(isolate, id).ToLocal(&source)) {
if (!LoadBuiltinSource(isolate, id).ToLocal(&source)) {
return {};
}
@ -288,7 +275,7 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompileInternal(
nullptr,
options);
// This could fail when there are early errors in the native modules,
// This could fail when there are early errors in the built-in modules,
// e.g. the syntax errors
Local<Function> fun;
if (!maybe_fun.ToLocal(&fun)) {
@ -342,10 +329,8 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompileInternal(
// Returns Local<Function> of the compiled module if return_code_cache
// is false (we are only compiling the function).
// Otherwise return a Local<Object> containing the cache.
MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
Local<Context> context,
const char* id,
Environment* optional_env) {
MaybeLocal<Function> BuiltinLoader::LookupAndCompile(
Local<Context> context, const char* id, Environment* optional_env) {
Result result;
std::vector<Local<String>> parameters;
Isolate* isolate = context->GetIsolate();
@ -412,9 +397,9 @@ MaybeLocal<Function> NativeModuleLoader::LookupAndCompile(
return maybe;
}
bool NativeModuleLoader::CompileAllBuiltins(Local<Context> context) {
NativeModuleLoader* loader = GetInstance();
std::vector<std::string> ids = loader->GetModuleIds();
bool BuiltinLoader::CompileAllBuiltins(Local<Context> context) {
BuiltinLoader* loader = GetInstance();
std::vector<std::string> ids = loader->GetBuiltinIds();
bool all_succeeded = true;
std::string v8_tools_prefix = "internal/deps/v8/tools/";
for (const auto& id : ids) {
@ -434,8 +419,8 @@ bool NativeModuleLoader::CompileAllBuiltins(Local<Context> context) {
return all_succeeded;
}
void NativeModuleLoader::CopyCodeCache(std::vector<CodeCacheInfo>* out) {
NativeModuleLoader* loader = GetInstance();
void BuiltinLoader::CopyCodeCache(std::vector<CodeCacheInfo>* out) {
BuiltinLoader* loader = GetInstance();
Mutex::ScopedLock lock(loader->code_cache_mutex());
auto in = loader->code_cache();
for (auto const& item : *in) {
@ -445,9 +430,8 @@ void NativeModuleLoader::CopyCodeCache(std::vector<CodeCacheInfo>* out) {
}
}
void NativeModuleLoader::RefreshCodeCache(
const std::vector<CodeCacheInfo>& in) {
NativeModuleLoader* loader = GetInstance();
void BuiltinLoader::RefreshCodeCache(const std::vector<CodeCacheInfo>& in) {
BuiltinLoader* loader = GetInstance();
Mutex::ScopedLock lock(loader->code_cache_mutex());
auto out = loader->code_cache();
for (auto const& item : in) {
@ -467,7 +451,7 @@ void NativeModuleLoader::RefreshCodeCache(
loader->has_code_cache_ = true;
}
void NativeModuleLoader::GetModuleCategories(
void BuiltinLoader::GetBuiltinCategories(
Local<Name> property, const PropertyCallbackInfo<Value>& info) {
Environment* env = Environment::GetCurrent(info);
Isolate* isolate = env->isolate();
@ -506,48 +490,47 @@ void NativeModuleLoader::GetModuleCategories(
info.GetReturnValue().Set(result);
}
void NativeModuleLoader::GetCacheUsage(
const FunctionCallbackInfo<Value>& args) {
void BuiltinLoader::GetCacheUsage(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
Isolate* isolate = env->isolate();
Local<Context> context = env->context();
Local<Object> result = Object::New(isolate);
Local<Value> native_modules_with_cache_js;
Local<Value> native_modules_without_cache_js;
Local<Value> native_modules_in_snapshot_js;
if (!ToV8Value(context, env->native_modules_with_cache)
.ToLocal(&native_modules_with_cache_js)) {
Local<Value> builtins_with_cache_js;
Local<Value> builtins_without_cache_js;
Local<Value> builtins_in_snapshot_js;
if (!ToV8Value(context, env->builtins_with_cache)
.ToLocal(&builtins_with_cache_js)) {
return;
}
if (result
->Set(env->context(),
OneByteString(isolate, "compiledWithCache"),
native_modules_with_cache_js)
builtins_with_cache_js)
.IsNothing()) {
return;
}
if (!ToV8Value(context, env->native_modules_without_cache)
.ToLocal(&native_modules_without_cache_js)) {
if (!ToV8Value(context, env->builtins_without_cache)
.ToLocal(&builtins_without_cache_js)) {
return;
}
if (result
->Set(env->context(),
OneByteString(isolate, "compiledWithoutCache"),
native_modules_without_cache_js)
builtins_without_cache_js)
.IsNothing()) {
return;
}
if (!ToV8Value(context, env->native_modules_in_snapshot)
.ToLocal(&native_modules_without_cache_js)) {
if (!ToV8Value(context, env->builtins_in_snapshot)
.ToLocal(&builtins_without_cache_js)) {
return;
}
if (result
->Set(env->context(),
OneByteString(isolate, "compiledInSnapshot"),
native_modules_without_cache_js)
builtins_without_cache_js)
.IsNothing()) {
return;
}
@ -555,32 +538,31 @@ void NativeModuleLoader::GetCacheUsage(
args.GetReturnValue().Set(result);
}
void NativeModuleLoader::ModuleIdsGetter(
Local<Name> property, const PropertyCallbackInfo<Value>& info) {
void BuiltinLoader::BuiltinIdsGetter(Local<Name> property,
const PropertyCallbackInfo<Value>& info) {
Isolate* isolate = info.GetIsolate();
std::vector<std::string> ids = GetInstance()->GetModuleIds();
std::vector<std::string> ids = GetInstance()->GetBuiltinIds();
info.GetReturnValue().Set(
ToV8Value(isolate->GetCurrentContext(), ids).ToLocalChecked());
}
void NativeModuleLoader::ConfigStringGetter(
void BuiltinLoader::ConfigStringGetter(
Local<Name> property, const PropertyCallbackInfo<Value>& info) {
info.GetReturnValue().Set(GetConfigString(info.GetIsolate()));
}
void NativeModuleLoader::RecordResult(const char* id,
NativeModuleLoader::Result result,
void BuiltinLoader::RecordResult(const char* id,
BuiltinLoader::Result result,
Environment* env) {
if (result == NativeModuleLoader::Result::kWithCache) {
env->native_modules_with_cache.insert(id);
if (result == BuiltinLoader::Result::kWithCache) {
env->builtins_with_cache.insert(id);
} else {
env->native_modules_without_cache.insert(id);
env->builtins_without_cache.insert(id);
}
}
void NativeModuleLoader::CompileFunction(
const FunctionCallbackInfo<Value>& args) {
void BuiltinLoader::CompileFunction(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
CHECK(args[0]->IsString());
node::Utf8Value id_v(env->isolate(), args[0].As<String>());
@ -593,8 +575,7 @@ void NativeModuleLoader::CompileFunction(
}
}
void NativeModuleLoader::HasCachedBuiltins(
const FunctionCallbackInfo<Value>& args) {
void BuiltinLoader::HasCachedBuiltins(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(
v8::Boolean::New(args.GetIsolate(), GetInstance()->has_code_cache_));
}
@ -602,7 +583,7 @@ void NativeModuleLoader::HasCachedBuiltins(
// TODO(joyeecheung): It is somewhat confusing that Class::Initialize
// is used to initialize to the binding, but it is the current convention.
// Rename this across the code base to something that makes more sense.
void NativeModuleLoader::Initialize(Local<Object> target,
void BuiltinLoader::Initialize(Local<Object> target,
Local<Value> unused,
Local<Context> context,
void* priv) {
@ -621,8 +602,8 @@ void NativeModuleLoader::Initialize(Local<Object> target,
.Check();
target
->SetAccessor(context,
FIXED_ONE_BYTE_STRING(isolate, "moduleIds"),
ModuleIdsGetter,
FIXED_ONE_BYTE_STRING(isolate, "builtinIds"),
BuiltinIdsGetter,
nullptr,
MaybeLocal<Value>(),
DEFAULT,
@ -632,8 +613,8 @@ void NativeModuleLoader::Initialize(Local<Object> target,
target
->SetAccessor(context,
FIXED_ONE_BYTE_STRING(isolate, "moduleCategories"),
GetModuleCategories,
FIXED_ONE_BYTE_STRING(isolate, "builtinCategories"),
GetBuiltinCategories,
nullptr,
Local<Value>(),
DEFAULT,
@ -641,30 +622,27 @@ void NativeModuleLoader::Initialize(Local<Object> target,
SideEffectType::kHasNoSideEffect)
.Check();
SetMethod(
context, target, "getCacheUsage", NativeModuleLoader::GetCacheUsage);
SetMethod(
context, target, "compileFunction", NativeModuleLoader::CompileFunction);
SetMethod(context, target, "getCacheUsage", BuiltinLoader::GetCacheUsage);
SetMethod(context, target, "compileFunction", BuiltinLoader::CompileFunction);
SetMethod(context, target, "hasCachedBuiltins", HasCachedBuiltins);
// internalBinding('native_module') should be frozen
// internalBinding('builtins') should be frozen
target->SetIntegrityLevel(context, IntegrityLevel::kFrozen).FromJust();
}
void NativeModuleLoader::RegisterExternalReferences(
void BuiltinLoader::RegisterExternalReferences(
ExternalReferenceRegistry* registry) {
registry->Register(ConfigStringGetter);
registry->Register(ModuleIdsGetter);
registry->Register(GetModuleCategories);
registry->Register(BuiltinIdsGetter);
registry->Register(GetBuiltinCategories);
registry->Register(GetCacheUsage);
registry->Register(CompileFunction);
registry->Register(HasCachedBuiltins);
}
} // namespace native_module
} // namespace builtins
} // namespace node
NODE_MODULE_CONTEXT_AWARE_INTERNAL(
native_module, node::native_module::NativeModuleLoader::Initialize)
NODE_MODULE_CONTEXT_AWARE_INTERNAL(builtins,
node::builtins::BuiltinLoader::Initialize)
NODE_MODULE_EXTERNAL_REFERENCE(
native_module,
node::native_module::NativeModuleLoader::RegisterExternalReferences)
builtins, node::builtins::BuiltinLoader::RegisterExternalReferences)

View File

@ -1,5 +1,5 @@
#ifndef SRC_NODE_NATIVE_MODULE_H_
#define SRC_NODE_NATIVE_MODULE_H_
#ifndef SRC_NODE_BUILTINS_H_
#define SRC_NODE_BUILTINS_H_
#if defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
@ -18,10 +18,10 @@ class PerProcessTest;
namespace node {
class SnapshotBuilder;
class ExternalReferenceRegistry;
namespace native_module {
namespace builtins {
using NativeModuleRecordMap = std::map<std::string, UnionBytes>;
using NativeModuleCacheMap =
using BuiltinSourceMap = std::map<std::string, UnionBytes>;
using BuiltinCodeCacheMap =
std::unordered_map<std::string,
std::unique_ptr<v8::ScriptCompiler::CachedData>>;
@ -30,14 +30,12 @@ struct CodeCacheInfo {
std::vector<uint8_t> data;
};
// The native (C++) side of the NativeModule in JS land, which
// handles compilation and caching of builtin modules (NativeModule)
// and bootstrappers, whose source are bundled into the binary
// as static data.
class NODE_EXTERN_PRIVATE NativeModuleLoader {
// Handles compilation and caching of built-in JavaScript modules and
// bootstrap scripts, whose source are bundled into the binary as static data.
class NODE_EXTERN_PRIVATE BuiltinLoader {
public:
NativeModuleLoader(const NativeModuleLoader&) = delete;
NativeModuleLoader& operator=(const NativeModuleLoader&) = delete;
BuiltinLoader(const BuiltinLoader&) = delete;
BuiltinLoader& operator=(const BuiltinLoader&) = delete;
static void RegisterExternalReferences(ExternalReferenceRegistry* registry);
static void Initialize(v8::Local<v8::Object> target,
@ -66,33 +64,33 @@ class NODE_EXTERN_PRIVATE NativeModuleLoader {
// Only allow access from friends.
friend class CodeCacheBuilder;
NativeModuleLoader();
static NativeModuleLoader* GetInstance();
BuiltinLoader();
static BuiltinLoader* GetInstance();
// Generated by tools/js2c.py as node_javascript.cc
void LoadJavaScriptSource(); // Loads data into source_
UnionBytes GetConfig(); // Return data for config.gypi
std::vector<std::string> GetModuleIds();
std::vector<std::string> GetBuiltinIds();
struct ModuleCategories {
struct BuiltinCategories {
bool is_initialized = false;
std::set<std::string> can_be_required;
std::set<std::string> cannot_be_required;
};
void InitializeModuleCategories();
void InitializeBuiltinCategories();
const std::set<std::string>& GetCannotBeRequired();
const std::set<std::string>& GetCanBeRequired();
bool CanBeRequired(const char* id);
bool CannotBeRequired(const char* id);
NativeModuleCacheMap* code_cache();
BuiltinCodeCacheMap* code_cache();
const Mutex& code_cache_mutex() const { return code_cache_mutex_; }
v8::ScriptCompiler::CachedData* GetCodeCache(const char* id) const;
enum class Result { kWithCache, kWithoutCache };
v8::MaybeLocal<v8::String> LoadBuiltinModuleSource(v8::Isolate* isolate,
v8::MaybeLocal<v8::String> LoadBuiltinSource(v8::Isolate* isolate,
const char* id);
// If an exception is encountered (e.g. source code contains
// syntax error), the returned value is empty.
@ -103,29 +101,29 @@ class NODE_EXTERN_PRIVATE NativeModuleLoader {
Result* result);
static void RecordResult(const char* id,
NativeModuleLoader::Result result,
BuiltinLoader::Result result,
Environment* env);
static void GetModuleCategories(
static void GetBuiltinCategories(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
static void GetCacheUsage(const v8::FunctionCallbackInfo<v8::Value>& args);
// Passing ids of builtin module source code into JS land as
// internalBinding('native_module').moduleIds
static void ModuleIdsGetter(v8::Local<v8::Name> property,
// Passing ids of built-in source code into JS land as
// internalBinding('builtins').builtinIds
static void BuiltinIdsGetter(v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
// Passing config.gypi into JS land as internalBinding('native_module').config
// Passing config.gypi into JS land as internalBinding('builtins').config
static void ConfigStringGetter(
v8::Local<v8::Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info);
// Compile a specific native module as a function
// Compile a specific built-in as a function
static void CompileFunction(const v8::FunctionCallbackInfo<v8::Value>& args);
static void HasCachedBuiltins(
const v8::FunctionCallbackInfo<v8::Value>& args);
static NativeModuleLoader instance_;
ModuleCategories module_categories_;
NativeModuleRecordMap source_;
NativeModuleCacheMap code_cache_;
static BuiltinLoader instance_;
BuiltinCategories builtin_categories_;
BuiltinSourceMap source_;
BuiltinCodeCacheMap code_cache_;
UnionBytes config_;
// Used to synchronize access to the code cache map
@ -135,10 +133,10 @@ class NODE_EXTERN_PRIVATE NativeModuleLoader {
friend class ::PerProcessTest;
};
} // namespace native_module
} // namespace builtins
} // namespace node
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
#endif // SRC_NODE_NATIVE_MODULE_H_
#endif // SRC_NODE_BUILTINS_H_

View File

@ -1,8 +1,8 @@
#include "env-inl.h"
#include "memory_tracker.h"
#include "node.h"
#include "node_builtins.h"
#include "node_i18n.h"
#include "node_native_module.h"
#include "node_options.h"
#include "util-inl.h"

View File

@ -167,7 +167,7 @@ ERRORS_WITH_CODE(V)
"The V8 platform used by this instance of Node does not support " \
"creating Workers") \
V(ERR_NON_CONTEXT_AWARE_DISABLED, \
"Loading non context-aware native modules has been disabled") \
"Loading non context-aware native addons has been disabled") \
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, \
"Script execution was interrupted by `SIGINT`") \
V(ERR_TLS_PSK_SET_IDENTIY_HINT_FAILED, "Failed to set PSK identity hint") \

View File

@ -56,6 +56,7 @@ class ExternalReferenceRegistry {
V(binding) \
V(blob) \
V(buffer) \
V(builtins) \
V(contextify) \
V(credentials) \
V(env_var) \
@ -67,7 +68,6 @@ class ExternalReferenceRegistry {
V(heap_utils) \
V(messaging) \
V(mksnapshot) \
V(native_module) \
V(options) \
V(os) \
V(performance) \

View File

@ -43,8 +43,8 @@ struct sockaddr;
namespace node {
namespace native_module {
class NativeModuleLoader;
namespace builtins {
class BuiltinLoader;
}
namespace per_process {

View File

@ -4,9 +4,9 @@
#include "crypto/crypto_util.h"
#endif // HAVE_OPENSSL
#include "debug_utils-inl.h"
#include "node_builtins.h"
#include "node_external_reference.h"
#include "node_internals.h"
#include "node_native_module.h"
#include "node_options-inl.h"
#include "node_snapshot_builder.h"
#include "node_snapshotable.h"

View File

@ -6,13 +6,13 @@
#include "debug_utils-inl.h"
#include "env-inl.h"
#include "node_blob.h"
#include "node_builtins.h"
#include "node_errors.h"
#include "node_external_reference.h"
#include "node_file.h"
#include "node_internals.h"
#include "node_main_instance.h"
#include "node_metadata.h"
#include "node_native_module.h"
#include "node_process.h"
#include "node_snapshot_builder.h"
#include "node_v8.h"
@ -42,14 +42,14 @@ using v8::Value;
const uint32_t SnapshotData::kMagic;
std::ostream& operator<<(std::ostream& output,
const native_module::CodeCacheInfo& info) {
output << "<native_module::CodeCacheInfo id=" << info.id
const builtins::CodeCacheInfo& info) {
output << "<builtins::CodeCacheInfo id=" << info.id
<< ", size=" << info.data.size() << ">\n";
return output;
}
std::ostream& operator<<(std::ostream& output,
const std::vector<native_module::CodeCacheInfo>& vec) {
const std::vector<builtins::CodeCacheInfo>& vec) {
output << "{\n";
for (const auto& info : vec) {
output << info;
@ -91,7 +91,7 @@ class FileIO {
template <typename T>
std::string GetName() const {
#define TYPE_LIST(V) \
V(native_module::CodeCacheInfo) \
V(builtins::CodeCacheInfo) \
V(PropInfo) \
V(std::string)
@ -389,27 +389,27 @@ size_t FileWriter::Write(const v8::StartupData& data) {
return written_total;
}
// Layout of native_module::CodeCacheInfo
// Layout of builtins::CodeCacheInfo
// [ 4/8 bytes ] length of the module id string
// [ ... ] |length| bytes of module id
// [ 4/8 bytes ] length of module code cache
// [ ... ] |length| bytes of module code cache
template <>
native_module::CodeCacheInfo FileReader::Read() {
Debug("Read<native_module::CodeCacheInfo>()\n");
builtins::CodeCacheInfo FileReader::Read() {
Debug("Read<builtins::CodeCacheInfo>()\n");
native_module::CodeCacheInfo result{ReadString(), ReadVector<uint8_t>()};
builtins::CodeCacheInfo result{ReadString(), ReadVector<uint8_t>()};
if (is_debug) {
std::string str = ToStr(result);
Debug("Read<native_module::CodeCacheInfo>() %s\n", str.c_str());
Debug("Read<builtins::CodeCacheInfo>() %s\n", str.c_str());
}
return result;
}
template <>
size_t FileWriter::Write(const native_module::CodeCacheInfo& data) {
Debug("\nWrite<native_module::CodeCacheInfo>() id = %s"
size_t FileWriter::Write(const builtins::CodeCacheInfo& data) {
Debug("\nWrite<builtins::CodeCacheInfo>() id = %s"
", size=%d\n",
data.id.c_str(),
data.data.size());
@ -417,8 +417,7 @@ size_t FileWriter::Write(const native_module::CodeCacheInfo& data) {
size_t written_total = WriteString(data.id);
written_total += WriteVector<uint8_t>(data.data);
Debug("Write<native_module::CodeCacheInfo>() wrote %d bytes\n",
written_total);
Debug("Write<builtins::CodeCacheInfo>() wrote %d bytes\n", written_total);
return written_total;
}
@ -640,7 +639,7 @@ EnvSerializeInfo FileReader::Read() {
per_process::Debug(DebugCategory::MKSNAPSHOT, "Read<EnvSerializeInfo>()\n");
EnvSerializeInfo result;
result.bindings = ReadVector<PropInfo>();
result.native_modules = ReadVector<std::string>();
result.builtins = ReadVector<std::string>();
result.async_hooks = Read<AsyncHooks::SerializeInfo>();
result.tick_info = Read<TickInfo::SerializeInfo>();
result.immediate_info = Read<ImmediateInfo::SerializeInfo>();
@ -663,7 +662,7 @@ size_t FileWriter::Write(const EnvSerializeInfo& data) {
// Use += here to ensure order of evaluation.
size_t written_total = WriteVector<PropInfo>(data.bindings);
written_total += WriteVector<std::string>(data.native_modules);
written_total += WriteVector<std::string>(data.builtins);
written_total += Write<AsyncHooks::SerializeInfo>(data.async_hooks);
written_total += Write<TickInfo::SerializeInfo>(data.tick_info);
written_total += Write<ImmediateInfo::SerializeInfo>(data.immediate_info);
@ -709,7 +708,7 @@ void SnapshotData::ToBlob(FILE* out) const {
written_total += w.Write<IsolateDataSerializeInfo>(isolate_data_info);
written_total += w.Write<EnvSerializeInfo>(env_info);
w.Debug("Write code_cache\n");
written_total += w.WriteVector<native_module::CodeCacheInfo>(code_cache);
written_total += w.WriteVector<builtins::CodeCacheInfo>(code_cache);
w.Debug("SnapshotData::ToBlob() Wrote %d bytes\n", written_total);
}
@ -734,7 +733,7 @@ void SnapshotData::FromBlob(SnapshotData* out, FILE* in) {
out->isolate_data_info = r.Read<IsolateDataSerializeInfo>();
out->env_info = r.Read<EnvSerializeInfo>();
r.Debug("Read code_cache\n");
out->code_cache = r.ReadVector<native_module::CodeCacheInfo>();
out->code_cache = r.ReadVector<builtins::CodeCacheInfo>();
r.Debug("SnapshotData::FromBlob() read %d bytes\n", r.read_total);
}
@ -778,7 +777,7 @@ static std::string FormatSize(size_t size) {
}
static void WriteStaticCodeCacheData(std::ostream* ss,
const native_module::CodeCacheInfo& info) {
const builtins::CodeCacheInfo& info) {
*ss << "static const uint8_t " << GetCodeCacheDefName(info.id) << "[] = {\n";
WriteVector(ss, info.data.data(), info.data.size());
*ss << "};";
@ -986,11 +985,10 @@ int SnapshotBuilder::Generate(SnapshotData* out,
#ifdef NODE_USE_NODE_CODE_CACHE
// Regenerate all the code cache.
if (!native_module::NativeModuleLoader::CompileAllBuiltins(
main_context)) {
if (!builtins::BuiltinLoader::CompileAllBuiltins(main_context)) {
return UNCAUGHT_EXCEPTION_ERROR;
}
native_module::NativeModuleLoader::CopyCodeCache(&(out->code_cache));
builtins::BuiltinLoader::CopyCodeCache(&(out->code_cache));
for (const auto& item : out->code_cache) {
std::string size_str = FormatSize(item.data.size());
per_process::Debug(DebugCategory::MKSNAPSHOT,

View File

@ -5,4 +5,4 @@ const assert = require('assert');
assert.throws(() => {
require(`./build/${common.buildType}/binding`);
}, /^Error: Loading non context-aware native modules has been disabled$/);
}, /^Error: Loading non context-aware native addons has been disabled$/);

View File

@ -4,7 +4,7 @@ const fs = require('fs');
const path = require('path');
const assert = require('assert');
// This test verifies that symlinked native modules can be required multiple
// This test verifies that symlinked native addons can be required multiple
// times without error. The symlinked module and the non-symlinked module
// should be the same instance. This expectation was not previously being
// tested and ended up being broken by https://github.com/nodejs/node/pull/5950.

View File

@ -1,18 +1,17 @@
#include "node_native_module.h"
#include "node_builtins.h"
#include "gtest/gtest.h"
#include "node_test_fixture.h"
#include <string>
using node::native_module::NativeModuleLoader;
using node::native_module::NativeModuleRecordMap;
using node::builtins::BuiltinLoader;
using node::builtins::BuiltinSourceMap;
class PerProcessTest : public ::testing::Test {
protected:
static const NativeModuleRecordMap get_sources_for_test() {
return NativeModuleLoader::instance_.source_;
static const BuiltinSourceMap get_sources_for_test() {
return BuiltinLoader::instance_.source_;
}
};
@ -20,15 +19,13 @@ namespace {
TEST_F(PerProcessTest, EmbeddedSources) {
const auto& sources = PerProcessTest::get_sources_for_test();
ASSERT_TRUE(
std::any_of(sources.cbegin(), sources.cend(),
[](auto p){ return p.second.is_one_byte(); }))
<< "NativeModuleLoader::source_ should have some 8bit items";
ASSERT_TRUE(std::any_of(sources.cbegin(), sources.cend(), [](auto p) {
return p.second.is_one_byte();
})) << "BuiltinLoader::source_ should have some 8bit items";
ASSERT_TRUE(
std::any_of(sources.cbegin(), sources.cend(),
[](auto p){ return !p.second.is_one_byte(); }))
<< "NativeModuleLoader::source_ should have some 16bit items";
ASSERT_TRUE(std::any_of(sources.cbegin(), sources.cend(), [](auto p) {
return !p.second.is_one_byte();
})) << "BuiltinLoader::source_ should have some 16bit items";
}
} // end namespace

View File

@ -23,7 +23,7 @@ tmpdir.refresh();
const urlTestFile = path.join(urlTestDir, path.basename(filename));
fs.mkdirSync(urlTestDir, { recursive: true });
fs.copyFileSync(filename, urlTestFile);
// Use a child process as indirection so that the native module is not loaded
// Use a child process as indirection so that the built-in modules is not loaded
// into this process and can be removed here.
const reportedFilename = child_process.spawnSync(
process.execPath,

View File

@ -12,6 +12,7 @@ const expectedModules = new Set([
'Internal Binding async_wrap',
'Internal Binding block_list',
'Internal Binding buffer',
'Internal Binding builtins',
'Internal Binding config',
'Internal Binding constants',
'Internal Binding contextify',
@ -24,7 +25,6 @@ const expectedModules = new Set([
'Internal Binding mksnapshot',
'Internal Binding messaging',
'Internal Binding module_wrap',
'Internal Binding native_module',
'Internal Binding options',
'Internal Binding performance',
'Internal Binding pipe_wrap',

View File

@ -12,8 +12,8 @@ const {
} = require('internal/test/binding');
const {
getCacheUsage,
moduleCategories: { canBeRequired }
} = internalBinding('native_module');
builtinCategories: { canBeRequired }
} = internalBinding('builtins');
for (const key of canBeRequired) {
require(`node:${key}`);

View File

@ -48,24 +48,24 @@ def ReadFile(filename):
TEMPLATE = """
#include "env-inl.h"
#include "node_native_module.h"
#include "node_builtins.h"
#include "node_internals.h"
namespace node {{
namespace native_module {{
namespace builtins {{
{0}
void NativeModuleLoader::LoadJavaScriptSource() {{
void BuiltinLoader::LoadJavaScriptSource() {{
{1}
}}
UnionBytes NativeModuleLoader::GetConfig() {{
UnionBytes BuiltinLoader::GetConfig() {{
return UnionBytes(config_raw, {2}); // config.gypi
}}
}} // namespace native_module
}} // namespace builtins
}} // namespace node
"""