Fix a lot of things and implement gc
This commit is contained in:
53
src/ops.rs
53
src/ops.rs
@@ -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(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user