MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / differential

Function differential

crates/fuzzing/src/oracles.rs:456–521  ·  view source on GitHub ↗

Evaluate the function identified by `name` in two different engine instances--`lhs` and `rhs`. Returns `Ok(true)` if more evaluations can happen or `Ok(false)` if the instances may have drifted apart and no more evaluations can happen. # Panics This will panic if the evaluation is different between engines (e.g., results are different, hashed instance is different, one side traps, etc.).

(
    lhs: &mut dyn DiffInstance,
    lhs_engine: &dyn DiffEngine,
    rhs: &mut WasmtimeInstance,
    name: &str,
    args: &[DiffValue],
    result_tys: &[DiffValueType],
)

Source from the content-addressed store, hash-verified

454/// This will panic if the evaluation is different between engines (e.g.,
455/// results are different, hashed instance is different, one side traps, etc.).
456pub fn differential(
457 lhs: &mut dyn DiffInstance,
458 lhs_engine: &dyn DiffEngine,
459 rhs: &mut WasmtimeInstance,
460 name: &str,
461 args: &[DiffValue],
462 result_tys: &[DiffValueType],
463) -> wasmtime::Result<bool> {
464 log::debug!("Evaluating: `{name}` with {args:?}");
465 let lhs_results = match lhs.evaluate(name, args, result_tys) {
466 Ok(Some(results)) => Ok(results),
467 Err(e) => Err(e),
468 // this engine couldn't execute this type signature, so discard this
469 // execution by returning success.
470 Ok(None) => return Ok(true),
471 };
472 log::debug!(" -> lhs results on {}: {:?}", lhs.name(), &lhs_results);
473
474 let rhs_results = rhs
475 .evaluate(name, args, result_tys)
476 // wasmtime should be able to invoke any signature, so unwrap this result
477 .map(|results| results.unwrap());
478 log::debug!(" -> rhs results on {}: {:?}", rhs.name(), &rhs_results);
479
480 // If Wasmtime hit its OOM condition, which is possible since it's set
481 // somewhat low while fuzzing, then don't return an error but return
482 // `false` indicating that differential fuzzing must stop. There's no
483 // guarantee the other engine has the same OOM limits as Wasmtime, and
484 // it's assumed that Wasmtime is configured to have a more conservative
485 // limit than the other engine.
486 if rhs.is_oom() {
487 return Ok(false);
488 }
489
490 match DiffEqResult::new(lhs_engine, lhs_results, rhs_results) {
491 DiffEqResult::Success(lhs, rhs) => assert_eq!(lhs, rhs),
492 DiffEqResult::Poisoned => return Ok(false),
493 DiffEqResult::Failed => {}
494 }
495
496 for (global, ty) in rhs.exported_globals() {
497 log::debug!("Comparing global `{global}`");
498 let lhs = match lhs.get_global(&global, ty) {
499 Some(val) => val,
500 None => continue,
501 };
502 let rhs = rhs.get_global(&global, ty).unwrap();
503 assert_eq!(lhs, rhs);
504 }
505 for (memory, shared) in rhs.exported_memories() {
506 log::debug!("Comparing memory `{memory}`");
507 let lhs = match lhs.get_memory(&memory, shared) {
508 Some(val) => val,
509 None => continue,
510 };
511 let rhs = rhs.get_memory(&memory, shared).unwrap();
512 if lhs == rhs {
513 continue;

Callers 1

execute_oneFunction · 0.85

Calls 10

OkFunction · 0.85
exported_globalsMethod · 0.80
exported_memoriesMethod · 0.80
newFunction · 0.50
evaluateMethod · 0.45
mapMethod · 0.45
unwrapMethod · 0.45
is_oomMethod · 0.45
get_globalMethod · 0.45
get_memoryMethod · 0.45

Tested by

no test coverage detected