Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ResourceLimiter API #737

Merged
merged 23 commits into from
Jul 4, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
71fa9d4
Sketch of support for ResourceLimiter API
graydon Jun 29, 2023
c4d66ee
Address review comments.
graydon Jun 30, 2023
8e0da23
Handle the 3 separate ResourceLimiter response types more correctly.
graydon Jun 30, 2023
6afb5ef
Fix typo in existing error message.
graydon Jun 30, 2023
610fae7
Add StoreLimits, StoreLimitsBuilder and docs from wasmtime.
graydon Jun 30, 2023
5f0a428
Fix unused-variable warnings.
graydon Jun 30, 2023
15ab197
Conditionalize ResourceLimiter on cfg(feature="std")
graydon Jun 30, 2023
bcfb80b
Add ResourceLimiter test and fix bugs it uncovered.
graydon Jun 30, 2023
09aaf8d
Avoid redundant limit and size storage in previous wasmtime-like design.
graydon Jun 30, 2023
8eeea83
Thread an ever-so-smaller &mut ResourceLimiterRef into the Executor
graydon Jun 30, 2023
7dc0251
Support no_std differently (import alloc::boxed::Box)
graydon Jul 1, 2023
071df16
Avoid storing &ResourceLimiterRef in Executor (maybe breaks SROA?)
graydon Jul 1, 2023
32da9ff
Fix no_std a little harder.
graydon Jul 1, 2023
9f68c38
Restore TableError::GrowOutOfBounds fields
graydon Jul 3, 2023
14b3c07
Remove now-redundant pub(crate)
graydon Jul 3, 2023
11a0739
Remove unnecessary cfg guard on alloc::boxed::Box
graydon Jul 3, 2023
8436a1c
Address clippy warnings
graydon Jul 3, 2023
1b07fa4
Fix doc reference.
graydon Jul 3, 2023
c005b8f
Some cleanups as requested in review.
graydon Jul 4, 2023
831ec46
Fix wasmi_core doc-link to wasmi, deps do not go that way.
graydon Jul 4, 2023
61d8e45
Fix s/State/Store/ doc typo
graydon Jul 4, 2023
a11d8c1
Add docs on Store::limiter
graydon Jul 4, 2023
25b4e7a
Fix new nightly clippy nit
graydon Jul 4, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions crates/core/src/trap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,13 @@ pub enum TrapCode {
/// internal bytecode so that fuel is consumed for each executed instruction.
/// This is useful to deterministically halt or yield a WebAssembly execution.
OutOfFuel,

/// This trap is raised when a growth operation was attempted and an
/// installed `ResourceLimiter` returned `Err(...)` from the associated
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
/// `table_growing` or `memory_growing` method, indicating a desire on the
/// part of the embedder to trap the interpreter rather than merely fail the
/// growth operation.
GrowthOperationLimited,
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
}

impl TrapCode {
Expand All @@ -305,6 +312,7 @@ impl TrapCode {
Self::StackOverflow => "call stack exhausted",
Self::BadSignature => "indirect call type mismatch",
Self::OutOfFuel => "all fuel consumed by WebAssembly",
Self::GrowthOperationLimited => "growth operation limited",
}
}
}
Expand Down
34 changes: 24 additions & 10 deletions crates/wasmi/src/engine/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ use crate::{
ValueStack,
},
func::FuncEntity,
store::ResourceLimiterRef,
table::TableEntity,
FuelConsumptionMode,
Func,
Expand Down Expand Up @@ -92,15 +93,25 @@ pub enum ReturnOutcome {
///
/// If the Wasm execution traps.
#[inline(never)]
pub fn execute_wasm<'engine>(
ctx: &mut StoreInner,
pub fn execute_wasm<'ctx, 'engine>(
ctx: &'ctx mut StoreInner,
cache: &'engine mut InstanceCache,
value_stack: &'engine mut ValueStack,
call_stack: &'engine mut CallStack,
code_map: &'engine CodeMap,
const_pool: ConstPoolView<'engine>,
resource_limiter: ResourceLimiterRef<'ctx>,
Robbepop marked this conversation as resolved.
Show resolved Hide resolved
) -> Result<WasmOutcome, TrapCode> {
Executor::new(ctx, cache, value_stack, call_stack, code_map, const_pool).execute()
Executor::new(
ctx,
cache,
value_stack,
call_stack,
code_map,
const_pool,
resource_limiter,
)
.execute()
}

/// The function signature of Wasm load operations.
Expand Down Expand Up @@ -168,6 +179,7 @@ struct Executor<'ctx, 'engine> {
code_map: &'engine CodeMap,
/// A read-only view to a pool of constant values.
const_pool: ConstPoolView<'engine>,
resource_limiter: ResourceLimiterRef<'ctx>,
}

macro_rules! forward_call {
Expand Down Expand Up @@ -195,6 +207,7 @@ impl<'ctx, 'engine> Executor<'ctx, 'engine> {
call_stack: &'engine mut CallStack,
code_map: &'engine CodeMap,
const_pool: ConstPoolView<'engine>,
resource_limiter: ResourceLimiterRef<'ctx>,
) -> Self {
let frame = call_stack.pop().expect("must have frame on the call stack");
let sp = value_stack.stack_ptr();
Expand All @@ -208,6 +221,7 @@ impl<'ctx, 'engine> Executor<'ctx, 'engine> {
call_stack,
code_map,
const_pool,
resource_limiter,
}
}

Expand Down Expand Up @@ -1097,9 +1111,8 @@ impl<'ctx, 'engine> Executor<'ctx, 'engine> {
let new_pages = this
.ctx
.resolve_memory_mut(memory)
.grow(delta)
.map(u32::from)
.map_err(|_| EntityGrowError::InvalidGrow)?;
.grow(delta, &mut this.resource_limiter)
.map(u32::from)?;
// The `memory.grow` operation might have invalidated the cached
// linear memory so we need to reset it in order for the cache to
// reload in case it is used again.
Expand Down Expand Up @@ -1217,10 +1230,11 @@ impl<'ctx, 'engine> Executor<'ctx, 'engine> {
|costs| costs.fuel_for_elements(u64::from(delta)),
|this| {
let table = this.cache.get_table(this.ctx, table_index);
this.ctx
.resolve_table_mut(&table)
.grow_untyped(delta, init)
.map_err(|_| EntityGrowError::InvalidGrow)
this.ctx.resolve_table_mut(&table).grow_untyped(
delta,
init,
&mut this.resource_limiter,
)
},
);
let result = match result {
Expand Down
4 changes: 3 additions & 1 deletion crates/wasmi/src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -793,18 +793,20 @@ impl<'engine> EngineExecutor<'engine> {
code.into()
}

let store_inner = &mut ctx.store.inner;
let (store_inner, resource_limiter) = ctx.store.store_inner_and_resource_limiter_ref();
let value_stack = &mut self.stack.values;
let call_stack = &mut self.stack.frames;
let code_map = &self.res.code_map;
let const_pool = self.res.const_pool.view();

execute_wasm(
store_inner,
cache,
value_stack,
call_stack,
code_map,
const_pool,
resource_limiter,
)
.map_err(make_trap)
}
Expand Down
2 changes: 2 additions & 0 deletions crates/wasmi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ mod externref;
mod func;
mod global;
mod instance;
mod limits;
mod linker;
mod memory;
mod module;
Expand Down Expand Up @@ -145,6 +146,7 @@ pub use self::{
},
global::{Global, GlobalType, Mutability},
instance::{Export, ExportsIter, Extern, ExternType, Instance},
limits::{ResourceLimiter, StoreLimits, StoreLimitsBuilder},
linker::Linker,
memory::{Memory, MemoryType},
module::{
Expand Down