| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 9f7899e commit 052e095
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -53,6 +53,7 @@ const { | |||
| 53 | 53 | SafeMap, | |
| 54 | 54 | SafeWeakMap, | |
| 55 | 55 | String, | |
| 56 | + Symbol, | ||
| 56 | 57 | StringPrototypeCharAt, | |
| 57 | 58 | StringPrototypeCharCodeAt, | |
| 58 | 59 | StringPrototypeEndsWith, | |
@@ -85,7 +86,12 @@ const { | |||
| 85 | 86 | setOwnProperty, | |
| 86 | 87 | getLazy, | |
| 87 | 88 | } = require('internal/util'); | |
| 88 | - const { internalCompileFunction } = require('internal/vm'); | ||
| 89 | + const { | ||
| 90 | + internalCompileFunction, | ||
| 91 | + makeContextifyScript, | ||
| 92 | + runScriptInThisContext, | ||
| 93 | + } = require('internal/vm'); | ||
| 94 | + | ||
| 89 | 95 | const assert = require('internal/assert'); | |
| 90 | 96 | const fs = require('fs'); | |
| 91 | 97 | const path = require('path'); | |
@@ -1236,7 +1242,6 @@ Module.prototype.require = function(id) { | |||
| 1236 | 1242 | let resolvedArgv; | |
| 1237 | 1243 | let hasPausedEntry = false; | |
| 1238 | 1244 | /** @type {import('vm').Script} */ | |
| 1239 | - let Script; | ||
| 1240 | 1245 | ||
| 1241 | 1246 | /** | |
| 1242 | 1247 | * Wraps the given content in a script and runs it in a new context. | |
@@ -1245,46 +1250,49 @@ let Script; | |||
| 1245 | 1250 | * @param {Module} cjsModuleInstance The CommonJS loader instance | |
| 1246 | 1251 | */ | |
| 1247 | 1252 | function wrapSafe(filename, content, cjsModuleInstance) { | |
| 1253 | + const hostDefinedOptionId = Symbol(`cjs:${filename}`); | ||
| 1254 | + async function importModuleDynamically(specifier, _, importAttributes) { | ||
| 1255 | + const cascadedLoader = getCascadedLoader(); | ||
| 1256 | + return cascadedLoader.import(specifier, normalizeReferrerURL(filename), | ||
| 1257 | + importAttributes); | ||
| 1258 | + } | ||
| 1248 | 1259 | if (patched) { | |
| 1249 | - const wrapper = Module.wrap(content); | ||
| 1250 | - if (Script === undefined) { | ||
| 1251 | - ({ Script } = require('vm')); | ||
| 1252 | - } | ||
| 1253 | - const script = new Script(wrapper, { | ||
| 1254 | - filename, | ||
| 1255 | - lineOffset: 0, | ||
| 1256 | - importModuleDynamically: async (specifier, _, importAttributes) => { | ||
| 1257 | - const cascadedLoader = getCascadedLoader(); | ||
| 1258 | - return cascadedLoader.import(specifier, normalizeReferrerURL(filename), | ||
| 1259 | - importAttributes); | ||
| 1260 | - }, | ||
| 1261 | - }); | ||
| 1260 | + const wrapped = Module.wrap(content); | ||
| 1261 | + const script = makeContextifyScript( | ||
| 1262 | + wrapped, // code | ||
| 1263 | + filename, // filename | ||
| 1264 | + 0, // lineOffset | ||
| 1265 | + 0, // columnOffset | ||
| 1266 | + undefined, // cachedData | ||
| 1267 | + false, // produceCachedData | ||
| 1268 | + undefined, // parsingContext | ||
| 1269 | + hostDefinedOptionId, // hostDefinedOptionId | ||
| 1270 | + importModuleDynamically, // importModuleDynamically | ||
| 1271 | + ); | ||
| 1262 | 1272 | ||
| 1263 | 1273 | // Cache the source map for the module if present. | |
| 1264 | 1274 | if (script.sourceMapURL) { | |
| 1265 | 1275 | maybeCacheSourceMap(filename, content, this, false, undefined, script.sourceMapURL); | |
| 1266 | 1276 | } | |
| 1267 | 1277 | ||
| 1268 | - return script.runInThisContext({ | ||
| 1269 | - displayErrors: true, | ||
| 1270 | - }); | ||
| 1278 | + return runScriptInThisContext(script, true, false); | ||
| 1271 | 1279 | } | |
| 1272 | 1280 | ||
| 1281 | + const params = [ 'exports', 'require', 'module', '__filename', '__dirname' ]; | ||
| 1273 | 1282 | try { | |
| 1274 | - const result = internalCompileFunction(content, [ | ||
| 1275 | - 'exports', | ||
| 1276 | - 'require', | ||
| 1277 | - 'module', | ||
| 1278 | - '__filename', | ||
| 1279 | - '__dirname', | ||
| 1280 | - ], { | ||
| 1281 | - filename, | ||
| 1282 | - importModuleDynamically(specifier, _, importAttributes) { | ||
| 1283 | - const cascadedLoader = getCascadedLoader(); | ||
| 1284 | - return cascadedLoader.import(specifier, normalizeReferrerURL(filename), | ||
| 1285 | - importAttributes); | ||
| 1286 | - }, | ||
| 1287 | - }); | ||
| 1283 | + const result = internalCompileFunction( | ||
| 1284 | + content, // code, | ||
| 1285 | + filename, // filename | ||
| 1286 | + 0, // lineOffset | ||
| 1287 | + 0, // columnOffset, | ||
| 1288 | + undefined, // cachedData | ||
| 1289 | + false, // produceCachedData | ||
| 1290 | + undefined, // parsingContext | ||
| 1291 | + undefined, // contextExtensions | ||
| 1292 | + params, // params | ||
| 1293 | + hostDefinedOptionId, // hostDefinedOptionId | ||
| 1294 | + importModuleDynamically, // importModuleDynamically | ||
| 1295 | + ); | ||
| 1288 | 1296 | ||
| 1289 | 1297 | // Cache the source map for the module if present. | |
| 1290 | 1298 | if (result.sourceMapURL) { | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,6 +1,7 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | + Symbol, | ||
| 4 | 5 | RegExpPrototypeExec, | |
| 5 | 6 | globalThis, | |
| 6 | 7 | } = primordials; | |
@@ -24,7 +25,9 @@ const { | |||
| 24 | 25 | emitAfter, | |
| 25 | 26 | popAsyncContext, | |
| 26 | 27 | } = require('internal/async_hooks'); | |
| 27 | - | ||
| 28 | + const { | ||
| 29 | + makeContextifyScript, runScriptInThisContext, | ||
| 30 | + } = require('internal/vm'); | ||
| 28 | 31 | // shouldAbortOnUncaughtToggle is a typed array for faster | |
| 29 | 32 | // communication with JS. | |
| 30 | 33 | const { shouldAbortOnUncaughtToggle } = internalBinding('util'); | |
@@ -52,8 +55,7 @@ function evalModule(source, print) { | |||
| 52 | 55 | ||
| 53 | 56 | function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { | |
| 54 | 57 | const CJSModule = require('internal/modules/cjs/loader').Module; | |
| 55 | - const { kVmBreakFirstLineSymbol } = require('internal/util'); | ||
| 56 | - const { pathToFileURL } = require('url'); | ||
| 58 | + const { pathToFileURL } = require('internal/url'); | ||
| 57 | 59 | ||
| 58 | 60 | const cwd = tryGetCwd(); | |
| 59 | 61 | const origModule = globalThis.module; // Set e.g. when called from the REPL. | |
@@ -78,16 +80,25 @@ function evalScript(name, body, breakFirstLine, print, shouldLoadESM = false) { | |||
| 78 | 80 | `; | |
| 79 | 81 | globalThis.__filename = name; | |
| 80 | 82 | RegExpPrototypeExec(/^/, ''); // Necessary to reset RegExp statics before user code runs. | |
| 81 | - const result = module._compile(script, `${name}-wrapper`)(() => | ||
| 82 | - require('vm').runInThisContext(body, { | ||
| 83 | - filename: name, | ||
| 84 | - displayErrors: true, | ||
| 85 | - [kVmBreakFirstLineSymbol]: !!breakFirstLine, | ||
| 86 | - importModuleDynamically(specifier, _, importAttributes) { | ||
| 87 | - const loader = asyncESM.esmLoader; | ||
| 88 | - return loader.import(specifier, baseUrl, importAttributes); | ||
| 89 | - }, | ||
| 90 | - })); | ||
| 83 | + const result = module._compile(script, `${name}-wrapper`)(() => { | ||
| 84 | + const hostDefinedOptionId = Symbol(name); | ||
| 85 | + async function importModuleDynamically(specifier, _, importAttributes) { | ||
| 86 | + const loader = asyncESM.esmLoader; | ||
| 87 | + return loader.import(specifier, baseUrl, importAttributes); | ||
| 88 | + } | ||
| 89 | + const script = makeContextifyScript( | ||
| 90 | + body, // code | ||
| 91 | + name, // filename, | ||
| 92 | + 0, // lineOffset | ||
| 93 | + 0, // columnOffset, | ||
| 94 | + undefined, // cachedData | ||
| 95 | + false, // produceCachedData | ||
| 96 | + undefined, // parsingContext | ||
| 97 | + hostDefinedOptionId, // hostDefinedOptionId | ||
| 98 | + importModuleDynamically, // importModuleDynamically | ||
| 99 | + ); | ||
| 100 | + return runScriptInThisContext(script, true, !!breakFirstLine); | ||
| 101 | + }); | ||
| 91 | 102 | if (print) { | |
| 92 | 103 | const { log } = require('internal/console/global'); | |
| 93 | 104 | log(result); | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1,30 +1,25 @@ | |||
| 1 | 1 | 'use strict'; | |
| 2 | 2 | ||
| 3 | 3 | const { | |
| 4 | - ArrayPrototypeForEach, | ||
| 4 | + ReflectApply, | ||
| 5 | 5 | Symbol, | |
| 6 | 6 | } = primordials; | |
| 7 | 7 | ||
| 8 | 8 | const { | |
| 9 | + ContextifyScript, | ||
| 9 | 10 | compileFunction, | |
| 10 | 11 | isContext: _isContext, | |
| 11 | 12 | } = internalBinding('contextify'); | |
| 13 | + const { | ||
| 14 | + runInContext, | ||
| 15 | + } = ContextifyScript.prototype; | ||
| 12 | 16 | const { | |
| 13 | 17 | default_host_defined_options, | |
| 14 | 18 | } = internalBinding('symbols'); | |
| 15 | 19 | const { | |
| 16 | - validateArray, | ||
| 17 | - validateBoolean, | ||
| 18 | - validateBuffer, | ||
| 19 | 20 | validateFunction, | |
| 20 | 21 | validateObject, | |
| 21 | - validateString, | ||
| 22 | - validateStringArray, | ||
| 23 | - validateInt32, | ||
| 24 | 22 | } = require('internal/validators'); | |
| 25 | - const { | ||
| 26 | - ERR_INVALID_ARG_TYPE, | ||
| 27 | - } = require('internal/errors').codes; | ||
| 28 | 23 | ||
| 29 | 24 | function isContext(object) { | |
| 30 | 25 | validateObject(object, 'object', { __proto__: null, allowArray: true }); | |
@@ -48,49 +43,20 @@ function getHostDefinedOptionId(importModuleDynamically, filename) { | |||
| 48 | 43 | return Symbol(filename); | |
| 49 | 44 | } | |
| 50 | 45 | ||
| 51 | - function internalCompileFunction(code, params, options) { | ||
| 52 | - validateString(code, 'code'); | ||
| 53 | - if (params !== undefined) { | ||
| 54 | - validateStringArray(params, 'params'); | ||
| 55 | - } | ||
| 56 | - const { | ||
| 57 | - filename = '', | ||
| 58 | - columnOffset = 0, | ||
| 59 | - lineOffset = 0, | ||
| 60 | - cachedData = undefined, | ||
| 61 | - produceCachedData = false, | ||
| 62 | - parsingContext = undefined, | ||
| 63 | - contextExtensions = [], | ||
| 64 | - importModuleDynamically, | ||
| 65 | - } = options; | ||
| 66 | - | ||
| 67 | - validateString(filename, 'options.filename'); | ||
| 68 | - validateInt32(columnOffset, 'options.columnOffset'); | ||
| 69 | - validateInt32(lineOffset, 'options.lineOffset'); | ||
| 70 | - if (cachedData !== undefined) | ||
| 71 | - validateBuffer(cachedData, 'options.cachedData'); | ||
| 72 | - validateBoolean(produceCachedData, 'options.produceCachedData'); | ||
| 73 | - if (parsingContext !== undefined) { | ||
| 74 | - if ( | ||
| 75 | - typeof parsingContext !== 'object' || | ||
| 76 | - parsingContext === null || | ||
| 77 | - !isContext(parsingContext) | ||
| 78 | - ) { | ||
| 79 | - throw new ERR_INVALID_ARG_TYPE( | ||
| 80 | - 'options.parsingContext', | ||
| 81 | - 'Context', | ||
| 82 | - parsingContext, | ||
| 83 | - ); | ||
| 84 | - } | ||
| 85 | - } | ||
| 86 | - validateArray(contextExtensions, 'options.contextExtensions'); | ||
| 87 | - ArrayPrototypeForEach(contextExtensions, (extension, i) => { | ||
| 88 | - const name = `options.contextExtensions[${i}]`; | ||
| 89 | - validateObject(extension, name, { __proto__: null, nullable: true }); | ||
| 46 | + function registerImportModuleDynamically(referrer, importModuleDynamically) { | ||
| 47 | + const { importModuleDynamicallyWrap } = require('internal/vm/module'); | ||
| 48 | + const { registerModule } = require('internal/modules/esm/utils'); | ||
| 49 | + registerModule(referrer, { | ||
| 50 | + __proto__: null, | ||
| 51 | + importModuleDynamically: | ||
| 52 | + importModuleDynamicallyWrap(importModuleDynamically), | ||
| 90 | 53 | }); | |
| 54 | + } | ||
| 91 | 55 | ||
| 92 | - const hostDefinedOptionId = | ||
| 93 | - getHostDefinedOptionId(importModuleDynamically, filename); | ||
| 56 | + function internalCompileFunction( | ||
| 57 | + code, filename, lineOffset, columnOffset, | ||
| 58 | + cachedData, produceCachedData, parsingContext, contextExtensions, | ||
| 59 | + params, hostDefinedOptionId, importModuleDynamically) { | ||
| 94 | 60 | const result = compileFunction( | |
| 95 | 61 | code, | |
| 96 | 62 | filename, | |
@@ -117,23 +83,65 @@ function internalCompileFunction(code, params, options) { | |||
| 117 | 83 | } | |
| 118 | 84 | ||
| 119 | 85 | if (importModuleDynamically !== undefined) { | |
| 120 | - validateFunction(importModuleDynamically, | ||
| 121 | - 'options.importModuleDynamically'); | ||
| 122 | - const { importModuleDynamicallyWrap } = require('internal/vm/module'); | ||
| 123 | - const wrapped = importModuleDynamicallyWrap(importModuleDynamically); | ||
| 124 | - const func = result.function; | ||
| 125 | - const { registerModule } = require('internal/modules/esm/utils'); | ||
| 126 | - registerModule(func, { | ||
| 127 | - __proto__: null, | ||
| 128 | - importModuleDynamically: wrapped, | ||
| 129 | - }); | ||
| 86 | + registerImportModuleDynamically(result.function, importModuleDynamically); | ||
| 130 | 87 | } | |
| 131 | 88 | ||
| 132 | 89 | return result; | |
| 133 | 90 | } | |
| 134 | 91 | ||
| 92 | + function makeContextifyScript(code, | ||
| 93 | + filename, | ||
| 94 | + lineOffset, | ||
| 95 | + columnOffset, | ||
| 96 | + cachedData, | ||
| 97 | + produceCachedData, | ||
| 98 | + parsingContext, | ||
| 99 | + hostDefinedOptionId, | ||
| 100 | + importModuleDynamically) { | ||
| 101 | + let script; | ||
| 102 | + // Calling `ReThrow()` on a native TryCatch does not generate a new | ||
| 103 | + // abort-on-uncaught-exception check. A dummy try/catch in JS land | ||
| 104 | + // protects against that. | ||
| 105 | + try { // eslint-disable-line no-useless-catch | ||
| 106 | + script = new ContextifyScript(code, | ||
| 107 | + filename, | ||
| 108 | + lineOffset, | ||
| 109 | + columnOffset, | ||
| 110 | + cachedData, | ||
| 111 | + produceCachedData, | ||
| 112 | + parsingContext, | ||
| 113 | + hostDefinedOptionId); | ||
| 114 | + } catch (e) { | ||
| 115 | + throw e; /* node-do-not-add-exception-line */ | ||
| 116 | + } | ||
| 117 | + | ||
| 118 | + if (importModuleDynamically !== undefined) { | ||
| 119 | + registerImportModuleDynamically(script, importModuleDynamically); | ||
| 120 | + } | ||
| 121 | + return script; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + // Internal version of vm.Script.prototype.runInThisContext() which skips | ||
| 125 | + // argument validation. | ||
| 126 | + function runScriptInThisContext(script, displayErrors, breakOnFirstLine) { | ||
| 127 | + return ReflectApply( | ||
| 128 | + runInContext, | ||
| 129 | + script, | ||
| 130 | + [ | ||
| 131 | + null, // sandbox - use current context | ||
| 132 | + -1, // timeout | ||
| 133 | + displayErrors, // displayErrors | ||
| 134 | + false, // breakOnSigint | ||
| 135 | + breakOnFirstLine, // breakOnFirstLine | ||
| 136 | + ], | ||
| 137 | + ); | ||
| 138 | + } | ||
| 139 | + | ||
| 135 | 140 | module.exports = { | |
| 136 | 141 | getHostDefinedOptionId, | |
| 137 | 142 | internalCompileFunction, | |
| 138 | 143 | isContext, | |
| 144 | + makeContextifyScript, | ||
| 145 | + registerImportModuleDynamically, | ||
| 146 | + runScriptInThisContext, | ||
| 139 | 147 | }; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments