Rename InvokeOutcome to ActionOutcome and move it to its own module.

This commit is contained in:
Dan Gohman
2018-12-06 02:52:54 -05:00
parent d9b4bd1de8
commit 06de604729
7 changed files with 113 additions and 103 deletions

77
lib/execute/src/action.rs Normal file
View File

@@ -0,0 +1,77 @@
//! Support for performing actions with a wasm module from the outside.
use cranelift_codegen::ir;
use std::string::String;
use std::vec::Vec;
/// A runtime value.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Value {
/// A runtime value with type i32.
I32(i32),
/// A runtime value with type i64.
I64(i64),
/// A runtime value with type f32.
F32(u32),
/// A runtime value with type f64.
F64(u64),
}
impl Value {
/// Return the type of this `Value`.
pub fn value_type(self) -> ir::Type {
match self {
Value::I32(_) => ir::types::I32,
Value::I64(_) => ir::types::I64,
Value::F32(_) => ir::types::F32,
Value::F64(_) => ir::types::F64,
}
}
/// Assuming this `Value` holds an `i32`, return that value.
pub fn unwrap_i32(self) -> i32 {
match self {
Value::I32(x) => x,
_ => panic!("unwrapping value of type {} as i32", self.value_type()),
}
}
/// Assuming this `Value` holds an `i64`, return that value.
pub fn unwrap_i64(self) -> i64 {
match self {
Value::I64(x) => x,
_ => panic!("unwrapping value of type {} as i64", self.value_type()),
}
}
/// Assuming this `Value` holds an `f32`, return that value.
pub fn unwrap_f32(self) -> u32 {
match self {
Value::F32(x) => x,
_ => panic!("unwrapping value of type {} as f32", self.value_type()),
}
}
/// Assuming this `Value` holds an `f64`, return that value.
pub fn unwrap_f64(self) -> u64 {
match self {
Value::F64(x) => x,
_ => panic!("unwrapping value of type {} as f64", self.value_type()),
}
}
}
/// The result of invoking a wasm function or reading a wasm global.
#[derive(Debug)]
pub enum ActionOutcome {
/// The action returned normally. Its return values are provided.
Returned {
/// The return values.
values: Vec<Value>,
},
/// A trap occurred while the action was executing.
Trapped {
/// The trap message.
message: String,
},
}

View File

@@ -1,6 +1,7 @@
//! TODO: Move the contents of this file to other files, as "execute.rs" is //! TODO: Move the contents of this file to other files, as "execute.rs" is
//! no longer a descriptive filename. //! no longer a descriptive filename.
use action::ActionOutcome;
use code::Code; use code::Code;
use cranelift_codegen::binemit::Reloc; use cranelift_codegen::binemit::Reloc;
use cranelift_codegen::isa::TargetIsa; use cranelift_codegen::isa::TargetIsa;
@@ -10,7 +11,7 @@ use cranelift_wasm::{
}; };
use export::{ExportValue, Resolver}; use export::{ExportValue, Resolver};
use instance::Instance; use instance::Instance;
use invoke::{invoke_by_index, InvokeOutcome}; use invoke::invoke_by_index;
use region::{protect, Protection}; use region::{protect, Protection};
use std::ptr::write_unaligned; use std::ptr::write_unaligned;
use std::string::String; use std::string::String;
@@ -378,10 +379,10 @@ pub fn finish_instantiation(
let vmctx = instance.vmctx(); let vmctx = instance.vmctx();
let result = invoke_by_index(code, isa, module, compilation, vmctx, start_index, &[])?; let result = invoke_by_index(code, isa, module, compilation, vmctx, start_index, &[])?;
match result { match result {
InvokeOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
assert!(values.is_empty()); assert!(values.is_empty());
} }
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
return Err(format!("start function trapped: {}", message)); return Err(format!("start function trapped: {}", message));
} }
} }

View File

@@ -1,8 +1,8 @@
//! Support for reading the value of a wasm global from outside the module. //! Support for reading the value of a wasm global from outside the module.
use action::Value;
use cranelift_codegen::ir; use cranelift_codegen::ir;
use cranelift_wasm::GlobalIndex; use cranelift_wasm::GlobalIndex;
use invoke::Value;
use std::string::String; use std::string::String;
use vmcontext::VMContext; use vmcontext::VMContext;
use wasmtime_environ::{Export, Module}; use wasmtime_environ::{Export, Module};

View File

@@ -1,5 +1,6 @@
//! Support for invoking wasm functions from outside a wasm module. //! Support for invoking wasm functions from outside a wasm module.
use action::{ActionOutcome, Value};
use code::Code; use code::Code;
use cranelift_codegen::ir::InstBuilder; use cranelift_codegen::ir::InstBuilder;
use cranelift_codegen::{binemit, ir, isa, Context}; use cranelift_codegen::{binemit, ir, isa, Context};
@@ -14,78 +15,6 @@ use traphandlers::call_wasm;
use vmcontext::VMContext; use vmcontext::VMContext;
use wasmtime_environ::{Compilation, Export, Module, RelocSink}; use wasmtime_environ::{Compilation, Export, Module, RelocSink};
/// A runtime value.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum Value {
/// A runtime value with type i32.
I32(i32),
/// A runtime value with type i64.
I64(i64),
/// A runtime value with type f32.
F32(u32),
/// A runtime value with type f64.
F64(u64),
}
impl Value {
/// Return the type of this `Value`.
pub fn value_type(self) -> ir::Type {
match self {
Value::I32(_) => ir::types::I32,
Value::I64(_) => ir::types::I64,
Value::F32(_) => ir::types::F32,
Value::F64(_) => ir::types::F64,
}
}
/// Assuming this `Value` holds an `i32`, return that value.
pub fn unwrap_i32(self) -> i32 {
match self {
Value::I32(x) => x,
_ => panic!("unwrapping value of type {} as i32", self.value_type()),
}
}
/// Assuming this `Value` holds an `i64`, return that value.
pub fn unwrap_i64(self) -> i64 {
match self {
Value::I64(x) => x,
_ => panic!("unwrapping value of type {} as i64", self.value_type()),
}
}
/// Assuming this `Value` holds an `f32`, return that value.
pub fn unwrap_f32(self) -> u32 {
match self {
Value::F32(x) => x,
_ => panic!("unwrapping value of type {} as f32", self.value_type()),
}
}
/// Assuming this `Value` holds an `f64`, return that value.
pub fn unwrap_f64(self) -> u64 {
match self {
Value::F64(x) => x,
_ => panic!("unwrapping value of type {} as f64", self.value_type()),
}
}
}
/// The result of invoking a wasm function.
#[derive(Debug)]
pub enum InvokeOutcome {
/// The function returned normally. Its return values are provided.
Returned {
/// The return values.
values: Vec<Value>,
},
/// A trap occurred while the function was executing.
Trapped {
/// The trap message.
message: String,
},
}
/// Jumps to the code region of memory and invoke the exported function /// Jumps to the code region of memory and invoke the exported function
pub fn invoke( pub fn invoke(
code: &mut Code, code: &mut Code,
@@ -95,7 +24,7 @@ pub fn invoke(
vmctx: *mut VMContext, vmctx: *mut VMContext,
function: &str, function: &str,
args: &[Value], args: &[Value],
) -> Result<InvokeOutcome, String> { ) -> Result<ActionOutcome, String> {
let fn_index = match module.exports.get(function) { let fn_index = match module.exports.get(function) {
Some(Export::Function(index)) => *index, Some(Export::Function(index)) => *index,
Some(_) => return Err(format!("exported item \"{}\" is not a function", function)), Some(_) => return Err(format!("exported item \"{}\" is not a function", function)),
@@ -113,7 +42,7 @@ pub fn invoke_by_index(
vmctx: *mut VMContext, vmctx: *mut VMContext,
fn_index: FuncIndex, fn_index: FuncIndex,
args: &[Value], args: &[Value],
) -> Result<InvokeOutcome, String> { ) -> Result<ActionOutcome, String> {
// TODO: Return Err if fn_index is out of bounds. // TODO: Return Err if fn_index is out of bounds.
let exec_code_buf = match module.defined_func_index(fn_index) { let exec_code_buf = match module.defined_func_index(fn_index) {
Some(def_fn_index) => { Some(def_fn_index) => {
@@ -152,7 +81,7 @@ fn call_through_wrapper(
vmctx: *mut VMContext, vmctx: *mut VMContext,
args: &[Value], args: &[Value],
sig: &ir::Signature, sig: &ir::Signature,
) -> Result<InvokeOutcome, String> { ) -> Result<ActionOutcome, String> {
for (index, value) in args.iter().enumerate() { for (index, value) in args.iter().enumerate() {
assert_eq!(value.value_type(), sig.params[index].value_type); assert_eq!(value.value_type(), sig.params[index].value_type);
} }
@@ -261,8 +190,8 @@ fn call_through_wrapper(
values.push(v); values.push(v);
} }
InvokeOutcome::Returned { values } ActionOutcome::Returned { values }
} }
Err(message) => InvokeOutcome::Trapped { message }, Err(message) => ActionOutcome::Trapped { message },
}) })
} }

View File

@@ -41,6 +41,7 @@ extern crate libc;
extern crate memoffset; extern crate memoffset;
extern crate cast; extern crate cast;
mod action;
mod code; mod code;
mod execute; mod execute;
mod export; mod export;
@@ -57,12 +58,13 @@ mod traphandlers;
mod vmcontext; mod vmcontext;
mod world; mod world;
pub use action::{ActionOutcome, Value};
pub use code::Code; pub use code::Code;
pub use execute::{compile_and_link_module, finish_instantiation}; pub use execute::{compile_and_link_module, finish_instantiation};
pub use export::{ExportValue, NullResolver, Resolver}; pub use export::{ExportValue, NullResolver, Resolver};
pub use get::get; pub use get::get;
pub use instance::Instance; pub use instance::Instance;
pub use invoke::{invoke, InvokeOutcome, Value}; pub use invoke::invoke;
pub use traphandlers::{call_wasm, LookupCodeSegment, RecordTrap, Unwind}; pub use traphandlers::{call_wasm, LookupCodeSegment, RecordTrap, Unwind};
pub use vmcontext::{VMContext, VMGlobal, VMMemory, VMTable}; pub use vmcontext::{VMContext, VMGlobal, VMMemory, VMTable};
pub use world::InstanceWorld; pub use world::InstanceWorld;

View File

@@ -1,13 +1,15 @@
use action::{ActionOutcome, Value};
use code::Code;
use cranelift_codegen::isa; use cranelift_codegen::isa;
use cranelift_wasm::{GlobalIndex, MemoryIndex}; use cranelift_wasm::{GlobalIndex, MemoryIndex};
use execute::{compile_and_link_module, finish_instantiation};
use export::Resolver; use export::Resolver;
use get::get;
use instance::Instance;
use invoke::invoke;
use std::str; use std::str;
use vmcontext::VMGlobal; use vmcontext::VMGlobal;
use wasmtime_environ::{Compilation, Module, ModuleEnvironment, Tunables}; use wasmtime_environ::{Compilation, Module, ModuleEnvironment, Tunables};
use {
compile_and_link_module, finish_instantiation, get, invoke, Code, Instance, InvokeOutcome,
Value,
};
/// A module, an instance of that module, and accompanying compilation artifacts. /// A module, an instance of that module, and accompanying compilation artifacts.
/// ///
@@ -62,7 +64,7 @@ impl InstanceWorld {
isa: &isa::TargetIsa, isa: &isa::TargetIsa,
function_name: &str, function_name: &str,
args: &[Value], args: &[Value],
) -> Result<InvokeOutcome, String> { ) -> Result<ActionOutcome, String> {
invoke( invoke(
code, code,
isa, isa,

View File

@@ -7,7 +7,7 @@ use std::io::Read;
use std::path::Path; use std::path::Path;
use std::str; use std::str;
use wabt::script::{self, Action, Command, CommandKind, ModuleBinary, ScriptParser}; use wabt::script::{self, Action, Command, CommandKind, ModuleBinary, ScriptParser};
use wasmtime_execute::{Code, InstanceWorld, InvokeOutcome, Value}; use wasmtime_execute::{ActionOutcome, Code, InstanceWorld, Value};
struct Instances { struct Instances {
current: Option<InstanceWorld>, current: Option<InstanceWorld>,
@@ -44,8 +44,7 @@ impl Instances {
self.namespace.insert(name, world); self.namespace.insert(name, world);
} }
// fixme: Rename InvokeOutcome to ActionOutcome. pub fn perform_action(&mut self, isa: &isa::TargetIsa, action: Action) -> ActionOutcome {
pub fn perform_action(&mut self, isa: &isa::TargetIsa, action: Action) -> InvokeOutcome {
match action { match action {
Action::Invoke { Action::Invoke {
module, module,
@@ -91,7 +90,7 @@ impl Instances {
.get(&field) .get(&field)
.expect(&format!("error getting {} in module {}", field, name)), .expect(&format!("error getting {} in module {}", field, name)),
}; };
InvokeOutcome::Returned { ActionOutcome::Returned {
values: vec![value], values: vec![value],
} }
} }
@@ -114,14 +113,14 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
instances.define_unnamed_module(&*isa, module) instances.define_unnamed_module(&*isa, module)
} }
CommandKind::PerformAction(action) => match instances.perform_action(&*isa, action) { CommandKind::PerformAction(action) => match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { .. } => {} ActionOutcome::Returned { .. } => {}
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
panic!("{}:{}: a trap occurred: {}", name, line, message); panic!("{}:{}: a trap occurred: {}", name, line, message);
} }
}, },
CommandKind::AssertReturn { action, expected } => { CommandKind::AssertReturn { action, expected } => {
match instances.perform_action(&*isa, action) { match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for (v, e) in values.iter().zip(expected.iter()) { for (v, e) in values.iter().zip(expected.iter()) {
match *e { match *e {
script::Value::I32(x) => { script::Value::I32(x) => {
@@ -139,7 +138,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
}; };
} }
} }
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
panic!( panic!(
"{}:{}: expected normal return, but a trap occurred: {}", "{}:{}: expected normal return, but a trap occurred: {}",
name, line, message name, line, message
@@ -149,11 +148,11 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
} }
CommandKind::AssertTrap { action, message } => { CommandKind::AssertTrap { action, message } => {
match instances.perform_action(&*isa, action) { match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { values } => panic!( ActionOutcome::Returned { values } => panic!(
"{}:{}: expected trap, but invoke returned with {:?}", "{}:{}: expected trap, but invoke returned with {:?}",
name, line, values name, line, values
), ),
InvokeOutcome::Trapped { ActionOutcome::Trapped {
message: trap_message, message: trap_message,
} => { } => {
println!( println!(
@@ -165,11 +164,11 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
} }
CommandKind::AssertExhaustion { action } => { CommandKind::AssertExhaustion { action } => {
match instances.perform_action(&*isa, action) { match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { values } => panic!( ActionOutcome::Returned { values } => panic!(
"{}:{}: expected exhaustion, but invoke returned with {:?}", "{}:{}: expected exhaustion, but invoke returned with {:?}",
name, line, values name, line, values
), ),
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
println!( println!(
"{}:{}: TODO: Check the exhaustion message: {}", "{}:{}: TODO: Check the exhaustion message: {}",
name, line, message name, line, message
@@ -179,7 +178,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
} }
CommandKind::AssertReturnCanonicalNan { action } => { CommandKind::AssertReturnCanonicalNan { action } => {
match instances.perform_action(&*isa, action) { match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for v in values.iter() { for v in values.iter() {
match v { match v {
Value::I32(_) | Value::I64(_) => { Value::I32(_) | Value::I64(_) => {
@@ -202,7 +201,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
}; };
} }
} }
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
panic!( panic!(
"{}:{}: expected canonical NaN return, but a trap occurred: {}", "{}:{}: expected canonical NaN return, but a trap occurred: {}",
name, line, message name, line, message
@@ -212,7 +211,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
} }
CommandKind::AssertReturnArithmeticNan { action } => { CommandKind::AssertReturnArithmeticNan { action } => {
match instances.perform_action(&*isa, action) { match instances.perform_action(&*isa, action) {
InvokeOutcome::Returned { values } => { ActionOutcome::Returned { values } => {
for v in values.iter() { for v in values.iter() {
match v { match v {
Value::I32(_) | Value::I64(_) => { Value::I32(_) | Value::I64(_) => {
@@ -235,7 +234,7 @@ pub fn wast_buffer(name: &str, isa: &isa::TargetIsa, wast: &[u8]) {
}; };
} }
} }
InvokeOutcome::Trapped { message } => { ActionOutcome::Trapped { message } => {
panic!( panic!(
"{}:{}: expected canonical NaN return, but a trap occurred: {}", "{}:{}: expected canonical NaN return, but a trap occurred: {}",
name, line, message name, line, message