From 8d78d9ef27d4f949d32841d8b515cadc2dfc3ea8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sat, 30 Jan 2021 23:19:13 +0100 Subject: [PATCH] lib: load v8_prof_processor dependencies as ESM The script versions are no longer available. PR-URL: https://github.com/nodejs/node/pull/37587 Reviewed-By: Jiawen Geng Reviewed-By: Colin Ihrig Reviewed-By: Myles Borins --- lib/internal/v8_prof_polyfill.js | 19 +++++--- lib/internal/v8_prof_processor.js | 76 +++++++++++++++++-------------- node.gyp | 22 ++++----- tools/js2c.py | 6 ++- 4 files changed, 70 insertions(+), 53 deletions(-) diff --git a/lib/internal/v8_prof_polyfill.js b/lib/internal/v8_prof_polyfill.js index ae98a03ab206d8..c4140bab54168c 100644 --- a/lib/internal/v8_prof_polyfill.js +++ b/lib/internal/v8_prof_polyfill.js @@ -40,7 +40,7 @@ if (module.id === 'internal/v8_prof_polyfill') return; // Node polyfill const fs = require('fs'); const cp = require('child_process'); -const os = { // eslint-disable-line no-unused-vars +const os = { system: function(name, args) { if (process.platform === 'linux' && name === 'nm') { // Filter out vdso and vsyscall entries. @@ -66,14 +66,13 @@ const os = { // eslint-disable-line no-unused-vars return out; } }; -const print = console.log; // eslint-disable-line no-unused-vars -function read(fileName) { // eslint-disable-line no-unused-vars +const print = console.log; +function read(fileName) { return fs.readFileSync(fileName, 'utf8'); } -const quit = process.exit; // eslint-disable-line no-unused-vars - +const quit = process.exit; // Polyfill "readline()". -const logFile = arguments[arguments.length - 1]; // eslint-disable-line no-undef +const logFile = globalThis.arguments[globalThis.arguments.length - 1]; try { fs.accessSync(logFile); } catch { @@ -161,3 +160,11 @@ function macCppfiltNm(out) { return prefix + (filtered[i++] || postfix); }); } + +Object.assign(globalThis, { + os, + print, + read, + quit, + readline, +}); diff --git a/lib/internal/v8_prof_processor.js b/lib/internal/v8_prof_processor.js index 0136bc7ba48623..ddfafca64c45f0 100644 --- a/lib/internal/v8_prof_processor.js +++ b/lib/internal/v8_prof_processor.js @@ -3,43 +3,51 @@ const { ArrayPrototypePush, ArrayPrototypeSlice, - JSONStringify, + StringPrototypeSlice, } = primordials; +const Buffer = require('buffer').Buffer; +const console = require('internal/console/global'); const vm = require('vm'); +const { SourceTextModule } = require('internal/vm/module'); -const scriptFiles = [ - 'internal/v8_prof_polyfill', - 'internal/deps/v8/tools/splaytree', - 'internal/deps/v8/tools/codemap', - 'internal/deps/v8/tools/csvparser', - 'internal/deps/v8/tools/consarray', - 'internal/deps/v8/tools/profile', - 'internal/deps/v8/tools/profile_view', - 'internal/deps/v8/tools/logreader', - 'internal/deps/v8/tools/arguments', - 'internal/deps/v8/tools/tickprocessor', - 'internal/deps/v8/tools/SourceMap', - 'internal/deps/v8/tools/tickprocessor-driver', -]; -let script = ''; - -for (const s of scriptFiles) { - script += internalBinding('natives')[s] + '\n'; -} +const natives = internalBinding('natives'); -const tickArguments = []; -if (process.platform === 'darwin') { - ArrayPrototypePush(tickArguments, '--mac'); -} else if (process.platform === 'win32') { - ArrayPrototypePush(tickArguments, '--windows'); +async function linker(specifier, referencingModule) { + // Transform "./file.mjs" to "file" + const file = StringPrototypeSlice(specifier, 2, -4); + const code = natives[`internal/deps/v8/tools/${file}`]; + return new SourceTextModule(code, { context: referencingModule.context }); } -ArrayPrototypePush(tickArguments, - ...ArrayPrototypeSlice(process.argv, 1)); -script = `(function(module, require) { - arguments = ${JSONStringify(tickArguments)}; - function write (s) { process.stdout.write(s) } - function printErr(err) { console.error(err); } - ${script} -})`; -vm.runInThisContext(script)(module, require); + +(async () => { + const tickArguments = []; + if (process.platform === 'darwin') { + ArrayPrototypePush(tickArguments, '--mac'); + } else if (process.platform === 'win32') { + ArrayPrototypePush(tickArguments, '--windows'); + } + ArrayPrototypePush(tickArguments, + ...ArrayPrototypeSlice(process.argv, 1)); + + const context = vm.createContext({ + arguments: tickArguments, + write(s) { process.stdout.write(s); }, + printErr(err) { console.error(err); }, + console, + process, + Buffer, + }); + + const polyfill = natives['internal/v8_prof_polyfill']; + const script = `(function(module, require) { + ${polyfill} + })`; + + vm.runInContext(script, context)(module, require); + + const tickProcessor = natives['internal/deps/v8/tools/tickprocessor-driver']; + const tickprocessorDriver = new SourceTextModule(tickProcessor, { context }); + await tickprocessorDriver.link(linker); + await tickprocessorDriver.evaluate(); +})(); diff --git a/node.gyp b/node.gyp index 63c8c50987b20e..bbb9c6d6cdaebf 100644 --- a/node.gyp +++ b/node.gyp @@ -264,17 +264,17 @@ 'lib/internal/streams/pipeline.js', 'lib/internal/streams/end-of-stream.js', 'lib/internal/streams/utils.js', - 'deps/v8/tools/splaytree.js', - 'deps/v8/tools/codemap.js', - 'deps/v8/tools/consarray.js', - 'deps/v8/tools/csvparser.js', - 'deps/v8/tools/profile.js', - 'deps/v8/tools/profile_view.js', - 'deps/v8/tools/logreader.js', - 'deps/v8/tools/arguments.js', - 'deps/v8/tools/tickprocessor.js', - 'deps/v8/tools/SourceMap.js', - 'deps/v8/tools/tickprocessor-driver.js', + 'deps/v8/tools/splaytree.mjs', + 'deps/v8/tools/codemap.mjs', + 'deps/v8/tools/consarray.mjs', + 'deps/v8/tools/csvparser.mjs', + 'deps/v8/tools/profile.mjs', + 'deps/v8/tools/profile_view.mjs', + 'deps/v8/tools/logreader.mjs', + 'deps/v8/tools/arguments.mjs', + 'deps/v8/tools/tickprocessor.mjs', + 'deps/v8/tools/sourcemap.mjs', + 'deps/v8/tools/tickprocessor-driver.mjs', 'deps/node-inspect/lib/_inspect.js', 'deps/node-inspect/lib/internal/inspect_client.js', 'deps/node-inspect/lib/internal/inspect_repl.js', diff --git a/tools/js2c.py b/tools/js2c.py index dd3ff9d5ca9f98..d40f28ce2bff2b 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -140,6 +140,8 @@ def JS2C(source_files, target): for filename in source_files['.js']: AddModule(filename, definitions, initializers) + for filename in source_files['.mjs']: + AddModule(filename, definitions, initializers) config_def, config_size = handle_config_gypi(source_files['config.gypi']) definitions.append(config_def) @@ -208,8 +210,8 @@ def main(): global is_verbose is_verbose = options.verbose source_files = functools.reduce(SourceFileByExt, options.sources, {}) - # Should have exactly 2 types: `.js`, and `.gypi` - assert len(source_files) == 2 + # Should have exactly 3 types: `.js`, `.mjs` and `.gypi` + assert len(source_files) == 3 # Currently config.gypi is the only `.gypi` file allowed assert source_files['.gypi'] == ['config.gypi'] source_files['config.gypi'] = source_files.pop('.gypi')[0]