VM-side work on values and objects to make it possible to locate fields.

This commit is contained in:
Jesse Brault 2026-03-13 00:01:55 -05:00
parent 55a84a98b3
commit 54e2a170a2
6 changed files with 82 additions and 6 deletions

View File

@ -327,12 +327,14 @@ mod tests {
} }
let mut ir_functions = compilation_unit.to_ir(&symbol_table); let mut ir_functions = compilation_unit.to_ir(&symbol_table);
let mut constants_table = ConstantsTable::new();
for ir_function in &mut ir_functions { for ir_function in &mut ir_functions {
println!("{}", ir_function); println!("{}", ir_function);
}
let mut constants_table = ConstantsTable::new();
for ir_function in &mut ir_functions {
let (_, stack_size) = ir_function.assign_registers(8); let (_, stack_size) = ir_function.assign_registers(8);
// let vm_function = ir_function.assemble(stack_size, &mut constants_table); let vm_function = ir_function.assemble(stack_size, &mut constants_table);
// println!("{}", vm_function) println!("{}", vm_function)
} }
} }
} }

View File

@ -27,8 +27,18 @@ pub enum IrExpression {
impl IrExpression { impl IrExpression {
pub fn move_operand(&self, constants_table: &mut ConstantsTable) -> MoveOperand { pub fn move_operand(&self, constants_table: &mut ConstantsTable) -> MoveOperand {
match self { match self {
IrExpression::Field(self_variable, _) => { IrExpression::Field(self_variable, field_index) => {
todo!() match self_variable.borrow().descriptor() {
IrVariableDescriptor::VirtualRegister(register_self_variable) => {
MoveOperand::Location(Location::RegisterField(
register_self_variable.assigned_register(),
*field_index,
))
}
IrVariableDescriptor::Stack(stack_self_variable) => MoveOperand::Location(
Location::StackFrameOffsetField(stack_self_variable.offset(), *field_index),
),
}
} }
IrExpression::Parameter(ir_parameter) => { IrExpression::Parameter(ir_parameter) => {
MoveOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset())) MoveOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset()))
@ -181,7 +191,17 @@ impl IrExpression {
pub fn return_operand(&self, constants_table: &mut ConstantsTable) -> ReturnOperand { pub fn return_operand(&self, constants_table: &mut ConstantsTable) -> ReturnOperand {
match self { match self {
IrExpression::Field(self_variable, field_index) => { IrExpression::Field(self_variable, field_index) => {
todo!() match self_variable.borrow().descriptor() {
IrVariableDescriptor::VirtualRegister(self_register_variable) => {
ReturnOperand::Location(Location::RegisterField(
self_register_variable.assigned_register(),
*field_index,
))
}
IrVariableDescriptor::Stack(self_stack_variable) => ReturnOperand::Location(
Location::StackFrameOffsetField(self_stack_variable.offset(), *field_index),
),
}
} }
IrExpression::Parameter(ir_parameter) => { IrExpression::Parameter(ir_parameter) => {
ReturnOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset())) ReturnOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset()))

View File

@ -86,6 +86,8 @@ impl Display for Instruction {
pub enum Location { pub enum Location {
Register(Register), Register(Register),
StackFrameOffset(StackFrameOffset), StackFrameOffset(StackFrameOffset),
RegisterField(Register, FieldIndex),
StackFrameOffsetField(StackFrameOffset, FieldIndex),
} }
impl Display for Location { impl Display for Location {
@ -101,6 +103,16 @@ impl Display for Location {
write!(f, "fp{}", offset) write!(f, "fp{}", offset)
} }
} }
Location::RegisterField(register, field_index) => {
write!(f, "r{}.{}", register, field_index)
}
Location::StackFrameOffsetField(offset, field_index) => {
if offset.is_positive() || *offset == 0 {
write!(f, "fp+{}.{}", offset, field_index)
} else {
write!(f, "fp-{}.{}", offset, field_index)
}
}
} }
} }
} }

View File

@ -7,6 +7,16 @@ pub struct Object {
fields: [Value], fields: [Value],
} }
impl Object {
pub fn fields(&self) -> &[Value] {
&self.fields
}
pub fn fields_mut(&mut self) -> &mut [Value] {
&mut self.fields
}
}
pub struct ObjectHeader { pub struct ObjectHeader {
field_count: usize, field_count: usize,
} }

View File

@ -1,3 +1,4 @@
use crate::vm::object::Object;
use std::fmt::{Display, Formatter}; use std::fmt::{Display, Formatter};
use std::rc::Rc; use std::rc::Rc;
@ -36,6 +37,14 @@ impl Value {
_ => panic!("Attempt to unwrap String; found {:?}", self), _ => panic!("Attempt to unwrap String; found {:?}", self),
} }
} }
pub fn unwrap_object(&self) -> &Object {
todo!()
}
pub fn unwrap_object_mut(&mut self) -> &mut Object {
todo!()
}
} }
impl Display for Value { impl Display for Value {

View File

@ -20,6 +20,16 @@ pub fn load_value<'a>(
)); ));
&stack[value_index] &stack[value_index]
} }
Location::RegisterField(register, field_index) => {
&registers[*register].unwrap_object().fields()[*field_index]
}
Location::StackFrameOffsetField(offset, field_index) => {
let value_index = fp.checked_add_signed(*offset).expect(&format!(
"Overflow when adding offset {} to fp {}",
*offset, fp
));
&stack[value_index].unwrap_object().fields()[*field_index]
}
} }
} }
@ -51,5 +61,18 @@ pub fn put_value(
)); ));
current_frame.stack_mut()[target_index] = value; current_frame.stack_mut()[target_index] = value;
} }
Location::RegisterField(register, field_index) => {
registers[*register].unwrap_object_mut().fields_mut()[*field_index] = value;
}
Location::StackFrameOffsetField(offset, field_index) => {
let fp = current_frame.fp();
let target_index = fp.checked_add_signed(*offset).expect(&format!(
"Failed to calculate target index from fp + offset ({} + {})",
fp, offset
));
current_frame.stack_mut()[target_index]
.unwrap_object_mut()
.fields_mut()[*field_index] = value;
}
} }
} }