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 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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()))
|
||||||
|
|||||||
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -20,6 +20,16 @@ pub fn load_value<'a>(
|
|||||||
));
|
));
|
||||||
&stack[value_index]
|
&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;
|
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