word_source: repair DECAY-RATE@ overflow guard and remove dead shadowed registrations
DECAY-RATE@ (physics_freeze_words.c) pushed to the data stack with no capacity check and no prior pop to make room, unlike its neighbors in the same file -- the one live, unconditional missing-guard bug the Isabelle sweep's ~15 candidate findings reduced to once checked against vm_push()'s real internal bounds check (see proof/FINDINGS.md SS2). Removed dictionary_manipulation_words.c's [ ] STATE and defining_words.c's DEFER IS DEFER@ (plus the now-orphaned defining_runtime_defer helper) -- all confirmed permanently shadowed by later dictionary registrations (defining_words.c and defer_words.c respectively), per FORTH's newest-first lookup. No behavior change: the removed code was already unreachable. Verified: hosted `make` builds clean under -Wall -Werror; the hosted self-test suite passes 965/965 implemented tests with no regressions. Three-architecture QEMU acceptance boot, all clean to ok> with an identical dict_hash=0x24b4279f0670aa3a across amd64/aarch64/riscv64 and identical 1003/965/0/0 test totals -- logs attached. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
3426d6a4a7
commit
dfdabcc2d7
@@ -14,8 +14,13 @@ begin
|
||||
`STATE` (Module 17, line 126). FORTH dictionary lookup finds the MOST
|
||||
RECENT definition of a name first, so defining_words.c's versions are
|
||||
the only ones ever reachable -- dictionary_manipulation_words.c's `[`/
|
||||
`]`/`STATE`/`INTERPRET` are permanently shadowed, dead code from the
|
||||
moment boot registration completes.
|
||||
`]`/`STATE` are permanently shadowed, dead code from the moment boot
|
||||
registration completes. CORRECTED 2026-08-14: `INTERPRET` is NOT part of
|
||||
this shadow -- defining_words.c never registers a word named INTERPRET
|
||||
at all (confirmed by grep), so dictionary_manipulation_words.c's
|
||||
INTERPRET is the only registration that exists and is live, not dead.
|
||||
The earlier version of this note (and proof/FINDINGS.md) incorrectly
|
||||
folded it into the shadowed group.
|
||||
|
||||
This also CORRECTS that file's finding, not just supersedes it: its
|
||||
`[`/`]`/`STATE` write/read a dead file-scope `static cell_t
|
||||
|
||||
@@ -37,16 +37,28 @@ begin
|
||||
(include/vm.h:431, the real per-VM STATE field actively used by
|
||||
vm.c/vm_core.c/vm_bootstrap.c/capsule_loader.c on both hosted and
|
||||
kernel builds). This static is a single process-wide variable, not
|
||||
even per-VM: in the Tripod multi-VM fleet, EVERY VM's `[`/`]`/
|
||||
`INTERPRET` mutates the SAME shared cell, and `STATE` pushes ITS
|
||||
address (a bare host pointer, not a VM address) -- identical across
|
||||
every VM instance. `vm->state_var` itself is correctly toggled
|
||||
elsewhere in the real interpreter loop, so the dictionary-space
|
||||
compile/interpret bookkeeping isn't broken, but these four FORTH
|
||||
words are effectively wired to a dead, cross-VM-shared shadow
|
||||
variable instead of the VM's own state. Modelled below using only
|
||||
`vm_mode` (which `[`/`]` DO correctly set) -- the dead static write
|
||||
has no vm_state counterpart and is simply omitted, not "fixed".
|
||||
even per-VM. CORRECTED 2026-08-14 -- these four words split into two
|
||||
different reachability classes, not one:
|
||||
- `[`, `]`, `STATE` are permanently SHADOWED (see StarForth_Defining_
|
||||
Words.thy's duplicate-registration finding) -- dead code, this
|
||||
static's misuse never executes for any live VM.
|
||||
- `INTERPRET` is NOT shadowed (defining_words.c registers no word by
|
||||
that name at all) -- it IS live and reachable, and its body really
|
||||
does execute `state_variable = 0;` on every call
|
||||
(dictionary_manipulation_words.c:392) alongside the correct
|
||||
`vm->mode = MODE_INTERPRET`. This write is functionally inert
|
||||
(nothing on any live path reads `state_variable`, since the only
|
||||
word that ever read it -- this file's own `STATE` -- is itself one
|
||||
of the shadowed three above), but it is live, executing code in a
|
||||
registered, tested word, not dead code to remove casually per
|
||||
.claude/CLAUDE.md's "never modify a registered, tested word"
|
||||
guidance. Reported, not touched.
|
||||
`vm->state_var` itself is correctly toggled elsewhere in the real
|
||||
interpreter loop regardless, so the dictionary-space compile/
|
||||
interpret bookkeeping isn't broken by any of this. Modelled below
|
||||
using only `vm_mode` (which `[`/`]` DO correctly set) -- the dead
|
||||
static write has no vm_state counterpart and is simply omitted, not
|
||||
"fixed".
|
||||
2. `dictionary_m_word_hidden`'s `#else` fallback branch (taken only if
|
||||
`WORD_HIDDEN` is undefined -- it is always defined per include/vm.h:
|
||||
181, so this branch is dead in every build configuration seen) calls
|
||||
|
||||
@@ -22,13 +22,14 @@ begin
|
||||
accessors with no vm_state counterpart, the same class of gap as every
|
||||
other hardware-boundary word in this console-fabric group.
|
||||
|
||||
── Finding: FB-WIDTH/FB-HEIGHT have no overflow guard ──────────────────
|
||||
Neither checks `ds_full` (or any capacity condition) before pushing --
|
||||
same hazard class as physics_freeze_words.c's DECAY-RATE@, the first
|
||||
instance of this sweep finding a missing overflow guard. Second
|
||||
instance now, both in diagnostic/hardware-boundary words that read as
|
||||
"just returns a number" and evidently didn't get the same underflow-
|
||||
guard-writing discipline as stack-manipulation words.
|
||||
── CORRECTED finding: FB-WIDTH/FB-HEIGHT are NOT missing a guard ───────
|
||||
Both push via C's `vm_push()` (src/stack_management.c:75), which bounds-
|
||||
checks internally (`if (vm->dsp >= STACK_SIZE - 1) ...`) before every
|
||||
write -- this file's earlier claim that neither checks capacity was a
|
||||
gap in this theory's abstract push model, not a real defect in the C.
|
||||
Re-verified 2026-08-14 during the sweep's repair pass; see
|
||||
proof/FINDINGS.md §2 for the full correction across all files this
|
||||
pattern was raised against.
|
||||
======================================================================== *)
|
||||
|
||||
(* ── PLOT ( x y color -- ) : hosted build ─────────────────────────────── *)
|
||||
@@ -67,7 +68,10 @@ lemma plot_kernel_not_modelled: True
|
||||
by simp
|
||||
|
||||
(* ── FB-WIDTH / FB-HEIGHT ( -- n ) : hosted build ─────────────────────── *)
|
||||
(* C: hosted branch pushes 0 unconditionally, no capacity guard at all. *)
|
||||
(* C: hosted branch pushes 0 via vm_push(), which bounds-checks internally
|
||||
(see corrected header finding above) -- the abstract push below still
|
||||
models an unconditional push since this theory's stack has no depth
|
||||
bound to violate, but the real C is guarded. *)
|
||||
|
||||
definition forth_fb_width_hosted :: "vm_state \<Rightarrow> vm_state" where
|
||||
"forth_fb_width_hosted vm = vm\<lparr>data_stack := 0 # data_stack vm\<rparr>"
|
||||
|
||||
@@ -144,8 +144,12 @@ lemma infer_early_exit_fetch_some_false:
|
||||
using assms by (simp add: forth_infer_early_exit_fetch_def)
|
||||
|
||||
lemma infer_fetch_words_no_overflow_guard: True
|
||||
\<comment> \<open>All five push unconditionally, no ds_full check -- another instance
|
||||
of the recurring missing-overflow-guard pattern.\<close>
|
||||
\<comment> \<open>CORRECTED 2026-08-14: all five push via VM_PUSH (include/vm.h:706-719),
|
||||
which resolves to the bounds-checked vm_push() in every build except one
|
||||
defining STARFORTH_PERFORMANCE -- confirmed by repo-wide grep to never be
|
||||
defined by any Makefile/Kconfig target here. Real but dormant hazard, not
|
||||
a live per-word bug; same finding as StarForth_Q48_Words.thy's header.
|
||||
See proof/FINDINGS.md \<section>2.\<close>
|
||||
by simp
|
||||
|
||||
(* ── Q.VARIANCE / INFER-DECAY-SLOPE / INFER-WINDOW-WIDTH
|
||||
@@ -233,15 +237,15 @@ lemma l8_table_force_target_not_modelled: True
|
||||
|
||||
(* ── Everything else -- NOT MODELLED ──────────────────────────────────── *)
|
||||
|
||||
lemma window_diversity_not_modelled: True \<comment> \<open>WINDOW-DIVERSITY: rolling_window_measure_diversity computes a fresh value from rw_history (a modelled field, but the diversity ALGORITHM over it is not) -- distinct from the already-stored rw_last_diversity. No overflow guard either.\<close>
|
||||
lemma window_diversity_not_modelled: True \<comment> \<open>WINDOW-DIVERSITY: rolling_window_measure_diversity computes a fresh value from rw_history (a modelled field, but the diversity ALGORITHM over it is not) -- distinct from the already-stored rw_last_diversity. Push is via VM_PUSH -- see corrected header note near infer_fetch_words_no_overflow_guard.\<close>
|
||||
by simp
|
||||
lemma infer_run_not_modelled: True \<comment> \<open>INFER-RUN: allocates last_inference_outputs on first call, walks the dictionary read-only for heat stats, then runs inference_engine_run -- a whole-subsystem algorithm. This is the ONLY word that writes `last_inference`, so no fetch-after-INFER-RUN lemma can be stated.\<close>
|
||||
by simp
|
||||
lemma l8_mode_not_modelled: True \<comment> \<open>L8-MODE: reads vm->ssm_l8_state's legacy 16-mode int -- see file header's representation-mismatch finding. No overflow guard.\<close>
|
||||
lemma l8_mode_not_modelled: True \<comment> \<open>L8-MODE: reads vm->ssm_l8_state's legacy 16-mode int -- see file header's representation-mismatch finding. Push is via VM_PUSH -- see corrected header note near infer_fetch_words_no_overflow_guard.\<close>
|
||||
by simp
|
||||
lemma l8_apply_not_modelled: True \<comment> \<open>L8-APPLY: no-op if !l8||!cfg, else ssm_apply_mode -- targets the same unmodelled legacy L8 state as L8-UPDATE.\<close>
|
||||
by simp
|
||||
lemma bayes_cache_mean_not_modelled: True \<comment> \<open>BAYES-CACHE-MEAN: hotwords_posterior_cache_hits over the unmodelled hot-words cache subsystem (StarForth_Physics_Benchmark_Words.thy). No overflow guard.\<close>
|
||||
lemma bayes_cache_mean_not_modelled: True \<comment> \<open>BAYES-CACHE-MEAN: hotwords_posterior_cache_hits over the unmodelled hot-words cache subsystem (StarForth_Physics_Benchmark_Words.thy). Push is via VM_PUSH -- see corrected header note near infer_fetch_words_no_overflow_guard.\<close>
|
||||
by simp
|
||||
lemma bayes_cache_lower_not_modelled: True by simp
|
||||
lemma bayes_cache_upper_not_modelled: True by simp
|
||||
|
||||
@@ -18,11 +18,11 @@ begin
|
||||
── Scope ─────────────────────────────────────────────────────────────
|
||||
The fallback (non-kernel-or-wrong-arch) behaviour of all six words is
|
||||
fully modelled: every one reduces to a fixed constant push (or, for
|
||||
ALT+TAB, a true no-op) with NO capacity guard before pushing -- the
|
||||
third and fourth instances of the missing-overflow-guard finding first
|
||||
raised in physics_freeze_words.c's DECAY-RATE@ (KBD-SCAN/VKBD-EVENT/
|
||||
VKBD-DEBUG/KEY-EVENT push 1-2 cells unconditionally; KBD-DEBUG pushes
|
||||
2). The real (matching kernel+arch) hardware-polling bodies are NOT
|
||||
ALT+TAB, a true no-op). CORRECTED 2026-08-14: all six push via C's
|
||||
`vm_push()` (src/stack_management.c:75), which bounds-checks internally
|
||||
-- the earlier "no capacity guard" claim here was a gap in this theory's
|
||||
abstract push model, not a real defect in the C; see proof/FINDINGS.md
|
||||
§2. The real (matching kernel+arch) hardware-polling bodies are NOT
|
||||
modelled: i8042_pop_scancode/virtio_input_pop_event/
|
||||
console_fb_toggle_graphics are all raw hardware/interrupt-state reads
|
||||
with no vm_state counterpart, the same class of gap as every other
|
||||
|
||||
@@ -29,13 +29,13 @@ begin
|
||||
on vm_find_word + vm_compile_word + vm_allot -- several already-flagged
|
||||
gaps compounded in one helper).
|
||||
|
||||
── Finding: three more push-only words with no overflow guard ─────────
|
||||
LOG-ERROR/WARN/INFO/TEST/DEBUG and LOG-LEVEL@ push unconditionally with
|
||||
no `ds_full` check -- the pattern first found at DECAY-RATE@
|
||||
(physics_freeze_words.c) and repeated across framebuffer_words.c/
|
||||
keyboard_words.c keeps recurring specifically in "just returns a
|
||||
constant/global" words; worth citing log_words.c as further evidence
|
||||
when this goes to Bob as an aggregated pattern rather than one-offs.
|
||||
── CORRECTED finding: LOG-* words are NOT missing a guard ─────────────
|
||||
LOG-ERROR/WARN/INFO/TEST/DEBUG and LOG-LEVEL@ all push via C's
|
||||
`vm_push()` (src/stack_management.c:75), which bounds-checks internally
|
||||
-- this file's earlier claim of a missing `ds_full` check was a gap in
|
||||
this theory's abstract push model, not a real defect in the C.
|
||||
Re-verified 2026-08-14; see proof/FINDINGS.md §2 for the full
|
||||
correction across every file this pattern was raised against.
|
||||
======================================================================== *)
|
||||
|
||||
definition LOG_ERROR_LEVEL :: cell where "LOG_ERROR_LEVEL = 0"
|
||||
@@ -120,7 +120,8 @@ lemma log_level_store_target_not_modelled: True
|
||||
|
||||
lemma log_level_fetch_not_modelled: True
|
||||
\<comment> \<open>Pushes log_get_level(), reading the same unmodelled global
|
||||
LOG-LEVEL! writes to. No overflow guard either -- see file header.\<close>
|
||||
LOG-LEVEL! writes to. Push is via vm_push(), which bounds-checks --
|
||||
see corrected file header.\<close>
|
||||
by simp
|
||||
|
||||
(* ── (do-log-N) runtime words -- NOT MODELLED ─────────────────────────── *)
|
||||
|
||||
@@ -28,7 +28,12 @@ begin
|
||||
`STARFORTH_PERFORMANCE`) path, consistent with this suite's general
|
||||
assumption that stack words check bounds; the fast-path variant is
|
||||
flagged, not modelled, since "no check at all" has no useful lemma to
|
||||
state beyond "anything can happen."
|
||||
state beyond "anything can happen." CONFIRMED 2026-08-14: repo-wide grep
|
||||
shows `STARFORTH_PERFORMANCE` is never defined by any Makefile or
|
||||
Kconfig target in this repo -- only referenced inside vm.h itself and
|
||||
stack_words.c. So under every configuration this repo currently builds,
|
||||
this file's words are on the safe path; the hazard is real but dormant,
|
||||
contingent on a build flag nothing sets today.
|
||||
|
||||
── Q48 operations reused from StarForth_Q48_16.thy ─────────────────────
|
||||
q48_add/q48_sub/q48_mul/q48_div/q48_from_u64/q48_to_u64 were already
|
||||
|
||||
Reference in New Issue
Block a user