Fail with Trap in Instance::new() instead of Error (#683)
This commit is contained in:
@@ -7,7 +7,7 @@ use wasmtime::*;
|
||||
struct HelloCallback;
|
||||
|
||||
impl Callable for HelloCallback {
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> {
|
||||
println!("Calling back...");
|
||||
println!("> Hello World!");
|
||||
Ok(())
|
||||
|
||||
@@ -7,7 +7,7 @@ use wasmtime::*;
|
||||
struct Callback;
|
||||
|
||||
impl Callable for Callback {
|
||||
fn call(&self, args: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, args: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
println!("Calling back...");
|
||||
println!("> {} {}", args[0].unwrap_i32(), args[1].unwrap_i64());
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::runtime::Store;
|
||||
use crate::trampoline::{generate_func_export, take_api_trap};
|
||||
use crate::trap::Trap;
|
||||
use crate::trap::{Trap, TrapInfo};
|
||||
use crate::types::FuncType;
|
||||
use crate::values::Val;
|
||||
use std::rc::Rc;
|
||||
@@ -18,7 +18,7 @@ use wasmtime_runtime::Export;
|
||||
/// struct TimesTwo;
|
||||
///
|
||||
/// impl wasmtime::Callable for TimesTwo {
|
||||
/// fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<wasmtime::Trap>> {
|
||||
/// fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), wasmtime::Trap> {
|
||||
/// let mut value = params[0].unwrap_i32();
|
||||
/// value *= 2;
|
||||
/// results[0] = value.into();
|
||||
@@ -75,7 +75,7 @@ use wasmtime_runtime::Export;
|
||||
/// let results = run_function
|
||||
/// .borrow()
|
||||
/// .call(&[original.into()])
|
||||
/// .map_err(|trap| trap.borrow().to_string())?;
|
||||
/// .map_err(|trap| trap.to_string())?;
|
||||
///
|
||||
/// // Compare that the results returned matches what we expect.
|
||||
/// assert_eq!(original * 2, results[0].unwrap_i32());
|
||||
@@ -87,11 +87,11 @@ pub trait Callable {
|
||||
/// `params` is an immutable list of parameters provided to the function.
|
||||
/// `results` is mutable list of results to be potentially set by your
|
||||
/// function. Produces a `Trap` if the function encounters any errors.
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>>;
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap>;
|
||||
}
|
||||
|
||||
pub(crate) trait WrappedCallable {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>>;
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap>;
|
||||
fn signature(&self) -> &ir::Signature {
|
||||
match self.wasmtime_export() {
|
||||
Export::Function { signature, .. } => signature,
|
||||
@@ -119,7 +119,7 @@ impl WasmtimeFn {
|
||||
}
|
||||
|
||||
impl WrappedCallable for WasmtimeFn {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
use std::cmp::max;
|
||||
use std::mem;
|
||||
|
||||
@@ -150,7 +150,7 @@ impl WrappedCallable for WasmtimeFn {
|
||||
.context()
|
||||
.compiler()
|
||||
.get_published_trampoline(body, &signature, value_size)
|
||||
.map_err(|_| HostRef::new(Trap::fake()))?; //was ActionError::Setup)?;
|
||||
.map_err(|e| Trap::new(format!("trampoline error: {:?}", e)))?;
|
||||
|
||||
// Call the trampoline.
|
||||
if let Err(message) = unsafe {
|
||||
@@ -160,8 +160,9 @@ impl WrappedCallable for WasmtimeFn {
|
||||
values_vec.as_mut_ptr() as *mut u8,
|
||||
)
|
||||
} {
|
||||
let trap = take_api_trap().unwrap_or_else(|| HostRef::new(Trap::new(message)));
|
||||
return Err(trap);
|
||||
let trap = take_api_trap()
|
||||
.unwrap_or_else(|| HostRef::new(TrapInfo::new(format!("call error: {}", message))));
|
||||
return Err(trap.into());
|
||||
}
|
||||
|
||||
// Load the return values out of `values_vec`.
|
||||
@@ -206,7 +207,7 @@ impl NativeCallable {
|
||||
}
|
||||
|
||||
impl WrappedCallable for NativeCallable {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
self.callable.call(params, results)
|
||||
}
|
||||
fn wasmtime_handle(&self) -> &InstanceHandle {
|
||||
|
||||
@@ -147,7 +147,7 @@ impl Func {
|
||||
self.r#type.results().len()
|
||||
}
|
||||
|
||||
pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>, HostRef<Trap>> {
|
||||
pub fn call(&self, params: &[Val]) -> Result<Box<[Val]>, Trap> {
|
||||
let mut results = vec![Val::null(); self.result_arity()];
|
||||
self.callable.call(params, &mut results)?;
|
||||
Ok(results.into_boxed_slice())
|
||||
|
||||
@@ -4,8 +4,9 @@ use crate::module::Module;
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::runtime::Store;
|
||||
use crate::trampoline::take_api_trap;
|
||||
use crate::trap::Trap;
|
||||
use crate::types::{ExportType, ExternType};
|
||||
use anyhow::Result;
|
||||
use anyhow::{Error, Result};
|
||||
use std::cell::RefCell;
|
||||
use std::collections::{HashMap, HashSet};
|
||||
use std::rc::Rc;
|
||||
@@ -31,7 +32,7 @@ pub fn instantiate_in_context(
|
||||
imports: Vec<(String, String, Extern)>,
|
||||
mut context: Context,
|
||||
exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
|
||||
) -> Result<(InstanceHandle, HashSet<Context>)> {
|
||||
) -> Result<(InstanceHandle, HashSet<Context>), Error> {
|
||||
let mut contexts = HashSet::new();
|
||||
let debug_info = context.debug_info();
|
||||
let mut resolver = SimpleResolver { imports };
|
||||
@@ -42,10 +43,12 @@ pub fn instantiate_in_context(
|
||||
exports,
|
||||
debug_info,
|
||||
)
|
||||
.map_err(|e| {
|
||||
// TODO wrap HostRef<Trap> into Error
|
||||
drop(take_api_trap());
|
||||
e
|
||||
.map_err(|e| -> Error {
|
||||
if let Some(trap) = take_api_trap() {
|
||||
Trap::from(trap).into()
|
||||
} else {
|
||||
e.into()
|
||||
}
|
||||
})?;
|
||||
contexts.insert(context);
|
||||
Ok((instance, contexts))
|
||||
@@ -68,7 +71,7 @@ impl Instance {
|
||||
store: &HostRef<Store>,
|
||||
module: &HostRef<Module>,
|
||||
externs: &[Extern],
|
||||
) -> Result<Instance> {
|
||||
) -> Result<Instance, Error> {
|
||||
let context = store.borrow_mut().context().clone();
|
||||
let exports = store.borrow_mut().global_exports().clone();
|
||||
let imports = module
|
||||
|
||||
@@ -28,6 +28,6 @@ pub use crate::instance::Instance;
|
||||
pub use crate::module::Module;
|
||||
pub use crate::r#ref::{AnyRef, HostInfo, HostRef};
|
||||
pub use crate::runtime::{Config, Engine, Store};
|
||||
pub use crate::trap::Trap;
|
||||
pub use crate::trap::{FrameInfo, Trap, TrapInfo};
|
||||
pub use crate::types::*;
|
||||
pub use crate::values::*;
|
||||
|
||||
@@ -96,6 +96,7 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m
|
||||
0
|
||||
}
|
||||
Err(trap) => {
|
||||
let trap = trap.trap_info_unchecked();
|
||||
record_api_trap(trap);
|
||||
1
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::cell::Cell;
|
||||
|
||||
use crate::r#ref::HostRef;
|
||||
use crate::Trap;
|
||||
use crate::TrapInfo;
|
||||
use wasmtime_environ::ir::{SourceLoc, TrapCode};
|
||||
use wasmtime_environ::TrapInformation;
|
||||
use wasmtime_jit::trampoline::binemit;
|
||||
@@ -10,10 +10,10 @@ use wasmtime_jit::trampoline::binemit;
|
||||
pub const API_TRAP_CODE: TrapCode = TrapCode::User(13);
|
||||
|
||||
thread_local! {
|
||||
static RECORDED_API_TRAP: Cell<Option<HostRef<Trap>>> = Cell::new(None);
|
||||
static RECORDED_API_TRAP: Cell<Option<HostRef<TrapInfo>>> = Cell::new(None);
|
||||
}
|
||||
|
||||
pub fn record_api_trap(trap: HostRef<Trap>) {
|
||||
pub fn record_api_trap(trap: HostRef<TrapInfo>) {
|
||||
RECORDED_API_TRAP.with(|data| {
|
||||
let trap = Cell::new(Some(trap));
|
||||
data.swap(&trap);
|
||||
@@ -24,7 +24,7 @@ pub fn record_api_trap(trap: HostRef<Trap>) {
|
||||
});
|
||||
}
|
||||
|
||||
pub fn take_api_trap() -> Option<HostRef<Trap>> {
|
||||
pub fn take_api_trap() -> Option<HostRef<TrapInfo>> {
|
||||
RECORDED_API_TRAP.with(|data| data.take())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,88 @@
|
||||
use crate::instance::Instance;
|
||||
use crate::r#ref::HostRef;
|
||||
use std::fmt;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FrameInfo;
|
||||
|
||||
impl FrameInfo {
|
||||
pub fn instance(&self) -> *const Instance {
|
||||
unimplemented!("FrameInfo::instance");
|
||||
}
|
||||
|
||||
pub fn func_index() -> usize {
|
||||
unimplemented!("FrameInfo::func_index");
|
||||
}
|
||||
|
||||
pub fn func_offset() -> usize {
|
||||
unimplemented!("FrameInfo::func_offset");
|
||||
}
|
||||
|
||||
pub fn module_offset() -> usize {
|
||||
unimplemented!("FrameInfo::module_offset");
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct TrapInfo {
|
||||
message: String,
|
||||
trace: Vec<FrameInfo>,
|
||||
}
|
||||
|
||||
impl TrapInfo {
|
||||
pub fn new<I: Into<String>>(message: I) -> Self {
|
||||
Self {
|
||||
message: message.into(),
|
||||
trace: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a reference the `message` stored in `Trap`.
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
|
||||
pub fn origin(&self) -> Option<&FrameInfo> {
|
||||
self.trace.first()
|
||||
}
|
||||
|
||||
pub fn trace(&self) -> &[FrameInfo] {
|
||||
&self.trace
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct to hold unsafe TrapInfo host reference, designed
|
||||
/// to be Send-able. The only access for it provided via the
|
||||
/// Trap::trap_info_unchecked() method.
|
||||
struct UnsafeTrapInfo(HostRef<TrapInfo>);
|
||||
|
||||
impl UnsafeTrapInfo {
|
||||
fn trap_info(&self) -> HostRef<TrapInfo> {
|
||||
self.0.clone()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl Send for UnsafeTrapInfo {}
|
||||
|
||||
impl fmt::Debug for UnsafeTrapInfo {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "UnsafeTrapInfo")
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct representing an aborted instruction execution, with a message
|
||||
/// indicating the cause.
|
||||
#[derive(Error, Debug)]
|
||||
#[error("Wasm trap: {message}")]
|
||||
pub struct Trap {
|
||||
message: String,
|
||||
info: Arc<Mutex<UnsafeTrapInfo>>,
|
||||
}
|
||||
|
||||
fn _assert_trap_is_sync_and_send(t: &Trap) -> (&dyn Sync, &dyn Send) {
|
||||
(t, t)
|
||||
}
|
||||
|
||||
impl Trap {
|
||||
@@ -15,20 +92,26 @@ impl Trap {
|
||||
/// let trap = wasmtime::Trap::new("unexpected error");
|
||||
/// assert_eq!("unexpected error", trap.message());
|
||||
/// ```
|
||||
pub fn new<I: Into<String>>(message: I) -> Trap {
|
||||
Self {
|
||||
message: message.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a `Trap` without defining a message for the trap. Mostly useful
|
||||
/// for prototypes and tests.
|
||||
pub fn fake() -> Trap {
|
||||
Self::new("TODO trap")
|
||||
pub fn new<I: Into<String>>(message: I) -> Self {
|
||||
Trap::from(HostRef::new(TrapInfo::new(message)))
|
||||
}
|
||||
|
||||
/// Returns a reference the `message` stored in `Trap`.
|
||||
pub fn message(&self) -> &str {
|
||||
&self.message
|
||||
}
|
||||
|
||||
/// Returns inner TrapInfo assotiated with the Trap.
|
||||
/// The method is unsafe: obtained TrapInfo is not thread safe.
|
||||
pub(crate) unsafe fn trap_info_unchecked(&self) -> HostRef<TrapInfo> {
|
||||
self.info.lock().unwrap().trap_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<HostRef<TrapInfo>> for Trap {
|
||||
fn from(trap_info: HostRef<TrapInfo>) -> Self {
|
||||
let message = trap_info.borrow().message().to_string();
|
||||
let info = Arc::new(Mutex::new(UnsafeTrapInfo(trap_info)));
|
||||
Trap { message, info }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
use super::{
|
||||
AnyRef, Callable, Engine, ExportType, Extern, ExternType, Func, FuncType, Global, GlobalType,
|
||||
HostInfo, HostRef, ImportType, Instance, Limits, Memory, MemoryType, Module, Store, Table,
|
||||
TableType, Trap, Val, ValType,
|
||||
TableType, Trap, TrapInfo, Val, ValType,
|
||||
};
|
||||
use std::rc::Rc;
|
||||
use std::{mem, ptr, slice};
|
||||
@@ -317,7 +317,7 @@ pub type wasm_message_t = wasm_name_t;
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
pub struct wasm_trap_t {
|
||||
trap: HostRef<Trap>,
|
||||
trap_info: HostRef<TrapInfo>,
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Clone)]
|
||||
@@ -469,7 +469,8 @@ pub unsafe extern "C" fn wasm_func_call(
|
||||
ptr::null_mut()
|
||||
}
|
||||
Err(trap) => {
|
||||
let trap = Box::new(wasm_trap_t { trap });
|
||||
let trap_info = trap.trap_info_unchecked();
|
||||
let trap = Box::new(wasm_trap_t { trap_info });
|
||||
Box::into_raw(trap)
|
||||
}
|
||||
}
|
||||
@@ -539,7 +540,7 @@ impl wasm_val_t {
|
||||
}
|
||||
|
||||
impl Callable for wasm_func_callback_t {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
let params = params
|
||||
.iter()
|
||||
.map(|p| wasm_val_t::from_val(p))
|
||||
@@ -549,7 +550,8 @@ impl Callable for wasm_func_callback_t {
|
||||
let out = unsafe { func(params.as_ptr(), out_results.as_mut_ptr()) };
|
||||
if !out.is_null() {
|
||||
let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) };
|
||||
return Err((*trap).into());
|
||||
let trap_info: HostRef<TrapInfo> = (*trap).into();
|
||||
return Err(Trap::from(trap_info));
|
||||
}
|
||||
for i in 0..results.len() {
|
||||
results[i] = out_results[i].val();
|
||||
@@ -558,9 +560,9 @@ impl Callable for wasm_func_callback_t {
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<HostRef<Trap>> for wasm_trap_t {
|
||||
fn into(self) -> HostRef<Trap> {
|
||||
self.trap
|
||||
impl Into<HostRef<TrapInfo>> for wasm_trap_t {
|
||||
fn into(self) -> HostRef<TrapInfo> {
|
||||
self.trap_info
|
||||
}
|
||||
}
|
||||
|
||||
@@ -571,7 +573,7 @@ struct CallbackWithEnv {
|
||||
}
|
||||
|
||||
impl Callable for CallbackWithEnv {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
let params = params
|
||||
.iter()
|
||||
.map(|p| wasm_val_t::from_val(p))
|
||||
@@ -581,7 +583,8 @@ impl Callable for CallbackWithEnv {
|
||||
let out = unsafe { func(self.env, params.as_ptr(), out_results.as_mut_ptr()) };
|
||||
if !out.is_null() {
|
||||
let trap: Box<wasm_trap_t> = unsafe { Box::from_raw(out) };
|
||||
return Err((*trap).into());
|
||||
let trap_info: HostRef<TrapInfo> = (*trap).into();
|
||||
return Err(Trap::from(trap_info));
|
||||
}
|
||||
for i in 0..results.len() {
|
||||
results[i] = out_results[i].val();
|
||||
@@ -677,12 +680,13 @@ pub unsafe extern "C" fn wasm_instance_new(
|
||||
}
|
||||
Box::into_raw(instance)
|
||||
}
|
||||
Err(_) => {
|
||||
Err(trap) => {
|
||||
if !result.is_null() {
|
||||
// TODO Unwrap trap from error
|
||||
let trap = Box::new(wasm_trap_t {
|
||||
trap: HostRef::new(Trap::new("trap during instantiation".to_string())),
|
||||
});
|
||||
let trap_info = match trap.downcast::<Trap>() {
|
||||
Ok(trap) => trap.trap_info_unchecked(),
|
||||
Err(_) => HostRef::new(TrapInfo::new("instance error".to_string())),
|
||||
};
|
||||
let trap = Box::new(wasm_trap_t { trap_info });
|
||||
(*result) = Box::into_raw(trap);
|
||||
}
|
||||
ptr::null_mut()
|
||||
@@ -925,7 +929,7 @@ pub unsafe extern "C" fn wasm_trap_new(
|
||||
}
|
||||
let message = String::from_utf8_lossy(message).to_string();
|
||||
let trap = Box::new(wasm_trap_t {
|
||||
trap: HostRef::new(Trap::new(message)),
|
||||
trap_info: HostRef::new(TrapInfo::new(message)),
|
||||
});
|
||||
Box::into_raw(trap)
|
||||
}
|
||||
@@ -933,7 +937,7 @@ pub unsafe extern "C" fn wasm_trap_new(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasm_trap_message(trap: *const wasm_trap_t, out: *mut wasm_message_t) {
|
||||
let mut buffer = Vec::new();
|
||||
buffer.extend_from_slice((*trap).trap.borrow().message().as_bytes());
|
||||
buffer.extend_from_slice((*trap).trap_info.borrow().message().as_bytes());
|
||||
buffer.reserve_exact(1);
|
||||
buffer.push(0);
|
||||
(*out).set_buffer(buffer);
|
||||
|
||||
@@ -20,7 +20,7 @@ fn test_import_calling_export() {
|
||||
}
|
||||
|
||||
impl Callable for Callback {
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> {
|
||||
self.other
|
||||
.borrow()
|
||||
.as_ref()
|
||||
|
||||
@@ -7,8 +7,8 @@ fn test_trap_return() -> Result<(), String> {
|
||||
struct HelloCallback;
|
||||
|
||||
impl Callable for HelloCallback {
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
Err(HostRef::new(Trap::new("test 123")))
|
||||
fn call(&self, _params: &[Val], _results: &mut [Val]) -> Result<(), Trap> {
|
||||
Err(Trap::new("test 123"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ fn test_trap_return() -> Result<(), String> {
|
||||
|
||||
let imports = vec![hello_func.into()];
|
||||
let instance = Instance::new(&store, &module, imports.as_slice())
|
||||
.map_err(|e| format!("failed to instantiate module: {}", e))?;
|
||||
.map_err(|e| format!("failed to instantiate module: {:?}", e))?;
|
||||
let run_func = instance.exports()[0]
|
||||
.func()
|
||||
.expect("expected function export");
|
||||
@@ -43,7 +43,7 @@ fn test_trap_return() -> Result<(), String> {
|
||||
.err()
|
||||
.expect("error calling function");
|
||||
|
||||
assert_eq!(e.borrow().message(), "test 123");
|
||||
assert_eq!(e.message(), "test 123");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use wasmtime::{
|
||||
pub fn dummy_imports(
|
||||
store: &HostRef<Store>,
|
||||
import_tys: &[ImportType],
|
||||
) -> Result<Vec<Extern>, HostRef<Trap>> {
|
||||
) -> Result<Vec<Extern>, Trap> {
|
||||
let mut imports = Vec::with_capacity(import_tys.len());
|
||||
for imp in import_tys {
|
||||
imports.push(match imp.ty() {
|
||||
@@ -45,7 +45,7 @@ impl DummyFunc {
|
||||
}
|
||||
|
||||
impl Callable for DummyFunc {
|
||||
fn call(&self, _params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, _params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
for (ret_ty, result) in self.0.results().iter().zip(results) {
|
||||
*result = dummy_value(ret_ty)?;
|
||||
}
|
||||
@@ -55,38 +55,38 @@ impl Callable for DummyFunc {
|
||||
}
|
||||
|
||||
/// Construct a dummy value for the given value type.
|
||||
pub fn dummy_value(val_ty: &ValType) -> Result<Val, HostRef<Trap>> {
|
||||
pub fn dummy_value(val_ty: &ValType) -> Result<Val, Trap> {
|
||||
Ok(match val_ty {
|
||||
ValType::I32 => Val::I32(0),
|
||||
ValType::I64 => Val::I64(0),
|
||||
ValType::F32 => Val::F32(0),
|
||||
ValType::F64 => Val::F64(0),
|
||||
ValType::V128 => {
|
||||
return Err(HostRef::new(Trap::new(
|
||||
return Err(Trap::new(
|
||||
"dummy_value: unsupported function return type: v128".to_string(),
|
||||
)))
|
||||
))
|
||||
}
|
||||
ValType::AnyRef => {
|
||||
return Err(HostRef::new(Trap::new(
|
||||
return Err(Trap::new(
|
||||
"dummy_value: unsupported function return type: anyref".to_string(),
|
||||
)))
|
||||
))
|
||||
}
|
||||
ValType::FuncRef => {
|
||||
return Err(HostRef::new(Trap::new(
|
||||
return Err(Trap::new(
|
||||
"dummy_value: unsupported function return type: funcref".to_string(),
|
||||
)))
|
||||
))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Construct a dummy global for the given global type.
|
||||
pub fn dummy_global(store: &HostRef<Store>, ty: GlobalType) -> Result<Global, HostRef<Trap>> {
|
||||
pub fn dummy_global(store: &HostRef<Store>, ty: GlobalType) -> Result<Global, Trap> {
|
||||
let val = dummy_value(ty.content())?;
|
||||
Ok(Global::new(store, ty, val))
|
||||
}
|
||||
|
||||
/// Construct a dummy table for the given table type.
|
||||
pub fn dummy_table(store: &HostRef<Store>, ty: TableType) -> Result<Table, HostRef<Trap>> {
|
||||
pub fn dummy_table(store: &HostRef<Store>, ty: TableType) -> Result<Table, Trap> {
|
||||
let init_val = dummy_value(&ty.element())?;
|
||||
Ok(Table::new(store, ty, init_val))
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ impl wasmtime::Callable for WrappedFn {
|
||||
&self,
|
||||
params: &[wasmtime::Val],
|
||||
returns: &mut [wasmtime::Val],
|
||||
) -> Result<(), wasmtime::HostRef<wasmtime::Trap>> {
|
||||
) -> Result<(), wasmtime::Trap> {
|
||||
let gil = Python::acquire_gil();
|
||||
let py = gil.python();
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any
|
||||
.borrow()
|
||||
.call(&[])
|
||||
{
|
||||
bail!("trapped: {:?}", trap.borrow());
|
||||
bail!("trapped: {:?}", trap);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -9,9 +9,9 @@ struct MyCall<F>(F);
|
||||
|
||||
impl<F> Callable for MyCall<F>
|
||||
where
|
||||
F: Fn(&[Val], &mut [Val]) -> Result<(), HostRef<Trap>>,
|
||||
F: Fn(&[Val], &mut [Val]) -> Result<(), Trap>,
|
||||
{
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), HostRef<Trap>> {
|
||||
fn call(&self, params: &[Val], results: &mut [Val]) -> Result<(), Trap> {
|
||||
(self.0)(params, results)
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ where
|
||||
fn wrap(
|
||||
store: &HostRef<Store>,
|
||||
ty: FuncType,
|
||||
callable: impl Fn(&[Val], &mut [Val]) -> Result<(), HostRef<Trap>> + 'static,
|
||||
callable: impl Fn(&[Val], &mut [Val]) -> Result<(), Trap> + 'static,
|
||||
) -> Func {
|
||||
Func::new(store, ty, Rc::new(MyCall(callable)))
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct WastContext {
|
||||
|
||||
enum Outcome<T = Vec<Val>> {
|
||||
Ok(T),
|
||||
Trap(HostRef<Trap>),
|
||||
Trap(Trap),
|
||||
}
|
||||
|
||||
impl WastContext {
|
||||
@@ -101,7 +101,7 @@ impl WastContext {
|
||||
.filter_map(|e| e.downcast_ref::<InstantiationError>())
|
||||
.next();
|
||||
if let Some(InstantiationError::StartTrap(msg)) = err {
|
||||
return Ok(Outcome::Trap(HostRef::new(Trap::new(msg.clone()))));
|
||||
return Ok(Outcome::Trap(Trap::new(msg.clone())));
|
||||
}
|
||||
return Err(e);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ impl WastContext {
|
||||
fn module(&mut self, instance_name: Option<&str>, module: &[u8]) -> Result<()> {
|
||||
let instance = match self.instantiate(module)? {
|
||||
Outcome::Ok(i) => i,
|
||||
Outcome::Trap(e) => bail!("instantiation failed with: {}", e.borrow().message()),
|
||||
Outcome::Trap(e) => bail!("instantiation failed with: {}", e.message()),
|
||||
};
|
||||
if let Some(name) = instance_name {
|
||||
self.instances.insert(name.to_string(), instance.clone());
|
||||
@@ -241,7 +241,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
},
|
||||
@@ -254,7 +253,6 @@ impl WastContext {
|
||||
bail!("{}\nexpected trap, got {:?}", context(span), values)
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
if t.message().contains(message) {
|
||||
continue;
|
||||
}
|
||||
@@ -283,7 +281,6 @@ impl WastContext {
|
||||
bail!("{}\nexpected trap, got {:?}", context(span), values)
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
if t.message().contains(message) {
|
||||
continue;
|
||||
}
|
||||
@@ -315,7 +312,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
@@ -340,7 +336,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
@@ -365,7 +360,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
@@ -390,7 +384,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
@@ -415,7 +408,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
@@ -440,7 +432,6 @@ impl WastContext {
|
||||
}
|
||||
}
|
||||
Outcome::Trap(t) => {
|
||||
let t = t.borrow();
|
||||
bail!("{}\nunexpected trap: {}", context(span), t.message())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,7 +349,10 @@ fn instantiate_module(
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()?;
|
||||
|
||||
let instance = HostRef::new(Instance::new(store, &module, &imports)?);
|
||||
let instance = HostRef::new(match Instance::new(store, &module, &imports) {
|
||||
Ok(instance) => instance,
|
||||
Err(trap) => bail!("Failed to instantiate {:?}: {:?}", path, trap),
|
||||
});
|
||||
|
||||
Ok((instance, module, data))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user