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

@ -232,25 +232,22 @@ 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
@ -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