1#![deny(missing_docs, unsafe_code)]
29
30pub use access::{mut_keys, mut_keys_set, mut_keys_slices, Access};
31pub use cached::LazyCache;
32#[doc(inline)]
33pub use essential_asm::{self as asm, Op};
34pub use essential_types as types;
35use essential_types::ContentAddress;
36#[doc(inline)]
37pub use future::ExecFuture;
38#[doc(inline)]
39pub use memory::Memory;
40#[doc(inline)]
41pub use op_access::OpAccess;
42#[doc(inline)]
43pub use repeat::Repeat;
44#[doc(inline)]
45pub use stack::Stack;
46#[doc(inline)]
47pub use state_read::StateRead;
48#[doc(inline)]
49pub use total_control_flow::ProgramControlFlow;
50#[doc(inline)]
51pub use vm::Vm;
52
53mod access;
54mod alu;
55pub mod bytecode;
56mod cached;
57mod crypto;
58pub mod error;
59mod future;
60mod memory;
61mod op_access;
62mod pred;
63mod repeat;
64mod sets;
65mod stack;
66mod state_read;
67pub mod sync;
68mod total_control_flow;
69mod vm;
70
71pub type BytecodeMapped<Bytes = Vec<u8>> = bytecode::BytecodeMapped<Op, Bytes>;
73pub type BytecodeMappedSlice<'a> = bytecode::BytecodeMappedSlice<'a, Op>;
75pub type BytecodeMappedLazy<I> = bytecode::BytecodeMappedLazy<Op, I>;
77
78pub type Gas = u64;
80
81#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
83pub struct GasLimit {
84 pub per_yield: Gas,
86 pub total: Gas,
88}
89
90#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
92pub(crate) enum OpKind {
93 Sync(OpSync),
95 Async(OpAsync),
97}
98
99#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
101pub struct OpAsync(asm::StateRead);
102
103#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, PartialOrd, Ord)]
105pub enum OpSync {
106 Access(asm::Access),
108 Alu(asm::Alu),
110 ControlFlow(asm::TotalControlFlow),
112 Crypto(asm::Crypto),
114 Memory(asm::Memory),
116 Pred(asm::Pred),
118 Stack(asm::Stack),
120}
121
122pub trait OpGasCost {
124 fn op_gas_cost(&self, op: &Op) -> Gas;
126}
127
128impl GasLimit {
129 pub const DEFAULT_PER_YIELD: Gas = 4_096;
133
134 pub const UNLIMITED: Self = Self {
136 per_yield: Self::DEFAULT_PER_YIELD,
137 total: Gas::MAX,
138 };
139}
140
141impl From<Op> for OpKind {
142 fn from(op: Op) -> Self {
143 match op {
144 Op::Access(op) => OpKind::Sync(OpSync::Access(op)),
145 Op::Alu(op) => OpKind::Sync(OpSync::Alu(op)),
146 Op::Crypto(op) => OpKind::Sync(OpSync::Crypto(op)),
147 Op::Memory(op) => OpKind::Sync(OpSync::Memory(op)),
148 Op::Pred(op) => OpKind::Sync(OpSync::Pred(op)),
149 Op::Stack(op) => OpKind::Sync(OpSync::Stack(op)),
150 Op::StateRead(op) => OpKind::Async(OpAsync(op)),
151 Op::TotalControlFlow(op) => OpKind::Sync(OpSync::ControlFlow(op)),
152 }
153 }
154}
155
156impl<F> OpGasCost for F
157where
158 F: Fn(&Op) -> Gas,
159{
160 fn op_gas_cost(&self, op: &Op) -> Gas {
161 (*self)(op)
162 }
163}
164
165#[cfg(feature = "tracing")]
171pub(crate) fn trace_op_res<OA, T, E>(
172 oa: &mut OA,
173 pc: usize,
174 stack: &Stack,
175 memory: &Memory,
176 op_res: Result<T, E>,
177) where
178 OA: OpAccess,
179 OA::Op: core::fmt::Debug,
180 E: core::fmt::Display,
181{
182 let op = oa
183 .op_access(pc)
184 .expect("must exist as retrieved previously")
185 .expect("must exist as retrieved previously");
186 let pc_op = format!("0x{:02X}: {op:?}", pc);
187 match op_res {
188 Ok(_) => {
189 tracing::trace!("{pc_op}\n ├── {:?}\n └── {:?}", stack, memory)
190 }
191 Err(ref err) => {
192 tracing::trace!("{pc_op}");
193 tracing::debug!("{err}");
194 }
195 }
196}