Move call_stack to Interpreter struct

This commit is contained in:
Wei Tang 2018-07-06 06:43:21 +08:00
parent df0e3ddd46
commit d39dd4c773
1 changed files with 12 additions and 11 deletions

View File

@ -48,14 +48,17 @@ enum RunResult {
pub struct Interpreter<'a, E: Externals + 'a> { pub struct Interpreter<'a, E: Externals + 'a> {
externals: &'a mut E, externals: &'a mut E,
value_stack: ValueStack, value_stack: ValueStack,
call_stack: Vec<FunctionContext>,
} }
impl<'a, E: Externals> Interpreter<'a, E> { impl<'a, E: Externals> Interpreter<'a, E> {
pub fn new(externals: &'a mut E) -> Interpreter<'a, E> { pub fn new(externals: &'a mut E) -> Interpreter<'a, E> {
let value_stack = ValueStack::with_limit(DEFAULT_VALUE_STACK_LIMIT); let value_stack = ValueStack::with_limit(DEFAULT_VALUE_STACK_LIMIT);
let call_stack = Vec::new();
Interpreter { Interpreter {
externals, externals,
value_stack, value_stack,
call_stack,
} }
} }
@ -72,10 +75,8 @@ impl<'a, E: Externals> Interpreter<'a, E> {
let initial_frame = FunctionContext::new(func.clone()); let initial_frame = FunctionContext::new(func.clone());
let mut call_stack = Vec::new(); self.call_stack.push(initial_frame);
call_stack.push(initial_frame); self.run_interpreter_loop()?;
self.run_interpreter_loop(&mut call_stack)?;
let opt_return_value = func.signature().return_type().map(|_vt| { let opt_return_value = func.signature().return_type().map(|_vt| {
self.value_stack.pop() self.value_stack.pop()
@ -87,9 +88,9 @@ impl<'a, E: Externals> Interpreter<'a, E> {
Ok(opt_return_value) Ok(opt_return_value)
} }
fn run_interpreter_loop(&mut self, call_stack: &mut Vec<FunctionContext>) -> Result<(), Trap> { fn run_interpreter_loop(&mut self) -> Result<(), Trap> {
loop { loop {
let mut function_context = call_stack let mut function_context = self.call_stack
.pop() .pop()
.expect("on loop entry - not empty; on loop continue - checking for emptiness; qed"); .expect("on loop entry - not empty; on loop continue - checking for emptiness; qed");
let function_ref = function_context.function.clone(); let function_ref = function_context.function.clone();
@ -112,22 +113,22 @@ impl<'a, E: Externals> Interpreter<'a, E> {
match function_return { match function_return {
RunResult::Return => { RunResult::Return => {
if call_stack.last().is_none() { if self.call_stack.last().is_none() {
// This was the last frame in the call stack. This means we // This was the last frame in the call stack. This means we
// are done executing. // are done executing.
return Ok(()); return Ok(());
} }
}, },
RunResult::NestedCall(nested_func) => { RunResult::NestedCall(nested_func) => {
if call_stack.len() + 1 >= DEFAULT_CALL_STACK_LIMIT { if self.call_stack.len() + 1 >= DEFAULT_CALL_STACK_LIMIT {
return Err(TrapKind::StackOverflow.into()); return Err(TrapKind::StackOverflow.into());
} }
match *nested_func.as_internal() { match *nested_func.as_internal() {
FuncInstanceInternal::Internal { .. } => { FuncInstanceInternal::Internal { .. } => {
let nested_context = FunctionContext::new(nested_func.clone()); let nested_context = FunctionContext::new(nested_func.clone());
call_stack.push(function_context); self.call_stack.push(function_context);
call_stack.push(nested_context); self.call_stack.push(nested_context);
}, },
FuncInstanceInternal::Host { ref signature, .. } => { FuncInstanceInternal::Host { ref signature, .. } => {
let args = prepare_function_args(signature, &mut self.value_stack); let args = prepare_function_args(signature, &mut self.value_stack);
@ -143,7 +144,7 @@ impl<'a, E: Externals> Interpreter<'a, E> {
if let Some(return_val) = return_val { if let Some(return_val) = return_val {
self.value_stack.push(return_val).map_err(Trap::new)?; self.value_stack.push(return_val).map_err(Trap::new)?;
} }
call_stack.push(function_context); self.call_stack.push(function_context);
} }
} }
}, },