mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
chalk's callable builder (a function whose prototype chain is set with
Object.setPrototypeOf, with style getters from Object.defineProperties)
already ran on the checked-dynamic model. What failed was the code
around it. Each fix is general and sits on a path that used to end in a
refusal or a runtime fence, or is confined to JavaScript files:
- package.json "imports" inside a --npm-static package resolve to the
shipped JS with the "node" condition hoisted, like the tsgo fs shadow;
- JavaScript object literals that the file reshapes at run time (keyed
writes with runtime keys, delete, Object.defineProperty/ies) map to
the checked-dynamic type, with the literals nested in them;
- a JavaScript class whose only member is a constructor that returns a
value and never reads `this` answers that value from `new` (the return
used to be discarded silently);
- `const { env } = process` binds the data member in JavaScript;
- `o && x` / `o || x` with an always-truthy object, array or function
left operand;
- Number.parseInt/parseFloat over checked-dynamic values apply ToString;
- Function.prototype as a value is one compiler-emitted function;
- calls of String.prototype-only names (bold, italics, ...) on untyped
receivers call the receiver's own or inherited member; a string
receiver throws the refusal at run time.
Programs without these patterns compile to identical bytes: the runtime
benchmark workloads, the self-hosted compiler (LLVM and executable) and
the TypeScript corpus IR were compared against the baseline.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
23 lines
678 B
JavaScript
23 lines
678 B
JavaScript
// Prototype getters named like String.prototype's HTML methods (bold,
|
|
// italics, link, big): each read builds a callable that wraps its input.
|
|
const wrap = (tag) => ({
|
|
get() {
|
|
const parent = this;
|
|
const builder = (text) => builder.prefix(text);
|
|
builder.prefix = (text) => parent.prefix(`<${tag}>` + text + `</${tag}>`);
|
|
Object.setPrototypeOf(builder, proto);
|
|
return builder;
|
|
},
|
|
});
|
|
const proto = Object.defineProperties(() => {}, {
|
|
bold: wrap("b"),
|
|
italics: wrap("i"),
|
|
link: wrap("a"),
|
|
big: wrap("big"),
|
|
red: wrap("red"),
|
|
});
|
|
const root = (text) => text;
|
|
root.prefix = (text) => text;
|
|
Object.setPrototypeOf(root, proto);
|
|
export default root;
|