MIR builder (modularized): fix Call emission to new schema; switch AwaitExpression; drop legacy Array* cases. Tests: fix optimizer test get_block signature. Interpreter: annotate unreachable legacy constructor path in execute_new().
This commit is contained in:
@ -106,6 +106,8 @@ impl NyashInterpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unified registry is authoritative; legacy implementation removed
|
// Unified registry is authoritative; legacy implementation removed
|
||||||
|
// NOTE: Legacy constructor path below is unreachable and kept only for reference during migration.
|
||||||
|
// TODO(migration): remove legacy block after all callsites are confirmed on Unified Registry.
|
||||||
return Err(RuntimeError::UndefinedClass { name: class.to_string() });
|
return Err(RuntimeError::UndefinedClass { name: class.to_string() });
|
||||||
|
|
||||||
// Try basic type constructors first
|
// Try basic type constructors first
|
||||||
|
|||||||
@ -182,14 +182,22 @@ impl MirBuilder {
|
|||||||
for arg in args {
|
for arg in args {
|
||||||
arg_values.push(self.build_expression(arg)?);
|
arg_values.push(self.build_expression(arg)?);
|
||||||
}
|
}
|
||||||
|
// Prepare function identifier as a const String value id
|
||||||
|
let func_val = self.value_gen.next();
|
||||||
|
self.emit_instruction(MirInstruction::Const {
|
||||||
|
dst: func_val,
|
||||||
|
value: ConstValue::String(name),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
// Destination for the call result
|
||||||
let dst = self.value_gen.next();
|
let dst = self.value_gen.next();
|
||||||
|
|
||||||
// For now, treat all function calls as Box method calls
|
// Emit Call with conservative read effects
|
||||||
self.emit_instruction(MirInstruction::Call {
|
self.emit_instruction(MirInstruction::Call {
|
||||||
dst,
|
dst: Some(dst),
|
||||||
function: name,
|
func: func_val,
|
||||||
arguments: arg_values,
|
args: arg_values,
|
||||||
|
effects: EffectMask::READ.add(Effect::ReadHeap),
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
Ok(dst)
|
Ok(dst)
|
||||||
@ -461,49 +469,11 @@ impl MirBuilder {
|
|||||||
self.build_field_access(*object.clone(), field.clone())
|
self.build_field_access(*object.clone(), field.clone())
|
||||||
},
|
},
|
||||||
|
|
||||||
ASTNode::ArrayAccess { array, index, .. } => {
|
|
||||||
// Build array and index expressions
|
|
||||||
let array_val = self.build_expression(*array)?;
|
|
||||||
let index_val = self.build_expression(*index)?;
|
|
||||||
|
|
||||||
// Generate ArrayGet instruction
|
|
||||||
let result = self.value_gen.next();
|
|
||||||
self.emit_instruction(MirInstruction::ArrayGet {
|
|
||||||
dst: result,
|
|
||||||
array: array_val,
|
|
||||||
index: index_val,
|
|
||||||
effects: EffectMask::READ.add(Effect::ReadHeap),
|
|
||||||
})?;
|
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
},
|
|
||||||
|
|
||||||
ASTNode::ArrayLiteral { elements, .. } => {
|
|
||||||
// Create new ArrayBox
|
|
||||||
let array_val = self.build_new_expression("ArrayBox".to_string(), vec![])?;
|
|
||||||
|
|
||||||
// Add each element
|
|
||||||
for elem in elements {
|
|
||||||
let elem_val = self.build_expression(elem)?;
|
|
||||||
|
|
||||||
// array.push(elem)
|
|
||||||
self.emit_instruction(MirInstruction::BoxCall {
|
|
||||||
dst: None,
|
|
||||||
box_val: array_val,
|
|
||||||
method: "push".to_string(),
|
|
||||||
args: vec![elem_val],
|
|
||||||
effects: EffectMask::WRITE.add(Effect::WriteHeap),
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(array_val)
|
|
||||||
},
|
|
||||||
|
|
||||||
ASTNode::New { class, arguments, .. } => {
|
ASTNode::New { class, arguments, .. } => {
|
||||||
self.build_new_expression(class.clone(), arguments.clone())
|
self.build_new_expression(class.clone(), arguments.clone())
|
||||||
},
|
},
|
||||||
|
|
||||||
ASTNode::Await { expression, .. } => {
|
ASTNode::AwaitExpression { expression, .. } => {
|
||||||
self.build_await_expression(*expression)
|
self.build_await_expression(*expression)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -511,7 +511,7 @@ mod tests {
|
|||||||
|
|
||||||
// Ensure TypeOp remains in bb0
|
// Ensure TypeOp remains in bb0
|
||||||
let f = module.get_function("main").unwrap();
|
let f = module.get_function("main").unwrap();
|
||||||
let block = f.get_block(&bb0).unwrap();
|
let block = f.get_block(bb0).unwrap();
|
||||||
let has_typeop = block.all_instructions().any(|i| matches!(i, MirInstruction::TypeOp { .. }));
|
let has_typeop = block.all_instructions().any(|i| matches!(i, MirInstruction::TypeOp { .. }));
|
||||||
assert!(has_typeop, "TypeOp should not be dropped by DCE when used by print");
|
assert!(has_typeop, "TypeOp should not be dropped by DCE when used by print");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user