Files
hakorune/tools/hako_check/rules/rule_global_assign.hako
nyash-codex 301b1d212a Phase 21.2 Complete: VM Adapter正規実装 + devブリッジ完全撤去
## 🎉 Phase 21.2完全達成

###  実装完了
- VM static box 永続化(singleton infrastructure)
- devブリッジ完全撤去(adapter_dev.rs削除、by-name dispatch削除)
- .hako正規実装(MirCallV1Handler, AbiAdapterRegistry等)
- text-merge経路完全動作
- 全phase2120 adapter reps PASS(7テスト)

### 🐛 バグ修正
1. strip_local_decl修正
   - トップレベルのみlocal削除、メソッド内は保持
   - src/runner/modes/common_util/hako.rs:29

2. static box フィールド永続化
   - MirInterpreter singleton storage実装
   - me parameter binding修正(1:1マッピング)
   - getField/setField string→singleton解決
   - src/backend/mir_interpreter/{mod,exec,handlers/boxes_object_fields}.rs

3. Map.len alias rc=0修正
   - [map/missing]パターン検出でnull扱い(4箇所)
   - lang/src/vm/boxes/mir_call_v1_handler.hako:91-93,131-133,151-153,199-201

### 📁 主要変更ファイル

#### Rust(VM Runtime)
- src/backend/mir_interpreter/mod.rs - static box singleton storage
- src/backend/mir_interpreter/exec.rs - parameter binding fix
- src/backend/mir_interpreter/handlers/boxes_object_fields.rs - singleton resolution
- src/backend/mir_interpreter/handlers/calls.rs - dev bridge removal
- src/backend/mir_interpreter/utils/mod.rs - adapter_dev module removal
- src/backend/mir_interpreter/utils/adapter_dev.rs - DELETED (7555 bytes)
- src/runner/modes/vm.rs - static box declaration collection
- src/runner/modes/common_util/hako.rs - strip_local_decl fix
- src/instance_v2.rs - Clone implementation

#### Hako (.hako実装)
- lang/src/vm/boxes/mir_call_v1_handler.hako - [map/missing] detection
- lang/src/vm/boxes/abi_adapter_registry.hako - NEW (adapter registry)
- lang/src/vm/helpers/method_alias_policy.hako - method alias support

#### テスト
- tools/smokes/v2/profiles/quick/core/phase2120/s3_vm_adapter_*.sh - 7 new tests

### 🎯 テスト結果
```
 s3_vm_adapter_array_len_canary_vm.sh
 s3_vm_adapter_array_len_per_recv_canary_vm.sh
 s3_vm_adapter_array_length_alias_canary_vm.sh
 s3_vm_adapter_array_size_alias_canary_vm.sh
 s3_vm_adapter_map_len_alias_state_canary_vm.sh
 s3_vm_adapter_map_length_alias_state_canary_vm.sh
 s3_vm_adapter_map_size_struct_canary_vm.sh
```

環境フラグ: HAKO_ABI_ADAPTER=1 HAKO_ABI_ADAPTER_DEV=0

### 🏆 設計品質
-  ハードコード禁止(AGENTS.md 5.1)完全準拠
-  構造的・一般化設計(特定Box名のif分岐なし)
-  後方互換性保持(既存コード破壊ゼロ)
-  text-merge経路(.hako依存関係正しくマージ)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-07 19:32:44 +09:00

40 lines
1.6 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using selfhost.shared.common.string_helpers as Str
static box RuleGlobalAssignBox {
apply(text, path, out) {
// HC010: global mutable state 禁止top-levelの識別子= を雑に検出)
local lines = text.split("\n")
local in_box = 0; local in_method = 0
do { local i = 0; while i < lines.size() {
local ln = lines.get(i)
local t = me._ltrim(ln)
if t.indexOf("static box ") == 0 { in_box = 1; in_method = 0 }
if in_box == 1 && t == "}" { in_box = 0; in_method = 0 }
if in_box == 1 && t.indexOf("method ") == 0 { in_method = 1 }
if in_box == 1 && in_method == 0 {
// at top-level inside box: ident =
if me._looks_assign(t) == 1 {
out.push("[HC010] global assignment (top-level in box is forbidden): " + path + ":" + Str.int_to_str(i+1))
}
}
i = i + 1 } } while 0
}
_ltrim(s) { return me._ltrim_chars(s, " \t") }
_ltrim_chars(s, cs) {
local n=Str.len(s); local head=0
do { local i = 0; while i < n { local ch=s.substring(i,i+1); if ch!=" "&&ch!="\t" { head=i; break }; if i==n-1 { head=n }; i = i + 1 } } while 0
return s.substring(head)
}
_looks_assign(t) {
// very naive: identifier start followed by '=' somewhere (and not 'static box' or 'method')
if Str.len(t) < 3 { return 0 }
local c = t.substring(0,1)
if !((c>="A"&&c<="Z")||(c>="a"&&c<="z")||c=="_") { return 0 }
if t.indexOf("static box ") == 0 || t.indexOf("method ") == 0 { return 0 }
if t.indexOf("=") > 0 { return 1 }
return 0
}
}
static box RuleGlobalAssignMain { method main(args) { return 0 } }