1#![allow(unused_variables)]
10
11use core::{ffi::c_char, marker::PhantomData};
12
13use wamr_sys::{
14 wasm_module_inst_t, wasm_runtime_deinstantiate, wasm_runtime_destroy_thread_env,
15 wasm_runtime_init_thread_env, wasm_runtime_instantiate,
16};
17
18use crate::{
19 helper::error_buf_to_string, helper::DEFAULT_ERROR_BUF_SIZE, module::Module, runtime::Runtime,
20 RuntimeError,
21};
22
23#[derive(Debug)]
24pub struct Instance<'module> {
25 instance: wasm_module_inst_t,
26 _phantom: PhantomData<Module<'module>>,
27}
28
29impl<'module> Instance<'module> {
30 pub fn new(
36 runtime: &Runtime,
37 module: &'module Module<'module>,
38 stack_size: u32,
39 ) -> Result<Self, RuntimeError> {
40 Self::new_with_args(runtime, module, stack_size, 0)
41 }
42
43 pub fn new_with_args(
51 _runtime: &Runtime,
52 module: &'module Module<'module>,
53 stack_size: u32,
54 heap_size: u32,
55 ) -> Result<Self, RuntimeError> {
56 let init_thd_env = unsafe { wasm_runtime_init_thread_env() };
57 if !init_thd_env {
58 return Err(RuntimeError::InstantiationFailure(String::from(
59 "thread signal env initialized failed",
60 )));
61 }
62
63 let mut error_buf = [0 as c_char; DEFAULT_ERROR_BUF_SIZE];
64 let instance = unsafe {
65 wasm_runtime_instantiate(
66 module.get_inner_module(),
67 stack_size,
68 heap_size,
69 error_buf.as_mut_ptr(),
70 error_buf.len() as u32,
71 )
72 };
73
74 if instance.is_null() {
75 match error_buf.len() {
76 0 => {
77 return Err(RuntimeError::InstantiationFailure(String::from(
78 "instantiation failed",
79 )))
80 }
81 _ => {
82 return Err(RuntimeError::InstantiationFailure(error_buf_to_string(
83 &error_buf,
84 )))
85 }
86 }
87 }
88
89 Ok(Instance {
90 instance,
91 _phantom: PhantomData,
92 })
93 }
94
95 pub fn get_inner_instance(&self) -> wasm_module_inst_t {
96 self.instance
97 }
98}
99
100impl Drop for Instance<'_> {
101 fn drop(&mut self) {
102 unsafe {
103 wasm_runtime_destroy_thread_env();
104 wasm_runtime_deinstantiate(self.instance);
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use crate::runtime::Runtime;
113 use wamr_sys::{
114 wasm_runtime_get_running_mode, RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT,
115 };
116
117 #[test]
118 fn test_instance_new() {
119 let runtime = Runtime::new().unwrap();
120
121 let binary = vec![
129 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f,
130 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64,
131 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
132 ];
133 let binary = binary.into_iter().map(|c| c as u8).collect::<Vec<u8>>();
134
135 let module = Module::from_vec(&runtime, binary, "add");
136 assert!(module.is_ok());
137
138 let module = &module.unwrap();
139
140 let instance = Instance::new_with_args(&runtime, module, 1024, 1024);
141 assert!(instance.is_ok());
142
143 let instance = Instance::new_with_args(&runtime, module, 1024, 0);
144 assert!(instance.is_ok());
145
146 let instance = instance.unwrap();
147 assert_eq!(
148 unsafe { wasm_runtime_get_running_mode(instance.get_inner_instance()) },
149 if cfg!(feature = "llvmjit") {
150 RunningMode_Mode_LLVM_JIT
151 } else {
152 RunningMode_Mode_Interp
153 }
154 );
155 }
156
157 #[test]
158 #[ignore]
159 fn test_instance_running_mode_default() {
160 let runtime = Runtime::builder().use_system_allocator().build().unwrap();
161
162 let binary = vec![
170 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f,
171 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64,
172 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
173 ];
174 let binary = binary.into_iter().map(|c| c as u8).collect::<Vec<u8>>();
175
176 let module = Module::from_vec(&runtime, binary, "");
177 assert!(module.is_ok());
178
179 let module = &module.unwrap();
180
181 let instance = Instance::new_with_args(&runtime, module, 1024, 1024);
182 assert!(instance.is_ok());
183
184 let instance = instance.unwrap();
185 assert_eq!(
186 unsafe { wasm_runtime_get_running_mode(instance.get_inner_instance()) },
187 if cfg!(feature = "llvmjit") {
188 RunningMode_Mode_LLVM_JIT
189 } else {
190 RunningMode_Mode_Interp
191 }
192 );
193 }
194
195 #[test]
196 #[ignore]
197 fn test_instance_running_mode_interpreter() {
198 let runtime = Runtime::builder()
199 .run_as_interpreter()
200 .use_system_allocator()
201 .build()
202 .unwrap();
203
204 let binary = vec![
212 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f,
213 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64,
214 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b,
215 ];
216 let binary = binary.into_iter().map(|c| c as u8).collect::<Vec<u8>>();
217
218 let module = Module::from_vec(&runtime, binary, "add");
219 assert!(module.is_ok());
220
221 let module = &module.unwrap();
222
223 let instance = Instance::new_with_args(&runtime, module, 1024, 1024);
224 assert!(instance.is_ok());
225
226 let instance = instance.unwrap();
227 assert_eq!(
228 unsafe { wasm_runtime_get_running_mode(instance.get_inner_instance()) },
229 RunningMode_Mode_Interp
230 );
231 }
232}