Files
scriptc/packages/runtime/test/object-core.test.ts
T
Malte UblandClaude Opus 5.5 dc1e8acc1d Store ordinary objects as a layout plus value slots
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>
2026-10-26 09:18:53 -07:00

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([]);
});