From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: John Kleinschmidt Date: Thu, 18 Feb 2021 17:35:39 -0500 Subject: build: add .mjs support to js2c V8 now uses .mjs files, so this updates js2c to handle those files. diff --git a/lib/internal/v8_prof_polyfill.js b/lib/internal/v8_prof_polyfill.js index 5f5922c5386543189d6ae9293108425cf212b054..605c7274c1fff1a2f1bd0b6c4f667f86145036bd 100644 --- a/lib/internal/v8_prof_polyfill.js +++ b/lib/internal/v8_prof_polyfill.js @@ -69,7 +69,7 @@ function read(fileName) { const quit = process.exit; // Polyfill "readline()". -const logFile = arguments[arguments.length - 1]; +const logFile = globalThis.arguments[globalThis.arguments.length - 1]; try { fs.accessSync(logFile); } catch(e) { @@ -159,3 +159,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 daae650b2ad8ef146eb3a55c95dc80e0dbc2e3d7..7d6c7dce30058a73427dc7705f3dd98c4a6f4319 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(); +})(); \ No newline at end of file diff --git a/tools/js2c.py b/tools/js2c.py index bca4c44a31d1ffe7c9ae15b6f60cd55e325f707d..7acb27e753e31429fbb5de30c62dd30a3be3b5bc 100755 --- a/tools/js2c.py +++ b/tools/js2c.py @@ -151,20 +151,21 @@ def JS2C(source_files, target, only_js): # Build source code lines definitions = [] initializers = [] - - for filename in source_files['.js']: - AddModule(filename, definitions, initializers) - - # Electron: Expose fs module without asar support. - if filename == 'lib/fs.js': - # Node's 'fs' and 'internal/fs/ have lazy-loaded circular - # dependencies. So to expose the unmodified Node 'fs' functionality here, - # we have to copy both 'fs' *and* 'internal/fs/' files and modify the - # copies to depend on each other instead of on our asarified 'fs' code. - AddModule('lib/original-fs.js', definitions, initializers, lambda _: ReadFile(filename).replace("require('internal/fs/", "require('internal/original-fs/")) - elif filename.startswith('lib/internal/fs/'): - original_fs_filename = filename.replace('internal/fs/', 'internal/original-fs/') - AddModule(original_fs_filename, definitions, initializers, lambda _: ReadFile(filename).replace("require('fs')", "require('original-fs')")) + for extension in source_files.keys(): + for filename in source_files[extension]: + if extension == '.js' or extension == '.mjs': + AddModule(filename, definitions, initializers) + + # Electron: Expose fs module without asar support. + if filename == 'lib/fs.js': + # Node's 'fs' and 'internal/fs/ have lazy-loaded circular + # dependencies. So to expose the unmodified Node 'fs' functionality here, + # we have to copy both 'fs' *and* 'internal/fs/' files and modify the + # copies to depend on each other instead of on our asarified 'fs' code. + AddModule('lib/original-fs.js', definitions, initializers, lambda _: ReadFile(filename).replace("require('internal/fs/", "require('internal/original-fs/")) + elif filename.startswith('lib/internal/fs/'): + original_fs_filename = filename.replace('internal/fs/', 'internal/original-fs/') + AddModule(original_fs_filename, definitions, initializers, lambda _: ReadFile(filename).replace("require('fs')", "require('original-fs')")) config_size = 0 if not only_js: @@ -240,7 +241,7 @@ def main(): if options.only_js: assert len(source_files) == 1 else: - assert len(source_files) == 2 + assert len(source_files) == 3 # Currently config.gypi is the only `.gypi` file allowed assert source_files['.gypi'][0].endswith('config.gypi') source_files['config.gypi'] = source_files.pop('.gypi')[0]