Skip to content

Commit

Permalink
Merge pull request #78 from sezna/alex/malloc-intrinsic
Browse files Browse the repository at this point in the history
add malloc intrinsic
  • Loading branch information
sezna authored Jun 29, 2024
2 parents 7bd6acb + be431d5 commit c3903bb
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 7 deletions.
26 changes: 21 additions & 5 deletions petr-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,9 @@ impl Lowerer {
return_destination: ReturnDestination,
) -> Result<Vec<IrOpcode>, LoweringError> {
let mut buf = vec![];
use petr_typecheck::Intrinsic::*;
match intrinsic {
petr_typecheck::Intrinsic::Puts(arg) => {
Puts(arg) => {
// puts takes one arg and it is a string
let arg_reg = self.fresh_reg();
buf.append(&mut self.lower_expr(arg, ReturnDestination::Reg(arg_reg))?);
Expand All @@ -283,10 +284,25 @@ impl Lowerer {
}
Ok(buf)
},
petr_typecheck::Intrinsic::Add(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Add),
petr_typecheck::Intrinsic::Multiply(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Multiply),
petr_typecheck::Intrinsic::Divide(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Divide),
petr_typecheck::Intrinsic::Subtract(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Subtract),
Add(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Add),
Multiply(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Multiply),
Divide(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Divide),
Subtract(lhs, rhs) => self.lower_arithmetic_op(lhs, rhs, return_destination, IrOpcode::Subtract),
Malloc(size) => {
let size_reg = self.fresh_reg();
let ptr_dest = self.fresh_reg();
buf.append(&mut self.lower_expr(size, ReturnDestination::Reg(size_reg))?);
buf.push(IrOpcode::Malloc(ptr_dest, size_reg));
match return_destination {
ReturnDestination::Reg(reg) => {
// `ptr_dest` will contain the ptr returned
// the user should check that the ptr is not null
// which would mean a failed allocation
buf.push(IrOpcode::Copy(reg, ptr_dest));
},
}
Ok(buf)
},
}
}

Expand Down
3 changes: 2 additions & 1 deletion petr-ir/src/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ ir_ops! {
Return "ret";
ReturnImmediate "reti" u64 imm;
PushPc "ppc";
StackPushImmediate "pushi" u64 imm
StackPushImmediate "pushi" u64 imm;
Malloc "malloc" Reg ptr_dest, Reg size
}

idx_map_key!(LabelId);
Expand Down
19 changes: 18 additions & 1 deletion petr-typecheck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,7 @@ pub enum Intrinsic {
Multiply(Box<TypedExpr>, Box<TypedExpr>),
Divide(Box<TypedExpr>, Box<TypedExpr>),
Subtract(Box<TypedExpr>, Box<TypedExpr>),
Malloc(Box<TypedExpr>),
}

impl std::fmt::Debug for Intrinsic {
Expand All @@ -318,6 +319,7 @@ impl std::fmt::Debug for Intrinsic {
Intrinsic::Multiply(lhs, rhs) => write!(f, "@multiply({:?}, {:?})", lhs, rhs),
Intrinsic::Divide(lhs, rhs) => write!(f, "@divide({:?}, {:?})", lhs, rhs),
Intrinsic::Subtract(lhs, rhs) => write!(f, "@subtract({:?}, {:?})", lhs, rhs),
Intrinsic::Malloc(size) => write!(f, "@malloc({:?})", size),
}
}
}
Expand Down Expand Up @@ -585,7 +587,22 @@ impl TypeCheck for ResolvedIntrinsic {
ty: tp!(int),
}
},
Malloc => todo!(),
Malloc => {
// malloc takes one integer (the number of bytes to allocate)
// and returns a pointer to the allocated memory
// will return `0` if the allocation fails
// in the future, this might change to _words_ of allocation,
// depending on the compilation target
if self.args.len() != 1 {
todo!("malloc arg len check");
}
let arg = self.args[0].type_check(ctx);
ctx.unify(&arg.ty(), &tp!(int));
TypedExpr::Intrinsic {
intrinsic: Intrinsic::Malloc(Box::new(arg)),
ty: tp!(int),
}
},
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions petr-vm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ function main() returns 'int ~hi(100)
expect!("Value(120)"),
)
}

#[test]
fn overflowing_sub() {
check(
Expand All @@ -139,6 +140,21 @@ function main() returns 'int - 0 1
expect!("Value(18446744073709551615)"),
)
}

#[test]
fn basic_malloc() {
check(
r#"
function main() returns 'int
let a = @malloc 1
let b = @malloc 1
let c = @malloc 5
let d = @malloc 1
d
"#,
expect!("Value(7)"),
)
}
}

pub struct Vm {
Expand Down Expand Up @@ -343,6 +359,13 @@ impl Vm {
self.state.program_counter = offset;
Ok(Continue)
},
IrOpcode::Malloc(ptr_dest, size) => {
let size = self.get_register(size)?;
let ptr = self.state.memory.len();
self.state.memory.resize(ptr + size.0 as usize, 0);
self.set_register(ptr_dest, Value(ptr as u64));
Ok(Continue)
},
}
}

Expand Down

0 comments on commit c3903bb

Please sign in to comment.