Fix a lot of things and implement gc

This commit is contained in:
2019-05-29 21:06:42 +02:00
parent c3876da74f
commit 84bdcf4b20
16 changed files with 146 additions and 55 deletions

View File

@@ -74,6 +74,7 @@ lazy_static! {
m[0xD1] = Operation::Op("NEWARRAY", newarray, vec![]);
m[0xD2] = Operation::Op("IALOAD", iaload, vec![]);
m[0xD3] = Operation::Op("IASTORE", iastore, vec![]);
m[0xD4] = Operation::Op("GC", gc, vec![]);
}
m
@@ -110,7 +111,7 @@ fn out(machine: &mut Machine) -> Result<()> {
let mut out = machine.stream_out.lock().unwrap();
out.write_all(&buffer).unwrap();
out.flush().unwrap();
return Ok(());
Ok(())
}
fn pop(machine: &mut Machine) -> Result<()> {
@@ -266,14 +267,20 @@ fn invokevirtual(machine: &mut Machine) -> Result<()> {
}
fn ireturn(machine: &mut Machine) -> Result<()> {
let mut prev_frame: Frame = match machine.frame.pop() {
Some(a) => a,
None => return Err("Got no frame... somehow..."),
};
let result = prev_frame.stack.pop()?;
let return_addr: i32 = prev_frame.get(0)?.try_into()?;
machine.cur_stack().push(result);
machine.block.seek(return_addr as usize)
// Lifetime for prev frame, allows gc to reap into the frame
{
let mut prev_frame: Frame = match machine.frame.pop() {
Some(a) => a,
None => return Err("Got no frame... somehow..."),
};
let result = prev_frame.stack.pop()?;
let return_addr: i32 = prev_frame.get(0)?.try_into()?;
machine.cur_stack().push(result);
machine.block.seek(return_addr as usize)?;
}
machine.heap.gc();
Ok(())
}
#[cfg(feature = "extra:sleep")]
@@ -323,40 +330,46 @@ fn netclose(machine: &mut Machine) -> Result<()> {
#[cfg(feature = "bonus:heap")]
fn newarray(machine: &mut Machine) -> Result<()> {
let size: i32 = machine.cur_stack().pop()?.try_into()?;
let heapref = machine.heap.alloc(size as usize);
machine.cur_stack().push(Value::HeapRef(heapref));
let heap = machine.heap.alloc(size as usize);
machine.cur_stack().push(Value::HeapRef(heap));
Ok(())
}
#[cfg(feature = "bonus:heap")]
fn iastore(machine: &mut Machine) -> Result<()> {
let heapref = match machine.cur_stack().pop()? {
use std::cell::RefCell;
let heap = match machine.cur_stack().pop()? {
Value::HeapRef(a) => a,
_ => return Err("Cannot use int as heapref"),
};
let index: i32 = machine.cur_stack().pop()?.try_into()?;
let value: i32 = machine.cur_stack().pop()?.try_into()?;
let value = machine.cur_stack().pop()?.clone();
let heap = machine.heap.get(heapref);
heap[index as usize] = value;
RefCell::borrow_mut(&heap)[index as usize] = value;
Ok(())
}
#[cfg(feature = "bonus:heap")]
fn iaload(machine: &mut Machine) -> Result<()> {
let heapref = match machine.cur_stack().pop()? {
let heap = match machine.cur_stack().pop()? {
Value::HeapRef(a) => a,
_ => return Err("Cannot use int as heapref"),
};
let index: i32 = machine.cur_stack().pop()?.try_into()?;
let value: i32;
let value: Value;
{
let heap = machine.heap.get(heapref);
value = heap[index as usize];
value = heap.borrow()[index as usize].clone();
}
machine.cur_stack().push(Value::Int(value));
machine.cur_stack().push(value);
Ok(())
}
#[cfg(feature = "bonus:heap")]
fn gc(machine: &mut Machine) -> Result<()> {
machine.heap.gc();
Ok(())
}