mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-27 06:43:19 +08:00
The first Object.freeze, Object.seal or Object.preventExtensions of a typed function creates its property table from the function's dynamic box. The box had no name, so later `f.name` reads answered "". The box now carries the function's JS name, as a closure flowing into any checked-dynamic slot does. The runtime's own callers (published values, os and node constants, the private-range block list, Wasm exports) freeze data they built, and now call scr_dyn_freeze_data, the freeze for values that are not functions. Object.isFrozen, Object.isSealed and Object.isExtensible read a function's existing table and answer false, false and true when it has none. Fully typed programs therefore link no dynamic-tier object code for these calls again.
46 lines
1.5 KiB
JavaScript
46 lines
1.5 KiB
JavaScript
// Object.freeze, seal and preventExtensions on functions, and the queries:
|
|
// they act on the function's own properties (name, length, prototype, and
|
|
// the ones a program assigns), as in Node. A frozen function still calls,
|
|
// and its properties still read.
|
|
const createHasher = (block) => {
|
|
const hash = (msg) => msg.length * block;
|
|
hash.outputLen = 32;
|
|
hash.blockLen = block;
|
|
hash.create = () => hash(" ".repeat(block));
|
|
return Object.freeze(hash);
|
|
};
|
|
const sha = createHasher(64);
|
|
console.log(sha("abc"), sha.outputLen, sha.blockLen, sha.create(), sha.name, sha.length);
|
|
console.log(Object.isFrozen(sha), Object.isSealed(sha), Object.isExtensible(sha));
|
|
try {
|
|
sha.extra = 1;
|
|
} catch (error) {
|
|
console.log(error.name, error.message);
|
|
}
|
|
try {
|
|
sha.outputLen = 64;
|
|
} catch (error) {
|
|
console.log(error.name);
|
|
}
|
|
console.log(sha.outputLen, sha.extra);
|
|
|
|
function plain(a, b) {
|
|
return a + b;
|
|
}
|
|
console.log(Object.isFrozen(plain), Object.isSealed(plain), Object.isExtensible(plain));
|
|
plain.tag = "t";
|
|
Object.seal(plain);
|
|
console.log(Object.isFrozen(plain), Object.isSealed(plain), Object.isExtensible(plain));
|
|
plain.tag = "u";
|
|
console.log(plain.tag, plain(1, 2), plain.name, plain.length);
|
|
|
|
const stopped = () => 0;
|
|
Object.preventExtensions(stopped);
|
|
console.log(Object.isFrozen(stopped), Object.isSealed(stopped), Object.isExtensible(stopped));
|
|
try {
|
|
stopped.late = 1;
|
|
} catch (error) {
|
|
console.log(error.name, error.message);
|
|
}
|
|
console.log(stopped.name, stopped.length);
|