Implements block-level unreachable code detection using MIR CFG information. Complements Phase 153's method-level HC019 with fine-grained analysis. Core Infrastructure (Complete): - CFG Extractor: Extract block reachability from MirModule - DeadBlockAnalyzerBox: HC020 rule for unreachable blocks - CLI Integration: --dead-blocks flag and rule execution - Test Cases: 4 comprehensive patterns (early return, constant false, infinite loop, break) - Smoke Test: Validation script for all test cases Implementation Details: - src/mir/cfg_extractor.rs: New module for CFG→JSON extraction - tools/hako_check/rules/rule_dead_blocks.hako: HC020 analyzer box - tools/hako_check/cli.hako: Added --dead-blocks flag and HC020 integration - apps/tests/hako_check/test_dead_blocks_*.hako: 4 test cases Architecture: - Follows Phase 153 boxed modular pattern (DeadCodeAnalyzerBox) - Optional CFG field in Analysis IR (backward compatible) - Uses MIR's built-in reachability computation - Gracefully skips if CFG unavailable Known Limitation: - CFG data bridge pending (Phase 155): analysis_consumer.hako needs MIR access - Current: DeadBlockAnalyzerBox implemented, but CFG not yet in Analysis IR - Estimated 2-3 hours to complete bridge in Phase 155 Test Coverage: - Unit tests: cfg_extractor (simple CFG, unreachable blocks) - Integration tests: 4 test cases ready (will activate with bridge) - Smoke test: tools/hako_check_deadblocks_smoke.sh Documentation: - phase154_mir_cfg_inventory.md: CFG structure investigation - phase154_implementation_summary.md: Complete implementation guide - hako_check_design.md: HC020 rule documentation Next Phase 155: - Implement CFG data bridge (extract_mir_cfg builtin) - Update analysis_consumer.hako to call bridge - Activate HC020 end-to-end testing 🤖 Generated with Claude Code (https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
47 lines
1.8 KiB
Markdown
47 lines
1.8 KiB
Markdown
# ArrayBox get/set -> Invalid arguments (plugin side)
|
|
|
|
Status: open (issue memo; see roadmap/CURRENT_TASK for up-to-date status)
|
|
|
|
Summary
|
|
|
|
- Error messages observed during AOT/LLVM smoke that touches ArrayBox:
|
|
- "Plugin invoke error: ArrayBox.set -> Invalid arguments"
|
|
- "Plugin invoke error: ArrayBox.get -> Invalid arguments"
|
|
- VInvoke(MapBox) path is stable; issue is isolated to ArrayBox plugin invocation.
|
|
|
|
Environment
|
|
|
|
- LLVM 18 / inkwell 0.5.0 (llvm18-0)
|
|
- nyash-rust with Phase 11.2 lowering
|
|
- tools/llvm_smoke.sh (Array smoke is gated via NYASH_LLVM_ARRAY_SMOKE=1)
|
|
|
|
Repro
|
|
|
|
1) Enable array smoke explicitly:
|
|
- `NYASH_LLVM_ARRAY_SMOKE=1 ./tools/llvm_smoke.sh release`
|
|
2) Observe plugin-side errors for ArrayBox.get/set.
|
|
|
|
Expected
|
|
|
|
- Array get/set should be routed to NyRT safety shims (`nyash_array_get_h/set_h`) with handle + index/value semantics that match the core VM.
|
|
|
|
Observed
|
|
|
|
- Plugin path is taken for ArrayBox.get/set and the plugin rejects arguments as invalid.
|
|
|
|
Notes / Hypothesis
|
|
|
|
- LLVM lowering is intended to map ArrayBox.get/set to NyRT shims. The plugin path should not be engaged for array core operations.
|
|
- If by-name fallback occurs (NYASH_LLVM_ALLOW_BY_NAME=1), the array methods might route to plugin-by-name with i64-only ABI and mismatched TLV types (index/value encoding).
|
|
|
|
Plan
|
|
|
|
1) Confirm lowering branch for BoxCall(ArrayBox.get/set) always selects NyRT shims under LLVM, regardless of by-name flag.
|
|
2) If by-name fallback is unavoidable in current scenario, ensure integer index/value are encoded/tagged correctly (tag=3 for i64) and receiver is a handle.
|
|
3) Add a targeted smoke (OFF by default) that calls only `get/set/length` and prints deterministic result.
|
|
4) Optional: Add debug env `NYASH_PLUGIN_TLV_DUMP=1` to print decoded TLV for failing invokes to speed diagnosis.
|
|
|
|
Workarounds
|
|
|
|
- Keep `NYASH_LLVM_ARRAY_SMOKE=0` in CI until fixed.
|