From 54e2a170a2f65720840a0c93f20a99a0279762c2 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Fri, 13 Mar 2026 00:01:55 -0500 Subject: [PATCH] VM-side work on values and objects to make it possible to locate fields. --- dmc-lib/src/ast/class.rs | 8 +++++--- dmc-lib/src/ir/ir_expression.rs | 26 +++++++++++++++++++++++--- dvm-lib/src/instruction.rs | 12 ++++++++++++ dvm-lib/src/vm/object.rs | 10 ++++++++++ dvm-lib/src/vm/value.rs | 9 +++++++++ dvm-lib/src/vm/value_util.rs | 23 +++++++++++++++++++++++ 6 files changed, 82 insertions(+), 6 deletions(-) diff --git a/dmc-lib/src/ast/class.rs b/dmc-lib/src/ast/class.rs index 4483ef9..d2834b0 100644 --- a/dmc-lib/src/ast/class.rs +++ b/dmc-lib/src/ast/class.rs @@ -327,12 +327,14 @@ mod tests { } let mut ir_functions = compilation_unit.to_ir(&symbol_table); - let mut constants_table = ConstantsTable::new(); for ir_function in &mut ir_functions { 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 vm_function = ir_function.assemble(stack_size, &mut constants_table); - // println!("{}", vm_function) + let vm_function = ir_function.assemble(stack_size, &mut constants_table); + println!("{}", vm_function) } } } diff --git a/dmc-lib/src/ir/ir_expression.rs b/dmc-lib/src/ir/ir_expression.rs index 3da22f2..88fa005 100644 --- a/dmc-lib/src/ir/ir_expression.rs +++ b/dmc-lib/src/ir/ir_expression.rs @@ -27,8 +27,18 @@ pub enum IrExpression { impl IrExpression { pub fn move_operand(&self, constants_table: &mut ConstantsTable) -> MoveOperand { match self { - IrExpression::Field(self_variable, _) => { - todo!() + IrExpression::Field(self_variable, field_index) => { + 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) => { MoveOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset())) @@ -181,7 +191,17 @@ impl IrExpression { pub fn return_operand(&self, constants_table: &mut ConstantsTable) -> ReturnOperand { match self { 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) => { ReturnOperand::Location(Location::StackFrameOffset(ir_parameter.stack_offset())) diff --git a/dvm-lib/src/instruction.rs b/dvm-lib/src/instruction.rs index 194475a..7a2f1de 100644 --- a/dvm-lib/src/instruction.rs +++ b/dvm-lib/src/instruction.rs @@ -86,6 +86,8 @@ impl Display for Instruction { pub enum Location { Register(Register), StackFrameOffset(StackFrameOffset), + RegisterField(Register, FieldIndex), + StackFrameOffsetField(StackFrameOffset, FieldIndex), } impl Display for Location { @@ -101,6 +103,16 @@ impl Display for Location { 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) + } + } } } } diff --git a/dvm-lib/src/vm/object.rs b/dvm-lib/src/vm/object.rs index a2b9ac4..482bbfe 100644 --- a/dvm-lib/src/vm/object.rs +++ b/dvm-lib/src/vm/object.rs @@ -7,6 +7,16 @@ pub struct Object { 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 { field_count: usize, } diff --git a/dvm-lib/src/vm/value.rs b/dvm-lib/src/vm/value.rs index be92a69..70fda00 100644 --- a/dvm-lib/src/vm/value.rs +++ b/dvm-lib/src/vm/value.rs @@ -1,3 +1,4 @@ +use crate::vm::object::Object; use std::fmt::{Display, Formatter}; use std::rc::Rc; @@ -36,6 +37,14 @@ impl Value { _ => 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 { diff --git a/dvm-lib/src/vm/value_util.rs b/dvm-lib/src/vm/value_util.rs index 752e5bd..25070da 100644 --- a/dvm-lib/src/vm/value_util.rs +++ b/dvm-lib/src/vm/value_util.rs @@ -20,6 +20,16 @@ pub fn load_value<'a>( )); &stack[value_index] } + Location::RegisterField(register, field_index) => { + ®isters[*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; } + 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; + } } }