VM-side work on values and objects to make it possible to locate fields.
This commit is contained in:
parent
55a84a98b3
commit
54e2a170a2
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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()))
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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,
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user