mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-22 05:01:33 +00:00
Support checking the execution limit exceeded error.
This commit is contained in:
@ -34,6 +34,9 @@ impl Metering {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
pub struct ExecutionLimitExceededError;
|
||||||
|
|
||||||
impl FunctionMiddleware for Metering {
|
impl FunctionMiddleware for Metering {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
fn feed_event<'a, 'b: 'a>(
|
fn feed_event<'a, 'b: 'a>(
|
||||||
@ -93,9 +96,8 @@ impl FunctionMiddleware for Metering {
|
|||||||
}));
|
}));
|
||||||
sink.push(Event::Internal(InternalEvent::Breakpoint(Box::new(
|
sink.push(Event::Internal(InternalEvent::Breakpoint(Box::new(
|
||||||
move |ctx| {
|
move |ctx| {
|
||||||
eprintln!("execution limit reached");
|
|
||||||
unsafe {
|
unsafe {
|
||||||
(ctx.throw)();
|
(ctx.throw)(Box::new(ExecutionLimitExceededError));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
))));
|
))));
|
||||||
@ -251,6 +253,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_traps_after_costly_call() {
|
fn test_traps_after_costly_call() {
|
||||||
|
use wasmer_runtime_core::error::RuntimeError;
|
||||||
let wasm_binary = wat2wasm(WAT).unwrap();
|
let wasm_binary = wat2wasm(WAT).unwrap();
|
||||||
|
|
||||||
let limit = 100u64;
|
let limit = 100u64;
|
||||||
@ -265,8 +268,13 @@ mod tests {
|
|||||||
let add_to: Func<(i32, i32), i32> = instance.func("add_to").unwrap();
|
let add_to: Func<(i32, i32), i32> = instance.func("add_to").unwrap();
|
||||||
let result = add_to.call(10_000_000, 4);
|
let result = add_to.call(10_000_000, 4);
|
||||||
|
|
||||||
// verify it errors
|
let err = result.unwrap_err();
|
||||||
assert_eq!(result.is_err(), true); // TODO assert that the trap is caused by PointsExausted
|
match err {
|
||||||
|
RuntimeError::Error { data } => {
|
||||||
|
assert!(data.downcast_ref::<ExecutionLimitExceededError>().is_some());
|
||||||
|
},
|
||||||
|
_ => unreachable!(),
|
||||||
|
}
|
||||||
|
|
||||||
// verify is uses the correct number of points
|
// verify is uses the correct number of points
|
||||||
assert_eq!(get_points_used(&instance), 109); // Used points will be slightly more than `limit` because of the way we do gas checking.
|
assert_eq!(get_points_used(&instance), 109); // Used points will be slightly more than `limit` because of the way we do gas checking.
|
||||||
|
@ -8,6 +8,7 @@ use crate::{
|
|||||||
types::{FuncIndex, FuncSig, SigIndex},
|
types::{FuncIndex, FuncSig, SigIndex},
|
||||||
};
|
};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
use std::any::Any;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
@ -43,7 +44,7 @@ impl fmt::Debug for InternalEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct BkptInfo {
|
pub struct BkptInfo {
|
||||||
pub throw: unsafe extern "C" fn() -> !,
|
pub throw: unsafe fn(Box<dyn Any>) -> !,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule, E: Debug> {
|
pub trait ModuleCodeGenerator<FCG: FunctionCodeGenerator<E>, RM: RunnableModule, E: Debug> {
|
||||||
|
@ -128,11 +128,12 @@ pub fn call_protected<T>(f: impl FnOnce() -> T) -> Result<T, CallProtError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe extern "C" fn throw() -> ! {
|
pub unsafe fn throw(payload: Box<dyn Any>) -> ! {
|
||||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||||
if *jmp_buf == [0; SETJMP_BUFFER_LEN] {
|
if *jmp_buf == [0; SETJMP_BUFFER_LEN] {
|
||||||
::std::process::abort();
|
::std::process::abort();
|
||||||
}
|
}
|
||||||
|
TRAP_EARLY_DATA.with(|cell| cell.replace(Some(payload)));
|
||||||
longjmp(jmp_buf as *mut ::nix::libc::c_void, 0xffff);
|
longjmp(jmp_buf as *mut ::nix::libc::c_void, 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@ use wasmer_runtime_core::{
|
|||||||
use wasmer_singlepass_backend::ModuleCodeGenerator as SinglePassMCG;
|
use wasmer_singlepass_backend::ModuleCodeGenerator as SinglePassMCG;
|
||||||
#[cfg(feature = "wasi")]
|
#[cfg(feature = "wasi")]
|
||||||
use wasmer_wasi;
|
use wasmer_wasi;
|
||||||
|
use wasmer_middleware_common::metering::Metering;
|
||||||
|
|
||||||
// stub module to make conditional compilation happy
|
// stub module to make conditional compilation happy
|
||||||
#[cfg(not(feature = "wasi"))]
|
#[cfg(not(feature = "wasi"))]
|
||||||
|
Reference in New Issue
Block a user