feat(mir): Phase 131-11-F - MIR JSON metadata 出力実装

## 実装内容
- mir_json_emit.rs に function-level metadata 追加
- PHI 命令に dst_type ヒント追加
- v0/v1 両 emitter で実装

## 成果物
-  metadata.value_types を JSON に出力
-  PHI dst_type を metadata から取得
-  ビルド成功(0 エラー)

## JSON 出力例
```json
{
  "functions": [{
    "metadata": {
      "value_types": {
        "1": "i64",
        "3": "i64"
      }
    }
  }]
}
```

## 既知の問題(Phase 131-11-E 再調査必要)
- MIR dump で PHI が String 型のまま
- Phase 131-11-E の TypeFacts 分離が完全に動作していない可能性

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
nyash-codex
2025-12-14 19:34:02 +09:00
parent 29d96b94e6
commit 413504d6de
4 changed files with 95 additions and 43 deletions

View File

@ -619,11 +619,6 @@ box Multi from StringBox, IntegerBox { } // 多重デリゲーションも可能
// ✅ 唯一の正しい形式
loop(condition) { }
// ❌ 削除済み構文
while condition { } // 使用不可
loop() { } // 使用不可
```
### 🌟 birth構文 - 生命をBoxに与える
```nyash
// 🌟 「Boxに生命を与える」直感的コンストラクタ

View File

@ -1,6 +1,6 @@
# JoinIR Design Map現役の地図
Status: Active
Status: SSOTnavigation
Scope: JoinIR の「Loop/If を JoinIR 化して MIR に統合する」導線検出→shape guard→lower→merge→契約検証
Related:
- SSOT: [`docs/development/current/main/joinir-architecture-overview.md`](../joinir-architecture-overview.md)
@ -10,6 +10,17 @@ Related:
このドキュメントは Phase ログではなく、「JoinIR を触る人が迷子にならず、どこを直すべきかが一発で分かる」ための設計図(地図)です。
詳細な経緯・作業ログは `docs/development/current/main/phases/``docs/development/current/main/investigations/` に分離します。
## 役割分担joinir-architecture-overview との分離)
このファイルは「実装導線の地図」の SSOT ですnavigation SSOT
意味論・契約・不変条件の本文normative`docs/development/current/main/joinir-architecture-overview.md` を SSOT とします。
使い分け:
- 「JoinIR が何を保証し、何を Fail-Fast で落とすべきか」→ `joinir-architecture-overview.md`
- 「どのファイルを触るべきか」「入口はどこか」「追加手順は?」→ この `joinir-design-map.md`
- 「経緯/ログ/切り分け」→ `docs/development/current/main/phases/``docs/development/current/main/investigations/`
---
## 1枚図: レイヤーAST → JoinIR → MIR → Backend

View File

@ -6,6 +6,13 @@
変更があったら、Phase ドキュメントではなく **このファイルを随時更新する** 方針。
併用ドキュメント(役割分担):
- **設計の正本(契約/不変条件/箱の責務)**: この `joinir-architecture-overview.md` を SSOT とする。
- **実装導線の地図(どのファイルを触るか/入口一覧/追加手順)**:
`docs/development/current/main/design/joinir-design-map.md` を参照する(ここには“場所”を書き、契約本文は本ファイルに寄せる)。
- docs の置き場所ルールSSOT: `docs/development/current/main/DOCS_LAYOUT.md`
---
## 0. 読み方ガイドReader's Guide

View File

@ -232,26 +232,23 @@ pub fn emit_mir_json_for_harness(
.iter()
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
.collect();
// dst_type hint: if all incoming values are String-ish, annotate result as String handle
let all_str =
inputs
.iter()
.all(|(_b, v)| match f.metadata.value_types.get(v) {
Some(MirType::String) => true,
Some(MirType::Box(bt)) if bt == "StringBox" => true,
_ => false,
});
if all_str {
insts.push(json!({
"op":"phi","dst": dst.as_u32(), "incoming": incoming,
"dst_type": {"kind":"handle","box_type":"StringBox"}
}));
} else {
insts.push(
json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming}),
);
// Phase 131-11-F: Add dst_type hint from metadata for all PHI instructions
let mut phi_inst = json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming});
if let Some(dst_type) = f.metadata.value_types.get(dst) {
let type_json = match dst_type {
MirType::Integer => json!("i64"),
MirType::String => json!({"kind": "string"}),
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
MirType::Bool => json!("i1"),
MirType::Void => json!("void"),
_ => json!(null),
};
if !type_json.is_null() {
phi_inst["dst_type"] = type_json;
}
}
insts.push(phi_inst);
}
}
// Non-PHI
// Non-PHI
@ -579,7 +576,29 @@ pub fn emit_mir_json_for_harness(
}
// Export parameter value-ids so a VM can bind arguments
let params: Vec<_> = f.params.iter().map(|v| v.as_u32()).collect();
funs.push(json!({"name": name, "params": params, "blocks": blocks}));
// Phase 131-11-F: Build metadata JSON from MIR metadata (SSOT)
let metadata_json = json!({
"value_types": f.metadata.value_types.iter().map(|(k, v)| {
let type_str = match v {
MirType::Integer => json!("i64"),
MirType::String => json!({"kind": "string"}),
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
MirType::Bool => json!("i1"),
MirType::Void => json!("void"),
MirType::Unknown => json!(null),
_ => json!(null),
};
(k.as_u32().to_string(), type_str)
}).collect::<serde_json::Map<String, serde_json::Value>>()
});
funs.push(json!({
"name": name,
"params": params,
"blocks": blocks,
"metadata": metadata_json
}));
}
// Phase 15.5: JSON v1 schema with environment variable control
@ -658,24 +677,22 @@ pub fn emit_mir_json_for_harness_bin(
.iter()
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
.collect();
let all_str =
inputs
.iter()
.all(|(_b, v)| match f.metadata.value_types.get(v) {
Some(MirType::String) => true,
Some(MirType::Box(bt)) if bt == "StringBox" => true,
_ => false,
});
if all_str {
insts.push(json!({
"op":"phi","dst": dst.as_u32(), "incoming": incoming,
"dst_type": {"kind":"handle","box_type":"StringBox"}
}));
} else {
insts.push(
json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming}),
);
// Phase 131-11-F: Add dst_type hint from metadata for all PHI instructions
let mut phi_inst = json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming});
if let Some(dst_type) = f.metadata.value_types.get(dst) {
let type_json = match dst_type {
MirType::Integer => json!("i64"),
MirType::String => json!({"kind": "string"}),
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
MirType::Bool => json!("i1"),
MirType::Void => json!("void"),
_ => json!(null),
};
if !type_json.is_null() {
phi_inst["dst_type"] = type_json;
}
}
insts.push(phi_inst);
emitted_defs.insert(dst.as_u32());
}
}
@ -947,7 +964,29 @@ pub fn emit_mir_json_for_harness_bin(
}
}
let params: Vec<_> = f.params.iter().map(|v| v.as_u32()).collect();
funs.push(json!({"name": name, "params": params, "blocks": blocks}));
// Phase 131-11-F: Build metadata JSON from MIR metadata (SSOT)
let metadata_json = json!({
"value_types": f.metadata.value_types.iter().map(|(k, v)| {
let type_str = match v {
MirType::Integer => json!("i64"),
MirType::String => json!({"kind": "string"}),
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
MirType::Bool => json!("i1"),
MirType::Void => json!("void"),
MirType::Unknown => json!(null),
_ => json!(null),
};
(k.as_u32().to_string(), type_str)
}).collect::<serde_json::Map<String, serde_json::Value>>()
});
funs.push(json!({
"name": name,
"params": params,
"blocks": blocks,
"metadata": metadata_json
}));
}
// Phase 155: Extract CFG information for hako_check