Skip to content

Commit

Permalink
esm: refactor to use more primordials
Browse files Browse the repository at this point in the history
PR-URL: #36019
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
aduh95 authored and BethGriggs committed Dec 15, 2020
1 parent b53068e commit 8d672b8
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 26 deletions.
4 changes: 2 additions & 2 deletions lib/internal/modules/esm/create_dynamic_module.js
Expand Up @@ -5,7 +5,7 @@ const {
ArrayPrototypeMap,
JSONStringify,
ObjectCreate,
Set,
SafeSet,
} = primordials;

let debug = require('internal/util/debuglog').debuglog('esm', (fn) => {
Expand Down Expand Up @@ -38,7 +38,7 @@ import.meta.done();
const { ModuleWrap, callbackMap } = internalBinding('module_wrap');
const m = new ModuleWrap(`${url}`, undefined, source, 0, 0);

const readyfns = new Set();
const readyfns = new SafeSet();
const reflect = {
exports: ObjectCreate(null),
onReady: (cb) => { readyfns.add(cb); },
Expand Down
10 changes: 8 additions & 2 deletions lib/internal/modules/esm/get_format.js
@@ -1,5 +1,8 @@
'use strict';
const { StringPrototypeStartsWith } = primordials;
const {
RegExpPrototypeExec,
StringPrototypeStartsWith,
} = primordials;
const { extname } = require('path');
const { getOptionValue } = require('internal/options');

Expand Down Expand Up @@ -39,7 +42,10 @@ function defaultGetFormat(url, context, defaultGetFormatUnused) {
}
const parsed = new URL(url);
if (parsed.protocol === 'data:') {
const [ , mime ] = /^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/.exec(parsed.pathname) || [ null, null, null ];
const [ , mime ] = RegExpPrototypeExec(
/^([^/]+\/[^;,]+)(?:[^,]*?)(;base64)?,/,
parsed.pathname,
) || [ null, null, null ];
const format = ({
'__proto__': null,
'text/javascript': 'module',
Expand Down
12 changes: 7 additions & 5 deletions lib/internal/modules/esm/get_source.js
@@ -1,5 +1,8 @@
'use strict';

const {
RegExpPrototypeExec,
} = primordials;
const { getOptionValue } = require('internal/options');
// Do not eagerly grab .manifest, it may be in TDZ
const policy = getOptionValue('--experimental-policy') ?
Expand All @@ -8,14 +11,13 @@ const policy = getOptionValue('--experimental-policy') ?

const { Buffer } = require('buffer');

const fs = require('fs');
const { URL } = require('url');
const { promisify } = require('internal/util');
const fs = require('internal/fs/promises').exports;
const { URL } = require('internal/url');
const {
ERR_INVALID_URL,
ERR_INVALID_URL_SCHEME,
} = require('internal/errors').codes;
const readFileAsync = promisify(fs.readFile);
const readFileAsync = fs.readFile;

const DATA_URL_PATTERN = /^[^/]+\/[^,;]+(?:[^,]*?)(;base64)?,([\s\S]*)$/;

Expand All @@ -25,7 +27,7 @@ async function defaultGetSource(url, { format } = {}, defaultGetSource) {
if (parsed.protocol === 'file:') {
source = await readFileAsync(parsed);
} else if (parsed.protocol === 'data:') {
const match = DATA_URL_PATTERN.exec(parsed.pathname);
const match = RegExpPrototypeExec(DATA_URL_PATTERN, parsed.pathname);
if (!match) {
throw new ERR_INVALID_URL(url);
}
Expand Down
5 changes: 3 additions & 2 deletions lib/internal/modules/esm/loader.js
Expand Up @@ -7,6 +7,7 @@ const {
FunctionPrototypeBind,
ObjectSetPrototypeOf,
SafeWeakMap,
StringPrototypeStartsWith,
} = primordials;

const {
Expand Down Expand Up @@ -126,8 +127,8 @@ class Loader {
}

if (this._resolve === defaultResolve &&
!url.startsWith('file:') &&
!url.startsWith('data:')
!StringPrototypeStartsWith(url, 'file:') &&
!StringPrototypeStartsWith(url, 'data:')
) {
throw new ERR_INVALID_RETURN_PROPERTY(
'file: or data: url', 'loader resolve', 'url', url
Expand Down
24 changes: 15 additions & 9 deletions lib/internal/modules/esm/module_job.js
Expand Up @@ -2,10 +2,15 @@

const {
ArrayPrototypeJoin,
ArrayPrototypeMap,
ArrayPrototypePush,
FunctionPrototype,
ObjectSetPrototypeOf,
PromiseAll,
PromiseResolve,
PromisePrototypeCatch,
ReflectApply,
SafeSet,
SafePromise,
StringPrototypeIncludes,
StringPrototypeMatch,
StringPrototypeReplace,
Expand All @@ -16,9 +21,9 @@ const { ModuleWrap } = internalBinding('module_wrap');

const { decorateErrorStack } = require('internal/util');
const assert = require('internal/assert');
const resolvedPromise = SafePromise.resolve();
const resolvedPromise = PromiseResolve();

function noop() {}
const noop = FunctionPrototype;

let hasPausedEntry = false;

Expand All @@ -35,7 +40,7 @@ class ModuleJob {
this.module = undefined;
// Expose the promise to the ModuleWrap directly for linking below.
// `this.module` is also filled in below.
this.modulePromise = moduleProvider.call(loader, url, isMain);
this.modulePromise = ReflectApply(moduleProvider, loader, [url, isMain]);

// Wait for the ModuleWrap instance being linked with all dependencies.
const link = async () => {
Expand All @@ -49,21 +54,21 @@ class ModuleJob {
const dependencyJobs = [];
const promises = this.module.link(async (specifier) => {
const jobPromise = this.loader.getModuleJob(specifier, url);
dependencyJobs.push(jobPromise);
ArrayPrototypePush(dependencyJobs, jobPromise);
const job = await jobPromise;
return job.modulePromise;
});

if (promises !== undefined)
await SafePromise.all(promises);
await PromiseAll(promises);

return SafePromise.all(dependencyJobs);
return PromiseAll(dependencyJobs);
};
// Promise for the list of all dependencyJobs.
this.linked = link();
// This promise is awaited later anyway, so silence
// 'unhandled rejection' warnings.
this.linked.catch(noop);
PromisePrototypeCatch(this.linked, noop);

// instantiated == deep dependency jobs wrappers are instantiated,
// and module wrapper is instantiated.
Expand All @@ -85,7 +90,8 @@ class ModuleJob {
}
jobsInGraph.add(moduleJob);
const dependencyJobs = await moduleJob.linked;
return PromiseAll(dependencyJobs.map(addJobsToDependencyGraph));
return PromiseAll(
ArrayPrototypeMap(dependencyJobs, addJobsToDependencyGraph));
};
await addJobsToDependencyGraph(this);

Expand Down
3 changes: 2 additions & 1 deletion lib/internal/modules/esm/resolve.js
Expand Up @@ -837,7 +837,8 @@ function defaultResolve(specifier, context = {}, defaultResolveUnused) {
[internalFS.realpathCacheKey]: realpathCache
});
const old = url;
url = pathToFileURL(real + (urlPath.endsWith(sep) ? '/' : ''));
url = pathToFileURL(
real + (StringPrototypeEndsWith(urlPath, sep) ? '/' : ''));
url.search = old.search;
url.hash = old.hash;
}
Expand Down
16 changes: 11 additions & 5 deletions lib/internal/modules/esm/translators.js
Expand Up @@ -3,6 +3,7 @@
/* global WebAssembly */

const {
ArrayPrototypeMap,
Boolean,
JSONParse,
ObjectGetPrototypeOf,
Expand All @@ -14,6 +15,7 @@ const {
SafeMap,
SafeSet,
StringPrototypeReplace,
StringPrototypeSlice,
StringPrototypeSplit,
StringPrototypeStartsWith,
SyntaxErrorPrototype,
Expand Down Expand Up @@ -277,9 +279,9 @@ function cjsPreparseModuleExports(filename) {
translators.set('builtin', async function builtinStrategy(url) {
debug(`Translating BuiltinModule ${url}`);
// Slice 'node:' scheme
const id = url.slice(5);
const id = StringPrototypeSlice(url, 5);
const module = loadNativeModule(id, url, true);
if (!url.startsWith('node:') || !module) {
if (!StringPrototypeStartsWith(url, 'node:') || !module) {
throw new ERR_UNKNOWN_BUILTIN_MODULE(url);
}
debug(`Loading BuiltinModule ${url}`);
Expand All @@ -291,7 +293,8 @@ translators.set('json', async function jsonStrategy(url) {
emitExperimentalWarning('Importing JSON modules');
debug(`Translating JSONModule ${url}`);
debug(`Loading JSONModule ${url}`);
const pathname = url.startsWith('file:') ? fileURLToPath(url) : null;
const pathname = StringPrototypeStartsWith(url, 'file:') ?
fileURLToPath(url) : null;
let modulePath;
let module;
if (pathname) {
Expand Down Expand Up @@ -365,8 +368,11 @@ translators.set('wasm', async function(url) {
}

const imports =
WebAssembly.Module.imports(compiled).map(({ module }) => module);
const exports = WebAssembly.Module.exports(compiled).map(({ name }) => name);
ArrayPrototypeMap(WebAssembly.Module.imports(compiled),
({ module }) => module);
const exports =
ArrayPrototypeMap(WebAssembly.Module.exports(compiled),
({ name }) => name);

return createDynamicModule(imports, exports, url, (reflect) => {
const { exports } = new WebAssembly.Instance(compiled, reflect.imports);
Expand Down
2 changes: 2 additions & 0 deletions test/parallel/test-bootstrap-modules.js
Expand Up @@ -46,6 +46,8 @@ const expectedModules = new Set([
'NativeModule internal/fixed_queue',
'NativeModule internal/fs/dir',
'NativeModule internal/fs/utils',
'NativeModule internal/fs/promises',
'NativeModule internal/fs/rimraf',
'NativeModule internal/idna',
'NativeModule internal/linkedlist',
'NativeModule internal/modules/run_main',
Expand Down

0 comments on commit 8d672b8

Please sign in to comment.