fix(builder): BoxCompilationContext clear()アプローチ確立
🎯 箱理論: swap累積バグを修正し、clear()で完全独立化を実現 ## 問題 - swap実装は ctx に変数が累積され、次のメソッドで汚染される - StageBArgsBox.resolve_src で ValueId(21) 未定義エラー ## 解決策 - swap → clear() に変更(開始時・終了時両方) - context_active mode: clear() のみ(完全独立) - legacy mode: saved_var_map で従来の挙動維持 ## 成果 ✅ StageBArgsBox.resolve_src - 成功! ❌ StageBBodyExtractorBox.build_body_src - 次の問題箇所(進展!) ## 実装 - src/mir/builder/builder_calls.rs: - 開始時: context_active なら clear()(swap削除) - 終了時: context_active なら clear()(swap back削除) - legacy mode: saved_var_map で復元 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Submodule docs/private updated: e54d615e5f...118726f606
@ -860,18 +860,6 @@ impl super::MirBuilder {
|
||||
params: Vec<String>,
|
||||
body: Vec<ASTNode>,
|
||||
) -> Result<(), String> {
|
||||
// 🎯 箱理論: コンテキスト分離(開始)
|
||||
// compilation_contextがある場合、その内容を既存のフィールドとswap
|
||||
// これにより、既存のコードを変更せずにコンテキスト分離を実現
|
||||
let context_active = self.compilation_context.is_some();
|
||||
if context_active {
|
||||
if let Some(ref mut ctx) = self.compilation_context {
|
||||
std::mem::swap(&mut self.variable_map, &mut ctx.variable_map);
|
||||
std::mem::swap(&mut self.value_origin_newbox, &mut ctx.value_origin_newbox);
|
||||
std::mem::swap(&mut self.value_types, &mut ctx.value_types);
|
||||
}
|
||||
}
|
||||
|
||||
// Derive static box context from function name prefix, e.g., "BoxName.method/N"
|
||||
let saved_static_ctx = self.current_static_box.clone();
|
||||
if let Some(pos) = func_name.find('.') {
|
||||
@ -880,6 +868,26 @@ impl super::MirBuilder {
|
||||
self.current_static_box = Some(box_name.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
// 🎯 箱理論: BoxCompilationContext と saved_var_map をモード別に管理
|
||||
// context_active = true の場合(BoxCompilationContext mode):
|
||||
// - clear() で完全独立化(各メソッドが汚染されない)
|
||||
// - swap は不要(累積バグの原因)
|
||||
// context_active = false の場合(Legacy mode):
|
||||
// - saved_var_map に退避して空から開始し、終了時に復元
|
||||
let context_active = self.compilation_context.is_some();
|
||||
let saved_var_map = if !context_active {
|
||||
Some(std::mem::take(&mut self.variable_map))
|
||||
} else {
|
||||
None
|
||||
};
|
||||
if context_active {
|
||||
// 🎯 箱理論: 完全独立化(clear のみ、swap 不要)
|
||||
self.variable_map.clear();
|
||||
self.value_origin_newbox.clear();
|
||||
self.value_types.clear();
|
||||
}
|
||||
|
||||
let signature = function_lowering::prepare_static_method_signature(
|
||||
func_name,
|
||||
¶ms,
|
||||
@ -890,7 +898,6 @@ impl super::MirBuilder {
|
||||
let function = super::MirFunction::new(signature, entry);
|
||||
let saved_function = self.current_function.take();
|
||||
let saved_block = self.current_block.take();
|
||||
let saved_var_map = std::mem::take(&mut self.variable_map);
|
||||
self.current_function = Some(function);
|
||||
self.current_block = Some(entry);
|
||||
self.ensure_block_exists(entry)?;
|
||||
@ -952,20 +959,22 @@ impl super::MirBuilder {
|
||||
}
|
||||
self.current_function = saved_function;
|
||||
self.current_block = saved_block;
|
||||
self.variable_map = saved_var_map;
|
||||
|
||||
// 🎯 箱理論: モード別に状態を復元
|
||||
if context_active {
|
||||
// 🎯 BoxCompilationContext mode: clear のみ(次回も完全独立)
|
||||
// swap は不要(累積バグを防ぐ)
|
||||
self.variable_map.clear();
|
||||
self.value_origin_newbox.clear();
|
||||
self.value_types.clear();
|
||||
} else if let Some(saved) = saved_var_map {
|
||||
// 従来モード: Main.main 側の variable_map を元に戻す
|
||||
self.variable_map = saved;
|
||||
}
|
||||
|
||||
// Restore static box context
|
||||
self.current_static_box = saved_static_ctx;
|
||||
|
||||
// 🎯 箱理論: コンテキスト分離(終了)
|
||||
// swap backでコンテキストに変更を保存
|
||||
if context_active {
|
||||
if let Some(ref mut ctx) = self.compilation_context {
|
||||
std::mem::swap(&mut self.variable_map, &mut ctx.variable_map);
|
||||
std::mem::swap(&mut self.value_origin_newbox, &mut ctx.value_origin_newbox);
|
||||
std::mem::swap(&mut self.value_types, &mut ctx.value_types);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ static box Stage1UsingResolverMini {
|
||||
|
||||
/// Verify MIR/SSA for ParserBox.parse_program2 in isolation by compiling a small wrapper.
|
||||
#[test]
|
||||
fn mir_parserbox_parse_program2_verifies() {
|
||||
fn mir_parserbox_parse_program2_harness_parses_minimal_source() {
|
||||
// Minimal wrapper that brings ParserBox into scope and calls parse_program2.
|
||||
let src = r#"
|
||||
using lang.compiler.parser.parser_box as ParserBox
|
||||
@ -84,15 +84,16 @@ static box ParserBoxHarness {
|
||||
}
|
||||
"#;
|
||||
|
||||
let ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok");
|
||||
// Stage‑3 構文キーワード `local` を含む最小ソースを ParserBoxHarness でパースする
|
||||
let harness_ast: ASTNode = NyashParser::parse_from_string(src).expect("parse ok");
|
||||
let mut mc = MirCompiler::with_options(false);
|
||||
let cr = mc.compile(ast).expect("compile");
|
||||
let cr = mc.compile(harness_ast).expect("compile");
|
||||
|
||||
let mut verifier = MirVerifier::new();
|
||||
if let Err(errors) = verifier.verify_module(&cr.module) {
|
||||
for e in &errors {
|
||||
eprintln!("[mir-verify] {}", e);
|
||||
}
|
||||
panic!("MIR verification failed for ParserBoxHarness.parse_program2");
|
||||
panic!("MIR verification failed for ParserBoxHarness");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user