Files
hakorune/src/mir/builder/calls/materializer.rs
nyash-codex f9d100ce01 chore: Phase 25.1 完了 - LoopForm v2/Stage1 CLI/環境変数削減 + Phase 26-D からの変更
Phase 25.1 完了成果:
-  LoopForm v2 テスト・ドキュメント・コメント完備
  - 4ケース(A/B/C/D)完全テストカバレッジ
  - 最小再現ケース作成(SSAバグ調査用)
  - SSOT文書作成(loopform_ssot.md)
  - 全ソースに [LoopForm] コメントタグ追加

-  Stage-1 CLI デバッグ環境構築
  - stage1_cli.hako 実装
  - stage1_bridge.rs ブリッジ実装
  - デバッグツール作成(stage1_debug.sh/stage1_minimal.sh)
  - アーキテクチャ改善提案文書

-  環境変数削減計画策定
  - 25変数の完全調査・分類
  - 6段階削減ロードマップ(25→5、80%削減)
  - 即時削除可能変数特定(NYASH_CONFIG/NYASH_DEBUG)

Phase 26-D からの累積変更:
- PHI実装改善(ExitPhiBuilder/HeaderPhiBuilder等)
- MIRビルダーリファクタリング
- 型伝播・最適化パス改善
- その他約300ファイルの累積変更

🎯 技術的成果:
- SSAバグ根本原因特定(条件分岐内loop変数変更)
- Region+next_iパターン適用完了(UsingCollectorBox等)
- LoopFormパターン文書化・テスト化完了
- セルフホスティング基盤強化

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: ChatGPT <noreply@openai.com>
Co-Authored-By: Task Assistant <task@anthropic.com>
2025-11-21 06:25:17 +09:00

129 lines
5.4 KiB
Rust
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.

/*!
* CallMaterializerBox - Call前処理・準備専用箱
*
* 箱理論の実践:
* - 箱にする: Call発行前の前処理を1箱に集約
* - 境界を作る: フォールバック処理・receiver実体化を分離
* - 状態最小: MirBuilderを引数として受け取る所有しない
*
* 責務:
* - try_global_fallback_handlers: Global関数のフォールバック処理
* - materialize_receiver_in_callee: Receiverの実体化pinning
* - Call発行前の準備処理全般
*/
use crate::mir::builder::{EffectMask, MirBuilder, MirInstruction, ValueId};
use crate::mir::definitions::call_unified::Callee;
/// Call前処理・準備専用箱
///
/// 箱理論:
/// - 単一責務: Call発行前の前処理のみ
/// - 状態レス: MirBuilderを引数で受け取る設計
/// - サポート役: 本体のCall発行をサポートする役割
pub struct CallMaterializerBox;
impl CallMaterializerBox {
/// Try fallback handlers for global functions
///
/// フォールバック処理の優先順位:
/// 1. Dev-only safety: condition_fn → always-true predicate
/// 2. Direct module function: module内の関数を直接呼び出し
/// 3. Unique static-method: name+arity → Box.name/Arity へ変換
pub fn try_global_fallback_handlers(
builder: &mut MirBuilder,
dst: Option<ValueId>,
name: &str,
args: &[ValueId],
) -> Result<Option<()>, String> {
// 0) Dev-only safety: treat condition_fn as always-true predicate when missing
if name == "condition_fn" {
let dstv = dst.unwrap_or_else(|| builder.next_value_id());
// Emit integer constant via ConstantEmissionBox
let one = crate::mir::builder::emission::constant::emit_integer(builder, 1);
if dst.is_none() {
// If a destination was not provided, copy into the allocated dstv
builder.emit_instruction(MirInstruction::Copy {
dst: dstv,
src: one,
})?;
crate::mir::builder::metadata::propagate::propagate(builder, one, dstv);
} else {
// If caller provided dst, ensure the computed value lands there
builder.emit_instruction(MirInstruction::Copy {
dst: dstv,
src: one,
})?;
crate::mir::builder::metadata::propagate::propagate(builder, one, dstv);
}
return Ok(Some(()));
}
// 1) Direct module function fallback: call by name if present
if let Some(ref module) = builder.current_module {
if module.functions.contains_key(name) {
let dstv = dst.unwrap_or_else(|| builder.next_value_id());
let name_const =
crate::mir::builder::name_const::make_name_const_result(builder, name)?;
builder.emit_instruction(MirInstruction::Call {
dst: Some(dstv),
func: name_const,
callee: Some(Callee::Global(name.to_string())),
args: args.to_vec(),
effects: EffectMask::IO,
})?;
builder.annotate_call_result_from_func_name(dstv, name);
return Ok(Some(()));
}
}
// 2) Unique static-method fallback: name+arity → Box.name/Arity
if let Some(cands) = builder.static_method_index.get(name) {
let mut matches: Vec<(String, usize)> = cands
.iter()
.cloned()
.filter(|(_, ar)| *ar == args.len())
.collect();
if matches.len() == 1 {
let (bx, _arity) = matches.remove(0);
let func_name = format!("{}.{}{}", bx, name, format!("/{}", args.len()));
// Emit legacy call directly to preserve behavior
let dstv = dst.unwrap_or_else(|| builder.next_value_id());
let name_const =
crate::mir::builder::name_const::make_name_const_result(builder, &func_name)?;
builder.emit_instruction(MirInstruction::Call {
dst: Some(dstv),
func: name_const,
callee: Some(Callee::Global(func_name.clone())),
args: args.to_vec(),
effects: EffectMask::IO,
})?;
// annotate
builder.annotate_call_result_from_func_name(dstv, func_name);
return Ok(Some(()));
}
}
Ok(None)
}
/// Ensure receiver is materialized in Callee::Method
///
/// Receiver実体化の目的:
/// - receiverをスロットにpinningして、start_new_blockで伝播可能に
/// - SSA不変条件の保持receiverが常に定義済みであることを保証
/// - デバッグトレース出力NYASH_BUILDER_TRACE_RECV=1
pub fn materialize_receiver_in_callee(
_builder: &mut MirBuilder,
callee: Callee,
) -> Result<Callee, String> {
// Phase 25.1j+:
// Receiver 実体化pinning + LocalSSAは ReceiverMaterializationBox
// crate::mir::builder::receiver側に一本化したよ。
// ここでは Callee 構造は変更せず、そのまま返す。
//
// NYASH_BUILDER_TRACE_RECV は新しい receiver.rs 側で扱う。
Ok(callee)
}
}