radix_engine/vm/
scrypto_vm.rs1use crate::errors::{RuntimeError, SystemUpstreamError};
2use crate::internal_prelude::*;
3use crate::vm::vm::VmInvoke;
4use crate::vm::wasm::*;
5use crate::vm::wasm_runtime::ScryptoRuntime;
6use crate::vm::VmApi;
7use radix_engine_interface::api::SystemApi;
8use radix_engine_interface::blueprints::package::CodeHash;
9use radix_engine_profiling_derive::trace_resources;
10
11pub struct ScryptoVm<W: WasmEngine> {
12 pub wasm_engine: W,
13 pub wasm_validator_config: WasmValidatorConfigV1,
14}
15
16impl<W: WasmEngine + Default> Default for ScryptoVm<W> {
17 fn default() -> Self {
18 Self {
19 wasm_engine: W::default(),
20 wasm_validator_config: WasmValidatorConfigV1::new(),
21 }
22 }
23}
24
25impl<W: WasmEngine> ScryptoVm<W> {
26 pub fn create_instance(
27 &self,
28 package_address: &PackageAddress,
29 code_hash: CodeHash,
30 instrumented_code: &[u8],
31 ) -> ScryptoVmInstance<W::WasmInstance> {
32 ScryptoVmInstance {
33 instance: self.wasm_engine.instantiate(code_hash, instrumented_code),
34 package_address: *package_address,
35 }
36 }
37}
38
39pub struct ScryptoVmInstance<I: WasmInstance> {
40 instance: I,
41 package_address: PackageAddress,
42}
43
44impl<I: WasmInstance> VmInvoke for ScryptoVmInstance<I> {
45 #[trace_resources(log=self.package_address.is_native_package(), log=self.package_address.to_hex(), log=export_name)]
46 fn invoke<Y: SystemApi<RuntimeError>, V: VmApi>(
47 &mut self,
48 export_name: &str,
49 args: &IndexedScryptoValue,
50 api: &mut Y,
51 vm_api: &V,
52 ) -> Result<IndexedScryptoValue, RuntimeError> {
53 let rtn = {
54 let mut runtime: Box<dyn WasmRuntime> = Box::new(ScryptoRuntime::new(
55 api,
56 self.package_address,
57 export_name.to_string(),
58 vm_api.get_scrypto_version(),
59 ));
60
61 let mut input = Vec::new();
62 input.push(
63 runtime
64 .allocate_buffer(args.as_slice().to_vec())
65 .expect("Failed to allocate buffer"),
66 );
67 self.instance
68 .invoke_export(export_name, input, &mut runtime)?
69 };
70
71 let output = IndexedScryptoValue::from_vec(rtn).map_err(|e| {
72 RuntimeError::SystemUpstreamError(SystemUpstreamError::OutputDecodeError(e))
73 })?;
74
75 Ok(output)
76 }
77}
78
79#[cfg(test)]
80mod tests {
81 const _: () = {
82 fn assert_sync<T: Sync>() {}
83
84 fn assert_all() {
85 #[cfg(not(feature = "alloc"))]
91 assert_sync::<crate::vm::ScryptoVm<crate::vm::wasm::DefaultWasmEngine>>();
92 }
93 };
94}