BBS: TELESC.NET.BR Assunto: get_all_msg_headers(): cold *_NULL fields read undefined via dot-acces De: Rob Swindell Data: Thu, 21 May 2026 14:38:28 -0700 ----------------------------------------------------------- https://gitlab.synchro.net/main/sbbs/-/issues/1143#note_8987 **SpiderMonkey 1.8.5 per-shape property-cache implementation references** All paths relative to the vendored tree `3rdp/src/mozjs/js-1.8.5/js/src/`. Canonical doc (cited in the header itself, `jspropertycache.h:51-53`): MDN *SpiderMonkey/Internals/Property cache* `https://developer.mozilla.org/en/SpiderMonkey/Internals/Property_cache` (now in archived Mozilla wiki content). **Data structures `jspropertycache.h`** - `class PropertyCache` `:160`; fixed-size direct-mapped table, `SIZE_LOG2 = 12` 4096 entries (`:164-169`). - `struct PropertyCacheEntry` `:121`; key = `kpc` (testing bytecode pc, `:123`) + `kshape` (shape of the key object, `:124`); value = `vcap`/`vword`. - hash over **(pc, kshape)** `hash()` `:215` (`((pc>>SIZE_LOG2 ^ pc) + kshape) & MASK`). - entry kinds: `adding()` `:128` (kshapevshape, predicted shape transition) vs `directHit()` `:129` (kshape==vshape). - `PCVal` tagged union (slot / shape / fun-obj) `:81`. **Hit/lookup path `jspropertycacheinlines.h`**, `PropertyCache::test()` `:73` - `kshape = obj->shape()` `:78`; `entry = table[hash(pc, kshape)]` `:79`. - validated by `entry->kpc == pc && entry->kshape == kshape` `:84`, then `matchShape(cx, pobj, entry->vshape())` `:92`. - **On a validated hit it returns the cached PCVal and never calls the resolve hook** the entry is keyed purely on `(pc, shape)`, and all bulk header objects share one shape lineage. This is the crux. **Fill `jspropertycache.cpp`**, `PropertyCache::fill()` `:51` - where entries are created (the predicted-transition / `adding` bookkeeping), with bail-outs `:62-128` (cache disabled, `!nativeContains`, dictionary-mode `:84`, non-native protos, overdeep chains). **GETPROP wiring `jsobj.cpp`** - found-path fill: `JS_PROPERTY_CACHE(cx).fill(cx, aobj, 0, protoIndex, obj2, shape)` `:5438` (under `JSGET_CACHE_RESULT`). - miss path that explicitly does **not** fill (`nofills++`) `:5366`. **Shapes `jsscope.cpp`**: `js_GenerateShape()` `:74` / `:99`; `Shape` in `jsscope.h`. The empirically-anchored part is just the first half: `test()` keys on `(pc, obj->shape())` and a validated hit bypasses resolve. The exact entry-transition bookkeeping that lets a same-shape header get mis-served `undefined` lives in the interplay of `fill()` (`:51`) and the `adding()`/`directHit()` validation in `test()` that's the spot to confirm the precise misprediction. n --- mSynchronetn hgVertrauen n hHome of Synchronet n gh[vert/cvs/bbs].synchro.net ----------------------------------------------------------- [Voltar]