Skip to content

Commit

Permalink
Change setting fuel to adding fuel
Browse files Browse the repository at this point in the history
  • Loading branch information
alexcrichton committed Jan 28, 2021
1 parent f078778 commit b892ff9
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 22 deletions.
8 changes: 4 additions & 4 deletions crates/fuzzing/src/oracles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ pub fn instantiate_with_config(

let mut timeout_state = SignalOnDrop::default();
match timeout {
Timeout::Fuel(fuel) => store.set_fuel_remaining(fuel),
Timeout::Fuel(fuel) => store.add_fuel(fuel),
// If a timeout is requested then we spawn a helper thread to wait for
// the requested time and then send us a signal to get interrupted. We
// also arrange for the thread's sleep to get interrupted if we return
Expand Down Expand Up @@ -418,7 +418,7 @@ pub fn spectest(fuzz_config: crate::generators::Config, test: crate::generators:
config.wasm_bulk_memory(false);
let store = Store::new(&Engine::new(&config));
if fuzz_config.consume_fuel {
store.set_fuel_remaining(i64::max_value() as u64);
store.add_fuel(u64::max_value());
}
let mut wast_context = WastContext::new(store);
wast_context.register_spectest().unwrap();
Expand All @@ -442,7 +442,7 @@ pub fn table_ops(
let engine = Engine::new(&config);
let store = Store::new(&engine);
if fuzz_config.consume_fuel {
store.set_fuel_remaining(i64::max_value() as u64);
store.add_fuel(u64::max_value());
}

let wasm = ops.to_wasm_binary();
Expand Down Expand Up @@ -557,7 +557,7 @@ pub fn differential_wasmi_execution(wasm: &[u8], config: &crate::generators::Con
let wasmtime_engine = Engine::new(&wasmtime_config);
let wasmtime_store = Store::new(&wasmtime_engine);
if config.consume_fuel {
wasmtime_store.set_fuel_remaining(i64::max_value() as u64);
wasmtime_store.add_fuel(u64::max_value());
}
let wasmtime_module =
Module::new(&wasmtime_engine, &wasm).expect("Wasmtime can compile module");
Expand Down
41 changes: 26 additions & 15 deletions crates/wasmtime/src/store.rs
Original file line number Diff line number Diff line change
Expand Up @@ -440,11 +440,6 @@ impl Store {
/// [`Config::consume_fuel`](crate::Config::consume_fuel) then this
/// function will return `None`. Also note that fuel, if enabled, must be
/// originally configured via [`Store::set_fuel_remaining`].
///
/// Finally, this will only return the amount of fuel consumed since
/// [`Store::set_fuel_remaining`] was last called, so this does not return
/// the total amount of fuel consumed for the entire lifetime of this
/// [`Store`].
pub fn fuel_consumed(&self) -> Option<u64> {
if !self.engine().config().tunables.consume_fuel {
return None;
Expand All @@ -453,8 +448,7 @@ impl Store {
Some(u64::try_from(self.inner.fuel_adj.get() + consumed).unwrap())
}

/// Updates the amount of fuel remaining in this [`Store`] available for
/// wasm to consume while executing.
/// Adds fuel to this [`Store`] for wasm to consume while executing.
///
/// For this method to work fuel consumption must be enabled via
/// [`Config::consume_fuel`](crate::Config::consume_fuel). By default a
Expand All @@ -469,15 +463,32 @@ impl Store {
///
/// This function will panic if the store's [`Config`](crate::Config) did
/// not have fuel consumption enabled.
///
/// This funtion will also panic if `remaining` is larger than
/// `i64::max_value()`.
pub fn set_fuel_remaining(&self, remaining: u64) {
pub fn add_fuel(&self, fuel: u64) {
assert!(self.engine().config().tunables.consume_fuel);
let remaining = i64::try_from(remaining).unwrap();
self.inner.fuel_adj.set(remaining);
unsafe {
*self.inner.interrupts.fuel_consumed.get() = -remaining;

// Fuel is stored as an i64, so we need to cast it. If the provided fuel
// value overflows that just assume that i64::max will suffice. Wasm
// execution isn't fast enough to burn through i64::max fuel in any
// reasonable amount of time anyway.
let fuel = i64::try_from(fuel).unwrap_or(i64::max_value());
let adj = self.inner.fuel_adj.get();
let consumed_ptr = unsafe { &mut *self.inner.interrupts.fuel_consumed.get() };

match (consumed_ptr.checked_sub(fuel), adj.checked_add(fuel)) {
// If we succesfully did arithmetic without overflowing then we can
// just update our fields.
(Some(consumed), Some(adj)) => {
self.inner.fuel_adj.set(adj);
*consumed_ptr = consumed;
}

// Otherwise something overflowed. Make sure that we preserve the
// amount of fuel that's already consumed, but otherwise assume that
// we were given infinite fuel.
_ => {
self.inner.fuel_adj.set(i64::max_value());
*consumed_ptr = (*consumed_ptr + adj) - i64::max_value();
}
}
}
}
Expand Down
5 changes: 2 additions & 3 deletions tests/all/fuel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,12 @@ fn run() -> Result<()> {
}

fn fuel_consumed(wasm: &[u8]) -> u64 {
const MAX: u64 = 10_000;
let mut config = Config::new();
config.consume_fuel(true);
let engine = Engine::new(&config);
let module = Module::new(&engine, wasm).unwrap();
let store = Store::new(&engine);
store.set_fuel_remaining(MAX);
store.add_fuel(u64::max_value());
drop(Instance::new(&store, &module, &[]));
store.fuel_consumed().unwrap()
}
Expand Down Expand Up @@ -114,7 +113,7 @@ fn iloop() {
let engine = Engine::new(&config);
let module = Module::new(&engine, wat).unwrap();
let store = Store::new(&engine);
store.set_fuel_remaining(10_000);
store.add_fuel(10_000);
let error = Instance::new(&store, &module, &[]).err().unwrap();
assert!(
error.to_string().contains("all fuel consumed"),
Expand Down

0 comments on commit b892ff9

Please sign in to comment.