Skip to content

Commit

Permalink
Dealloc vecs when leaving scope (#42)
Browse files Browse the repository at this point in the history
* dealloc vecs

* fix

* fix

* clippy
  • Loading branch information
jarkonik authored Dec 1, 2021
1 parent 1007db5 commit d4ac876
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 35 deletions.
20 changes: 20 additions & 0 deletions src/compiler/frame.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::compiler::var::Var;
use crate::llvm;
use std::collections::HashMap;
use std::convert::TryInto;

pub struct Frame {
env: HashMap<String, Var>,
Expand All @@ -27,4 +28,23 @@ impl Frame {
pub fn remove(&mut self, literal: &str) {
self.env.remove(&literal.to_string());
}

pub fn dealloc(&self, context: &llvm::Context, builder: &llvm::Builder) {
for val in self.env.values() {
if let Var::Vec(v) = val {
let fun_type = context.function_type(
context.void_type(),
&[context.double_type().pointer_type(0)],
false,
);

let fun_addr = stdlib::vecfree as usize;
let ptr = context.const_u64_to_ptr(
context.const_u64(fun_addr.try_into().unwrap()),
fun_type.pointer_type(0),
);
builder.build_call(&ptr, &[builder.build_load(v, "")], "");
}
}
}
}
72 changes: 42 additions & 30 deletions src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,21 @@ impl Visitor<Value> for Compiler {
.iter()
.map(|arg| match self.walk(arg) {
Value::Numeric(n) => n,
Value::Vec(v) => v,
Value::Vec(v) => {
let fun_type = self.context.function_type(
self.context.double_type().pointer_type(0),
&[self.context.double_type().pointer_type(0)],
false,
);

let fun_addr = stdlib::veccopy as usize;
let ptr = self.context.const_u64_to_ptr(
self.context.const_u64(fun_addr.try_into().unwrap()),
fun_type.pointer_type(0),
);

self.builder.build_call(&ptr, &[v], "")
}
Value::Function { val, .. } => val,
_ => todo!("{:?}", self.walk(arg)),
})
Expand Down Expand Up @@ -698,7 +712,7 @@ impl Compiler {
| Value::Vec(v)
| Value::Bool(v) => self.builder.create_store(v, &ptr),
Value::Function { val: v, .. } => v,
_ => todo!(),
_ => todo!("{:?}", val),
};

self.stack.last_mut().unwrap().set(literal, var);
Expand Down Expand Up @@ -798,36 +812,34 @@ impl Compiler {
last_val = self.walk(&stmt);
}

// for (_, val) in &self.stack.last().unwrap().env {
// match val {
// Value::Vec(v) => {
// let fun_type = self.context.function_type(
// self.context.void_type(),
// &[self.context.void_type().pointer_type(0)],
// false,
// );

// let fun_addr = unsafe {
// std::mem::transmute::<*const (), u64>(stdlib::vecfree as *const ())
// };
// let ptr = self.context.const_u64_to_ptr(
// self.context.const_u64(fun_addr),
// fun_type.pointer_type(0),
// );
// self.builder
// .build_call(&ptr, &[self.builder.build_load(v, "")], "");
// }
// _ => (),
// }
// }
let frame = self.stack.pop().unwrap();

let ret_val = match last_val {
Value::Null => None,
Value::Numeric(n) => Some(n),
Value::Vec(n) => {
let fun_type = self.context.function_type(
self.context.double_type().pointer_type(0),
&[self.context.double_type().pointer_type(0)],
false,
);

let fun_addr = stdlib::veccopy as usize;
let ptr = self.context.const_u64_to_ptr(
self.context.const_u64(fun_addr.try_into().unwrap()),
fun_type.pointer_type(0),
);

Some(self.builder.build_call(&ptr, &[n], ""))
}
_ => todo!("{:?}", last_val),
};

self.stack.pop();
frame.dealloc(&self.context, &self.builder);

match last_val {
Value::Null => self.builder.build_ret_void(),
Value::Numeric(n) => self.builder.build_ret(n),
Value::Vec(n) => self.builder.build_ret(n),
_ => todo!("{:?}", last_val),
match ret_val {
Some(v) => self.builder.build_ret(v),
None => self.builder.build_ret_void(),
};

self.builder.position_builder_at_end(&curr);
Expand Down
19 changes: 14 additions & 5 deletions stdlib/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,16 @@ pub unsafe extern "C" fn vecset(
idx: f64,
value: f64,
) -> *mut std::vec::Vec<f64> {
let mut v = Box::from_raw(vec);
let v = Box::from_raw(vec);
let mut new_vec = v.to_vec();
Box::into_raw(v);

while v.len() <= idx as usize {
v.push(0.0);
while new_vec.len() <= idx as usize {
new_vec.push(0.0);
}
v[idx as usize] = value;
new_vec[idx as usize] = value;

Box::into_raw(v)
Box::into_raw(Box::new(new_vec))
}

pub extern "C" fn vecget(vec: *mut Vec<f64>, idx: f64) -> f64 {
Expand All @@ -42,3 +44,10 @@ pub unsafe extern "C" fn len(vec: *mut Vec<f64>) -> f64 {
pub unsafe extern "C" fn vecfree(vec: *mut Vec<f64>) {
Box::from_raw(vec);
}

pub extern "C" fn veccopy(vec: *mut Vec<f64>) -> *mut std::vec::Vec<f64> {
let v = unsafe { Box::from_raw(vec as *mut Vec<f64>) };
let new_vec = v.to_vec();
Box::into_raw(Box::new(v));
Box::into_raw(Box::new(new_vec))
}

0 comments on commit d4ac876

Please sign in to comment.