mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-11-02 07:43:42 +08:00
A checked object (SCR_DYN_OBJ) now starts in layout mode: v.obj.layout names its key sequence, a node of the thread's interned transition tree, and v.obj.slots holds one 8-byte value per key, where every property used to take a 48-byte entry. All properties of a layout-mode object are writable, enumerable, configurable data properties. An accessor, a non-default attribute, a delete, more than 64 keys, spent layout budgets, publication to other threads, or any code that reads entries directly moves the object to dictionary mode (today's entries) for good, so unported paths stay correct. Layouts replace the dynamic tier's lazily computed hidden classes (ScrJsShape) and keep their budgets. Inline caches key on the layout pointer and read the slot directly; JSON.parse builds objects along layouts; stringify, key enumeration, release, trace and the runtime read cache read slots in place. The emitted index-signature checks read members through runtime accessors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
25 lines
1018 B
TypeScript
25 lines
1018 B
TypeScript
import { readdirSync, readFileSync } from "node:fs";
|
|
import { join } from "node:path";
|
|
import { expect, test } from "vitest";
|
|
|
|
const src = join(import.meta.dirname, "..", "src");
|
|
|
|
/* Ordinary objects keep their properties behind the object core: units
|
|
* outside it read and adjust them through the scr_dyn.h own-property
|
|
* accessors (scr_dyn_obj_count, scr_dyn_obj_prop_at, ...), so the core can
|
|
* change how it stores them. */
|
|
const CORE = new Set(["scr_json.c", "scr_js_object.c", "scr_dyn.h"]);
|
|
|
|
test("only the object core reads ordinary objects' storage", () => {
|
|
const offenders: string[] = [];
|
|
for (const name of readdirSync(src)) {
|
|
if (!/\.(c|h)$/.test(name) || name.endsWith(".test.c") || CORE.has(name)) continue;
|
|
const lines = readFileSync(join(src, name), "utf8").split("\n");
|
|
lines.forEach((line, i) => {
|
|
if (/\bv\.obj\.(entries|slots|layout|len|cap|index)\b/.test(line))
|
|
offenders.push(`${name}:${i + 1}: ${line.trim()}`);
|
|
});
|
|
}
|
|
expect(offenders).toEqual([]);
|
|
});
|