Move FunctionContext::new's call to push_frame to Interpreter::run_function.

This makes it more consistent with run_block and others, and also means
that FunctionContext::new doesn't need to be passed the function body
and doesn't need to return a Result, which simplify its users.
This commit is contained in:
Dan Gohman 2017-06-02 09:22:03 -07:00
parent 9e32f7bc21
commit 7e63159a1b
3 changed files with 9 additions and 11 deletions

View File

@ -356,7 +356,7 @@ impl ModuleInstanceInterface for ModuleInstance {
let value_stack_limit = outer.value_stack_limit; let value_stack_limit = outer.value_stack_limit;
let frame_stack_limit = outer.frame_stack_limit; let frame_stack_limit = outer.frame_stack_limit;
let locals = prepare_function_locals(actual_function_type, function_body, &mut outer)?; let locals = prepare_function_locals(actual_function_type, function_body, &mut outer)?;
let mut innner = FunctionContext::new(self, outer.externals, value_stack_limit, frame_stack_limit, actual_function_type, function_code, locals)?; let mut innner = FunctionContext::new(self, outer.externals, value_stack_limit, frame_stack_limit, actual_function_type, locals);
Interpreter::run_function(&mut innner, function_code) Interpreter::run_function(&mut innner, function_code)
} }
} }

View File

@ -65,6 +65,9 @@ pub struct BlockFrame {
impl Interpreter { impl Interpreter {
pub fn run_function(context: &mut FunctionContext, body: &[Opcode]) -> Result<Option<RuntimeValue>, Error> { pub fn run_function(context: &mut FunctionContext, body: &[Opcode]) -> Result<Option<RuntimeValue>, Error> {
let return_type = context.return_type;
context.push_frame(body.len() - 1, body.len() - 1, return_type)?;
Interpreter::execute_block(context, body)?; Interpreter::execute_block(context, body)?;
match context.return_type { match context.return_type {
BlockType::Value(_) => Ok(Some(context.value_stack_mut().pop()?)), BlockType::Value(_) => Ok(Some(context.value_stack_mut().pop()?)),
@ -874,8 +877,8 @@ impl Interpreter {
} }
impl<'a> FunctionContext<'a> { impl<'a> FunctionContext<'a> {
pub fn new(module: &'a ModuleInstance, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, body: &[Opcode], args: Vec<VariableInstance>) -> Result<Self, Error> { pub fn new(module: &'a ModuleInstance, externals: &'a HashMap<String, Arc<ModuleInstanceInterface + 'a>>, value_stack_limit: usize, frame_stack_limit: usize, function: &FunctionType, args: Vec<VariableInstance>) -> Self {
let mut context = FunctionContext { FunctionContext {
module: module, module: module,
externals: externals, externals: externals,
return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult), return_type: function.return_type().map(|vt| BlockType::Value(vt)).unwrap_or(BlockType::NoResult),
@ -883,12 +886,7 @@ impl<'a> FunctionContext<'a> {
frame_stack: StackWithLimit::with_limit(frame_stack_limit), frame_stack: StackWithLimit::with_limit(frame_stack_limit),
locals: args, locals: args,
position: 0, position: 0,
}; }
context.push_frame(body.len() - 1, body.len() - 1, match function.return_type() {
Some(value_type) => BlockType::Value(value_type),
None => BlockType::NoResult,
})?;
Ok(context)
} }
pub fn module(&self) -> &ModuleInstance { pub fn module(&self) -> &ModuleInstance {

View File

@ -15,11 +15,11 @@ fn run_function_i32(body: &Opcodes, arg: i32) -> Result<i32, Error> {
let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32)); let ftype = FunctionType::new(vec![ValueType::I32], Some(ValueType::I32));
let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap(); let module = ModuleInstance::new(Weak::default(), Module::default()).unwrap();
let externals = HashMap::new(); let externals = HashMap::new();
let mut context = FunctionContext::new(&module, &externals, 1024, 1024, &ftype, body.elements(), vec![ let mut context = FunctionContext::new(&module, &externals, 1024, 1024, &ftype, vec![
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(arg)).unwrap(), // arg
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1 VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local1
VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2 VariableInstance::new(true, VariableType::I32, RuntimeValue::I32(0)).unwrap(), // local2
])?; ]);
Interpreter::run_function(&mut context, body.elements()) Interpreter::run_function(&mut context, body.elements())
.map(|v| v.unwrap().try_into().unwrap()) .map(|v| v.unwrap().try_into().unwrap())
} }