- RoutingDecision の missing_caps を Vec<CapabilityTag> に変更(型安全化) - error_tags は to_tag() メソッドで自動生成 - 全 callsite を enum variant に修正 - capability_tags モジュール(文字列定数群)を完全削除 - 全テスト PASS(型安全性向上を確認) - フォーマット適用
293 lines
12 KiB
Rust
293 lines
12 KiB
Rust
use super::{convert_join_module_to_mir_with_meta, JoinIrVmBridgeError};
|
||
use crate::mir::join_ir::frontend::JoinFuncMetaMap;
|
||
use crate::mir::join_ir::JoinModule;
|
||
use crate::mir::MirModule;
|
||
use std::collections::BTreeMap;
|
||
|
||
#[cfg(feature = "normalized_dev")]
|
||
use crate::config::env::joinir_dev::{current_joinir_mode, JoinIrMode};
|
||
#[cfg(feature = "normalized_dev")]
|
||
use crate::mir::join_ir::normalized::shape_guard::{self, NormalizedDevShape};
|
||
#[cfg(feature = "normalized_dev")]
|
||
use crate::mir::join_ir::normalized::{
|
||
normalize_pattern1_minimal, normalize_pattern2_minimal, NormalizedModule,
|
||
};
|
||
#[cfg(feature = "normalized_dev")]
|
||
use crate::mir::join_ir::JoinIrPhase;
|
||
#[cfg(feature = "normalized_dev")]
|
||
use crate::mir::join_ir_vm_bridge::lower_normalized_to_mir_minimal;
|
||
#[cfg(feature = "normalized_dev")]
|
||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||
|
||
/// Structured JoinIR → MIR(既存経路)の明示エントリ。
|
||
pub(crate) fn lower_joinir_structured_to_mir_with_meta(
|
||
module: &JoinModule,
|
||
meta: &JoinFuncMetaMap,
|
||
) -> Result<MirModule, JoinIrVmBridgeError> {
|
||
if !module.is_structured() {
|
||
return Err(JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] expected Structured JoinIR module",
|
||
));
|
||
}
|
||
|
||
convert_join_module_to_mir_with_meta(module, meta)
|
||
}
|
||
|
||
/// Normalized JoinIR → MIR(現状は Structured に戻して既存ブリッジを再利用)。
|
||
#[cfg(feature = "normalized_dev")]
|
||
#[allow(dead_code)]
|
||
pub(crate) fn lower_joinir_normalized_to_mir_with_meta(
|
||
module: &NormalizedModule,
|
||
meta: &JoinFuncMetaMap,
|
||
) -> Result<MirModule, JoinIrVmBridgeError> {
|
||
if module.phase != JoinIrPhase::Normalized {
|
||
return Err(JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] expected Normalized JoinIR module",
|
||
));
|
||
}
|
||
|
||
let structured = module.to_structured().ok_or_else(|| {
|
||
JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] normalized module missing Structured snapshot (dev-only)",
|
||
)
|
||
})?;
|
||
|
||
lower_joinir_structured_to_mir_with_meta(&structured, meta)
|
||
}
|
||
|
||
#[cfg(feature = "normalized_dev")]
|
||
fn normalize_for_shape(
|
||
module: &JoinModule,
|
||
shape: NormalizedDevShape,
|
||
) -> Result<NormalizedModule, JoinIrVmBridgeError> {
|
||
let result = match shape {
|
||
NormalizedDevShape::Pattern1Mini => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern1_minimal(module)))
|
||
}
|
||
NormalizedDevShape::Pattern2Mini
|
||
| NormalizedDevShape::JsonparserSkipWsMini
|
||
| NormalizedDevShape::JsonparserSkipWsReal
|
||
| NormalizedDevShape::JsonparserAtoiMini
|
||
| NormalizedDevShape::JsonparserAtoiReal
|
||
| NormalizedDevShape::JsonparserParseNumberReal => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern2_minimal(module)))
|
||
}
|
||
NormalizedDevShape::SelfhostTokenScanP2 => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_token_scan_p2(module)
|
||
.expect("selfhost P2 normalization failed")
|
||
})),
|
||
NormalizedDevShape::SelfhostTokenScanP2Accum => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_token_scan_p2_accum(module)
|
||
.expect("selfhost P2 accum normalization failed")
|
||
})),
|
||
// Phase 47-A: P3 minimal normalization
|
||
NormalizedDevShape::Pattern3IfSumMinimal => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_pattern3_if_sum_minimal(module)
|
||
.expect("P3 normalization failed")
|
||
})),
|
||
// Phase 47-B: P3 extended normalization
|
||
NormalizedDevShape::Pattern3IfSumMulti => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_pattern3_if_sum_multi_minimal(module)
|
||
.expect("P3 multi normalization failed")
|
||
})),
|
||
NormalizedDevShape::Pattern3IfSumJson => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_pattern3_if_sum_json_minimal(module)
|
||
.expect("P3 json normalization failed")
|
||
})),
|
||
NormalizedDevShape::SelfhostIfSumP3 => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_if_sum_p3(module)
|
||
.expect("selfhost P3 normalization failed")
|
||
})),
|
||
NormalizedDevShape::SelfhostIfSumP3Ext => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_if_sum_p3_ext(module)
|
||
.expect("selfhost P3 ext normalization failed")
|
||
})),
|
||
// Phase 53: selfhost P2/P3 practical variations (delegate to existing normalizers)
|
||
NormalizedDevShape::SelfhostArgsParseP2 => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern2_minimal(module)))
|
||
}
|
||
NormalizedDevShape::SelfhostStmtCountP3 => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_if_sum_p3_ext(module)
|
||
.expect("selfhost stmt_count P3 normalization failed")
|
||
})),
|
||
// Phase 54: selfhost P2/P3 shape growth (delegate to existing normalizers)
|
||
NormalizedDevShape::SelfhostVerifySchemaP2 => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern2_minimal(module)))
|
||
}
|
||
NormalizedDevShape::SelfhostDetectFormatP3 => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_selfhost_if_sum_p3_ext(module)
|
||
.expect("selfhost detect_format P3 normalization failed")
|
||
})),
|
||
// Phase 48-A: P4 minimal normalization
|
||
NormalizedDevShape::Pattern4ContinueMinimal => catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_pattern4_continue_minimal(module)
|
||
.expect("P4 normalization failed")
|
||
})),
|
||
// Phase 48-B: JsonParser continue skip_ws (array/object)
|
||
NormalizedDevShape::JsonparserParseArrayContinueSkipWs => {
|
||
catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_jsonparser_parse_array_continue_skip_ws(
|
||
module,
|
||
)
|
||
.expect("P4 array normalization failed")
|
||
}))
|
||
}
|
||
NormalizedDevShape::JsonparserParseObjectContinueSkipWs => {
|
||
catch_unwind(AssertUnwindSafe(|| {
|
||
crate::mir::join_ir::normalized::normalize_jsonparser_parse_object_continue_skip_ws(
|
||
module,
|
||
)
|
||
.expect("P4 object normalization failed")
|
||
}))
|
||
}
|
||
// Phase 89: Continue + Early Return pattern (dev-only, delegates to P2 for now)
|
||
NormalizedDevShape::PatternContinueReturnMinimal => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern2_minimal(module)))
|
||
}
|
||
// Phase 90: Parse String Composite pattern (dev-only, delegates to P2 for now)
|
||
NormalizedDevShape::ParseStringCompositeMinimal => {
|
||
catch_unwind(AssertUnwindSafe(|| normalize_pattern2_minimal(module)))
|
||
}
|
||
};
|
||
|
||
match result {
|
||
Ok(norm) => Ok(norm),
|
||
Err(_) => Err(JoinIrVmBridgeError::new(format!(
|
||
"[joinir/bridge/normalized] normalization failed for shape {:?}",
|
||
shape
|
||
))),
|
||
}
|
||
}
|
||
|
||
#[cfg(feature = "normalized_dev")]
|
||
fn try_normalized_direct_bridge(
|
||
module: &JoinModule,
|
||
meta: &JoinFuncMetaMap,
|
||
shapes: &[NormalizedDevShape],
|
||
allow_structured_fallback: bool,
|
||
use_env_guard: bool,
|
||
) -> Result<Option<MirModule>, JoinIrVmBridgeError> {
|
||
if shapes.is_empty() {
|
||
crate::mir::join_ir_vm_bridge::normalized_bridge::log_dev(
|
||
"fallback",
|
||
"normalized dev enabled but shape unsupported; using Structured path",
|
||
true,
|
||
);
|
||
return if allow_structured_fallback {
|
||
Ok(None)
|
||
} else {
|
||
Err(JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] canonical normalized route requested but shape unsupported",
|
||
))
|
||
};
|
||
}
|
||
|
||
let exec = || {
|
||
let debug = crate::mir::join_ir::normalized::dev_env::normalized_dev_logs_enabled();
|
||
for &shape in shapes {
|
||
if debug {
|
||
crate::mir::join_ir_vm_bridge::normalized_bridge::log_dev(
|
||
"direct",
|
||
format!("attempting normalized→MIR for {:?}", shape),
|
||
false,
|
||
);
|
||
}
|
||
match normalize_for_shape(module, shape) {
|
||
Ok(norm) => {
|
||
let mir =
|
||
lower_normalized_to_mir_minimal(&norm, meta, allow_structured_fallback)?;
|
||
crate::mir::join_ir_vm_bridge::normalized_bridge::log_dev(
|
||
"direct",
|
||
format!(
|
||
"normalized→MIR succeeded (shape={:?}, functions={})",
|
||
shape,
|
||
norm.functions.len()
|
||
),
|
||
false,
|
||
);
|
||
return Ok(Some(mir));
|
||
}
|
||
Err(err) => {
|
||
if debug {
|
||
crate::mir::join_ir_vm_bridge::normalized_bridge::log_dev(
|
||
"direct",
|
||
format!(
|
||
"{:?} normalization failed: {} (continuing)",
|
||
shape, err.message
|
||
),
|
||
false,
|
||
);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if allow_structured_fallback {
|
||
Ok(None)
|
||
} else {
|
||
Err(JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] canonical normalized route failed for all shapes",
|
||
))
|
||
}
|
||
};
|
||
|
||
if use_env_guard {
|
||
crate::mir::join_ir::normalized::dev_env::with_dev_env_if_unset(exec)
|
||
} else {
|
||
exec()
|
||
}
|
||
}
|
||
|
||
/// JoinIR → MIR の単一入口。Mode に応じて Normalized/Structured 経路を選択。
|
||
///
|
||
/// Phase 45: JoinIrMode 導入による統一ルーティング:
|
||
/// - Canonical P2-Core shapes → 常に Normalized→MIR(direct)(mode 無視)
|
||
/// - NormalizedDev → サポート形状のみ Normalized path、それ以外 Structured path
|
||
/// - StructuredOnly | NormalizedCanonical → Structured path
|
||
pub(crate) fn bridge_joinir_to_mir_with_meta(
|
||
module: &JoinModule,
|
||
meta: &JoinFuncMetaMap,
|
||
) -> Result<MirModule, JoinIrVmBridgeError> {
|
||
#[cfg(feature = "normalized_dev")]
|
||
{
|
||
let mode = current_joinir_mode();
|
||
|
||
// Canonical set (P2/P3/P4): Always uses Normalized→MIR(direct) regardless of mode/env
|
||
let canonical_shapes = shape_guard::canonical_shapes(module);
|
||
if !canonical_shapes.is_empty() {
|
||
match try_normalized_direct_bridge(module, meta, &canonical_shapes, false, false)? {
|
||
Some(mir) => return Ok(mir),
|
||
None => {
|
||
return Err(JoinIrVmBridgeError::new(
|
||
"[joinir/bridge] canonical normalized route returned None unexpectedly",
|
||
))
|
||
}
|
||
}
|
||
}
|
||
|
||
// Phase 45: Mode によるルーティング分岐
|
||
match mode {
|
||
JoinIrMode::NormalizedDev => {
|
||
// サポート形状のみ Normalized path を試行、失敗時は Structured fallback
|
||
let shapes = shape_guard::direct_shapes(module);
|
||
match try_normalized_direct_bridge(module, meta, &shapes, true, true)? {
|
||
Some(mir) => return Ok(mir),
|
||
None => {} // Fallback to Structured
|
||
}
|
||
}
|
||
JoinIrMode::StructuredOnly | JoinIrMode::NormalizedCanonical => {
|
||
// Structured path のみ使用
|
||
// (NormalizedCanonical は将来 Phase 46+ で canonical migration 完了後に専用経路を持つ)
|
||
}
|
||
}
|
||
}
|
||
|
||
lower_joinir_structured_to_mir_with_meta(module, meta)
|
||
}
|
||
|
||
/// JoinIR → MIR(メタなし)呼び出しのユーティリティ。
|
||
pub(crate) fn bridge_joinir_to_mir(module: &JoinModule) -> Result<MirModule, JoinIrVmBridgeError> {
|
||
let empty_meta: JoinFuncMetaMap = BTreeMap::new();
|
||
bridge_joinir_to_mir_with_meta(module, &empty_meta)
|
||
}
|