mirror of
https://github.com/imjasonh/nescript
synced 2026-07-10 09:42:37 +00:00
codegen+CLAUDE: harden Call arity and document the silent-drop review checklist
Phase 3/4 of the post-PR-#31 audit.
### Call args > 4 is now an assert
`IrOp::Call` silently `.take(4)`-d the arg list with a comment
claiming the analyzer's E0506 check made the extras unreachable.
Replace with an explicit `assert!(args.len() <= 4, ...)` so if
the analyzer ever regresses, the codegen crashes loudly instead
of miscompiling the call. Iterate over all args (not just the
first 4) since the assert guarantees correctness.
### CLAUDE.md: new-feature PR checklist
Document the lesson the audit taught: every new language-feature
PR must include (1) an example exercising it, (2) a runtime
*behaviour* assertion (not just a "ROM validates" shape check),
(3) a negative test for invalid use. Call out the specific
address-map lookup pattern (`if let Some(&addr) = map.get(..)`
with no else) that shipped the state-local bug, and recommend
the `IrCodeGen::var_addr` / explicit `.unwrap_or_else(|| panic!)`
idiom instead.
Chose not to add a regex-based CI tripwire for "silently" /
"for now" comments because the false-positive rate against
legitimate design decisions ("silently truncate to 8 bits per
the cast spec", etc.) would train contributors to ignore it.
The durable checklist in CLAUDE.md is what next agents need.
https://claude.ai/code/session_01AoQ678uVeqpyayvWHpfDhC
This commit is contained in:
parent
48bae97c51
commit
00f1305564
2 changed files with 53 additions and 4 deletions
|
|
@ -1397,10 +1397,17 @@ impl<'a> IrCodeGen<'a> {
|
|||
}
|
||||
IrOp::Call(dest, name, args) => {
|
||||
// Pass up to 4 arguments via zero-page slots $04-$07.
|
||||
// Arguments beyond the fourth are silently dropped
|
||||
// (the analyzer has already validated arity against
|
||||
// the declared signature).
|
||||
for (i, arg) in args.iter().enumerate().take(4) {
|
||||
// E0506 rejects function declarations with more than
|
||||
// four parameters, so a call with >4 args is a
|
||||
// compiler-internal inconsistency — panic rather than
|
||||
// silently drop the extras (PR-#31-shaped miscompile).
|
||||
assert!(
|
||||
args.len() <= 4,
|
||||
"internal compiler error: Call to {name:?} with \
|
||||
{} args (max 4); E0506 should have caught this",
|
||||
args.len()
|
||||
);
|
||||
for (i, arg) in args.iter().enumerate() {
|
||||
self.load_temp(*arg);
|
||||
self.emit(STA, AM::ZeroPage(0x04 + i as u8));
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue