From 78ceeec6bedb521dfd2a44530bee9fea62afb289 Mon Sep 17 00:00:00 2001 From: Luca Casonato Date: Mon, 31 Jul 2023 21:45:32 +0200 Subject: [PATCH] perf: faster node globals access in cjs (#19997) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bartek IwaƄczuk --- .../cjs-local-global-decls/1.0.0/index.js | 1 - ext/node/polyfills/01_require.js | 37 ++++++++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/cli/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js b/cli/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js index c7b90e5b75..5aa546d914 100644 --- a/cli/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js +++ b/cli/tests/testdata/npm/registry/@denotest/cjs-local-global-decls/1.0.0/index.js @@ -1,4 +1,3 @@ // package that has all the locals defined const Buffer = 1, clearImmediate = 1, clearInterval = 1, clearTimeout = 1, console = 1, global = 1, process = 1, setImmediate = 1, setInterval = 1, setTimeout = 1, globalThis = 1; -const exports = 2; require("./other.js"); diff --git a/ext/node/polyfills/01_require.js b/ext/node/polyfills/01_require.js index a21754ca7a..c58dad9a46 100644 --- a/ext/node/polyfills/01_require.js +++ b/ext/node/polyfills/01_require.js @@ -40,6 +40,8 @@ const { Error, TypeError, } = primordials; +import { nodeGlobals } from "ext:deno_node/00_globals.js"; + import _httpAgent from "ext:deno_node/_http_agent.mjs"; import _httpOutgoing from "ext:deno_node/_http_outgoing.ts"; import _streamDuplex from "ext:deno_node/internal/streams/duplex.mjs"; @@ -915,9 +917,15 @@ Module.prototype.require = function (id) { } }; +// The module wrapper looks slightly different to Node. Instead of using one +// wrapper function, we use two. The first one exists to performance optimize +// access to magic node globals, like `Buffer` or `process`. The second one +// is the actual wrapper function we run the users code in. +// The only observable difference is that in Deno `arguments.callee` is not +// null. Module.wrapper = [ - "(function (exports, require, module, __filename, __dirname) { (function () {", - "\n}).call(this); })", + "(function (exports, require, module, __filename, __dirname, Buffer, clearImmediate, clearInterval, clearTimeout, console, global, process, setImmediate, setInterval, setTimeout, performance) { (function (exports, require, module, __filename, __dirname) {", + "\n}).call(this, exports, require, module, __filename, __dirname); })", ]; Module.wrap = function (script) { script = script.replace(/^#!.*?\n/, ""); @@ -982,6 +990,20 @@ Module.prototype._compile = function (content, filename) { ops.op_require_break_on_next_statement(); } + const { + Buffer, + clearImmediate, + clearInterval, + clearTimeout, + console, + global, + process, + setImmediate, + setInterval, + setTimeout, + performance, + } = nodeGlobals; + const result = compiledWrapper.call( thisValue, exports, @@ -989,6 +1011,17 @@ Module.prototype._compile = function (content, filename) { this, filename, dirname, + Buffer, + clearImmediate, + clearInterval, + clearTimeout, + console, + global, + process, + setImmediate, + setInterval, + setTimeout, + performance, ); if (requireDepth === 0) { statCache = null;