mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-26 06:34:20 +08:00
A refused statement in a JavaScript function body was dropped without a diagnostic or runtime fence when the body lowered inside a capture buffer whose owner kept the result. tryLowerExpression lowers the receiver of `(function () { ... }).call(this)` or `.apply(...)` and a computed class base that way: the refused statement (for example `console.log(root === module.exports)`) was missing from the kept function, its diagnostic was handed back to the enclosing statement, and that statement, having lowered cleanly, filed it as an informational runtime-fence entry. The program printed nothing for that statement.
lowerStmts now emits the statement's runtime fence inside a buffer as well (Lowerer.capturedRuntimeFence, the same message deferToRuntimeFence would give), leaving the diagnostics with the buffer's owner. The three JavaScript class initializer sites that skipped their fence under a buffer (static field, instance field, static initializer block) do the same. An owner that discards the candidate discards the fence with it, so every program that compiled before keeps byte-identical IR unless it contained such a dropped statement: all 3006 corpus programs produce the same IR as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
15 lines
458 B
TypeScript
15 lines
458 B
TypeScript
// Function expressions lowered speculatively — an `.apply` receiver and a
|
|
// computed class base — report a refused statement in their body like any
|
|
// other function: the statement never disappears from the build.
|
|
(function () {
|
|
console.log("wrapper");
|
|
console.log(eval("1 + 1"));
|
|
}).apply(null, []);
|
|
|
|
class Base {}
|
|
class Derived extends (function () {
|
|
console.log(new Function("return 1")());
|
|
return Base;
|
|
})() {}
|
|
console.log(typeof Derived);
|