GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — vm: use internal versions of compileFunction and Script · nodejs/node@3999362

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
  • lib
    • internal
      • modules
        • cjs
          • loader.js
        • esm
          • translators.js
      • process
        • execution.js
      • vm.js
    • repl.js
    • vm.js
  • test/message
    • eval_messages.out
    • stdin_messages.out
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎lib/internal/modules/cjs/loader.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/cjs/loader.js
+40-33Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const {
5252
SafeMap,
5353
SafeWeakMap,
5454
String,
55+
Symbol,
5556
StringPrototypeCharAt,
5657
StringPrototypeCharCodeAt,
5758
StringPrototypeEndsWith,
@@ -84,7 +85,12 @@ const {
8485
setOwnProperty,
8586
getLazy,
8687
} = require('internal/util');
87-
const { internalCompileFunction } = require('internal/vm');
88+
const {
89+
internalCompileFunction,
90+
makeContextifyScript,
91+
runScriptInThisContext,
92+
} = require('internal/vm');
93+
8894
const assert = require('internal/assert');
8995
const fs = require('fs');
9096
const path = require('path');
@@ -1240,7 +1246,6 @@ Module.prototype.require = function(id) {
12401246
let resolvedArgv;
12411247
let hasPausedEntry = false;
12421248
/** @type {import('vm').Script} */
1243-
let Script;
12441249

12451250
/**
12461251
* Wraps the given content in a script and runs it in a new context.
@@ -1250,47 +1255,49 @@ let Script;
12501255
* @param {object} codeCache The SEA code cache
12511256
*/
12521257
function wrapSafe(filename, content, cjsModuleInstance, codeCache) {
1258+
const hostDefinedOptionId = Symbol(`cjs:${filename}`);
1259+
async function importModuleDynamically(specifier, _, importAttributes) {
1260+
const cascadedLoader = getCascadedLoader();
1261+
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
1262+
importAttributes);
1263+
}
12531264
if (patched) {
1254-
const wrapper = Module.wrap(content);
1255-
if (Script === undefined) {
1256-
({ Script } = require('vm'));
1257-
}
1258-
const script = new Script(wrapper, {
1259-
filename,
1260-
lineOffset: 0,
1261-
importModuleDynamically: async (specifier, _, importAttributes) => {
1262-
const cascadedLoader = getCascadedLoader();
1263-
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
1264-
importAttributes);
1265-
},
1266-
});
1265+
const wrapped = Module.wrap(content);
1266+
const script = makeContextifyScript(
1267+
wrapped, // code
1268+
filename, // filename
1269+
0, // lineOffset
1270+
0, // columnOffset
1271+
undefined, // cachedData
1272+
false, // produceCachedData
1273+
undefined, // parsingContext
1274+
hostDefinedOptionId, // hostDefinedOptionId
1275+
importModuleDynamically, // importModuleDynamically
1276+
);
12671277

12681278
// Cache the source map for the module if present.
12691279
if (script.sourceMapURL) {
12701280
maybeCacheSourceMap(filename, content, this, false, undefined, script.sourceMapURL);
12711281
}
12721282

1273-
return script.runInThisContext({
1274-
displayErrors: true,
1275-
});
1283+
return runScriptInThisContext(script, true, false);
12761284
}
12771285

1286+
const params = [ 'exports', 'require', 'module', '__filename', '__dirname' ];
12781287
try {
1279-
const result = internalCompileFunction(content, [
1280-
'exports',
1281-
'require',
1282-
'module',
1283-
'__filename',
1284-
'__dirname',
1285-
], {
1286-
filename,
1287-
cachedData: codeCache,
1288-
importModuleDynamically(specifier, _, importAttributes) {
1289-
const cascadedLoader = getCascadedLoader();
1290-
return cascadedLoader.import(specifier, normalizeReferrerURL(filename),
1291-
importAttributes);
1292-
},
1293-
});
1288+
const result = internalCompileFunction(
1289+
content, // code,
1290+
filename, // filename
1291+
0, // lineOffset
1292+
0, // columnOffset,
1293+
codeCache, // cachedData
1294+
false, // produceCachedData
1295+
undefined, // parsingContext
1296+
undefined, // contextExtensions
1297+
params, // params
1298+
hostDefinedOptionId, // hostDefinedOptionId
1299+
importModuleDynamically, // importModuleDynamically
1300+
);
12941301

12951302
// The code cache is used for SEAs only.
12961303
if (codeCache &&
Collapse file

‎lib/internal/modules/esm/translators.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/esm/translators.js
+23-12Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ const {
1515
StringPrototypeReplaceAll,
1616
StringPrototypeSlice,
1717
StringPrototypeStartsWith,
18+
Symbol,
1819
SyntaxErrorPrototype,
1920
globalThis: { WebAssembly },
2021
} = primordials;
@@ -192,19 +193,29 @@ function enrichCJSError(err, content, filename) {
192193
*/
193194
function loadCJSModule(module, source, url, filename) {
194195
let compiledWrapper;
196+
async function importModuleDynamically(specifier, _, importAttributes) {
197+
return asyncESM.esmLoader.import(specifier, url, importAttributes);
198+
}
195199
try {
196-
compiledWrapper = internalCompileFunction(source, [
197-
'exports',
198-
'require',
199-
'module',
200-
'__filename',
201-
'__dirname',
202-
], {
203-
filename,
204-
importModuleDynamically(specifier, _, importAttributes) {
205-
return asyncESM.esmLoader.import(specifier, url, importAttributes);
206-
},
207-
}).function;
200+
compiledWrapper = internalCompileFunction(
201+
source, // code,
202+
filename, // filename
203+
0, // lineOffset
204+
0, // columnOffset,
205+
undefined, // cachedData
206+
false, // produceCachedData
207+
undefined, // parsingContext
208+
undefined, // contextExtensions
209+
[ // params
210+
'exports',
211+
'require',
212+
'module',
213+
'__filename',
214+
'__dirname',
215+
],
216+
Symbol(`cjs:${filename}`), // hostDefinedOptionsId
217+
importModuleDynamically, // importModuleDynamically
218+
).function;
208219
} catch (err) {
209220
enrichCJSError(err, source, url);
210221
throw err;
Collapse file

‎lib/internal/process/execution.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/execution.js
+23-12Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict';
22

33
const {
4+
Symbol,
45
RegExpPrototypeExec,
56
globalThis,
67
} = primordials;
@@ -25,7 +26,9 @@ const {
2526
emitAfter,
2627
popAsyncContext,
2728
} = require('internal/async_hooks');
28-
29+
const {
30+
makeContextifyScript, runScriptInThisContext,
31+
} = require('internal/vm');
2932
// shouldAbortOnUncaughtToggle is a typed array for faster
3033
// communication with JS.
3134
const { shouldAbortOnUncaughtToggle } = internalBinding('util');
@@ -53,7 +56,6 @@ function evalModule(source, print) {
5356

5457
function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) {
5558
const CJSModule = require('internal/modules/cjs/loader').Module;
56-
const { kVmBreakFirstLineSymbol } = require('internal/util');
5759
const { pathToFileURL } = require('internal/url');
5860

5961
const cwd = tryGetCwd();
@@ -79,16 +81,25 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) {
7981
`;
8082
globalThis.__filename = name;
8183
RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs.
82-
const result = module._compile(script, `${name}-wrapper`)(() =>
83-
require('vm').runInThisContext(body, {
84-
filename: name,
85-
displayErrors: true,
86-
[kVmBreakFirstLineSymbol]: !!breakFirstLine,
87-
importModuleDynamically(specifier, _, importAttributes) {
88-
const loader = asyncESM.esmLoader;
89-
return loader.import(specifier, baseUrl, importAttributes);
90-
},
91-
}));
84+
const result = module._compile(script, `${name}-wrapper`)(() => {
85+
const hostDefinedOptionId = Symbol(name);
86+
async function importModuleDynamically(specifier, _, importAttributes) {
87+
const loader = asyncESM.esmLoader;
88+
return loader.import(specifier, baseUrl, importAttributes);
89+
}
90+
const script = makeContextifyScript(
91+
body, // code
92+
name, // filename,
93+
0, // lineOffset
94+
0, // columnOffset,
95+
undefined, // cachedData
96+
false, // produceCachedData
97+
undefined, // parsingContext
98+
hostDefinedOptionId, // hostDefinedOptionId
99+
importModuleDynamically, // importModuleDynamically
100+
);
101+
return runScriptInThisContext(script, true, !!breakFirstLine);
102+
});
92103
if (print) {
93104
const { log } = require('internal/console/global');
94105
log(result);
Collapse file

‎lib/internal/vm.js‎

Copy file name to clipboard
+69-62Lines changed: 69 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
'use strict';
22

33
const {
4-
ArrayPrototypeForEach,
4+
ReflectApply,
55
Symbol,
66
} = primordials;
77

88
const {
9+
ContextifyScript,
910
compileFunction,
1011
isContext: _isContext,
1112
} = internalBinding('contextify');
13+
const {
14+
runInContext,
15+
} = ContextifyScript.prototype;
1216
const {
1317
default_host_defined_options,
1418
} = internalBinding('symbols');
1519
const {
16-
validateArray,
17-
validateBoolean,
18-
validateBuffer,
1920
validateFunction,
2021
validateObject,
21-
validateString,
22-
validateStringArray,
2322
kValidateObjectAllowArray,
24-
kValidateObjectAllowNullable,
25-
validateInt32,
2623
} = require('internal/validators');
27-
const {
28-
ERR_INVALID_ARG_TYPE,
29-
} = require('internal/errors').codes;
3024

3125
function isContext(object) {
3226
validateObject(object, 'object', kValidateObjectAllowArray);
@@ -50,49 +44,20 @@ function getHostDefinedOptionId(importModuleDynamically, filename) {
5044
return Symbol(filename);
5145
}
5246

53-
function internalCompileFunction(code, params, options) {
54-
validateString(code, 'code');
55-
if (params !== undefined) {
56-
validateStringArray(params, 'params');
57-
}
58-
const {
59-
filename = '',
60-
columnOffset = 0,
61-
lineOffset = 0,
62-
cachedData = undefined,
63-
produceCachedData = false,
64-
parsingContext = undefined,
65-
contextExtensions = [],
66-
importModuleDynamically,
67-
} = options;
68-
69-
validateString(filename, 'options.filename');
70-
validateInt32(columnOffset, 'options.columnOffset');
71-
validateInt32(lineOffset, 'options.lineOffset');
72-
if (cachedData !== undefined)
73-
validateBuffer(cachedData, 'options.cachedData');
74-
validateBoolean(produceCachedData, 'options.produceCachedData');
75-
if (parsingContext !== undefined) {
76-
if (
77-
typeof parsingContext !== 'object' ||
78-
parsingContext === null ||
79-
!isContext(parsingContext)
80-
) {
81-
throw new ERR_INVALID_ARG_TYPE(
82-
'options.parsingContext',
83-
'Context',
84-
parsingContext,
85-
);
86-
}
87-
}
88-
validateArray(contextExtensions, 'options.contextExtensions');
89-
ArrayPrototypeForEach(contextExtensions, (extension, i) => {
90-
const name = `options.contextExtensions[${i}]`;
91-
validateObject(extension, name, kValidateObjectAllowNullable);
47+
function registerImportModuleDynamically(referrer, importModuleDynamically) {
48+
const { importModuleDynamicallyWrap } = require('internal/vm/module');
49+
const { registerModule } = require('internal/modules/esm/utils');
50+
registerModule(referrer, {
51+
__proto__: null,
52+
importModuleDynamically:
53+
importModuleDynamicallyWrap(importModuleDynamically),
9254
});
55+
}
9356

94-
const hostDefinedOptionId =
95-
getHostDefinedOptionId(importModuleDynamically, filename);
57+
function internalCompileFunction(
58+
code, filename, lineOffset, columnOffset,
59+
cachedData, produceCachedData, parsingContext, contextExtensions,
60+
params, hostDefinedOptionId, importModuleDynamically) {
9661
const result = compileFunction(
9762
code,
9863
filename,
@@ -119,23 +84,65 @@ function internalCompileFunction(code, params, options) {
11984
}
12085

12186
if (importModuleDynamically !== undefined) {
122-
validateFunction(importModuleDynamically,
123-
'options.importModuleDynamically');
124-
const { importModuleDynamicallyWrap } = require('internal/vm/module');
125-
const wrapped = importModuleDynamicallyWrap(importModuleDynamically);
126-
const func = result.function;
127-
const { registerModule } = require('internal/modules/esm/utils');
128-
registerModule(func, {
129-
__proto__: null,
130-
importModuleDynamically: wrapped,
131-
});
87+
registerImportModuleDynamically(result.function, importModuleDynamically);
13288
}
13389

13490
return result;
13591
}
13692

93+
function makeContextifyScript(code,
94+
filename,
95+
lineOffset,
96+
columnOffset,
97+
cachedData,
98+
produceCachedData,
99+
parsingContext,
100+
hostDefinedOptionId,
101+
importModuleDynamically) {
102+
let script;
103+
// Calling `ReThrow()` on a native TryCatch does not generate a new
104+
// abort-on-uncaught-exception check. A dummy try/catch in JS land
105+
// protects against that.
106+
try { // eslint-disable-line no-useless-catch
107+
script = new ContextifyScript(code,
108+
filename,
109+
lineOffset,
110+
columnOffset,
111+
cachedData,
112+
produceCachedData,
113+
parsingContext,
114+
hostDefinedOptionId);
115+
} catch (e) {
116+
throw e; /* node-do-not-add-exception-line */
117+
}
118+
119+
if (importModuleDynamically !== undefined) {
120+
registerImportModuleDynamically(script, importModuleDynamically);
121+
}
122+
return script;
123+
}
124+
125+
// Internal version of vm.Script.prototype.runInThisContext() which skips
126+
// argument validation.
127+
function runScriptInThisContext(script, displayErrors, breakOnFirstLine) {
128+
return ReflectApply(
129+
runInContext,
130+
script,
131+
[
132+
null, // sandbox - use current context
133+
-1, // timeout
134+
displayErrors, // displayErrors
135+
false, // breakOnSigint
136+
breakOnFirstLine, // breakOnFirstLine
137+
],
138+
);
139+
}
140+
137141
module.exports = {
138142
getHostDefinedOptionId,
139143
internalCompileFunction,
140144
isContext,
145+
makeContextifyScript,
146+
registerImportModuleDynamically,
147+
runScriptInThisContext,
141148
};

0 commit comments

Comments
0 (0)
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.