fix(mir/builder): use function-local ValueId throughout MIR builder
Phase 25.1b: Complete SSA fix - eliminate all global ValueId usage in function contexts. Root cause: ~75 locations throughout MIR builder were using global value generator (self.value_gen.next()) instead of function-local allocator (f.next_value_id()), causing SSA verification failures and runtime "use of undefined value" errors. Solution: - Added next_value_id() helper that automatically chooses correct allocator - Fixed 19 files with ~75 occurrences of ValueId allocation - All function-context allocations now use function-local IDs Files modified: - src/mir/builder/utils.rs: Added next_value_id() helper, fixed 8 locations - src/mir/builder/builder_calls.rs: 17 fixes - src/mir/builder/ops.rs: 8 fixes - src/mir/builder/stmts.rs: 7 fixes - src/mir/builder/emission/constant.rs: 6 fixes - src/mir/builder/rewrite/*.rs: 10 fixes - + 13 other files Verification: - cargo build --release: SUCCESS - Simple tests with NYASH_VM_VERIFY_MIR=1: Zero undefined errors - Multi-parameter static methods: All working Known remaining: ValueId(22) in Stage-B (separate issue to investigate) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -93,7 +93,7 @@ impl super::MirBuilder {
|
||||
if let CallTarget::Global(ref name) = target {
|
||||
// 0) Dev-only safety: treat condition_fn as always-true predicate when missing
|
||||
if name == "condition_fn" {
|
||||
let dstv = dst.unwrap_or_else(|| self.value_gen.next());
|
||||
let dstv = dst.unwrap_or_else(|| self.next_value_id());
|
||||
// Emit integer constant via ConstantEmissionBox
|
||||
let one = crate::mir::builder::emission::constant::emit_integer(self, 1);
|
||||
if dst.is_none() {
|
||||
@ -110,7 +110,7 @@ impl super::MirBuilder {
|
||||
// 1) Direct module function fallback: call by name if present
|
||||
if let Some(ref module) = self.current_module {
|
||||
if module.functions.contains_key(name) {
|
||||
let dstv = dst.unwrap_or_else(|| self.value_gen.next());
|
||||
let dstv = dst.unwrap_or_else(|| self.next_value_id());
|
||||
let name_const = match crate::mir::builder::name_const::make_name_const_result(self, name) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e),
|
||||
@ -137,7 +137,7 @@ impl super::MirBuilder {
|
||||
let (bx, _arity) = matches.remove(0);
|
||||
let func_name = format!("{}.{}{}", bx, name, format!("/{}", arity_for_try));
|
||||
// Emit legacy call directly to preserve behavior
|
||||
let dstv = dst.unwrap_or_else(|| self.value_gen.next());
|
||||
let dstv = dst.unwrap_or_else(|| self.next_value_id());
|
||||
let name_const = match crate::mir::builder::name_const::make_name_const_result(self, &func_name) {
|
||||
Ok(v) => v,
|
||||
Err(e) => return Err(e),
|
||||
@ -314,7 +314,7 @@ impl super::MirBuilder {
|
||||
// Create a string constant for the function name via NameConstBox
|
||||
let name_const = crate::mir::builder::name_const::make_name_const_result(self, &name)?;
|
||||
// Allocate a destination if not provided so we can annotate it
|
||||
let actual_dst = if let Some(d) = dst { d } else { self.value_gen.next() };
|
||||
let actual_dst = if let Some(d) = dst { d } else { self.next_value_id() };
|
||||
let mut args = args;
|
||||
crate::mir::builder::ssa::local::finalize_args(self, &mut args);
|
||||
self.emit_instruction(MirInstruction::Call {
|
||||
@ -416,7 +416,7 @@ impl super::MirBuilder {
|
||||
}
|
||||
ASTNode::New { class, arguments, .. } if class == "IntegerBox" && arguments.len() == 1 => {
|
||||
let iv = match self.build_expression(arguments[0].clone()) { Ok(v) => v, Err(e) => return Some(Err(e)) };
|
||||
let fv = self.value_gen.next();
|
||||
let fv = self.next_value_id();
|
||||
if let Err(e) = self.emit_instruction(MirInstruction::TypeOp { dst: fv, op: TypeOpKind::Cast, value: iv, ty: MirType::Float }) { return Some(Err(e)); }
|
||||
math_args.push(fv);
|
||||
}
|
||||
@ -429,13 +429,13 @@ impl super::MirBuilder {
|
||||
}
|
||||
}
|
||||
// new MathBox()
|
||||
let math_recv = self.value_gen.next();
|
||||
let math_recv = self.next_value_id();
|
||||
if let Err(e) = self.emit_constructor_call(math_recv, "MathBox".to_string(), vec![]) { return Some(Err(e)); }
|
||||
self.value_origin_newbox.insert(math_recv, "MathBox".to_string());
|
||||
// birth()
|
||||
if let Err(e) = self.emit_method_call(None, math_recv, "birth".to_string(), vec![]) { return Some(Err(e)); }
|
||||
// call method
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
if let Err(e) = self.emit_method_call(Some(dst), math_recv, name.to_string(), math_args) { return Some(Err(e)); }
|
||||
Some(Ok(dst))
|
||||
}
|
||||
@ -458,7 +458,7 @@ impl super::MirBuilder {
|
||||
let iface = env_field.as_str();
|
||||
let m = method;
|
||||
let mut extern_call = |iface_name: &str, method_name: &str, effects: EffectMask, returns: bool| -> Result<ValueId, String> {
|
||||
let result_id = self.value_gen.next();
|
||||
let result_id = self.next_value_id();
|
||||
self.emit_instruction(MirInstruction::ExternCall { dst: if returns { Some(result_id) } else { None }, iface_name: iface_name.to_string(), method_name: method_name.to_string(), args: arg_values.clone(), effects })?;
|
||||
if returns {
|
||||
Ok(result_id)
|
||||
@ -490,7 +490,7 @@ impl super::MirBuilder {
|
||||
for a in arguments {
|
||||
match self.build_expression(a.clone()) { Ok(v) => arg_values.push(v), Err(e) => return Some(Err(e)) }
|
||||
}
|
||||
let result_id = self.value_gen.next();
|
||||
let result_id = self.next_value_id();
|
||||
let fun_name = format!("{}.{}{}", cls_name, method, format!("/{}", arg_values.len()));
|
||||
let fun_val = match crate::mir::builder::name_const::make_name_const_result(self, &fun_name) {
|
||||
Ok(v) => v,
|
||||
@ -541,7 +541,7 @@ impl super::MirBuilder {
|
||||
if let Some(type_name) = special_handlers::extract_string_literal(&args[1]) {
|
||||
let val = self.build_expression(args[0].clone())?;
|
||||
let ty = special_handlers::parse_type_name_to_mir(&type_name);
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
let op = if name == "isType" {
|
||||
TypeOpKind::Check
|
||||
} else {
|
||||
@ -569,7 +569,7 @@ impl super::MirBuilder {
|
||||
|
||||
// Special-case: global str(x) → x.str() に正規化(内部は関数へ統一される)
|
||||
if name == "str" && arg_values.len() == 1 {
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
// Use unified method emission; downstream rewrite will functionize as needed
|
||||
self.emit_method_call(Some(dst), arg_values[0], "str".to_string(), vec![])?;
|
||||
return Ok(dst);
|
||||
@ -582,7 +582,7 @@ impl super::MirBuilder {
|
||||
|
||||
if !use_unified {
|
||||
// Legacy path
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
|
||||
// === ChatGPT5 Pro Design: Type-safe function call resolution ===
|
||||
// Resolve call target using new type-safe system; if it fails, try static-method fallback
|
||||
@ -599,7 +599,7 @@ impl super::MirBuilder {
|
||||
.collect();
|
||||
if matches.len() == 1 {
|
||||
let (bx, _arity) = matches.remove(0);
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
let func_name = format!("{}.{}{}", bx, name, format!("/{}", arg_values.len()));
|
||||
// Emit unified global call to the lowered static method function
|
||||
self.emit_unified_call(Some(dst), CallTarget::Global(func_name), arg_values)?;
|
||||
@ -619,7 +619,7 @@ impl super::MirBuilder {
|
||||
.collect();
|
||||
if cands.len() == 1 {
|
||||
let func_name = cands.remove(0);
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
self.emit_legacy_call(Some(dst), CallTarget::Global(func_name), arg_values)?;
|
||||
return Ok(dst);
|
||||
}
|
||||
@ -644,7 +644,7 @@ impl super::MirBuilder {
|
||||
Ok(dst)
|
||||
} else {
|
||||
// Unified path for builtins/externs
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
self.emit_unified_call(
|
||||
Some(dst),
|
||||
CallTarget::Global(name),
|
||||
@ -713,7 +713,7 @@ impl super::MirBuilder {
|
||||
let mut call_args = Vec::with_capacity(arity + 1);
|
||||
call_args.push(me_id);
|
||||
call_args.extend(arg_values.into_iter());
|
||||
let dst = self.value_gen.next();
|
||||
let dst = self.next_value_id();
|
||||
// Emit as unified global call to lowered function
|
||||
self.emit_unified_call(
|
||||
Some(dst),
|
||||
@ -762,7 +762,7 @@ impl super::MirBuilder {
|
||||
arg_values.push(self.build_expression(arg)?);
|
||||
}
|
||||
let parent_value = crate::mir::builder::emission::constant::emit_string(self, parent);
|
||||
let result_id = self.value_gen.next();
|
||||
let result_id = self.next_value_id();
|
||||
self.emit_box_or_plugin_call(
|
||||
Some(result_id),
|
||||
parent_value,
|
||||
|
||||
Reference in New Issue
Block a user