[scripts, ci] (P7): a purity gate for Espryt's re-keyed memo families

P3b/P4b deepening, landing under the P7 program (PLAN-PH-P34B-P7.md 1.2, wave 2-D
package D2): "一条纯度 grep 门:split 构建下这些 memo 键里不得出现前端指针类型;接 CI".

scripts/ci/espryt_memo_purity.py, a sibling of link_seam_purity.py in the same style:
a hard-coded source list, a code_only() comment strip, (pattern, message) rules, and
a --self-test that runs the negative controls and then the real scan in one
invocation - which is what lets test.yml pass only --self-test and still get the
gate. Wired in next to link_seam_purity.py.

It scopes the rules to the BRACES of the families the plan names -
ResolvedTextureBindingMemo, SamplerPassMemo, UnitSamplerLookupMemo, TwinLookupMemo,
StateBackendObjectRegistry (the program registry and its five siblings) - plus the
image sweep, which is seven file statics rather than a struct and is matched by name.
Scoping matters: these two files pass frontend pointers around legitimately in
hundreds of places, and a file-wide grep would be a list of exceptions rather than a
gate.

Guard-awareness is a small conditional walker, not a preprocessor: it recognises
#if MOBILEGL_PIPE_LEGACY_MEMOS, #if !MOBILEGL_BUILD_DISAGGREGATED and the #else of
#if MOBILEGL_BUILD_DISAGGREGATED, which is every spelling these files use, and says
so in the docstring.

Six allow-list entries, each carrying its one-line reason. The two that matter:
StateBackendObjectRegistry's UnorderedMap<StateObject*, Entry> and
ResolvedTextureBindingMemo's type-erased `const void* program` are the PULL build's
only arms - deleting them moves pull .text and fails G1's 0/0/0/0, so they retire
with the pull path (P13), not here. The other four are memo VALUES rather than keys.

Seven negative controls turn red; four positive controls stay green, including a
LEGACY_MEMOS arm, the #else of a DISAGGREGATED arm, the allow-listed type-erased key
and a frontend pointer outside every memo family. Verified once more by injecting a
fresh unguarded ProgramObject* field into the real ResolvedTextureBindingMemo: the
gate reddens and names it.
This commit is contained in:
2026-09-22 17:31:51 -04:00
parent 5617c5c3b3
commit 6567bc1e16
2 changed files with 240 additions and 0 deletions
+10
View File
@@ -3110,6 +3110,16 @@ jobs:
- name: The link seam owns physical storage and keeps link dispatch out of callers
run: python3 scripts/ci/link_seam_purity.py --self-test
# The same shape for Espryt's re-keyed memos (P3b/P4b, PLAN-PH-P34B-P7.md 1.2). P4a/P5f
# moved the resolved-binding, sampler-pass, image-sweep, twin-registry, unit-sampler and
# twin-lookup memos onto {slot, gen} handles and applier serials; the legacy pointer-keyed
# arms stayed behind MOBILEGL_PIPE_LEGACY_MEMOS / !MOBILEGL_BUILD_DISAGGREGATED because
# they are the PULL build's only arms and G1 pins that build's .text. Nothing checked that
# a NEW frontend-pointer key could not appear outside those arms. --self-test runs the
# negative controls and then the real scan in the same invocation, as its sibling does.
- name: Espryt memo keys carry no frontend pointer outside the legacy arms
run: python3 scripts/ci/espryt_memo_purity.py --self-test
# The same question for the symbol tool the P1 gate is written in terms of.
- name: The symbol report's buckets and gates can still fail
run: python3 scripts/symbol_report.py --self-test