Files
scriptc/tests/corpus/function-integrity.js
T
Chris Tate 858328703b Name typed functions' property tables and keep runtime freezes data-only
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.
2026-10-21 10:34:21 -05:00

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);