sp_virtualization/
forwarder.rs1use crate::{
19 host_functions::{virtualization as host_fn, CompiledModule, ExecBuffer, ExecStatus},
20 CompileStatus, ExecError, ExecResult, InstanceId, InstantiateError, MemoryError, ModuleError,
21 ModuleId,
22};
23
24pub struct Module(ModuleId);
26
27impl Module {
28 pub fn from_bytes(
37 bytes: &[u8],
38 identifier: Option<&[u8]>,
39 ) -> Result<(Self, CompileStatus), ModuleError> {
40 let CompiledModule { id, status } = host_fn::compile_from_bytes(bytes, identifier)?;
41 Ok((Self(id), status))
42 }
43
44 pub fn lookup(identifier: &[u8]) -> Result<Self, ModuleError> {
51 Ok(Self(host_fn::lookup(identifier)?))
52 }
53
54 pub fn from_storage_key(
61 storage_key: &[u8],
62 child_trie: &[u8],
63 ) -> Result<(Self, CompileStatus), ModuleError> {
64 let CompiledModule { id, status } =
65 host_fn::compile_from_storage_key(storage_key, child_trie)?;
66 Ok((Self(id), status))
67 }
68
69 pub fn instantiate(&self) -> Result<Instance, InstantiateError> {
70 Ok(Instance(host_fn::instantiate(self.0)?))
71 }
72}
73
74pub struct Instance(InstanceId);
76
77impl Drop for Instance {
78 fn drop(&mut self) {
79 host_fn::destroy(self.0).ok();
80 }
81}
82
83impl core::fmt::Debug for Instance {
84 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
85 f.debug_tuple("Instance").field(&self.0).finish()
86 }
87}
88
89impl Instance {
90 pub fn prepare(self, function: &[u8]) -> Result<Execution, (Self, ExecError)> {
91 match host_fn::prepare(self.0, function) {
92 Ok(()) => {
93 let instance_id = self.0;
94 core::mem::forget(self);
95 Ok(Execution(instance_id))
96 },
97 Err(err) => Err((self, err)),
98 }
99 }
100}
101
102pub struct Execution(InstanceId);
104
105impl Drop for Execution {
106 fn drop(&mut self) {
107 host_fn::destroy(self.0).ok();
108 }
109}
110
111impl Execution {
112 pub fn run(self, gas_left: i64, a0: u64) -> ExecResult<Instance, Self> {
113 let mut buf = ExecBuffer::default();
114 let status_byte = match host_fn::run(self.0, gas_left, a0, &mut buf) {
115 Ok(s) => s,
116 Err(err) => {
117 let instance_id = self.0;
118 core::mem::forget(self);
119 return ExecResult::Error { instance: Instance(instance_id), error: err };
120 },
121 };
122 let status: ExecStatus = status_byte.try_into().expect("invalid status from host; qed");
123 match status {
124 ExecStatus::Finished => {
125 let instance_id = self.0;
126 core::mem::forget(self);
127 ExecResult::Finished { instance: Instance(instance_id), gas_left: buf.gas_left }
128 },
129 ExecStatus::Syscall => ExecResult::Syscall {
130 execution: self,
131 gas_left: buf.gas_left,
132 syscall_symbol: buf.syscall_symbol,
133 a0: buf.a0,
134 a1: buf.a1,
135 a2: buf.a2,
136 a3: buf.a3,
137 a4: buf.a4,
138 a5: buf.a5,
139 },
140 }
141 }
142
143 pub fn read_memory(&mut self, offset: u32, dest: &mut [u8]) -> Result<(), MemoryError> {
144 host_fn::read_memory(self.0, offset, dest)
145 }
146
147 pub fn write_memory(&mut self, offset: u32, src: &[u8]) -> Result<(), MemoryError> {
148 host_fn::write_memory(self.0, offset, src)
149 }
150}