Found while fixing #10661 (PR #10675) and explicitly scoped out of it. Pre-existing, unrelated to that fix.
.name on a function or class produced by Perry's new Function interpreter only resolves correctly when the
source string is a compile-time-visible literal. When the source is built by runtime string concatenation, .name
comes back "" — for both named function expressions and named classes.
// literal source: .name works
const A = new Function("return function named() {}")();
console.log(A.name); // "named"
// concatenated source: .name is ""
const parts = ["return function ", "named", "() {}"];
const B = new Function(parts.join(""))();
console.log(B.name); // "" (Node: "named")
Runtime concatenation is the realistic case, not the exotic one. generate-function — used by mysql2 and
well beyond it — builds its source exactly this way (Array.prototype.join). The literal form is what hand-written
tests use, which is presumably why this has gone unnoticed.
mysql2 does not depend on .name, so this blocked nothing there. But anything doing name-based registration,
debugging output, or dispatch on dynamically generated functions would see it.
Likely mechanism worth checking first: the name is probably being recovered from the compile-time AST of the
source literal rather than from the interpreted function object itself, so a non-literal source has no AST to
recover it from.
Context: this came out of work toward deleting Perry's hand-written Rust reimplementations of npm packages in
favour of compiling the real ones.
Found while fixing #10661 (PR #10675) and explicitly scoped out of it. Pre-existing, unrelated to that fix.
.nameon a function or class produced by Perry'snew Functioninterpreter only resolves correctly when thesource string is a compile-time-visible literal. When the source is built by runtime string concatenation,
.namecomes back
""— for both named function expressions and named classes.Runtime concatenation is the realistic case, not the exotic one.
generate-function— used by mysql2 andwell beyond it — builds its source exactly this way (
Array.prototype.join). The literal form is what hand-writtentests use, which is presumably why this has gone unnoticed.
mysql2 does not depend on
.name, so this blocked nothing there. But anything doing name-based registration,debugging output, or dispatch on dynamically generated functions would see it.
Likely mechanism worth checking first: the name is probably being recovered from the compile-time AST of the
source literal rather than from the interpreted function object itself, so a non-literal source has no AST to
recover it from.
Context: this came out of work toward deleting Perry's hand-written Rust reimplementations of npm packages in
favour of compiling the real ones.