1use crate::{
6 backend::RunnableModule,
7 backing::{ImportBacking, LocalBacking},
8 error::{CallResult, InvokeError, ResolveError, ResolveResult, Result, RuntimeError},
9 export::{Context, Export, ExportIter, Exportable, FuncPointer},
10 global::Global,
11 import::{ImportObject, LikeNamespace},
12 loader::Loader,
13 memory::Memory,
14 module::{ExportIndex, Module, ModuleInfo, ModuleInner},
15 sig_registry::SigRegistry,
16 structures::TypedIndex,
17 table::Table,
18 typed_func::{Func, Wasm, WasmTypeList},
19 types::{FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, TableIndex, Type, Value},
20 vm::{self, InternalField},
21};
22#[cfg(unix)]
23use crate::{
24 fault::{pop_code_version, push_code_version},
25 state::CodeVersion,
26};
27use smallvec::{smallvec, SmallVec};
28use std::{
29 borrow::Borrow,
30 mem,
31 pin::Pin,
32 ptr::{self, NonNull},
33 sync::{Arc, Mutex},
34};
35
36pub(crate) struct InstanceInner {
37 #[allow(dead_code)]
38 pub(crate) backing: LocalBacking,
39 import_backing: ImportBacking,
40 pub(crate) vmctx: *mut vm::Ctx,
41 #[allow(dead_code)]
43 code_version_pushed: bool,
44}
45
46unsafe impl Send for InstanceInner {}
48
49impl Drop for InstanceInner {
50 fn drop(&mut self) {
51 unsafe { Box::from_raw(self.vmctx) };
53 #[cfg(unix)]
55 {
56 if self.code_version_pushed {
57 pop_code_version();
58 }
59 }
60 }
61}
62
63pub struct Instance {
71 pub module: Arc<ModuleInner>,
73 inner: Pin<Box<InstanceInner>>,
74 pub exports: Exports,
76 #[allow(dead_code)]
77 import_object: ImportObject,
78}
79
80impl Instance {
81 pub(crate) fn new(module: Arc<ModuleInner>, imports: &ImportObject) -> Result<Instance> {
82 let mut vmctx: Box<mem::MaybeUninit<vm::Ctx>> =
86 Box::new(mem::MaybeUninit::<vm::Ctx>::zeroed());
87
88 let import_backing = ImportBacking::new(&module, &imports, vmctx.as_mut_ptr())?;
89 let backing = LocalBacking::new(&module, &import_backing, vmctx.as_mut_ptr())?;
90
91 let mut inner = Box::pin(InstanceInner {
92 backing,
93 import_backing,
94 vmctx: vmctx.as_mut_ptr(),
95 code_version_pushed: false,
96 });
97
98 unsafe {
101 let backing = &mut *(&mut inner.backing as *mut _);
102 let import_backing = &mut *(&mut inner.import_backing as *mut _);
103 let real_ctx = match imports.call_state_creator() {
104 Some((data, dtor)) => {
105 vm::Ctx::new_with_data(backing, import_backing, &module, data, dtor)
106 }
107 None => vm::Ctx::new(backing, import_backing, &module),
108 };
109 vmctx.as_mut_ptr().write(real_ctx);
110 };
111 Box::leak(vmctx);
112
113 let exports = Exports {
114 module: module.clone(),
115 instance_inner: &*inner as *const InstanceInner,
116 };
117
118 #[cfg(unix)]
121 {
122 let push_code_version_logic = || {
123 if let Some(msm) = module.runnable_module.get_module_state_map() {
124 push_code_version(CodeVersion {
125 baseline: true,
126 msm,
127 base: module.runnable_module.get_code()?.as_ptr() as usize,
128 backend: match module.info.backend.as_ref() {
132 "llvm" => "llvm",
133 "cranelift" => "cranelift",
134 "singlepass" => "singlepass",
135 "auto" => "auto",
136 _ => "unknown backend",
137 },
138 runnable_module: module.runnable_module.clone(),
139 });
140 Some(())
141 } else {
142 None
143 }
144 };
145 inner.code_version_pushed = push_code_version_logic().is_some();
146 }
147
148 let instance = Instance {
149 module,
150 inner,
151 exports,
152 import_object: imports.clone(),
153 };
154
155 if let Some(start_index) = instance.module.info.start_func {
156 let func_ptr = match start_index.local_or_import(&instance.module.info) {
160 LocalOrImport::Local(local_func_index) => instance
161 .module
162 .runnable_module
163 .get_func(&instance.module.info, local_func_index)
164 .unwrap(),
165 LocalOrImport::Import(import_func_index) => NonNull::new(
166 instance.inner.import_backing.vm_functions[import_func_index].func as *mut _,
167 )
168 .unwrap(),
169 };
170
171 let ctx_ptr = match start_index.local_or_import(&instance.module.info) {
172 LocalOrImport::Local(_) => instance.inner.vmctx,
173 LocalOrImport::Import(imported_func_index) => {
174 instance.inner.import_backing.vm_functions[imported_func_index]
175 .func_ctx
176 .vmctx
177 .as_ptr()
178 }
179 };
180
181 let sig_index = *instance
182 .module
183 .info
184 .func_assoc
185 .get(start_index)
186 .expect("broken invariant, incorrect func index");
187
188 let wasm_trampoline = instance
189 .module
190 .runnable_module
191 .get_trampoline(&instance.module.info, sig_index)
192 .expect("wasm trampoline");
193
194 let start_func: Func<(), (), Wasm> =
195 unsafe { Func::from_raw_parts(wasm_trampoline, func_ptr, None, ctx_ptr) };
196
197 start_func.call()?;
198 }
199
200 Ok(instance)
201 }
202
203 pub fn load<T: Loader>(&self, loader: T) -> ::std::result::Result<T::Instance, T::Error> {
205 loader.load(&**self.module.runnable_module, &self.module.info, unsafe {
206 &*self.inner.vmctx
207 })
208 }
209
210 #[deprecated(
230 since = "0.17.0",
231 note = "Please use `instance.exports.get(name)` instead"
232 )]
233 pub fn func<Args, Rets>(&self, name: &str) -> ResolveResult<Func<Args, Rets, Wasm>>
234 where
235 Args: WasmTypeList,
236 Rets: WasmTypeList,
237 {
238 self.exports.get(name)
239 }
240
241 pub fn resolve_func(&self, name: &str) -> ResolveResult<usize> {
243 resolve_func_index(&*self.module, name).map(|fi| fi.index())
244 }
245
246 #[deprecated(
261 since = "0.17.0",
262 note = "Please use `instance.exports.get(name)` instead"
263 )]
264 pub fn dyn_func(&self, name: &str) -> ResolveResult<DynFunc> {
265 self.exports.get(name)
266 }
267
268 pub fn call(&self, name: &str, params: &[Value]) -> CallResult<Vec<Value>> {
308 let func: DynFunc = self.exports.get(name)?;
309 func.call(params)
310 }
311
312 pub fn context(&self) -> &vm::Ctx {
317 unsafe { &*self.inner.vmctx }
318 }
319
320 pub fn context_mut(&mut self) -> &mut vm::Ctx {
325 unsafe { &mut *self.inner.vmctx }
326 }
327
328 pub fn exports(&self) -> ExportIter {
331 ExportIter::new(&self.module, &self.inner)
332 }
333
334 pub fn module(&self) -> Module {
336 Module::new(Arc::clone(&self.module))
337 }
338
339 pub fn get_internal(&self, field: &InternalField) -> u64 {
341 self.inner.backing.internals.0[field.index()]
342 }
343
344 pub fn set_internal(&mut self, field: &InternalField, value: u64) {
346 self.inner.backing.internals.0[field.index()] = value;
347 }
348}
349
350fn resolve_func_index(module: &ModuleInner, name: &str) -> ResolveResult<FuncIndex> {
352 let export_index =
353 module
354 .info
355 .exports
356 .map
357 .get(name)
358 .ok_or_else(|| ResolveError::ExportNotFound {
359 name: name.to_string(),
360 })?;
361
362 if let ExportIndex::Func(func_index) = export_index {
363 Ok(*func_index)
364 } else {
365 Err(ResolveError::ExportWrongType {
366 name: name.to_string(),
367 }
368 .into())
369 }
370}
371
372impl InstanceInner {
373 pub(crate) fn get_export_from_index(
374 &self,
375 module: &ModuleInner,
376 export_index: &ExportIndex,
377 ) -> Export {
378 match export_index {
379 ExportIndex::Func(func_index) => {
380 let (func, ctx, signature) = self.get_func_from_index(module, *func_index);
381
382 Export::Function {
383 func,
384 ctx: match ctx {
385 Context::Internal => Context::External(self.vmctx),
386 ctx @ Context::External(_) => ctx,
387 ctx @ Context::ExternalWithEnv(_, _) => ctx,
388 },
389 signature,
390 }
391 }
392 ExportIndex::Memory(memory_index) => {
393 let memory = self.get_memory_from_index(module, *memory_index);
394 Export::Memory(memory)
395 }
396 ExportIndex::Global(global_index) => {
397 let global = self.get_global_from_index(module, *global_index);
398 Export::Global(global)
399 }
400 ExportIndex::Table(table_index) => {
401 let table = self.get_table_from_index(module, *table_index);
402 Export::Table(table)
403 }
404 }
405 }
406
407 fn get_func_from_index(
408 &self,
409 module: &ModuleInner,
410 func_index: FuncIndex,
411 ) -> (FuncPointer, Context, Arc<FuncSig>) {
412 let sig_index = *module
413 .info
414 .func_assoc
415 .get(func_index)
416 .expect("broken invariant, incorrect func index");
417
418 let (func_ptr, ctx) = match func_index.local_or_import(&module.info) {
419 LocalOrImport::Local(local_func_index) => (
420 module
421 .runnable_module
422 .get_func(&module.info, local_func_index)
423 .expect("broken invariant, func resolver not synced with module.exports")
424 .cast()
425 .as_ptr() as *const _,
426 Context::Internal,
427 ),
428 LocalOrImport::Import(imported_func_index) => {
429 let imported_func = &self.import_backing.vm_functions[imported_func_index];
430 let func_ctx = &*imported_func.func_ctx;
431
432 (
433 imported_func.func as *const _,
434 Context::ExternalWithEnv(func_ctx.vmctx.as_ptr(), func_ctx.func_env),
435 )
436 }
437 };
438
439 let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]);
440
441 (unsafe { FuncPointer::new(func_ptr) }, ctx, signature)
442 }
443
444 fn get_memory_from_index(&self, module: &ModuleInner, mem_index: MemoryIndex) -> Memory {
445 match mem_index.local_or_import(&module.info) {
446 LocalOrImport::Local(local_mem_index) => self.backing.memories[local_mem_index].clone(),
447 LocalOrImport::Import(imported_mem_index) => {
448 self.import_backing.memories[imported_mem_index].clone()
449 }
450 }
451 }
452
453 fn get_global_from_index(&self, module: &ModuleInner, global_index: GlobalIndex) -> Global {
454 match global_index.local_or_import(&module.info) {
455 LocalOrImport::Local(local_global_index) => {
456 self.backing.globals[local_global_index].clone()
457 }
458 LocalOrImport::Import(import_global_index) => {
459 self.import_backing.globals[import_global_index].clone()
460 }
461 }
462 }
463
464 fn get_table_from_index(&self, module: &ModuleInner, table_index: TableIndex) -> Table {
465 match table_index.local_or_import(&module.info) {
466 LocalOrImport::Local(local_table_index) => {
467 self.backing.tables[local_table_index].clone()
468 }
469 LocalOrImport::Import(imported_table_index) => {
470 self.import_backing.tables[imported_table_index].clone()
471 }
472 }
473 }
474}
475
476impl LikeNamespace for Instance {
477 fn get_export(&self, name: &str) -> Option<Export> {
478 let export_index = self.module.info.exports.map.get(name)?;
479
480 Some(self.inner.get_export_from_index(&self.module, export_index))
481 }
482
483 fn get_exports(&self) -> Vec<(String, Export)> {
484 unimplemented!("Use the exports method instead");
485 }
486
487 fn maybe_insert(&mut self, _name: &str, _export: Export) -> Option<()> {
488 None
489 }
490}
491
492use std::rc::Rc;
493impl LikeNamespace for Rc<Instance> {
494 fn get_export(&self, name: &str) -> Option<Export> {
495 let export_index = self.module.info.exports.map.get(name)?;
496
497 Some(self.inner.get_export_from_index(&self.module, export_index))
498 }
499
500 fn get_exports(&self) -> Vec<(String, Export)> {
501 unimplemented!("Use the exports method instead");
502 }
503
504 fn maybe_insert(&mut self, _name: &str, _export: Export) -> Option<()> {
505 None
506 }
507}
508
509impl LikeNamespace for Arc<Mutex<Instance>> {
510 fn get_export(&self, name: &str) -> Option<Export> {
511 let instance = self.lock().unwrap();
512 let export_index = instance.module.info.exports.map.get(name)?;
513
514 Some(
515 instance
516 .inner
517 .get_export_from_index(&instance.module, export_index),
518 )
519 }
520
521 fn get_exports(&self) -> Vec<(String, Export)> {
522 unimplemented!("Use the exports method instead");
523 }
524
525 fn maybe_insert(&mut self, _name: &str, _export: Export) -> Option<()> {
526 None
527 }
528}
529
530#[must_use]
531fn call_func_with_index(
532 info: &ModuleInfo,
533 runnable: &dyn RunnableModule,
534 import_backing: &ImportBacking,
535 local_ctx: *mut vm::Ctx,
536 func_index: FuncIndex,
537 args: &[Value],
538 rets: &mut Vec<Value>,
539) -> CallResult<()> {
540 let sig_index = *info
541 .func_assoc
542 .get(func_index)
543 .expect("broken invariant, incorrect func index");
544
545 let signature = &info.signatures[sig_index];
546
547 let func_ptr = match func_index.local_or_import(info) {
548 LocalOrImport::Local(local_func_index) => {
549 runnable.get_func(info, local_func_index).unwrap()
550 }
551 LocalOrImport::Import(import_func_index) => {
552 NonNull::new(import_backing.vm_functions[import_func_index].func as *mut _).unwrap()
553 }
554 };
555
556 let ctx_ptr = match func_index.local_or_import(info) {
557 LocalOrImport::Local(_) => local_ctx,
558 LocalOrImport::Import(imported_func_index) => import_backing.vm_functions
559 [imported_func_index]
560 .func_ctx
561 .vmctx
562 .as_ptr(),
563 };
564
565 let wasm = runnable
566 .get_trampoline(info, sig_index)
567 .expect("wasm trampoline");
568
569 call_func_with_index_inner(ctx_ptr, func_ptr, signature, wasm, args, rets)
570}
571
572pub(crate) fn call_func_with_index_inner(
573 ctx_ptr: *mut vm::Ctx,
574 func_ptr: NonNull<vm::Func>,
575 signature: &FuncSig,
576 wasm: Wasm,
577 args: &[Value],
578 rets: &mut Vec<Value>,
579) -> CallResult<()> {
580 rets.clear();
581
582 let num_results = signature.returns().len();
583 let num_results = num_results
584 + signature
585 .returns()
586 .iter()
587 .filter(|&&ty| ty == Type::V128)
588 .count();
589 rets.reserve(num_results);
590
591 if !signature.check_param_value_types(args) {
592 Err(ResolveError::Signature {
593 expected: signature.clone(),
594 found: args.iter().map(|val| val.ty()).collect(),
595 })?
596 }
597
598 let mut raw_args: SmallVec<[u64; 8]> = SmallVec::new();
599 for v in args {
600 match v {
601 Value::I32(i) => {
602 raw_args.push(*i as u64);
603 }
604 Value::I64(i) => {
605 raw_args.push(*i as u64);
606 }
607 Value::F32(f) => {
608 raw_args.push(f.to_bits() as u64);
609 }
610 Value::F64(f) => {
611 raw_args.push(f.to_bits() as u64);
612 }
613 Value::V128(v) => {
614 let bytes = v.to_le_bytes();
615 let mut lo = [0u8; 8];
616 lo.clone_from_slice(&bytes[0..8]);
617 raw_args.push(u64::from_le_bytes(lo));
618 let mut hi = [0u8; 8];
619 hi.clone_from_slice(&bytes[8..16]);
620 raw_args.push(u64::from_le_bytes(hi));
621 }
622 }
623 }
624
625 let Wasm {
626 trampoline,
627 invoke,
628 invoke_env,
629 } = wasm;
630
631 let run_wasm = |result_space: *mut u64| -> CallResult<()> {
632 let mut error_out = None;
633
634 let success = unsafe {
635 invoke(
636 trampoline,
637 ctx_ptr,
638 func_ptr,
639 raw_args.as_ptr(),
640 result_space,
641 &mut error_out,
642 invoke_env,
643 )
644 };
645
646 if success {
647 Ok(())
648 } else {
649 let error: RuntimeError = error_out.map_or_else(
650 || RuntimeError::InvokeError(InvokeError::FailedWithNoError),
651 Into::into,
652 );
653 Err(error.into())
654 }
655 };
656
657 let raw_to_value = |raw, ty| match ty {
658 Type::I32 => Value::I32(raw as i32),
659 Type::I64 => Value::I64(raw as i64),
660 Type::F32 => Value::F32(f32::from_bits(raw as u32)),
661 Type::F64 => Value::F64(f64::from_bits(raw)),
662 Type::V128 => unreachable!("V128 does not map to any single value"),
663 };
664
665 match signature.returns() {
666 &[] => {
667 run_wasm(ptr::null_mut())?;
668 Ok(())
669 }
670 &[Type::V128] => {
671 let mut result = [0u64; 2];
672
673 run_wasm(result.as_mut_ptr())?;
674
675 let mut bytes = [0u8; 16];
676 let lo = result[0].to_le_bytes();
677 let hi = result[1].to_le_bytes();
678 bytes[..8].clone_from_slice(&lo);
679 bytes[8..16].clone_from_slice(&hi);
680 rets.push(Value::V128(u128::from_le_bytes(bytes)));
681 Ok(())
682 }
683 &[ty] => {
684 let mut result = 0u64;
685
686 run_wasm(&mut result)?;
687
688 rets.push(raw_to_value(result, ty));
689
690 Ok(())
691 }
692 result_tys @ _ => {
693 let mut results: SmallVec<[u64; 8]> = smallvec![0; num_results];
694
695 run_wasm(results.as_mut_ptr())?;
696
697 rets.extend(
698 results
699 .iter()
700 .zip(result_tys.iter())
701 .map(|(&raw, &ty)| raw_to_value(raw, ty)),
702 );
703
704 Ok(())
705 }
706 }
707}
708
709pub struct DynFunc<'a> {
711 pub(crate) signature: Arc<FuncSig>,
712 module: &'a ModuleInner,
713 pub(crate) instance_inner: &'a InstanceInner,
714 func_index: FuncIndex,
715}
716
717impl<'a> DynFunc<'a> {
718 pub fn call(&self, params: &[Value]) -> CallResult<Vec<Value>> {
741 let mut results = Vec::new();
742
743 call_func_with_index(
744 &self.module.info,
745 &**self.module.runnable_module,
746 &self.instance_inner.import_backing,
747 self.instance_inner.vmctx,
748 self.func_index,
749 params,
750 &mut results,
751 )?;
752
753 Ok(results)
754 }
755
756 pub fn signature(&self) -> &FuncSig {
758 &*self.signature
759 }
760
761 pub fn raw(&self) -> *const vm::Func {
763 match self.func_index.local_or_import(&self.module.info) {
764 LocalOrImport::Local(local_func_index) => self
765 .module
766 .runnable_module
767 .get_func(&self.module.info, local_func_index)
768 .unwrap()
769 .as_ptr(),
770 LocalOrImport::Import(import_func_index) => {
771 self.instance_inner.import_backing.vm_functions[import_func_index].func
772 }
773 }
774 }
775}
776
777impl<'a> Exportable<'a> for Memory {
778 fn get_self(exports: &'a Exports, name: &str) -> ResolveResult<Self> {
779 let (inst_inner, module) = exports.get_inner();
780 let export_index =
781 module
782 .info
783 .exports
784 .map
785 .get(name)
786 .ok_or_else(|| ResolveError::ExportNotFound {
787 name: name.to_string(),
788 })?;
789 if let ExportIndex::Memory(idx) = export_index {
790 Ok(inst_inner.get_memory_from_index(module, *idx))
791 } else {
792 Err(ResolveError::ExportWrongType {
793 name: name.to_string(),
794 })
795 }
796 }
797}
798
799impl<'a> Exportable<'a> for Table {
800 fn get_self(exports: &'a Exports, name: &str) -> ResolveResult<Self> {
801 let (inst_inner, module) = exports.get_inner();
802 let export_index =
803 module
804 .info
805 .exports
806 .map
807 .get(name)
808 .ok_or_else(|| ResolveError::ExportNotFound {
809 name: name.to_string(),
810 })?;
811 if let ExportIndex::Table(idx) = export_index {
812 Ok(inst_inner.get_table_from_index(module, *idx))
813 } else {
814 Err(ResolveError::ExportWrongType {
815 name: name.to_string(),
816 })
817 }
818 }
819}
820
821impl<'a> Exportable<'a> for Global {
822 fn get_self(exports: &'a Exports, name: &str) -> ResolveResult<Self> {
823 let (inst_inner, module) = exports.get_inner();
824 let export_index =
825 module
826 .info
827 .exports
828 .map
829 .get(name)
830 .ok_or_else(|| ResolveError::ExportNotFound {
831 name: name.to_string(),
832 })?;
833 if let ExportIndex::Global(idx) = export_index {
834 Ok(inst_inner.get_global_from_index(module, *idx))
835 } else {
836 Err(ResolveError::ExportWrongType {
837 name: name.to_string(),
838 })
839 }
840 }
841}
842
843impl<'a> Exportable<'a> for DynFunc<'a> {
844 fn get_self(exports: &'a Exports, name: &str) -> ResolveResult<Self> {
845 let (inst_inner, module) = exports.get_inner();
846 let func_index = resolve_func_index(module, name)?;
847
848 let sig_index = *module
849 .info
850 .func_assoc
851 .get(func_index)
852 .expect("broken invariant, incorrect func index");
853 let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]);
854
855 Ok(DynFunc {
856 signature,
857 module: &module,
858 instance_inner: &inst_inner,
859 func_index: func_index,
860 })
861 }
862}
863
864impl<'a, Args: WasmTypeList, Rets: WasmTypeList> Exportable<'a> for Func<'a, Args, Rets, Wasm> {
865 fn get_self(exports: &'a Exports, name: &str) -> ResolveResult<Self> {
866 let (inst_inner, module) = exports.get_inner();
867
868 let func_index = resolve_func_index(module, name)?;
869
870 let sig_index = *module
871 .info
872 .func_assoc
873 .get(func_index)
874 .expect("broken invariant, incorrect func index");
875 let signature = SigRegistry.lookup_signature_ref(&module.info.signatures[sig_index]);
876
877 if signature.params() != Args::types() || signature.returns() != Rets::types() {
878 Err(ResolveError::Signature {
879 expected: (*signature).clone(),
880 found: Args::types().to_vec(),
881 })?;
882 }
883
884 let ctx = match func_index.local_or_import(&module.info) {
885 LocalOrImport::Local(_) => inst_inner.vmctx,
886 LocalOrImport::Import(imported_func_index) => inst_inner.import_backing.vm_functions
887 [imported_func_index]
888 .func_ctx
889 .vmctx
890 .as_ptr(),
891 };
892
893 let func_wasm_inner = module
894 .runnable_module
895 .get_trampoline(&module.info, sig_index)
896 .unwrap();
897
898 let (func_ptr, func_env) = match func_index.local_or_import(&module.info) {
899 LocalOrImport::Local(local_func_index) => (
900 module
901 .runnable_module
902 .get_func(&module.info, local_func_index)
903 .unwrap(),
904 None,
905 ),
906 LocalOrImport::Import(import_func_index) => {
907 let imported_func = &inst_inner.import_backing.vm_functions[import_func_index];
908
909 (
910 NonNull::new(imported_func.func as *mut _).unwrap(),
911 imported_func.func_ctx.func_env,
912 )
913 }
914 };
915
916 let typed_func: Func<Args, Rets, Wasm> =
917 unsafe { Func::from_raw_parts(func_wasm_inner, func_ptr, func_env, ctx) };
918
919 Ok(typed_func)
920 }
921}
922
923pub struct Exports {
928 instance_inner: *const InstanceInner,
934 module: Arc<ModuleInner>,
935}
936
937unsafe impl Send for Exports {}
940
941impl Exports {
942 pub fn get<'a, T: Exportable<'a>>(&'a self, name: &str) -> ResolveResult<T> {
965 T::get_self(self, name)
966 }
967
968 fn get_inner(&self) -> (&InstanceInner, &ModuleInner) {
970 let inst_inner = unsafe { &*self.instance_inner };
971 let module = self.module.borrow();
972 (inst_inner, module)
973 }
974
975 pub fn into_iter(&self) -> ExportIter {
986 let (inst_inner, module) = self.get_inner();
987 ExportIter::new(&module, &inst_inner)
988 }
989}
990
991#[cfg(test)]
992mod test {
993 use super::*;
994
995 fn is_send<T: Send>() {}
996
997 #[test]
998 fn test_instance_is_send() {
999 is_send::<Instance>();
1000 }
1001}