Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
62 commits
Select commit Hold shift + click to select a range
cd0a3d3
Initial CLI argument parsing for RR
arjunr2 Jun 4, 2025
016f6b4
Validate RR args with clap
arjunr2 Jun 5, 2025
bd6859f
Setup `RRConfig` for runtime access
arjunr2 Jun 5, 2025
2533f7e
Add rr buffers to `Store`
arjunr2 Jun 5, 2025
21c9e98
Determinism config enforcement during RR
arjunr2 Jun 10, 2025
1dbaa03
Added RR event buffers
arjunr2 Jun 13, 2025
63f96cf
Initial RR serde support
arjunr2 Jun 16, 2025
b832a44
Support types for `RREvent`
arjunr2 Jun 17, 2025
94364b0
Refactor RR infrastructure
arjunr2 Jun 18, 2025
34e78a1
Add compressed validation/no-validation for Record
arjunr2 Jun 20, 2025
a0012df
Added event callback closures
arjunr2 Jun 23, 2025
aeb3c0b
Add replay injection with function call stubbing on trampoline
arjunr2 Jun 23, 2025
89dec1e
Added RR buffer test
arjunr2 Jun 24, 2025
0ed8b80
Clarify docs for RR cli
arjunr2 Jun 24, 2025
e2591d9
Refactor event interface from enum to typed event structs
arjunr2 Jul 1, 2025
b6866f7
Refactor events to indepedent module
arjunr2 Jul 1, 2025
c5d6b62
Added component host function entry/exit event recording
arjunr2 Jul 2, 2025
586ba3a
Added component host function entry/exit (shallow) replay support
arjunr2 Jul 2, 2025
89ea484
fixup! Added component host function entry/exit (shallow) replay support
arjunr2 Jul 3, 2025
f21361b
Support dynamic entrypoints and defining linker imports as trap durin…
arjunr2 Jul 7, 2025
3f187d7
Ensure replay completion and restructure events directory
arjunr2 Jul 8, 2025
73d2a1c
Add recording for lowering, lowering-stores, and reallocations
arjunr2 Jul 9, 2025
8226774
Tighten mutability references acquision points for lowering contexts
arjunr2 Jul 9, 2025
478d4ce
Support event action and iterator on replayer
arjunr2 Jul 11, 2025
8a1347f
fixup! Support event action and iterator on replayer
arjunr2 Jul 11, 2025
7169109
Support recording of memory slice bytes with `MemorySliceCell`
arjunr2 Jul 11, 2025
3a93791
MVP for RR component model complete
arjunr2 Jul 15, 2025
7a1f754
Change interface names for buffers and store
arjunr2 Jul 15, 2025
2f6716b
Added macro wrappers for record/replay stubs
arjunr2 Jul 15, 2025
836ab80
Add `RecordMetadata` to the trace to support optional replay validation
arjunr2 Jul 15, 2025
d2df9f4
Move unsafe for valraw transmute out of rr module
arjunr2 Jul 15, 2025
2c803f9
Added enum in host call rr stubs for readability
arjunr2 Jul 16, 2025
423b19e
fixup! Added enum in host call rr stubs for readability
arjunr2 Jul 16, 2025
0cb5ce1
Switch `rr_event` macro syntax
arjunr2 Jul 16, 2025
42101ea
Initial feature gating of RR for type info; fix doc inclusion for com…
arjunr2 Jul 16, 2025
7c7a60e
Enum and rr type gating for core wasm; bugfix in component lowering type
arjunr2 Jul 16, 2025
0cac3b8
Change all prints to log interface
arjunr2 Jul 18, 2025
d0346fb
Remove `ValRawSer` struct abstraction
arjunr2 Jul 18, 2025
81f8bae
Add wasmtime version to recorded trace
arjunr2 Jul 18, 2025
fdd8b45
Initial support for generic RR readers/writers
arjunr2 Jul 24, 2025
65118cf
Move RR buffer sanity checks into `Drop` implementations
arjunr2 Jul 24, 2025
ceadca3
Added `InstantiationEvent` for checksumming components; also fix repl…
arjunr2 Jul 24, 2025
6cc4147
Added buffered reader/writers for RR
arjunr2 Jul 25, 2025
c15be6e
Fix some defaults and docs
arjunr2 Jul 25, 2025
d819287
Added internal RR event buffering with configurable window size
arjunr2 Jul 28, 2025
4e8e2f8
Prevent memory export during RR for core wasm
arjunr2 Jul 28, 2025
9a056c6
Remove dead code attributes
arjunr2 Jul 28, 2025
217ddd2
Added `replay` command to CLI; refactor config api
arjunr2 Jul 29, 2025
8d3d374
fixup! Added `replay` command to CLI; refactor config api
arjunr2 Jul 29, 2025
03421d6
Added `no_std` support for RR
arjunr2 Jul 29, 2025
2918403
Added RR feature gating and style nits
arjunr2 Jul 30, 2025
8ae8f84
Add notes about `rr` feature configurability
arjunr2 Jul 31, 2025
fdc6887
Refactor type validation across the RR stack
arjunr2 Aug 1, 2025
b500f07
Transition away from macros in component RR
arjunr2 Aug 1, 2025
a468a11
Cleanup core RR funcs and validation flows
arjunr2 Aug 5, 2025
f55bbff
Refactor validation API
arjunr2 Aug 5, 2025
c852b12
Move to typefunc for host function entry validation
arjunr2 Aug 5, 2025
b0dfb0f
Add validation tests and gating across whole project
arjunr2 Aug 5, 2025
205f436
Added configuration flag for deserialization buffer
arjunr2 Aug 6, 2025
a2beaef
Doc comment style fix
arjunr2 Aug 6, 2025
6afb9c1
Added panic stubs for rr in libcalls
arjunr2 Aug 6, 2025
0025593
fixup! Added panic stubs for rr in libcalls
arjunr2 Aug 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,14 @@ gc-drc = ["gc", "wasmtime/gc-drc", "wasmtime-cli-flags/gc-drc"]
gc-null = ["gc", "wasmtime/gc-null", "wasmtime-cli-flags/gc-null"]
pulley = ["wasmtime-cli-flags/pulley"]
stack-switching = ["wasmtime/stack-switching", "wasmtime-cli-flags/stack-switching"]
# `rr` only configures the base infrastructure and is not practically useful by itself
# Use `rr-component` or `rr-core` for generating record/replay events for components/core wasm
# respectively
# Use `rr-validate` for additional validation checks over the above two features
rr = ["wasmtime-cli-flags/rr"]
rr-component = ["wasmtime/rr-component", "rr"]
rr-core = ["wasmtime/rr-core", "rr"]
rr-validate = ["wasmtime/rr-validate", "wasmtime-cli-flags/rr-validate"]

# CLI subcommands for the `wasmtime` executable. See `wasmtime $cmd --help`
# for more information on each subcommand.
Expand Down
2 changes: 2 additions & 0 deletions crates/cli-flags/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,5 @@ threads = ["wasmtime/threads"]
memory-protection-keys = ["wasmtime/memory-protection-keys"]
pulley = ["wasmtime/pulley"]
stack-switching = ["wasmtime/stack-switching"]
rr = ["wasmtime/rr"]
rr-validate = ["wasmtime/rr-validate"]
81 changes: 81 additions & 0 deletions crates/cli-flags/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -478,6 +478,25 @@ wasmtime_option_group! {
}
}

wasmtime_option_group! {
#[derive(PartialEq, Clone, Deserialize)]
#[serde(rename_all = "kebab-case", deny_unknown_fields)]
pub struct RecordOptions {
/// Filesystem endpoint to store the recorded execution trace
pub path: Option<String>,
/// Include (optional) signatures to facilitate validation checks during replay
/// (see `wasmtime replay` for details).
pub validation_metadata: Option<bool>,
/// Window size of internal buffering for record events (large windows offer more opportunities
/// for coalescing events at the cost of memory usage).
pub event_window_size: Option<usize>,
}

enum Record {
...
}
}

#[derive(Debug, Clone, PartialEq)]
pub struct WasiNnGraph {
pub format: String,
Expand Down Expand Up @@ -528,6 +547,18 @@ pub struct CommonOptions {
#[serde(skip)]
wasi_raw: Vec<opt::CommaSeparated<Wasi>>,

/// Options to enable and configure execution recording, `-R help` to see all.
///
/// Generates of a serialized trace of the Wasm module execution that captures all
/// non-determinism observable by the module. This trace can subsequently be
/// re-executed in a determinstic, embedding-agnostic manner (see the `wasmtime replay` command).
///
/// Note: Minimal configs for deterministic Wasm semantics will be
/// enforced during recording by default (NaN canonicalization, deterministic relaxed SIMD)
#[arg(short = 'R', long = "record", value_name = "KEY[=VAL[,..]]")]
#[serde(skip)]
record_raw: Vec<opt::CommaSeparated<Record>>,

// These fields are filled in by the `configure` method below via the
// options parsed from the CLI above. This is what the CLI should use.
#[arg(skip)]
Expand All @@ -554,6 +585,10 @@ pub struct CommonOptions {
#[serde(rename = "wasi", default)]
pub wasi: WasiOptions,

#[arg(skip)]
#[serde(rename = "record", default)]
pub record: RecordOptions,

/// The target triple; default is the host triple
#[arg(long, value_name = "TARGET")]
#[serde(skip)]
Expand Down Expand Up @@ -600,12 +635,14 @@ impl CommonOptions {
debug_raw: Vec::new(),
wasm_raw: Vec::new(),
wasi_raw: Vec::new(),
record_raw: Vec::new(),
configured: true,
opts: Default::default(),
codegen: Default::default(),
debug: Default::default(),
wasm: Default::default(),
wasi: Default::default(),
record: Default::default(),
target: None,
config: None,
}
Expand All @@ -623,12 +660,14 @@ impl CommonOptions {
self.debug = toml_options.debug;
self.wasm = toml_options.wasm;
self.wasi = toml_options.wasi;
self.record = toml_options.record;
}
self.opts.configure_with(&self.opts_raw);
self.codegen.configure_with(&self.codegen_raw);
self.debug.configure_with(&self.debug_raw);
self.wasm.configure_with(&self.wasm_raw);
self.wasi.configure_with(&self.wasi_raw);
self.record.configure_with(&self.record_raw);
Ok(())
}

Expand Down Expand Up @@ -970,6 +1009,35 @@ impl CommonOptions {
true => err,
}

let record = &self.record;
match_feature! {
["rr" : record.path.clone()]
path => {
use std::{io::BufWriter, sync::Arc};
use wasmtime::{RecordConfig, RecordSettings};
let default_settings = RecordSettings::default();
match_feature! {
["rr-validate": record.validation_metadata]
_v => (),
_ => err,
}
config.enable_record(RecordConfig {
writer_initializer: Arc::new(move || {
Box::new(BufWriter::new(fs::File::create(&path).unwrap()))
}),
settings: RecordSettings {
add_validation: record
.validation_metadata
.unwrap_or(default_settings.add_validation),
event_window_size: record
.event_window_size
.unwrap_or(default_settings.event_window_size),
},
})?
},
_ => err,
}

Ok(config)
}

Expand Down Expand Up @@ -1074,6 +1142,7 @@ mod tests {
[debug]
[wasm]
[wasi]
[record]
"#;
let mut common_options: CommonOptions = toml::from_str(basic_toml).unwrap();
common_options.config(None).unwrap();
Expand Down Expand Up @@ -1195,6 +1264,8 @@ impl fmt::Display for CommonOptions {
wasm,
wasi_raw,
wasi,
record_raw,
record,
configured,
target,
config,
Expand All @@ -1211,13 +1282,15 @@ impl fmt::Display for CommonOptions {
let wasi_flags;
let wasm_flags;
let debug_flags;
let record_flags;

if *configured {
codegen_flags = codegen.to_options();
debug_flags = debug.to_options();
wasi_flags = wasi.to_options();
wasm_flags = wasm.to_options();
opts_flags = opts.to_options();
record_flags = record.to_options();
} else {
codegen_flags = codegen_raw
.iter()
Expand All @@ -1228,6 +1301,11 @@ impl fmt::Display for CommonOptions {
wasi_flags = wasi_raw.iter().flat_map(|t| t.0.iter()).cloned().collect();
wasm_flags = wasm_raw.iter().flat_map(|t| t.0.iter()).cloned().collect();
opts_flags = opts_raw.iter().flat_map(|t| t.0.iter()).cloned().collect();
record_flags = record_raw
.iter()
.flat_map(|t| t.0.iter())
.cloned()
.collect();
}

for flag in codegen_flags {
Expand All @@ -1245,6 +1323,9 @@ impl fmt::Display for CommonOptions {
for flag in debug_flags {
write!(f, "-D{flag} ")?;
}
for flag in record_flags {
write!(f, "-R{flag} ")?;
}

Ok(())
}
Expand Down
2 changes: 2 additions & 0 deletions crates/environ/src/component/artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ pub struct ComponentArtifacts {
pub types: ComponentTypes,
/// Serialized metadata about all included core wasm modules.
pub static_modules: PrimaryMap<StaticModuleIndex, CompiledModuleInfo>,
/// A SHA-256 checksum of the source Wasm binary from which the component was compiled
pub checksum: [u8; 32],
}

/// Runtime state that a component retains to support its operation.
Expand Down
20 changes: 19 additions & 1 deletion crates/wasmtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ wat = { workspace = true, optional = true }
serde = { workspace = true }
serde_derive = { workspace = true }
serde_json = { workspace = true, optional = true }
postcard = { workspace = true }
postcard = { workspace = true, optional = true }
indexmap = { workspace = true }
once_cell = { version = "1.12.0", optional = true }
rayon = { version = "1.0", optional = true }
Expand All @@ -62,6 +62,8 @@ smallvec = { workspace = true, optional = true }
hashbrown = { workspace = true, features = ["default-hasher"] }
bitflags = { workspace = true }
futures = { workspace = true, features = ["alloc"], optional = true }
embedded-io = { version = "0.6.1", features = ["alloc"], optional = true }
sha2 = "0.10.2"

[target.'cfg(target_os = "windows")'.dependencies.windows-sys]
workspace = true
Expand Down Expand Up @@ -325,6 +327,7 @@ addr2line = ["dep:addr2line", "dep:gimli", "std"]
# Many features of the Wasmtime crate implicitly require this `std` feature.
# This will be automatically enabled if necessary.
std = [
'dep:postcard',
'postcard/use-std',
'wasmtime-environ/std',
'object/std',
Expand Down Expand Up @@ -393,3 +396,18 @@ component-model-async = [
"wasmtime-component-macro?/component-model-async",
"dep:futures"
]


# `rr` only configures the base infrastructure and is not practically useful by itself
# Use `rr-component` or `rr-core` for generating record/replay events for components/core wasm
# respectively
rr = ["dep:embedded-io", "dep:postcard"]
# RR for components
rr-component = ["component-model", "rr"]
# RR for core wasm
rr-core = ["rr"]

# Support for validation signatures/checks during record/replay respectively.
# This feature only makes sense if 'rr-component' or 'rr-core' is enabled
rr-validate = ["rr"]

2 changes: 2 additions & 0 deletions crates/wasmtime/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use crate::Engine;
use crate::hash_map::HashMap;
use crate::hash_set::HashSet;
use crate::prelude::*;
use sha2::{Digest, Sha256};
use std::{
any::Any,
borrow::Cow,
Expand Down Expand Up @@ -198,6 +199,7 @@ pub(crate) fn build_component_artifacts<T: FinishedObject>(
ty,
types,
static_modules: compilation_artifacts.modules,
checksum: Sha256::digest(binary).into(),
};
object.serialize_info(&artifacts);

Expand Down
Loading