Main evaluator loop and setting up the initial stack frame.
An interpreter for MIR used in CTFE and by miri
Global machine state as well as implementation of the interpreter engine
Machine
trait.
This is a “monotonic FxHashMap
”: A FxHashMap
that, when shared, can be pushed to but not
otherwise mutated. We also box items in the map. This means we can safely provide
shared references into existing items in the FxHashMap
, because they will not be dropped
(from being removed) or moved (because they are boxed).
The API is completely tailored to what memory.rs
needs. It is still in
a separate file to minimize the amount of code that has to care about the unsafety.
Implements a map from integer indices to data.
Rather than storing data for every index, internally, this maps entire ranges to the data.
To this end, the APIs all work on ranges, not on individual integers. Ranges are split as
necessary (e.g., when [0,5) is first associated with X, and then [1,2) is mutated).
Users must not depend on whether a range is coalesced or not, even though this is observable
via the iteration APIs.
Extra per-allocation data
The information that makes up a memory access: offset and size.
A reference to some allocation that was already bounds-checked for the given region
and had the on-access machine hooks run.
A reference to some allocation that was already bounds-checked for the given region
and had the on-access machine hooks run.
This type represents an Allocation in the Miri/CTFE core engine.
Details of an access to uninitialized bytes / bad pointer bytes where it is not allowed.
Tracking pointer provenance
Holds all of the relevant data for when unwinding hits a try
frame.
A monotone clock used for Instant
simulation.
0 is used to indicate that the id was not yet assigned and,
therefore, is not a valid identifier.
Interned types generally have an Outer
type and an Inner
type, where
Outer
is a newtype around Interned<Inner>
, and all the operations are
done on Outer
, because all occurrences are interned. E.g. Ty
is an
outer type and TyKind
is its inner type.
A stack frame.
Extra data stored with each stack frame
What we store about a frame in an interpreter backtrace.
Uniquely identifies one of the following:
0 is used to indicate that the id was not yet assigned and,
therefore, is not a valid identifier.
Packages the kind of error we got from the const code interpreter
up with a Rust-level backtrace of where the error occurred.
These should always be constructed by calling .into()
on
an InterpError
. In rustc_mir::interpret
, we have throw_err_*
macros for this.
An item in the per-location borrow stack.
Input argument for tcx.lit_to_const
.
A MemPlace with its layout. Constructing it is only possible in this module.
Configuration needed to spawn a Miri instance.
The machine itself.
0 is used to indicate that the id was not yet assigned and,
therefore, is not a valid identifier.
Represents a pointer in the Miri engine.
Precomputed layouts of primitive types
State for tracking recursive validation of references
0 is used to indicate that the id was not yet assigned and,
therefore, is not a valid identifier.
Information about a size mismatch.
Extra per-location state.
Extra per-allocation state.
A thread identifier.
A set of threads.
Tree structure with both parents and children since we want to be
able to traverse the tree efficiently in both directions.
We have our own error type that does not know about the AllocId
; that information
is added when converting to InterpError
.
The return value of get_alloc_info
indicates the “kind” of the allocation.
Valid atomic fence orderings, subset of atomic::Ordering.
Valid atomic read orderings, subset of atomic::Ordering.
Valid atomic read-write orderings, alias of atomic::Ordering (not non-exhaustive).
Valid atomic write orderings, subset of atomic::Ordering.
Which borrow tracking method to use
Details of why a pointer had to be in-bounds.
Extra things to check for during validation of CTFE results.
An argment passed to a function.
The value of a function pointer.
An allocation in the global (tcx-managed) memory can be either a function pointer,
a static, or a “real” allocation with some data in it.
An Immediate
represents a single immediate self-contained Rust value.
A contiguous chunk of initialized or uninitialized memory.
How a constant value should be interned.
Error information for when the program we executed turned out not to actually be a valid
program. This cannot happen in stand-alone Miri, but it can happen during CTFE/ConstProp
where we work on generic code or execution does not have all information available.
Error type for tcx.lit_to_const
.
Information required for the sound usage of a MemPlace
.
Extra memory kinds
Miri specific diagnostics
Indicates which permission is granted (by this item to some pointers)
Pointer provenance.
The “extra” information a pointer has over a regular AllocId.
Error information for when the program exhausted the resources granted to it
by the interpreter.
Policy on whether to recurse into fields to retag
A Scalar
represents an immediate, primitive value existing outside of a
memory::Allocation
. It is in many ways like a small chunk of an Allocation
, up to 16 bytes in
size. Like a range of bytes in an Allocation
, a Scalar
can either represent the raw bytes
of a simple value or a pointer into another Allocation
Data returned by Machine::stack_pop,
to provide further control over the popping of the stack frame
Details of premature program termination.
A specific moment in time.
Error information for when the program caused Undefined Behavior.
Error information for when the program did something that might (or might not) be correct
to do according to the Rust spec, but due to limitations in the interpreter, the
operation could not be carried out. These limitations can differ between CTFE and the
Miri engine, e.g., CTFE does not support dereferencing pointers at integral addresses.
Functionality required for the bytes of an Allocation
.
The functionality needed by memory to manage its allocations
Methods of this trait signifies a point where CTFE evaluation would fail
and some use case dependent behaviour can instead be applied.
A trait for machine-specific errors (or other “machine stop” conditions).
Whether this kind of memory is allowed to leak
A little trait that’s useful to be inherited by extension traits.
A thing that we can project into, and that has a layout.
This trait abstracts over the kind of provenance that is associated with a Pointer
. It is
mostly opaque; the Machine
trait extends it with some more operations that also have access to
some global state.
The Debug
rendering is used to display bare provenance, and for the default impl of fmt
.
The Readable
trait describes interpreter values that one can read from.
How to traverse a value and what to do when we are at the leaves.
The Weiteable
trait describes interpreter values that can be written to.