cranelift_wasm/environ/
spec.rs

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
9use crate::state::FuncTranslationState;
10use crate::{
11    DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, Heap, HeapData, Memory, MemoryIndex,
12    Table, TableIndex, Tag, TagIndex, TypeConvert, TypeIndex, WasmError, WasmFuncType,
13    WasmHeapType, WasmResult,
14};
15use cranelift_codegen::cursor::FuncCursor;
16use cranelift_codegen::ir::immediates::Offset32;
17use cranelift_codegen::ir::{self, InstBuilder, Type};
18use cranelift_codegen::isa::TargetFrontendConfig;
19use cranelift_entity::PrimaryMap;
20use cranelift_frontend::FunctionBuilder;
21use std::boxed::Box;
22use std::string::ToString;
23use wasmparser::{FuncValidator, FunctionBody, Operator, ValidatorResources, WasmFeatures};
24use wasmtime_types::{ConstExpr, ModuleInternedTypeIndex};
25
26/// The value of a WebAssembly global variable.
27#[derive(Clone, Copy)]
28pub enum GlobalVariable {
29    /// This is a constant global with a value known at compile time.
30    Const(ir::Value),
31
32    /// This is a variable in memory that should be referenced through a `GlobalValue`.
33    Memory {
34        /// The address of the global variable storage.
35        gv: ir::GlobalValue,
36        /// An offset to add to the address.
37        offset: Offset32,
38        /// The global variable's type.
39        ty: ir::Type,
40    },
41
42    /// This is a global variable that needs to be handled by the environment.
43    Custom,
44}
45
46/// Environment affecting the translation of a WebAssembly.
47pub trait TargetEnvironment: TypeConvert {
48    /// Get the information needed to produce Cranelift IR for the given target.
49    fn target_config(&self) -> TargetFrontendConfig;
50
51    /// Whether to enable Spectre mitigations for heap accesses.
52    fn heap_access_spectre_mitigation(&self) -> bool;
53
54    /// Whether to add proof-carrying-code facts to verify memory accesses.
55    fn proof_carrying_code(&self) -> bool;
56
57    /// Get the Cranelift integer type to use for native pointers.
58    ///
59    /// This returns `I64` for 64-bit architectures and `I32` for 32-bit architectures.
60    fn pointer_type(&self) -> ir::Type {
61        ir::Type::int(u16::from(self.target_config().pointer_bits())).unwrap()
62    }
63
64    /// Get the size of a native pointer, in bytes.
65    fn pointer_bytes(&self) -> u8 {
66        self.target_config().pointer_bytes()
67    }
68
69    /// Get the Cranelift reference type to use for the given Wasm reference
70    /// type.
71    ///
72    /// Returns a pair of the CLIF reference type to use and a boolean that
73    /// describes whether the value should be included in GC stack maps or not.
74    fn reference_type(&self, ty: WasmHeapType) -> (ir::Type, bool);
75}
76
77/// Environment affecting the translation of a single WebAssembly function.
78///
79/// A `FuncEnvironment` trait object is required to translate a WebAssembly function to Cranelift
80/// IR. The function environment provides information about the WebAssembly module as well as the
81/// runtime environment.
82pub trait FuncEnvironment: TargetEnvironment {
83    /// Is the given parameter of the given function a wasm-level parameter, as opposed to a hidden
84    /// parameter added for use by the implementation?
85    fn is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool {
86        signature.params[index].purpose == ir::ArgumentPurpose::Normal
87    }
88
89    /// Does the given parameter require inclusion in stack maps?
90    fn param_needs_stack_map(&self, signature: &ir::Signature, index: usize) -> bool;
91
92    /// Does the given result require inclusion in stack maps?
93    fn sig_ref_result_needs_stack_map(&self, sig_ref: ir::SigRef, index: usize) -> bool;
94
95    /// Does the given result require inclusion in stack maps?
96    fn func_ref_result_needs_stack_map(
97        &self,
98        func: &ir::Function,
99        func_ref: ir::FuncRef,
100        index: usize,
101    ) -> bool;
102
103    /// Is the given return of the given function a wasm-level parameter, as
104    /// opposed to a hidden parameter added for use by the implementation?
105    fn is_wasm_return(&self, signature: &ir::Signature, index: usize) -> bool {
106        signature.returns[index].purpose == ir::ArgumentPurpose::Normal
107    }
108
109    /// Called after the locals for a function have been parsed, and the number
110    /// of variables defined by this function is provided.
111    fn after_locals(&mut self, num_locals_defined: usize) {
112        let _ = num_locals_defined;
113    }
114
115    /// Set up the necessary preamble definitions in `func` to access the global variable
116    /// identified by `index`.
117    ///
118    /// The index space covers both imported globals and globals defined by the module.
119    ///
120    /// Return the global variable reference that should be used to access the global and the
121    /// WebAssembly type of the global.
122    fn make_global(
123        &mut self,
124        func: &mut ir::Function,
125        index: GlobalIndex,
126    ) -> WasmResult<GlobalVariable>;
127
128    /// Get the heaps for this function environment.
129    ///
130    /// The returned map should provide heap format details (encoded in
131    /// `HeapData`) for each `Heap` that was previously returned by
132    /// `make_heap()`. The translator will first call make_heap for each Wasm
133    /// memory, and then later when translating code, will invoke `heaps()` to
134    /// learn how to access the environment's implementation of each memory.
135    fn heaps(&self) -> &PrimaryMap<Heap, HeapData>;
136
137    /// Set up the necessary preamble definitions in `func` to access the linear memory identified
138    /// by `index`.
139    ///
140    /// The index space covers both imported and locally declared memories.
141    fn make_heap(&mut self, func: &mut ir::Function, index: MemoryIndex) -> WasmResult<Heap>;
142
143    /// Set up a signature definition in the preamble of `func` that can be used for an indirect
144    /// call with signature `index`.
145    ///
146    /// The signature may contain additional arguments needed for an indirect call, but the
147    /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
148    /// arguments.
149    ///
150    /// The signature will only be used for indirect calls, even if the module has direct function
151    /// calls with the same WebAssembly type.
152    fn make_indirect_sig(
153        &mut self,
154        func: &mut ir::Function,
155        index: TypeIndex,
156    ) -> WasmResult<ir::SigRef>;
157
158    /// Set up an external function definition in the preamble of `func` that can be used to
159    /// directly call the function `index`.
160    ///
161    /// The index space covers both imported functions and functions defined in the current module.
162    ///
163    /// The function's signature may contain additional arguments needed for a direct call, but the
164    /// arguments marked as `ArgumentPurpose::Normal` must correspond to the WebAssembly signature
165    /// arguments.
166    ///
167    /// The function's signature will only be used for direct calls, even if the module has
168    /// indirect calls with the same WebAssembly type.
169    fn make_direct_func(
170        &mut self,
171        func: &mut ir::Function,
172        index: FuncIndex,
173    ) -> WasmResult<ir::FuncRef>;
174
175    /// Translate a `call` WebAssembly instruction at `pos`.
176    ///
177    /// Insert instructions at `pos` for a direct call to the function `callee_index`.
178    ///
179    /// The function reference `callee` was previously created by `make_direct_func()`.
180    ///
181    /// Return the call instruction whose results are the WebAssembly return values.
182    fn translate_call(
183        &mut self,
184        builder: &mut FunctionBuilder,
185        _callee_index: FuncIndex,
186        callee: ir::FuncRef,
187        call_args: &[ir::Value],
188    ) -> WasmResult<ir::Inst> {
189        Ok(builder.ins().call(callee, call_args))
190    }
191
192    /// Translate a `call_indirect` WebAssembly instruction at `pos`.
193    ///
194    /// Insert instructions at `pos` for an indirect call to the function `callee` in the table
195    /// `table_index` with WebAssembly signature `sig_index`. The `callee` value will have type
196    /// `i32`.
197    ///
198    /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
199    ///
200    /// Return the call instruction whose results are the WebAssembly return values.
201    /// Returns `None` if this statically traps instead of creating a call
202    /// instruction.
203    fn translate_call_indirect(
204        &mut self,
205        builder: &mut FunctionBuilder,
206        table_index: TableIndex,
207        sig_index: TypeIndex,
208        sig_ref: ir::SigRef,
209        callee: ir::Value,
210        call_args: &[ir::Value],
211    ) -> WasmResult<Option<ir::Inst>>;
212
213    /// Translate a `return_call` WebAssembly instruction at the builder's
214    /// current position.
215    ///
216    /// Insert instructions at the builder's current position for a direct tail
217    /// call to the function `callee_index`.
218    ///
219    /// The function reference `callee` was previously created by `make_direct_func()`.
220    ///
221    /// Return the call instruction whose results are the WebAssembly return values.
222    fn translate_return_call(
223        &mut self,
224        builder: &mut FunctionBuilder,
225        _callee_index: FuncIndex,
226        callee: ir::FuncRef,
227        call_args: &[ir::Value],
228    ) -> WasmResult<()> {
229        builder.ins().return_call(callee, call_args);
230        Ok(())
231    }
232
233    /// Translate a `return_call_indirect` WebAssembly instruction at the
234    /// builder's current position.
235    ///
236    /// Insert instructions at the builder's current position for an indirect
237    /// tail call to the function `callee` in the table `table_index` with
238    /// WebAssembly signature `sig_index`. The `callee` value will have type
239    /// `i32`.
240    ///
241    /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
242    fn translate_return_call_indirect(
243        &mut self,
244        builder: &mut FunctionBuilder,
245        table_index: TableIndex,
246        sig_index: TypeIndex,
247        sig_ref: ir::SigRef,
248        callee: ir::Value,
249        call_args: &[ir::Value],
250    ) -> WasmResult<()>;
251
252    /// Translate a `return_call_ref` WebAssembly instruction at the builder's
253    /// given position.
254    ///
255    /// Insert instructions at the builder's current position for an indirect
256    /// tail call to the function `callee`. The `callee` value will be a Wasm
257    /// funcref that may need to be translated to a native function address
258    /// depending on your implementation of this trait.
259    ///
260    /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
261    fn translate_return_call_ref(
262        &mut self,
263        builder: &mut FunctionBuilder,
264        sig_ref: ir::SigRef,
265        callee: ir::Value,
266        call_args: &[ir::Value],
267    ) -> WasmResult<()>;
268
269    /// Translate a `call_ref` WebAssembly instruction at the builder's current
270    /// position.
271    ///
272    /// Insert instructions at the builder's current position for an indirect
273    /// call to the function `callee`. The `callee` value will be a Wasm funcref
274    /// that may need to be translated to a native function address depending on
275    /// your implementation of this trait.
276    ///
277    /// The signature `sig_ref` was previously created by `make_indirect_sig()`.
278    ///
279    /// Return the call instruction whose results are the WebAssembly return values.
280    fn translate_call_ref(
281        &mut self,
282        builder: &mut FunctionBuilder,
283        sig_ref: ir::SigRef,
284        callee: ir::Value,
285        call_args: &[ir::Value],
286    ) -> WasmResult<ir::Inst>;
287
288    /// Translate a `memory.grow` WebAssembly instruction.
289    ///
290    /// The `index` provided identifies the linear memory to grow, and `heap` is the heap reference
291    /// returned by `make_heap` for the same index.
292    ///
293    /// The `val` value is the requested memory size in pages.
294    ///
295    /// Returns the old size (in pages) of the memory.
296    fn translate_memory_grow(
297        &mut self,
298        pos: FuncCursor,
299        index: MemoryIndex,
300        heap: Heap,
301        val: ir::Value,
302    ) -> WasmResult<ir::Value>;
303
304    /// Translates a `memory.size` WebAssembly instruction.
305    ///
306    /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
307    /// returned by `make_heap` for the same index.
308    ///
309    /// Returns the size in pages of the memory.
310    fn translate_memory_size(
311        &mut self,
312        pos: FuncCursor,
313        index: MemoryIndex,
314        heap: Heap,
315    ) -> WasmResult<ir::Value>;
316
317    /// Translate a `memory.copy` WebAssembly instruction.
318    ///
319    /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
320    /// returned by `make_heap` for the same index.
321    fn translate_memory_copy(
322        &mut self,
323        pos: FuncCursor,
324        src_index: MemoryIndex,
325        src_heap: Heap,
326        dst_index: MemoryIndex,
327        dst_heap: Heap,
328        dst: ir::Value,
329        src: ir::Value,
330        len: ir::Value,
331    ) -> WasmResult<()>;
332
333    /// Translate a `memory.fill` WebAssembly instruction.
334    ///
335    /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
336    /// returned by `make_heap` for the same index.
337    fn translate_memory_fill(
338        &mut self,
339        pos: FuncCursor,
340        index: MemoryIndex,
341        heap: Heap,
342        dst: ir::Value,
343        val: ir::Value,
344        len: ir::Value,
345    ) -> WasmResult<()>;
346
347    /// Translate a `memory.init` WebAssembly instruction.
348    ///
349    /// The `index` provided identifies the linear memory to query, and `heap` is the heap reference
350    /// returned by `make_heap` for the same index. `seg_index` is the index of the segment to copy
351    /// from.
352    fn translate_memory_init(
353        &mut self,
354        pos: FuncCursor,
355        index: MemoryIndex,
356        heap: Heap,
357        seg_index: u32,
358        dst: ir::Value,
359        src: ir::Value,
360        len: ir::Value,
361    ) -> WasmResult<()>;
362
363    /// Translate a `data.drop` WebAssembly instruction.
364    fn translate_data_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
365
366    /// Translate a `table.size` WebAssembly instruction.
367    fn translate_table_size(&mut self, pos: FuncCursor, index: TableIndex)
368        -> WasmResult<ir::Value>;
369
370    /// Translate a `table.grow` WebAssembly instruction.
371    fn translate_table_grow(
372        &mut self,
373        pos: FuncCursor,
374        table_index: TableIndex,
375        delta: ir::Value,
376        init_value: ir::Value,
377    ) -> WasmResult<ir::Value>;
378
379    /// Translate a `table.get` WebAssembly instruction.
380    fn translate_table_get(
381        &mut self,
382        builder: &mut FunctionBuilder,
383        table_index: TableIndex,
384        index: ir::Value,
385    ) -> WasmResult<ir::Value>;
386
387    /// Translate a `table.set` WebAssembly instruction.
388    fn translate_table_set(
389        &mut self,
390        builder: &mut FunctionBuilder,
391        table_index: TableIndex,
392        value: ir::Value,
393        index: ir::Value,
394    ) -> WasmResult<()>;
395
396    /// Translate a `table.copy` WebAssembly instruction.
397    fn translate_table_copy(
398        &mut self,
399        pos: FuncCursor,
400        dst_table_index: TableIndex,
401        src_table_index: TableIndex,
402        dst: ir::Value,
403        src: ir::Value,
404        len: ir::Value,
405    ) -> WasmResult<()>;
406
407    /// Translate a `table.fill` WebAssembly instruction.
408    fn translate_table_fill(
409        &mut self,
410        pos: FuncCursor,
411        table_index: TableIndex,
412        dst: ir::Value,
413        val: ir::Value,
414        len: ir::Value,
415    ) -> WasmResult<()>;
416
417    /// Translate a `table.init` WebAssembly instruction.
418    fn translate_table_init(
419        &mut self,
420        pos: FuncCursor,
421        seg_index: u32,
422        table_index: TableIndex,
423        dst: ir::Value,
424        src: ir::Value,
425        len: ir::Value,
426    ) -> WasmResult<()>;
427
428    /// Translate a `elem.drop` WebAssembly instruction.
429    fn translate_elem_drop(&mut self, pos: FuncCursor, seg_index: u32) -> WasmResult<()>;
430
431    /// Translate a `ref.null T` WebAssembly instruction.
432    fn translate_ref_null(&mut self, pos: FuncCursor, ty: WasmHeapType) -> WasmResult<ir::Value>;
433
434    /// Translate a `ref.is_null` WebAssembly instruction.
435    fn translate_ref_is_null(&mut self, pos: FuncCursor, value: ir::Value)
436        -> WasmResult<ir::Value>;
437
438    /// Translate a `ref.func` WebAssembly instruction.
439    fn translate_ref_func(
440        &mut self,
441        pos: FuncCursor,
442        func_index: FuncIndex,
443    ) -> WasmResult<ir::Value>;
444
445    /// Translate a `global.get` WebAssembly instruction at `pos` for a global
446    /// that is custom.
447    fn translate_custom_global_get(
448        &mut self,
449        builder: &mut FunctionBuilder,
450        global_index: GlobalIndex,
451    ) -> WasmResult<ir::Value>;
452
453    /// Translate a `global.set` WebAssembly instruction at `pos` for a global
454    /// that is custom.
455    fn translate_custom_global_set(
456        &mut self,
457        builder: &mut FunctionBuilder,
458        global_index: GlobalIndex,
459        val: ir::Value,
460    ) -> WasmResult<()>;
461
462    /// Translate an `i32.atomic.wait` or `i64.atomic.wait` WebAssembly instruction.
463    /// The `index` provided identifies the linear memory containing the value
464    /// to wait on, and `heap` is the heap reference returned by `make_heap`
465    /// for the same index.  Whether the waited-on value is 32- or 64-bit can be
466    /// determined by examining the type of `expected`, which must be only I32 or I64.
467    ///
468    /// Note that the `addr` here is the host linear memory address rather
469    /// than a relative wasm linear memory address. The type of this value is
470    /// the same as the host's pointer.
471    ///
472    /// Returns an i32, which is negative if the helper call failed.
473    fn translate_atomic_wait(
474        &mut self,
475        pos: FuncCursor,
476        index: MemoryIndex,
477        heap: Heap,
478        addr: ir::Value,
479        expected: ir::Value,
480        timeout: ir::Value,
481    ) -> WasmResult<ir::Value>;
482
483    /// Translate an `atomic.notify` WebAssembly instruction.
484    /// The `index` provided identifies the linear memory containing the value
485    /// to wait on, and `heap` is the heap reference returned by `make_heap`
486    /// for the same index.
487    ///
488    /// Note that the `addr` here is the host linear memory address rather
489    /// than a relative wasm linear memory address. The type of this value is
490    /// the same as the host's pointer.
491    ///
492    /// Returns an i64, which is negative if the helper call failed.
493    fn translate_atomic_notify(
494        &mut self,
495        pos: FuncCursor,
496        index: MemoryIndex,
497        heap: Heap,
498        addr: ir::Value,
499        count: ir::Value,
500    ) -> WasmResult<ir::Value>;
501
502    /// Translate an `i32` value into an `i31ref`.
503    fn translate_ref_i31(&mut self, pos: FuncCursor, val: ir::Value) -> WasmResult<ir::Value>;
504
505    /// Sign-extend an `i31ref` into an `i32`.
506    fn translate_i31_get_s(&mut self, pos: FuncCursor, i31ref: ir::Value) -> WasmResult<ir::Value>;
507
508    /// Zero-extend an `i31ref` into an `i32`.
509    fn translate_i31_get_u(&mut self, pos: FuncCursor, i31ref: ir::Value) -> WasmResult<ir::Value>;
510
511    /// Emit code at the beginning of every wasm loop.
512    ///
513    /// This can be used to insert explicit interrupt or safepoint checking at
514    /// the beginnings of loops.
515    fn translate_loop_header(&mut self, _builder: &mut FunctionBuilder) -> WasmResult<()> {
516        // By default, don't emit anything.
517        Ok(())
518    }
519
520    /// Optional callback for the `FunctionEnvironment` performing this translation to maintain
521    /// internal state or prepare custom state for the operator to translate
522    fn before_translate_operator(
523        &mut self,
524        _op: &Operator,
525        _builder: &mut FunctionBuilder,
526        _state: &FuncTranslationState,
527    ) -> WasmResult<()> {
528        Ok(())
529    }
530
531    /// Optional callback for the `FunctionEnvironment` performing this translation to maintain
532    /// internal state or finalize custom state for the operator that was translated
533    fn after_translate_operator(
534        &mut self,
535        _op: &Operator,
536        _builder: &mut FunctionBuilder,
537        _state: &FuncTranslationState,
538    ) -> WasmResult<()> {
539        Ok(())
540    }
541
542    /// Optional callback for the `FuncEnvironment` performing this translation
543    /// to maintain, prepare, or finalize custom, internal state when we
544    /// statically determine that a Wasm memory access will unconditionally
545    /// trap, rendering the rest of the block unreachable. Called just before
546    /// the unconditional trap is emitted.
547    fn before_unconditionally_trapping_memory_access(
548        &mut self,
549        _builder: &mut FunctionBuilder,
550    ) -> WasmResult<()> {
551        Ok(())
552    }
553
554    /// Optional callback for the `FunctionEnvironment` performing this translation to perform work
555    /// before the function body is translated.
556    fn before_translate_function(
557        &mut self,
558        _builder: &mut FunctionBuilder,
559        _state: &FuncTranslationState,
560    ) -> WasmResult<()> {
561        Ok(())
562    }
563
564    /// Optional callback for the `FunctionEnvironment` performing this translation to perform work
565    /// after the function body is translated.
566    fn after_translate_function(
567        &mut self,
568        _builder: &mut FunctionBuilder,
569        _state: &FuncTranslationState,
570    ) -> WasmResult<()> {
571        Ok(())
572    }
573
574    /// Whether or not to force relaxed simd instructions to have deterministic
575    /// lowerings meaning they will produce the same results across all hosts,
576    /// regardless of the cost to performance.
577    fn relaxed_simd_deterministic(&self) -> bool {
578        true
579    }
580
581    /// Whether or not the target being translated for has a native fma
582    /// instruction. If it does not then when relaxed simd isn't deterministic
583    /// the translation of the `f32x4.relaxed_fma` instruction, for example,
584    /// will do a multiplication and then an add instead of the fused version.
585    fn has_native_fma(&self) -> bool {
586        false
587    }
588
589    /// Returns whether this is an x86 target, which may alter lowerings of
590    /// relaxed simd instructions.
591    fn is_x86(&self) -> bool {
592        false
593    }
594
595    /// Returns whether the CLIF `x86_blendv` instruction should be used for the
596    /// relaxed simd `*.relaxed_laneselect` instruction for the specified type.
597    fn use_x86_blendv_for_relaxed_laneselect(&self, ty: Type) -> bool {
598        let _ = ty;
599        false
600    }
601
602    /// Returns whether the CLIF `x86_pshufb` instruction should be used for the
603    /// `i8x16.relaxed_swizzle` instruction.
604    fn use_x86_pshufb_for_relaxed_swizzle(&self) -> bool {
605        false
606    }
607
608    /// Returns whether the CLIF `x86_pmulhrsw` instruction should be used for
609    /// the `i8x16.relaxed_q15mulr_s` instruction.
610    fn use_x86_pmulhrsw_for_relaxed_q15mul(&self) -> bool {
611        false
612    }
613
614    /// Returns whether the CLIF `x86_pmaddubsw` instruction should be used for
615    /// the relaxed-simd dot-product instructions instruction.
616    fn use_x86_pmaddubsw_for_dot(&self) -> bool {
617        false
618    }
619
620    /// Inserts code before a function return.
621    fn handle_before_return(&mut self, _retvals: &[ir::Value], _builder: &mut FunctionBuilder) {}
622
623    /// Inserts code before a load.
624    fn before_load(
625        &mut self,
626        _builder: &mut FunctionBuilder,
627        _val_size: u8,
628        _addr: ir::Value,
629        _offset: u64,
630    ) {
631    }
632
633    /// Inserts code before a store.
634    fn before_store(
635        &mut self,
636        _builder: &mut FunctionBuilder,
637        _val_size: u8,
638        _addr: ir::Value,
639        _offset: u64,
640    ) {
641    }
642
643    /// Inserts code before updating a global.
644    fn update_global(
645        &mut self,
646        _builder: &mut FunctionBuilder,
647        _global_index: u32,
648        _value: ir::Value,
649    ) {
650    }
651
652    /// Inserts code before memory.grow.
653    fn before_memory_grow(
654        &mut self,
655        _builder: &mut FunctionBuilder,
656        _num_bytes: ir::Value,
657        _mem_index: MemoryIndex,
658    ) {
659    }
660}
661
662/// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the
663/// [`translate_module`](fn.translate_module.html) function. These methods should not be called
664/// by the user, they are only for `cranelift-wasm` internal use.
665pub trait ModuleEnvironment<'data>: TypeConvert {
666    /// Provides the number of types up front. By default this does nothing, but
667    /// implementations can use this to preallocate memory if desired.
668    fn reserve_types(&mut self, _num: u32) -> WasmResult<()> {
669        Ok(())
670    }
671
672    /// Declares a function signature to the environment.
673    fn declare_type_func(&mut self, wasm_func_type: WasmFuncType) -> WasmResult<()>;
674
675    /// Translates a type index to its signature index, only called for type
676    /// indices which point to functions.
677    fn type_to_signature(&self, index: TypeIndex) -> WasmResult<ModuleInternedTypeIndex> {
678        let _ = index;
679        Err(WasmError::Unsupported("module linking".to_string()))
680    }
681
682    /// Provides the number of imports up front. By default this does nothing, but
683    /// implementations can use this to preallocate memory if desired.
684    fn reserve_imports(&mut self, _num: u32) -> WasmResult<()> {
685        Ok(())
686    }
687
688    /// Declares a function import to the environment.
689    fn declare_func_import(
690        &mut self,
691        index: TypeIndex,
692        module: &'data str,
693        field: &'data str,
694    ) -> WasmResult<()>;
695
696    /// Declares a table import to the environment.
697    fn declare_table_import(
698        &mut self,
699        table: Table,
700        module: &'data str,
701        field: &'data str,
702    ) -> WasmResult<()>;
703
704    /// Declares a memory import to the environment.
705    fn declare_memory_import(
706        &mut self,
707        memory: Memory,
708        module: &'data str,
709        field: &'data str,
710    ) -> WasmResult<()>;
711
712    /// Declares an tag import to the environment.
713    fn declare_tag_import(
714        &mut self,
715        tag: Tag,
716        module: &'data str,
717        field: &'data str,
718    ) -> WasmResult<()> {
719        let _ = (tag, module, field);
720        Err(WasmError::Unsupported("wasm tags".to_string()))
721    }
722
723    /// Declares a global import to the environment.
724    fn declare_global_import(
725        &mut self,
726        global: Global,
727        module: &'data str,
728        field: &'data str,
729    ) -> WasmResult<()>;
730
731    /// Notifies the implementation that all imports have been declared.
732    fn finish_imports(&mut self) -> WasmResult<()> {
733        Ok(())
734    }
735
736    /// Provides the number of defined functions up front. By default this does nothing, but
737    /// implementations can use this to preallocate memory if desired.
738    fn reserve_func_types(&mut self, _num: u32) -> WasmResult<()> {
739        Ok(())
740    }
741
742    /// Declares the type (signature) of a local function in the module.
743    fn declare_func_type(&mut self, index: TypeIndex) -> WasmResult<()>;
744
745    /// Provides the number of defined tables up front. By default this does nothing, but
746    /// implementations can use this to preallocate memory if desired.
747    fn reserve_tables(&mut self, _num: u32) -> WasmResult<()> {
748        Ok(())
749    }
750
751    /// Declares a table to the environment.
752    fn declare_table(&mut self, table: Table) -> WasmResult<()>;
753
754    /// Provides the number of defined memories up front. By default this does nothing, but
755    /// implementations can use this to preallocate memory if desired.
756    fn reserve_memories(&mut self, _num: u32) -> WasmResult<()> {
757        Ok(())
758    }
759
760    /// Declares a memory to the environment
761    fn declare_memory(&mut self, memory: Memory) -> WasmResult<()>;
762
763    /// Provides the number of defined tags up front. By default this does nothing, but
764    /// implementations can use this to preallocate memory if desired.
765    fn reserve_tags(&mut self, _num: u32) -> WasmResult<()> {
766        Ok(())
767    }
768
769    /// Declares an tag to the environment
770    fn declare_tag(&mut self, tag: Tag) -> WasmResult<()> {
771        let _ = tag;
772        Err(WasmError::Unsupported("wasm tags".to_string()))
773    }
774
775    /// Provides the number of defined globals up front. By default this does nothing, but
776    /// implementations can use this to preallocate memory if desired.
777    fn reserve_globals(&mut self, _num: u32) -> WasmResult<()> {
778        Ok(())
779    }
780
781    /// Declares a global to the environment.
782    fn declare_global(&mut self, global: Global, init: ConstExpr) -> WasmResult<()>;
783
784    /// Provides the number of exports up front. By default this does nothing, but
785    /// implementations can use this to preallocate memory if desired.
786    fn reserve_exports(&mut self, _num: u32) -> WasmResult<()> {
787        Ok(())
788    }
789
790    /// Declares a function export to the environment.
791    fn declare_func_export(&mut self, func_index: FuncIndex, name: &'data str) -> WasmResult<()>;
792
793    /// Declares a table export to the environment.
794    fn declare_table_export(&mut self, table_index: TableIndex, name: &'data str)
795        -> WasmResult<()>;
796
797    /// Declares a memory export to the environment.
798    fn declare_memory_export(
799        &mut self,
800        memory_index: MemoryIndex,
801        name: &'data str,
802    ) -> WasmResult<()>;
803
804    /// Declares an tag export to the environment.
805    fn declare_tag_export(&mut self, tag_index: TagIndex, name: &'data str) -> WasmResult<()> {
806        let _ = (tag_index, name);
807        Err(WasmError::Unsupported("wasm tags".to_string()))
808    }
809
810    /// Declares a global export to the environment.
811    fn declare_global_export(
812        &mut self,
813        global_index: GlobalIndex,
814        name: &'data str,
815    ) -> WasmResult<()>;
816
817    /// Notifies the implementation that all exports have been declared.
818    fn finish_exports(&mut self) -> WasmResult<()> {
819        Ok(())
820    }
821
822    /// Declares the optional start function.
823    fn declare_start_func(&mut self, index: FuncIndex) -> WasmResult<()>;
824
825    /// Provides the number of element initializers up front. By default this does nothing, but
826    /// implementations can use this to preallocate memory if desired.
827    fn reserve_table_elements(&mut self, _num: u32) -> WasmResult<()> {
828        Ok(())
829    }
830
831    /// Fills a declared table with references to functions in the module.
832    fn declare_table_elements(
833        &mut self,
834        table_index: TableIndex,
835        base: Option<GlobalIndex>,
836        offset: u32,
837        elements: Box<[FuncIndex]>,
838    ) -> WasmResult<()>;
839
840    /// Declare a passive element segment.
841    fn declare_passive_element(
842        &mut self,
843        index: ElemIndex,
844        elements: Box<[FuncIndex]>,
845    ) -> WasmResult<()>;
846
847    /// Indicates that a declarative element segment was seen in the wasm
848    /// module.
849    fn declare_elements(&mut self, elements: Box<[FuncIndex]>) -> WasmResult<()> {
850        let _ = elements;
851        Ok(())
852    }
853
854    /// Provides the number of passive data segments up front.
855    ///
856    /// By default this does nothing, but implementations may use this to
857    /// pre-allocate memory if desired.
858    fn reserve_passive_data(&mut self, count: u32) -> WasmResult<()> {
859        let _ = count;
860        Ok(())
861    }
862
863    /// Declare a passive data segment.
864    fn declare_passive_data(&mut self, data_index: DataIndex, data: &'data [u8]) -> WasmResult<()>;
865
866    /// Indicates how many functions the code section reports and the byte
867    /// offset of where the code sections starts.
868    fn reserve_function_bodies(&mut self, bodies: u32, code_section_offset: u64) {
869        let _ = (bodies, code_section_offset);
870    }
871
872    /// Provides the contents of a function body.
873    fn define_function_body(
874        &mut self,
875        validator: FuncValidator<ValidatorResources>,
876        body: FunctionBody<'data>,
877    ) -> WasmResult<()>;
878
879    /// Provides the number of data initializers up front. By default this does nothing, but
880    /// implementations can use this to preallocate memory if desired.
881    fn reserve_data_initializers(&mut self, _num: u32) -> WasmResult<()> {
882        Ok(())
883    }
884
885    /// Fills a declared memory with bytes at module instantiation.
886    fn declare_data_initialization(
887        &mut self,
888        memory_index: MemoryIndex,
889        base: Option<GlobalIndex>,
890        offset: u64,
891        data: &'data [u8],
892    ) -> WasmResult<()>;
893
894    /// Declares the name of a module to the environment.
895    ///
896    /// By default this does nothing, but implementations can use this to read
897    /// the module name subsection of the custom name section if desired.
898    fn declare_module_name(&mut self, _name: &'data str) {}
899
900    /// Declares the name of a function to the environment.
901    ///
902    /// By default this does nothing, but implementations can use this to read
903    /// the function name subsection of the custom name section if desired.
904    fn declare_func_name(&mut self, _func_index: FuncIndex, _name: &'data str) {}
905
906    /// Declares the name of a function's local to the environment.
907    ///
908    /// By default this does nothing, but implementations can use this to read
909    /// the local name subsection of the custom name section if desired.
910    fn declare_local_name(&mut self, _func_index: FuncIndex, _local_index: u32, _name: &'data str) {
911    }
912
913    /// Indicates that a custom section has been found in the wasm file
914    fn custom_section(&mut self, _name: &'data str, _data: &'data [u8]) -> WasmResult<()> {
915        Ok(())
916    }
917
918    /// Returns the list of enabled wasm features this translation will be using.
919    fn wasm_features(&self) -> WasmFeatures {
920        WasmFeatures::default()
921    }
922}