1 //! All the runtime support necessary for the wasm to cranelift translation is formalized by the
2 //! traits `FunctionEnvironment` and `ModuleEnvironment`.
3 //!
4 //! There are skeleton implementations of these traits in the `dummy` module, and complete
5 //! implementations in [Wasmtime].
6 //!
7 //! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
8 
9 use crate::state::FuncTranslationState;
10 use crate::translation_utils::{
11     DataIndex, ElemIndex, EntityIndex, EntityType, Event, EventIndex, FuncIndex, Global,
12     GlobalIndex, InstanceIndex, InstanceTypeIndex, Memory, MemoryIndex, ModuleIndex,
13     ModuleTypeIndex, SignatureIndex, Table, TableIndex, TypeIndex,
14 };
15 use core::convert::From;
16 use core::convert::TryFrom;
17 use cranelift_codegen::cursor::FuncCursor;
18 use cranelift_codegen::ir::immediates::Offset32;
19 use cranelift_codegen::ir::{self, InstBuilder};
20 use cranelift_codegen::isa::TargetFrontendConfig;
21 use cranelift_frontend::FunctionBuilder;
22 #[cfg(feature = "enable-serde")]
23 use serde::{Deserialize, Serialize};
24 use std::boxed::Box;
25 use std::string::ToString;
26 use std::vec::Vec;
27 use thiserror::Error;
28 use wasmparser::ValidatorResources;
29 use wasmparser::{BinaryReaderError, FuncValidator, FunctionBody, Operator, WasmFeatures};
30 
31 /// WebAssembly value type -- equivalent of `wasmparser`'s Type.
32 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
33 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
34 pub enum WasmType {
35     /// I32 type
36     I32,
37     /// I64 type
38     I64,
39     /// F32 type
40     F32,
41     /// F64 type
42     F64,
43     /// V128 type
44     V128,
45     /// FuncRef type
46     FuncRef,
47     /// ExternRef type
48     ExternRef,
49     /// ExnRef type
50     ExnRef,
51 }
52 
53 impl TryFrom<wasmparser::Type> for WasmType {
54     type Error = WasmError;
try_from(ty: wasmparser::Type) -> Result<Self, Self::Error>55     fn try_from(ty: wasmparser::Type) -> Result<Self, Self::Error> {
56         use wasmparser::Type::*;
57         match ty {
58             I32 => Ok(WasmType::I32),
59             I64 => Ok(WasmType::I64),
60             F32 => Ok(WasmType::F32),
61             F64 => Ok(WasmType::F64),
62             V128 => Ok(WasmType::V128),
63             FuncRef => Ok(WasmType::FuncRef),
64             ExternRef => Ok(WasmType::ExternRef),
65             ExnRef => Ok(WasmType::ExnRef),
66             EmptyBlockType | Func => Err(WasmError::InvalidWebAssembly {
67                 message: "unexpected value type".to_string(),
68                 offset: 0,
69             }),
70         }
71     }
72 }
73 
74 impl From<WasmType> for wasmparser::Type {
from(ty: WasmType) -> wasmparser::Type75     fn from(ty: WasmType) -> wasmparser::Type {
76         match ty {
77             WasmType::I32 => wasmparser::Type::I32,
78             WasmType::I64 => wasmparser::Type::I64,
79             WasmType::F32 => wasmparser::Type::F32,
80             WasmType::F64 => wasmparser::Type::F64,
81             WasmType::V128 => wasmparser::Type::V128,
82             WasmType::FuncRef => wasmparser::Type::FuncRef,
83             WasmType::ExternRef => wasmparser::Type::ExternRef,
84             WasmType::ExnRef => wasmparser::Type::ExnRef,
85         }
86     }
87 }
88 
89 /// WebAssembly function type -- equivalent of `wasmparser`'s FuncType.
90 #[derive(Debug, Clone, Eq, PartialEq, Hash)]
91 #[cfg_attr(feature = "enable-serde", derive(Serialize, Deserialize))]
92 pub struct WasmFuncType {
93     /// Function params types.
94     pub params: Box<[WasmType]>,
95     /// Returns params types.
96     pub returns: Box<[WasmType]>,
97 }
98 
99 impl TryFrom<wasmparser::FuncType> for WasmFuncType {
100     type Error = WasmError;
try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error>101     fn try_from(ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
102         Ok(Self {
103             params: ty
104                 .params
105                 .into_vec()
106                 .into_iter()
107                 .map(WasmType::try_from)
108                 .collect::<Result<_, Self::Error>>()?,
109             returns: ty
110                 .returns
111                 .into_vec()
112                 .into_iter()
113                 .map(WasmType::try_from)
114                 .collect::<Result<_, Self::Error>>()?,
115         })
116     }
117 }
118 
119 /// The value of a WebAssembly global variable.
120 #[derive(Clone, Copy)]
121 pub enum GlobalVariable {
122     /// This is a constant global with a value known at compile time.
123     Const(ir::Value),
124 
125     /// This is a variable in memory that should be referenced through a `GlobalValue`.
126     Memory {
127         /// The address of the global variable storage.
128         gv: ir::GlobalValue,
129         /// An offset to add to the address.
130         offset: Offset32,
131         /// The global variable's type.
132         ty: ir::Type,
133     },
134 
135     /// This is a global variable that needs to be handled by the environment.
136     Custom,
137 }
138 
139 /// A WebAssembly translation error.
140 ///
141 /// When a WebAssembly function can't be translated, one of these error codes will be returned
142 /// to describe the failure.
143 #[derive(Error, Debug)]
144 pub enum WasmError {
145     /// The input WebAssembly code is invalid.
146     ///
147     /// This error code is used by a WebAssembly translator when it encounters invalid WebAssembly
148     /// code. This should never happen for validated WebAssembly code.
149     #[error("Invalid input WebAssembly code at offset {offset}: {message}")]
150     InvalidWebAssembly {
151         /// A string describing the validation error.
152         message: std::string::String,
153         /// The bytecode offset where the error occurred.
154         offset: usize,
155     },
156 
157     /// A feature used by the WebAssembly code is not supported by the embedding environment.
158     ///
159     /// Embedding environments may have their own limitations and feature restrictions.
160     #[error("Unsupported feature: {0}")]
161     Unsupported(std::string::String),
162 
163     /// An implementation limit was exceeded.
164     ///
165     /// Cranelift can compile very large and complicated functions, but the [implementation has
166     /// limits][limits] that cause compilation to fail when they are exceeded.
167     ///
168     /// [limits]: https://github.com/bytecodealliance/wasmtime/blob/main/cranelift/docs/ir.md#implementation-limits
169     #[error("Implementation limit exceeded")]
170     ImplLimitExceeded,
171 
172     /// Any user-defined error.
173     #[error("User error: {0}")]
174     User(std::string::String),
175 }
176 
177 /// Return an `Err(WasmError::Unsupported(msg))` where `msg` the string built by calling `format!`
178 /// on the arguments to this macro.
179 #[macro_export]
180 macro_rules! wasm_unsupported {
181     ($($arg:tt)*) => { $crate::environ::WasmError::Unsupported(format!($($arg)*)) }
182 }
183 
184 impl From<BinaryReaderError> for WasmError {
185     /// Convert from a `BinaryReaderError` to a `WasmError`.
from(e: BinaryReaderError) -> Self186     fn from(e: BinaryReaderError) -> Self {
187         Self::InvalidWebAssembly {
188             message: e.message().into(),
189             offset: e.offset(),
190         }
191     }
192 }
193 
194 /// A convenient alias for a `Result` that uses `WasmError` as the error type.
195 pub type WasmResult<T> = Result<T, WasmError>;
196 
197 /// How to return from functions.
198 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
199 pub enum ReturnMode {
200     /// Use normal return instructions as needed.
201     NormalReturns,
202     /// Use a single fallthrough return at the end of the function.
203     FallthroughReturn,
204 }
205 
206 /// An entry in the alias section of a wasm module (from the module linking
207 /// proposal)
208 pub enum Alias<'a> {
209     /// An outer module's module is being aliased into our own index space.
210     OuterModule {
211         /// The number of modules above us that we're referencing.
212         relative_depth: u32,
213         /// The module index in the outer module's index space we're referencing.
214         index: ModuleIndex,
215     },
216 
217     /// An outer module's type is being aliased into our own index space
218     ///
219     /// Note that the index here is in the outer module's index space, not our
220     /// own.
221     OuterType {
222         /// The number of modules above us that we're referencing.
223         relative_depth: u32,
224         /// The type index in the outer module's index space we're referencing.
225         index: TypeIndex,
226     },
227 
228     /// A previously created instance is having one of its exports aliased into
229     /// our index space.
230     InstanceExport {
231         /// The index we're aliasing.
232         instance: InstanceIndex,
233         /// The nth export that we're inserting into our own index space
234         /// locally.
235         export: &'a str,
236     },
237 }
238 
239 /// Environment affecting the translation of a WebAssembly.
240 pub trait TargetEnvironment {
241     /// Get the information needed to produce Cranelift IR for the given target.
target_config(&self) -> TargetFrontendConfig242     fn target_config(&self) -> TargetFrontendConfig;
243 
244     /// Get the Cranelift integer type to use for native pointers.
245     ///
246     /// This returns `I64` for 64-bit architectures and `I32` for 32-bit architectures.
pointer_type(&self) -> ir::Type247     fn pointer_type(&self) -> ir::Type {
248         ir::Type::int(u16::from(self.target_config().pointer_bits())).unwrap()
249     }
250 
251     /// Get the size of a native pointer, in bytes.
pointer_bytes(&self) -> u8252     fn pointer_bytes(&self) -> u8 {
253         self.target_config().pointer_bytes()
254     }
255 
256     /// Get the Cranelift reference type to use for the given Wasm reference
257     /// type.
258     ///
259     /// By default, this returns `R64` for 64-bit architectures and `R32` for
260     /// 32-bit architectures. If you override this, then you should also
261     /// override `FuncEnvironment::{translate_ref_null, translate_ref_is_null}`
262     /// as well.
reference_type(&self, ty: WasmType) -> ir::Type263     fn reference_type(&self, ty: WasmType) -> ir::Type {
264         let _ = ty;
265         match self.pointer_type() {
266             ir::types::I32 => ir::types::R32,
267             ir::types::I64 => ir::types::R64,
268             _ => panic!("unsupported pointer type"),
269         }
270     }
271 }
272 
273 /// Environment affecting the translation of a single WebAssembly function.
274 ///
275 /// A `FuncEnvironment` trait object is required to translate a WebAssembly function to Cranelift
276 /// IR. The function environment provides information about the WebAssembly module as well as the
277 /// runtime environment.
278 pub trait FuncEnvironment: TargetEnvironment {
279     /// Is the given parameter of the given function a wasm-level parameter, as opposed to a hidden
280     /// parameter added for use by the implementation?
is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool281     fn is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool {
282         signature.params[index].purpose == ir::ArgumentPurpose::Normal
283     }
284 
285     /// Is the given return of the given function a wasm-level parameter, as
286     /// opposed to a hidden parameter added for use by the implementation?
is_wasm_return(&self, signature: &ir::Signature, index: usize) -> bool287     fn is_wasm_return(&self, signature: &ir::Signature, index: usize) -> bool {
288         signature.returns[index].purpose == ir::ArgumentPurpose::Normal
289     }
290 
291     /// Should the code be structured to use a single `fallthrough_return` instruction at the end
292     /// of the function body, rather than `return` instructions as needed? This is used by VMs
293     /// to append custom epilogues.
return_mode(&self) -> ReturnMode294     fn return_mode(&self) -> ReturnMode {
295         ReturnMode::NormalReturns
296     }
297 
298     /// Called after the locals for a function have been parsed, and the number
299     /// of variables defined by this function is provided.
after_locals(&mut self, num_locals_defined: usize)300     fn after_locals(&mut self, num_locals_defined: usize) {
301         drop(num_locals_defined);
302     }
303 
304     /// Set up the necessary preamble definitions in `func` to access the global variable
305     /// identified by `index`.
306     ///
307     /// The index space covers both imported globals and globals defined by the module.
308     ///
309     /// Return the global variable reference that should be used to access the global and the
310     /// WebAssembly type of the global.
make_global( &mut self, func: &mut ir::Function, index: GlobalIndex, ) -> WasmResult<GlobalVariable>311     fn make_global(
312         &mut self,
313         func: &mut ir::Function,
314         index: GlobalIndex,
315     ) -> WasmResult<GlobalVariable>;
316 
317     /// Set up the necessary preamble definitions in `func` to access the linear memory identified
318     /// by `index`.
319     ///
320     /// The index space covers both imported and locally declared memories.
make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<ir::Heap>321     fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<ir::Heap>;
322 
323     /// Set up the necessary preamble definitions in `func` to access the table identified
324     /// by `index`.
325     ///
326     /// The index space covers both imported and locally declared tables.
make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> WasmResult<ir::Table>327     fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> WasmResult<ir::Table>;
328 
329     /// Set up a signature definition in the preamble of `func` that can be used for an indirect
330     /// call with signature `index`.
331     ///
332     /// The signature may contain additional arguments needed for an indirect call, but the
333     /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
334     /// arguments.
335     ///
336     /// The signature will only be used for indirect calls, even if the module has direct function
337     /// calls with the same WebAssembly type.
make_indirect_sig( &mut self, func: &mut ir::Function, index: TypeIndex, ) -> WasmResult<ir::SigRef>338     fn make_indirect_sig(
339         &mut self,
340         func: &mut ir::Function,
341         index: TypeIndex,
342     ) -> WasmResult<ir::SigRef>;
343 
344     /// Set up an external function definition in the preamble of `func` that can be used to
345     /// directly call the function `index`.
346     ///
347     /// The index space covers both imported functions and functions defined in the current module.
348     ///
349     /// The function's signature may contain additional arguments needed for a direct call, but the
350     /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
351     /// arguments.
352     ///
353     /// The function's signature will only be used for direct calls, even if the module has
354     /// indirect calls with the same WebAssembly type.
make_direct_func( &mut self, func: &mut ir::Function, index: FuncIndex, ) -> WasmResult<ir::FuncRef>355     fn make_direct_func(
356         &mut self,
357         func: &mut ir::Function,
358         index: FuncIndex,
359     ) -> WasmResult<ir::FuncRef>;
360 
361     /// Translate a `call_indirect` WebAssembly instruction at `pos`.
362     ///
363     /// Insert instructions at `pos` for an indirect call to the function `callee` in the table
364     /// `table_index` with WebAssembly signature `sig_index`. The `callee` value will have type
365     /// `i32`.
366     ///
367     /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
368     ///
369     /// Return the call instruction whose results are the WebAssembly return values.
370     #[cfg_attr(feature = "cargo-clippy", allow(clippy::too_many_arguments))]
translate_call_indirect( &mut self, pos: FuncCursor, table_index: TableIndex, table: ir::Table, sig_index: TypeIndex, sig_ref: ir::SigRef, callee: ir::Value, call_args: &[ir::Value], ) -> WasmResult<ir::Inst>371     fn translate_call_indirect(
372         &mut self,
373         pos: FuncCursor,
374         table_index: TableIndex,
375         table: ir::Table,
376         sig_index: TypeIndex,
377         sig_ref: ir::SigRef,
378         callee: ir::Value,
379         call_args: &[ir::Value],
380     ) -> WasmResult<ir::Inst>;
381 
382     /// Translate a `call` WebAssembly instruction at `pos`.
383     ///
384     /// Insert instructions at `pos` for a direct call to the function `callee_index`.
385     ///
386     /// The function reference `callee` was previously created by `make_direct_func()`.
387     ///
388     /// Return the call instruction whose results are the WebAssembly return values.
translate_call( &mut self, mut pos: FuncCursor, _callee_index: FuncIndex, callee: ir::FuncRef, call_args: &[ir::Value], ) -> WasmResult<ir::Inst>389     fn translate_call(
390         &mut self,
391         mut pos: FuncCursor,
392         _callee_index: FuncIndex,
393         callee: ir::FuncRef,
394         call_args: &[ir::Value],
395     ) -> WasmResult<ir::Inst> {
396         Ok(pos.ins().call(callee, call_args))
397     }
398 
399     /// Translate a `memory.grow` WebAssembly instruction.
400     ///
401     /// The `index` provided identifies the linear memory to grow, and `heap` is the heap reference
402     /// returned by `make_heap` for the same index.
403     ///
404     /// The `val` value is the requested memory size in pages.
405     ///
406     /// Returns the old size (in pages) of the memory.
translate_memory_grow( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, val: ir::Value, ) -> WasmResult<ir::Value>407     fn translate_memory_grow(
408         &mut self,
409         pos: FuncCursor,
410         index: MemoryIndex,
411         heap: ir::Heap,
412         val: ir::Value,
413     ) -> WasmResult<ir::Value>;
414 
415     /// Translates a `memory.size` WebAssembly instruction.
416     ///
417     /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
418     /// returned by `make_heap` for the same index.
419     ///
420     /// Returns the size in pages of the memory.
translate_memory_size( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, ) -> WasmResult<ir::Value>421     fn translate_memory_size(
422         &mut self,
423         pos: FuncCursor,
424         index: MemoryIndex,
425         heap: ir::Heap,
426     ) -> WasmResult<ir::Value>;
427 
428     /// Translate a `memory.copy` WebAssembly instruction.
429     ///
430     /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
431     /// returned by `make_heap` for the same index.
translate_memory_copy( &mut self, pos: FuncCursor, src_index: MemoryIndex, src_heap: ir::Heap, dst_index: MemoryIndex, dst_heap: ir::Heap, dst: ir::Value, src: ir::Value, len: ir::Value, ) -> WasmResult<()>432     fn translate_memory_copy(
433         &mut self,
434         pos: FuncCursor,
435         src_index: MemoryIndex,
436         src_heap: ir::Heap,
437         dst_index: MemoryIndex,
438         dst_heap: ir::Heap,
439         dst: ir::Value,
440         src: ir::Value,
441         len: ir::Value,
442     ) -> WasmResult<()>;
443 
444     /// Translate a `memory.fill` WebAssembly instruction.
445     ///
446     /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
447     /// returned by `make_heap` for the same index.
translate_memory_fill( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, dst: ir::Value, val: ir::Value, len: ir::Value, ) -> WasmResult<()>448     fn translate_memory_fill(
449         &mut self,
450         pos: FuncCursor,
451         index: MemoryIndex,
452         heap: ir::Heap,
453         dst: ir::Value,
454         val: ir::Value,
455         len: ir::Value,
456     ) -> WasmResult<()>;
457 
458     /// Translate a `memory.init` WebAssembly instruction.
459     ///
460     /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
461     /// returned by `make_heap` for the same index. `seg_index` is the index of the segment to copy
462     /// from.
463     #[allow(clippy::too_many_arguments)]
translate_memory_init( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, seg_index: u32, dst: ir::Value, src: ir::Value, len: ir::Value, ) -> WasmResult<()>464     fn translate_memory_init(
465         &mut self,
466         pos: FuncCursor,
467         index: MemoryIndex,
468         heap: ir::Heap,
469         seg_index: u32,
470         dst: ir::Value,
471         src: ir::Value,
472         len: ir::Value,
473     ) -> WasmResult<()>;
474 
475     /// Translate a `data.drop` WebAssembly instruction.
translate_data_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>476     fn translate_data_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
477 
478     /// Translate a `table.size` WebAssembly instruction.
translate_table_size( &mut self, pos: FuncCursor, index: TableIndex, table: ir::Table, ) -> WasmResult<ir::Value>479     fn translate_table_size(
480         &mut self,
481         pos: FuncCursor,
482         index: TableIndex,
483         table: ir::Table,
484     ) -> WasmResult<ir::Value>;
485 
486     /// Translate a `table.grow` WebAssembly instruction.
translate_table_grow( &mut self, pos: FuncCursor, table_index: TableIndex, table: ir::Table, delta: ir::Value, init_value: ir::Value, ) -> WasmResult<ir::Value>487     fn translate_table_grow(
488         &mut self,
489         pos: FuncCursor,
490         table_index: TableIndex,
491         table: ir::Table,
492         delta: ir::Value,
493         init_value: ir::Value,
494     ) -> WasmResult<ir::Value>;
495 
496     /// Translate a `table.get` WebAssembly instruction.
translate_table_get( &mut self, builder: &mut FunctionBuilder, table_index: TableIndex, table: ir::Table, index: ir::Value, ) -> WasmResult<ir::Value>497     fn translate_table_get(
498         &mut self,
499         builder: &mut FunctionBuilder,
500         table_index: TableIndex,
501         table: ir::Table,
502         index: ir::Value,
503     ) -> WasmResult<ir::Value>;
504 
505     /// Translate a `table.set` WebAssembly instruction.
translate_table_set( &mut self, builder: &mut FunctionBuilder, table_index: TableIndex, table: ir::Table, value: ir::Value, index: ir::Value, ) -> WasmResult<()>506     fn translate_table_set(
507         &mut self,
508         builder: &mut FunctionBuilder,
509         table_index: TableIndex,
510         table: ir::Table,
511         value: ir::Value,
512         index: ir::Value,
513     ) -> WasmResult<()>;
514 
515     /// Translate a `table.copy` WebAssembly instruction.
516     #[allow(clippy::too_many_arguments)]
translate_table_copy( &mut self, pos: FuncCursor, dst_table_index: TableIndex, dst_table: ir::Table, src_table_index: TableIndex, src_table: ir::Table, dst: ir::Value, src: ir::Value, len: ir::Value, ) -> WasmResult<()>517     fn translate_table_copy(
518         &mut self,
519         pos: FuncCursor,
520         dst_table_index: TableIndex,
521         dst_table: ir::Table,
522         src_table_index: TableIndex,
523         src_table: ir::Table,
524         dst: ir::Value,
525         src: ir::Value,
526         len: ir::Value,
527     ) -> WasmResult<()>;
528 
529     /// Translate a `table.fill` WebAssembly instruction.
translate_table_fill( &mut self, pos: FuncCursor, table_index: TableIndex, dst: ir::Value, val: ir::Value, len: ir::Value, ) -> WasmResult<()>530     fn translate_table_fill(
531         &mut self,
532         pos: FuncCursor,
533         table_index: TableIndex,
534         dst: ir::Value,
535         val: ir::Value,
536         len: ir::Value,
537     ) -> WasmResult<()>;
538 
539     /// Translate a `table.init` WebAssembly instruction.
540     #[allow(clippy::too_many_arguments)]
translate_table_init( &mut self, pos: FuncCursor, seg_index: u32, table_index: TableIndex, table: ir::Table, dst: ir::Value, src: ir::Value, len: ir::Value, ) -> WasmResult<()>541     fn translate_table_init(
542         &mut self,
543         pos: FuncCursor,
544         seg_index: u32,
545         table_index: TableIndex,
546         table: ir::Table,
547         dst: ir::Value,
548         src: ir::Value,
549         len: ir::Value,
550     ) -> WasmResult<()>;
551 
552     /// Translate a `elem.drop` WebAssembly instruction.
translate_elem_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>553     fn translate_elem_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
554 
555     /// Translate a `ref.null T` WebAssembly instruction.
556     ///
557     /// By default, translates into a null reference type.
558     ///
559     /// Override this if you don't use Cranelift reference types for all Wasm
560     /// reference types (e.g. you use a raw pointer for `funcref`s) or if the
561     /// null sentinel is not a null reference type pointer for your type. If you
562     /// override this method, then you should also override
563     /// `translate_ref_is_null` as well.
translate_ref_null(&mut self, mut pos: FuncCursor, ty: WasmType) -> WasmResult<ir::Value>564     fn translate_ref_null(&mut self, mut pos: FuncCursor, ty: WasmType) -> WasmResult<ir::Value> {
565         let _ = ty;
566         Ok(pos.ins().null(self.reference_type(ty)))
567     }
568 
569     /// Translate a `ref.is_null` WebAssembly instruction.
570     ///
571     /// By default, assumes that `value` is a Cranelift reference type, and that
572     /// a null Cranelift reference type is the null value for all Wasm reference
573     /// types.
574     ///
575     /// If you override this method, you probably also want to override
576     /// `translate_ref_null` as well.
translate_ref_is_null( &mut self, mut pos: FuncCursor, value: ir::Value, ) -> WasmResult<ir::Value>577     fn translate_ref_is_null(
578         &mut self,
579         mut pos: FuncCursor,
580         value: ir::Value,
581     ) -> WasmResult<ir::Value> {
582         let is_null = pos.ins().is_null(value);
583         Ok(pos.ins().bint(ir::types::I32, is_null))
584     }
585 
586     /// Translate a `ref.func` WebAssembly instruction.
translate_ref_func( &mut self, pos: FuncCursor, func_index: FuncIndex, ) -> WasmResult<ir::Value>587     fn translate_ref_func(
588         &mut self,
589         pos: FuncCursor,
590         func_index: FuncIndex,
591     ) -> WasmResult<ir::Value>;
592 
593     /// Translate a `global.get` WebAssembly instruction at `pos` for a global
594     /// that is custom.
translate_custom_global_get( &mut self, pos: FuncCursor, global_index: GlobalIndex, ) -> WasmResult<ir::Value>595     fn translate_custom_global_get(
596         &mut self,
597         pos: FuncCursor,
598         global_index: GlobalIndex,
599     ) -> WasmResult<ir::Value>;
600 
601     /// Translate a `global.set` WebAssembly instruction at `pos` for a global
602     /// that is custom.
translate_custom_global_set( &mut self, pos: FuncCursor, global_index: GlobalIndex, val: ir::Value, ) -> WasmResult<()>603     fn translate_custom_global_set(
604         &mut self,
605         pos: FuncCursor,
606         global_index: GlobalIndex,
607         val: ir::Value,
608     ) -> WasmResult<()>;
609 
610     /// Translate an `i32.atomic.wait` or `i64.atomic.wait` WebAssembly instruction.
611     /// The `index` provided identifies the linear memory containing the value
612     /// to wait on, and `heap` is the heap reference returned by `make_heap`
613     /// for the same index.  Whether the waited-on value is 32- or 64-bit can be
614     /// determined by examining the type of `expected`, which must be only I32 or I64.
615     ///
616     /// Returns an i32, which is negative if the helper call failed.
translate_atomic_wait( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, addr: ir::Value, expected: ir::Value, timeout: ir::Value, ) -> WasmResult<ir::Value>617     fn translate_atomic_wait(
618         &mut self,
619         pos: FuncCursor,
620         index: MemoryIndex,
621         heap: ir::Heap,
622         addr: ir::Value,
623         expected: ir::Value,
624         timeout: ir::Value,
625     ) -> WasmResult<ir::Value>;
626 
627     /// Translate an `atomic.notify` WebAssembly instruction.
628     /// The `index` provided identifies the linear memory containing the value
629     /// to wait on, and `heap` is the heap reference returned by `make_heap`
630     /// for the same index.
631     ///
632     /// Returns an i64, which is negative if the helper call failed.
translate_atomic_notify( &mut self, pos: FuncCursor, index: MemoryIndex, heap: ir::Heap, addr: ir::Value, count: ir::Value, ) -> WasmResult<ir::Value>633     fn translate_atomic_notify(
634         &mut self,
635         pos: FuncCursor,
636         index: MemoryIndex,
637         heap: ir::Heap,
638         addr: ir::Value,
639         count: ir::Value,
640     ) -> WasmResult<ir::Value>;
641 
642     /// Emit code at the beginning of every wasm loop.
643     ///
644     /// This can be used to insert explicit interrupt or safepoint checking at
645     /// the beginnings of loops.
translate_loop_header(&mut self, _builder: &mut FunctionBuilder) -> WasmResult<()>646     fn translate_loop_header(&mut self, _builder: &mut FunctionBuilder) -> WasmResult<()> {
647         // By default, don't emit anything.
648         Ok(())
649     }
650 
651     /// Optional callback for the `FunctionEnvironment` performing this translation to maintain
652     /// internal state or prepare custom state for the operator to translate
before_translate_operator( &mut self, _op: &Operator, _builder: &mut FunctionBuilder, _state: &FuncTranslationState, ) -> WasmResult<()>653     fn before_translate_operator(
654         &mut self,
655         _op: &Operator,
656         _builder: &mut FunctionBuilder,
657         _state: &FuncTranslationState,
658     ) -> WasmResult<()> {
659         Ok(())
660     }
661 
662     /// Optional callback for the `FunctionEnvironment` performing this translation to maintain
663     /// internal state or finalize custom state for the operator that was translated
after_translate_operator( &mut self, _op: &Operator, _builder: &mut FunctionBuilder, _state: &FuncTranslationState, ) -> WasmResult<()>664     fn after_translate_operator(
665         &mut self,
666         _op: &Operator,
667         _builder: &mut FunctionBuilder,
668         _state: &FuncTranslationState,
669     ) -> WasmResult<()> {
670         Ok(())
671     }
672 
673     /// Optional callback for the `FunctionEnvironment` performing this translation to perform work
674     /// before the function body is translated.
before_translate_function( &mut self, _builder: &mut FunctionBuilder, _state: &FuncTranslationState, ) -> WasmResult<()>675     fn before_translate_function(
676         &mut self,
677         _builder: &mut FunctionBuilder,
678         _state: &FuncTranslationState,
679     ) -> WasmResult<()> {
680         Ok(())
681     }
682 
683     /// Optional callback for the `FunctionEnvironment` performing this translation to perform work
684     /// after the function body is translated.
after_translate_function( &mut self, _builder: &mut FunctionBuilder, _state: &FuncTranslationState, ) -> WasmResult<()>685     fn after_translate_function(
686         &mut self,
687         _builder: &mut FunctionBuilder,
688         _state: &FuncTranslationState,
689     ) -> WasmResult<()> {
690         Ok(())
691     }
692 }
693 
694 /// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the
695 /// [`translate_module`](fn.translate_module.html) function. These methods should not be called
696 /// by the user, they are only for `cranelift-wasm` internal use.
697 pub trait ModuleEnvironment<'data>: TargetEnvironment {
698     /// Provides the number of types up front. By default this does nothing, but
699     /// implementations can use this to preallocate memory if desired.
reserve_types(&mut self, _num: u32) -> WasmResult<()>700     fn reserve_types(&mut self, _num: u32) -> WasmResult<()> {
701         Ok(())
702     }
703 
704     /// Declares a function signature to the environment.
declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>705     fn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>;
706 
707     /// Declares a module type signature to the environment.
declare_type_module( &mut self, imports: &[(&'data str, Option<&'data str>, EntityType)], exports: &[(&'data str, EntityType)], ) -> WasmResult<()>708     fn declare_type_module(
709         &mut self,
710         imports: &[(&'data str, Option<&'data str>, EntityType)],
711         exports: &[(&'data str, EntityType)],
712     ) -> WasmResult<()> {
713         drop((imports, exports));
714         Err(WasmError::Unsupported("module linking".to_string()))
715     }
716 
717     /// Declares an instance type signature to the environment.
declare_type_instance(&mut self, exports: &[(&'data str, EntityType)]) -> WasmResult<()>718     fn declare_type_instance(&mut self, exports: &[(&'data str, EntityType)]) -> WasmResult<()> {
719         drop(exports);
720         Err(WasmError::Unsupported("module linking".to_string()))
721     }
722 
723     /// Translates a type index to its signature index, only called for type
724     /// indices which point to functions.
type_to_signature(&self, index: TypeIndex) -> WasmResult<SignatureIndex>725     fn type_to_signature(&self, index: TypeIndex) -> WasmResult<SignatureIndex> {
726         drop(index);
727         Err(WasmError::Unsupported("module linking".to_string()))
728     }
729 
730     /// Translates a type index to its module type index, only called for type
731     /// indices which point to modules.
type_to_module_type(&self, index: TypeIndex) -> WasmResult<ModuleTypeIndex>732     fn type_to_module_type(&self, index: TypeIndex) -> WasmResult<ModuleTypeIndex> {
733         drop(index);
734         Err(WasmError::Unsupported("module linking".to_string()))
735     }
736 
737     /// Translates a type index to its instance type index, only called for type
738     /// indices which point to instances.
type_to_instance_type(&self, index: TypeIndex) -> WasmResult<InstanceTypeIndex>739     fn type_to_instance_type(&self, index: TypeIndex) -> WasmResult<InstanceTypeIndex> {
740         drop(index);
741         Err(WasmError::Unsupported("module linking".to_string()))
742     }
743 
744     /// Provides the number of imports up front. By default this does nothing, but
745     /// implementations can use this to preallocate memory if desired.
reserve_imports(&mut self, _num: u32) -> WasmResult<()>746     fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> {
747         Ok(())
748     }
749 
750     /// Declares a function import to the environment.
declare_func_import( &mut self, index: TypeIndex, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>751     fn declare_func_import(
752         &mut self,
753         index: TypeIndex,
754         module: &'data str,
755         field: Option<&'data str>,
756     ) -> WasmResult<()>;
757 
758     /// Declares a table import to the environment.
declare_table_import( &mut self, table: Table, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>759     fn declare_table_import(
760         &mut self,
761         table: Table,
762         module: &'data str,
763         field: Option<&'data str>,
764     ) -> WasmResult<()>;
765 
766     /// Declares a memory import to the environment.
declare_memory_import( &mut self, memory: Memory, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>767     fn declare_memory_import(
768         &mut self,
769         memory: Memory,
770         module: &'data str,
771         field: Option<&'data str>,
772     ) -> WasmResult<()>;
773 
774     /// Declares an event import to the environment.
declare_event_import( &mut self, event: Event, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>775     fn declare_event_import(
776         &mut self,
777         event: Event,
778         module: &'data str,
779         field: Option<&'data str>,
780     ) -> WasmResult<()> {
781         drop((event, module, field));
782         Err(WasmError::Unsupported("wasm events".to_string()))
783     }
784 
785     /// Declares a global import to the environment.
declare_global_import( &mut self, global: Global, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>786     fn declare_global_import(
787         &mut self,
788         global: Global,
789         module: &'data str,
790         field: Option<&'data str>,
791     ) -> WasmResult<()>;
792 
793     /// Declares a module import to the environment.
declare_module_import( &mut self, ty_index: TypeIndex, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>794     fn declare_module_import(
795         &mut self,
796         ty_index: TypeIndex,
797         module: &'data str,
798         field: Option<&'data str>,
799     ) -> WasmResult<()> {
800         drop((ty_index, module, field));
801         Err(WasmError::Unsupported("module linking".to_string()))
802     }
803 
804     /// Declares an instance import to the environment.
declare_instance_import( &mut self, ty_index: TypeIndex, module: &'data str, field: Option<&'data str>, ) -> WasmResult<()>805     fn declare_instance_import(
806         &mut self,
807         ty_index: TypeIndex,
808         module: &'data str,
809         field: Option<&'data str>,
810     ) -> WasmResult<()> {
811         drop((ty_index, module, field));
812         Err(WasmError::Unsupported("module linking".to_string()))
813     }
814 
815     /// Notifies the implementation that all imports have been declared.
finish_imports(&mut self) -> WasmResult<()>816     fn finish_imports(&mut self) -> WasmResult<()> {
817         Ok(())
818     }
819 
820     /// Provides the number of defined functions up front. By default this does nothing, but
821     /// implementations can use this to preallocate memory if desired.
reserve_func_types(&mut self, _num: u32) -> WasmResult<()>822     fn reserve_func_types(&mut self, _num: u32) -> WasmResult<()> {
823         Ok(())
824     }
825 
826     /// Declares the type (signature) of a local function in the module.
declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>827     fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>;
828 
829     /// Provides the number of defined tables up front. By default this does nothing, but
830     /// implementations can use this to preallocate memory if desired.
reserve_tables(&mut self, _num: u32) -> WasmResult<()>831     fn reserve_tables(&mut self, _num: u32) -> WasmResult<()> {
832         Ok(())
833     }
834 
835     /// Declares a table to the environment.
declare_table(&mut self, table: Table) -> WasmResult<()>836     fn declare_table(&mut self, table: Table) -> WasmResult<()>;
837 
838     /// Provides the number of defined memories up front. By default this does nothing, but
839     /// implementations can use this to preallocate memory if desired.
reserve_memories(&mut self, _num: u32) -> WasmResult<()>840     fn reserve_memories(&mut self, _num: u32) -> WasmResult<()> {
841         Ok(())
842     }
843 
844     /// Declares a memory to the environment
declare_memory(&mut self, memory: Memory) -> WasmResult<()>845     fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>;
846 
847     /// Provides the number of defined events up front. By default this does nothing, but
848     /// implementations can use this to preallocate memory if desired.
reserve_events(&mut self, _num: u32) -> WasmResult<()>849     fn reserve_events(&mut self, _num: u32) -> WasmResult<()> {
850         Ok(())
851     }
852 
853     /// Declares an event to the environment
declare_event(&mut self, event: Event) -> WasmResult<()>854     fn declare_event(&mut self, event: Event) -> WasmResult<()> {
855         drop(event);
856         Err(WasmError::Unsupported("wasm events".to_string()))
857     }
858 
859     /// Provides the number of defined globals up front. By default this does nothing, but
860     /// implementations can use this to preallocate memory if desired.
reserve_globals(&mut self, _num: u32) -> WasmResult<()>861     fn reserve_globals(&mut self, _num: u32) -> WasmResult<()> {
862         Ok(())
863     }
864 
865     /// Declares a global to the environment.
declare_global(&mut self, global: Global) -> WasmResult<()>866     fn declare_global(&mut self, global: Global) -> WasmResult<()>;
867 
868     /// Provides the number of exports up front. By default this does nothing, but
869     /// implementations can use this to preallocate memory if desired.
reserve_exports(&mut self, _num: u32) -> WasmResult<()>870     fn reserve_exports(&mut self, _num: u32) -> WasmResult<()> {
871         Ok(())
872     }
873 
874     /// Declares a function export to the environment.
declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>875     fn declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>;
876 
877     /// Declares a table export to the environment.
declare_table_export(&mut self, table_index: TableIndex, name: &'data str) -> WasmResult<()>878     fn declare_table_export(&mut self, table_index: TableIndex, name: &'data str)
879         -> WasmResult<()>;
880 
881     /// Declares a memory export to the environment.
declare_memory_export( &mut self, memory_index: MemoryIndex, name: &'data str, ) -> WasmResult<()>882     fn declare_memory_export(
883         &mut self,
884         memory_index: MemoryIndex,
885         name: &'data str,
886     ) -> WasmResult<()>;
887 
888     /// Declares an event export to the environment.
declare_event_export( &mut self, event_index: EventIndex, name: &'data str, ) -> WasmResult<()>889     fn declare_event_export(
890         &mut self,
891         event_index: EventIndex,
892         name: &'data str,
893     ) -> WasmResult<()> {
894         drop((event_index, name));
895         Err(WasmError::Unsupported("wasm events".to_string()))
896     }
897 
898     /// Declares a global export to the environment.
declare_global_export( &mut self, global_index: GlobalIndex, name: &'data str, ) -> WasmResult<()>899     fn declare_global_export(
900         &mut self,
901         global_index: GlobalIndex,
902         name: &'data str,
903     ) -> WasmResult<()>;
904 
905     /// Declares an instance export to the environment.
declare_instance_export( &mut self, index: InstanceIndex, name: &'data str, ) -> WasmResult<()>906     fn declare_instance_export(
907         &mut self,
908         index: InstanceIndex,
909         name: &'data str,
910     ) -> WasmResult<()> {
911         drop((index, name));
912         Err(WasmError::Unsupported("module linking".to_string()))
913     }
914 
915     /// Declares an instance export to the environment.
declare_module_export(&mut self, index: ModuleIndex, name: &'data str) -> WasmResult<()>916     fn declare_module_export(&mut self, index: ModuleIndex, name: &'data str) -> WasmResult<()> {
917         drop((index, name));
918         Err(WasmError::Unsupported("module linking".to_string()))
919     }
920 
921     /// Notifies the implementation that all exports have been declared.
finish_exports(&mut self) -> WasmResult<()>922     fn finish_exports(&mut self) -> WasmResult<()> {
923         Ok(())
924     }
925 
926     /// Declares the optional start function.
declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>927     fn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>;
928 
929     /// Provides the number of element initializers up front. By default this does nothing, but
930     /// implementations can use this to preallocate memory if desired.
reserve_table_elements(&mut self, _num: u32) -> WasmResult<()>931     fn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()> {
932         Ok(())
933     }
934 
935     /// Fills a declared table with references to functions in the module.
declare_table_elements( &mut self, table_index: TableIndex, base: Option<GlobalIndex>, offset: u32, elements: Box<[FuncIndex]>, ) -> WasmResult<()>936     fn declare_table_elements(
937         &mut self,
938         table_index: TableIndex,
939         base: Option<GlobalIndex>,
940         offset: u32,
941         elements: Box<[FuncIndex]>,
942     ) -> WasmResult<()>;
943 
944     /// Declare a passive element segment.
declare_passive_element( &mut self, index: ElemIndex, elements: Box<[FuncIndex]>, ) -> WasmResult<()>945     fn declare_passive_element(
946         &mut self,
947         index: ElemIndex,
948         elements: Box<[FuncIndex]>,
949     ) -> WasmResult<()>;
950 
951     /// Indicates that a declarative element segment was seen in the wasm
952     /// module.
declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()>953     fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()> {
954         drop(elements);
955         Ok(())
956     }
957 
958     /// Provides the number of passive data segments up front.
959     ///
960     /// By default this does nothing, but implementations may use this to
961     /// pre-allocate memory if desired.
reserve_passive_data(&mut self, count: u32) -> WasmResult<()>962     fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> {
963         let _ = count;
964         Ok(())
965     }
966 
967     /// Declare a passive data segment.
declare_passive_data(&mut self, data_index: DataIndex, data: &'data [u8]) -> WasmResult<()>968     fn declare_passive_data(&mut self, data_index: DataIndex, data: &'data [u8]) -> WasmResult<()>;
969 
970     /// Indicates how many functions the code section reports and the byte
971     /// offset of where the code sections starts.
reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64)972     fn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64) {
973         drop((bodies, code_section_offset));
974     }
975 
976     /// Provides the contents of a function body.
define_function_body( &mut self, validator: FuncValidator<ValidatorResources>, body: FunctionBody<'data>, ) -> WasmResult<()>977     fn define_function_body(
978         &mut self,
979         validator: FuncValidator<ValidatorResources>,
980         body: FunctionBody<'data>,
981     ) -> WasmResult<()>;
982 
983     /// Provides the number of data initializers up front. By default this does nothing, but
984     /// implementations can use this to preallocate memory if desired.
reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()>985     fn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()> {
986         Ok(())
987     }
988 
989     /// Fills a declared memory with bytes at module instantiation.
declare_data_initialization( &mut self, memory_index: MemoryIndex, base: Option<GlobalIndex>, offset: u32, data: &'data [u8], ) -> WasmResult<()>990     fn declare_data_initialization(
991         &mut self,
992         memory_index: MemoryIndex,
993         base: Option<GlobalIndex>,
994         offset: u32,
995         data: &'data [u8],
996     ) -> WasmResult<()>;
997 
998     /// Declares the name of a module to the environment.
999     ///
1000     /// By default this does nothing, but implementations can use this to read
1001     /// the module name subsection of the custom name section if desired.
declare_module_name(&mut self, _name: &'data str)1002     fn declare_module_name(&mut self, _name: &'data str) {}
1003 
1004     /// Declares the name of a function to the environment.
1005     ///
1006     /// By default this does nothing, but implementations can use this to read
1007     /// the function name subsection of the custom name section if desired.
declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str)1008     fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str) {}
1009 
1010     /// Declares the name of a function's local to the environment.
1011     ///
1012     /// By default this does nothing, but implementations can use this to read
1013     /// the local name subsection of the custom name section if desired.
declare_local_name(&mut self, _func_index: FuncIndex, _local_index: u32, _name: &'data str)1014     fn declare_local_name(&mut self, _func_index: FuncIndex, _local_index: u32, _name: &'data str) {
1015     }
1016 
1017     /// Indicates that a custom section has been found in the wasm file
custom_section(&mut self, _name: &'data str, _data: &'data [u8]) -> WasmResult<()>1018     fn custom_section(&mut self, _name: &'data str, _data: &'data [u8]) -> WasmResult<()> {
1019         Ok(())
1020     }
1021 
1022     /// Returns the list of enabled wasm features this translation will be using.
wasm_features(&self) -> WasmFeatures1023     fn wasm_features(&self) -> WasmFeatures {
1024         WasmFeatures::default()
1025     }
1026 
1027     /// Indicates that this module will have `amount` submodules.
1028     ///
1029     /// Note that this is just child modules of this module, and each child
1030     /// module may have yet more submodules.
reserve_modules(&mut self, amount: u32)1031     fn reserve_modules(&mut self, amount: u32) {
1032         drop(amount);
1033     }
1034 
1035     /// Called at the beginning of translating a module.
1036     ///
1037     /// Note that for nested modules this may be called multiple times.
module_start(&mut self)1038     fn module_start(&mut self) {}
1039 
1040     /// Called at the end of translating a module.
1041     ///
1042     /// Note that for nested modules this may be called multiple times.
module_end(&mut self)1043     fn module_end(&mut self) {}
1044 
1045     /// Indicates that this module will have `amount` instances.
reserve_instances(&mut self, amount: u32)1046     fn reserve_instances(&mut self, amount: u32) {
1047         drop(amount);
1048     }
1049 
1050     /// Declares a new instance which this module will instantiate before it's
1051     /// instantiated.
declare_instance( &mut self, module: ModuleIndex, args: Vec<(&'data str, EntityIndex)>, ) -> WasmResult<()>1052     fn declare_instance(
1053         &mut self,
1054         module: ModuleIndex,
1055         args: Vec<(&'data str, EntityIndex)>,
1056     ) -> WasmResult<()> {
1057         drop((module, args));
1058         Err(WasmError::Unsupported("wasm instance".to_string()))
1059     }
1060 
1061     /// Declares a new alias being added to this module.
1062     ///
1063     /// The alias comes from the `instance` specified (or the parent if `None`
1064     /// is supplied) and the index is either in the module's own index spaces
1065     /// for the parent or an index into the exports for nested instances.
declare_alias(&mut self, alias: Alias<'data>) -> WasmResult<()>1066     fn declare_alias(&mut self, alias: Alias<'data>) -> WasmResult<()> {
1067         drop(alias);
1068         Err(WasmError::Unsupported("wasm alias".to_string()))
1069     }
1070 }
1071