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:
@ -619,11 +619,6 @@ box Multi from StringBox, IntegerBox { } // 多重デリゲーションも可能
|
|||||||
// ✅ 唯一の正しい形式
|
// ✅ 唯一の正しい形式
|
||||||
loop(condition) { }
|
loop(condition) { }
|
||||||
|
|
||||||
// ❌ 削除済み構文
|
|
||||||
while condition { } // 使用不可
|
|
||||||
loop() { } // 使用不可
|
|
||||||
```
|
|
||||||
|
|
||||||
### 🌟 birth構文 - 生命をBoxに与える
|
### 🌟 birth構文 - 生命をBoxに与える
|
||||||
```nyash
|
```nyash
|
||||||
// 🌟 「Boxに生命を与える」直感的コンストラクタ
|
// 🌟 「Boxに生命を与える」直感的コンストラクタ
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
# JoinIR Design Map(現役の地図)
|
# JoinIR Design Map(現役の地図)
|
||||||
|
|
||||||
Status: Active
|
Status: SSOT(navigation)
|
||||||
Scope: JoinIR の「Loop/If を JoinIR 化して MIR に統合する」導線(検出→shape guard→lower→merge→契約検証)
|
Scope: JoinIR の「Loop/If を JoinIR 化して MIR に統合する」導線(検出→shape guard→lower→merge→契約検証)
|
||||||
Related:
|
Related:
|
||||||
- SSOT: [`docs/development/current/main/joinir-architecture-overview.md`](../joinir-architecture-overview.md)
|
- SSOT: [`docs/development/current/main/joinir-architecture-overview.md`](../joinir-architecture-overview.md)
|
||||||
@ -10,6 +10,17 @@ Related:
|
|||||||
このドキュメントは Phase ログではなく、「JoinIR を触る人が迷子にならず、どこを直すべきかが一発で分かる」ための設計図(地図)です。
|
このドキュメントは Phase ログではなく、「JoinIR を触る人が迷子にならず、どこを直すべきかが一発で分かる」ための設計図(地図)です。
|
||||||
詳細な経緯・作業ログは `docs/development/current/main/phases/` と `docs/development/current/main/investigations/` に分離します。
|
詳細な経緯・作業ログは `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)
|
## 1枚図: レイヤー(AST → JoinIR → MIR → Backend)
|
||||||
|
|||||||
@ -6,6 +6,13 @@
|
|||||||
|
|
||||||
変更があったら、Phase ドキュメントではなく **このファイルを随時更新する** 方針。
|
変更があったら、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)
|
## 0. 読み方ガイド(Reader's Guide)
|
||||||
|
|||||||
@ -232,26 +232,23 @@ pub fn emit_mir_json_for_harness(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
|
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
|
||||||
.collect();
|
.collect();
|
||||||
// dst_type hint: if all incoming values are String-ish, annotate result as String handle
|
// Phase 131-11-F: Add dst_type hint from metadata for all PHI instructions
|
||||||
let all_str =
|
let mut phi_inst = json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming});
|
||||||
inputs
|
if let Some(dst_type) = f.metadata.value_types.get(dst) {
|
||||||
.iter()
|
let type_json = match dst_type {
|
||||||
.all(|(_b, v)| match f.metadata.value_types.get(v) {
|
MirType::Integer => json!("i64"),
|
||||||
Some(MirType::String) => true,
|
MirType::String => json!({"kind": "string"}),
|
||||||
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
|
||||||
_ => false,
|
MirType::Bool => json!("i1"),
|
||||||
});
|
MirType::Void => json!("void"),
|
||||||
if all_str {
|
_ => json!(null),
|
||||||
insts.push(json!({
|
};
|
||||||
"op":"phi","dst": dst.as_u32(), "incoming": incoming,
|
if !type_json.is_null() {
|
||||||
"dst_type": {"kind":"handle","box_type":"StringBox"}
|
phi_inst["dst_type"] = type_json;
|
||||||
}));
|
|
||||||
} else {
|
|
||||||
insts.push(
|
|
||||||
json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
insts.push(phi_inst);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Non-PHI
|
// Non-PHI
|
||||||
// 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
|
// Export parameter value-ids so a VM can bind arguments
|
||||||
let params: Vec<_> = f.params.iter().map(|v| v.as_u32()).collect();
|
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
|
// Phase 15.5: JSON v1 schema with environment variable control
|
||||||
@ -658,24 +677,22 @@ pub fn emit_mir_json_for_harness_bin(
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
|
.map(|(b, v)| json!([v.as_u32(), b.as_u32()]))
|
||||||
.collect();
|
.collect();
|
||||||
let all_str =
|
// Phase 131-11-F: Add dst_type hint from metadata for all PHI instructions
|
||||||
inputs
|
let mut phi_inst = json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming});
|
||||||
.iter()
|
if let Some(dst_type) = f.metadata.value_types.get(dst) {
|
||||||
.all(|(_b, v)| match f.metadata.value_types.get(v) {
|
let type_json = match dst_type {
|
||||||
Some(MirType::String) => true,
|
MirType::Integer => json!("i64"),
|
||||||
Some(MirType::Box(bt)) if bt == "StringBox" => true,
|
MirType::String => json!({"kind": "string"}),
|
||||||
_ => false,
|
MirType::Box(bt) => json!({"kind": "handle", "box_type": bt}),
|
||||||
});
|
MirType::Bool => json!("i1"),
|
||||||
if all_str {
|
MirType::Void => json!("void"),
|
||||||
insts.push(json!({
|
_ => json!(null),
|
||||||
"op":"phi","dst": dst.as_u32(), "incoming": incoming,
|
};
|
||||||
"dst_type": {"kind":"handle","box_type":"StringBox"}
|
if !type_json.is_null() {
|
||||||
}));
|
phi_inst["dst_type"] = type_json;
|
||||||
} else {
|
|
||||||
insts.push(
|
|
||||||
json!({"op":"phi","dst": dst.as_u32(), "incoming": incoming}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
insts.push(phi_inst);
|
||||||
emitted_defs.insert(dst.as_u32());
|
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();
|
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
|
// Phase 155: Extract CFG information for hako_check
|
||||||
|
|||||||
Reference in New Issue
Block a user