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

Function step

cranelift/interpreter/src/step.rs:62–1342  ·  view source on GitHub ↗

Interpret a single Cranelift instruction. Note that program traps and interpreter errors are distinct: a program trap results in `Ok(Flow::Trap(...))` whereas an interpretation error (e.g. the types of two values are incompatible) results in `Err(...)`.

(state: &mut dyn State<'a>, inst_context: I)

Source from the content-addressed store, hash-verified

60/// distinct: a program trap results in `Ok(Flow::Trap(...))` whereas an interpretation error (e.g.
61/// the types of two values are incompatible) results in `Err(...)`.
62pub fn step<'a, I>(state: &mut dyn State<'a>, inst_context: I) -> Result<ControlFlow<'a>, StepError>
63where
64 I: InstructionContext,
65{
66 let inst = inst_context.data();
67 let ctrl_ty = inst_context.controlling_type().unwrap();
68 trace!(
69 "Step: {}{}",
70 inst.opcode(),
71 if ctrl_ty.is_invalid() {
72 String::new()
73 } else {
74 format!(".{ctrl_ty}")
75 }
76 );
77
78 // The following closures make the `step` implementation much easier to express. Note that they
79 // frequently close over the `state` or `inst_context` for brevity.
80
81 // Retrieve the current value for an instruction argument.
82 let arg = |index: usize| -> DataValue {
83 let value_ref = inst_context.args()[index];
84 state.current_frame().get(value_ref).clone()
85 };
86
87 // Retrieve the current values for all of an instruction's arguments.
88 let args = || -> SmallVec<[DataValue; 1]> { state.collect_values(inst_context.args()) };
89
90 // Retrieve the current values for a range of an instruction's arguments.
91 let args_range = |indexes: RangeFrom<usize>| -> Result<SmallVec<[DataValue; 1]>, StepError> {
92 Ok(SmallVec::<[DataValue; 1]>::from(&args()[indexes]))
93 };
94
95 // Retrieve the immediate value for an instruction, expecting it to exist.
96 let imm = || -> DataValue {
97 match inst {
98 InstructionData::UnaryConst {
99 constant_handle,
100 opcode,
101 } => {
102 let buffer = state
103 .get_current_function()
104 .dfg
105 .constants
106 .get(constant_handle);
107 match (ctrl_ty.bytes(), opcode) {
108 (_, Opcode::F128const) => {
109 DataValue::F128(buffer.try_into().expect("a 16-byte data buffer"))
110 }
111 (16, Opcode::Vconst) => DataValue::V128(
112 buffer.as_slice().try_into().expect("a 16-byte data buffer"),
113 ),
114 (8, Opcode::Vconst) => {
115 DataValue::V64(buffer.as_slice().try_into().expect("an 8-byte data buffer"))
116 }
117 (4, Opcode::Vconst) => {
118 DataValue::V32(buffer.as_slice().try_into().expect("a 4-byte data buffer"))
119 }

Callers 1

blockMethod · 0.85

Calls 15

OkFunction · 0.85
fromFunction · 0.85
sum_unsignedFunction · 0.85
unary_arithFunction · 0.85
binary_arithFunction · 0.85
collect_block_argsFunction · 0.85
LibCallEnum · 0.85
MemoryErrorEnum · 0.85
bitselectFunction · 0.85
icmpFunction · 0.85
extractlanesFunction · 0.85

Tested by

no test coverage detected