Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Function references #5288

Merged
merged 101 commits into from
May 26, 2023
Merged
Show file tree
Hide file tree
Changes from 98 commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
3799e10
Make wasmtime-types type check
dhil Jul 29, 2022
7a4bc7e
Make wasmtime-environ type check.
dhil Nov 17, 2022
6e73ec4
Make wasmtime-runtime type check
dhil Jul 29, 2022
cb0fa63
Make cranelift-wasm type check
dhil Aug 2, 2022
11acbe2
Make wasmtime-cranelift type check
dhil Nov 17, 2022
37c32fc
Make wasmtime type check
dhil Aug 2, 2022
5af12e6
Make wasmtime-wast type check
dhil Aug 2, 2022
98b26b0
Make testsuite compile
dhil Nov 14, 2022
1c6eb7e
Address Luna's comments
dhil Nov 17, 2022
0c69cba
Restore compatibility with effect-handlers/wasm-tools#func-ref-2
dhil Aug 5, 2022
931feeb
Add function refs feature flag; support testing
Aug 16, 2022
4897c59
Provide function references support in helpers
Nov 17, 2022
fda8182
Implement ref.as_non_null
dhil Aug 16, 2022
1959304
Add br_on_null
CosineP Aug 16, 2022
e14fde5
Update Cargo.lock to use wasm-tools with peek
Nov 14, 2022
6e31760
Add call_ref
CosineP Aug 18, 2022
aa71b96
Support typed function references in ref.null
Nov 17, 2022
1f411e6
Implement br_on_non_null
Oct 8, 2022
a589b99
Remove extraneous flag; default func refs false
Nov 17, 2022
b6d81e2
Use IndirectCallToNull trap code for call_ref
Nov 17, 2022
99fba53
Factor common call_indirect / call_ref into a fn
Nov 20, 2022
c199f2d
Remove copypasta clippy attribute / format
Nov 20, 2022
8e33f18
Add a some more tests for typed table instructions
Dec 5, 2022
8482369
Fix missing typed cases for table_grow, table_fill
Dec 6, 2022
d30c76e
Document trap code; remove answered question
Dec 6, 2022
20907e8
Mark wasm-tools to wasmtime reftype infallible
Dec 6, 2022
9d0482f
Fix reversed conditional
Dec 6, 2022
71a7e96
Scope externref/funcref shorthands within WasmRefType
Dec 6, 2022
6765ecb
Merge with upstream
dhil Feb 16, 2023
15eb6fa
Make wasmtime compile again
dhil Feb 17, 2023
1a34bd7
Fix warnings
dhil Feb 17, 2023
8b413b7
Merge with upstream
dhil Feb 17, 2023
e9f2e5e
Remove Bot from the type algebra
dhil Feb 17, 2023
e577829
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Feb 21, 2023
bba26c1
Fix table tests.
dhil Feb 21, 2023
4dbb57e
Fix table{get,set} tests.
dhil Feb 21, 2023
7e1f9b2
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Feb 22, 2023
93d2614
Insert subtype check to fix local_get tests.
dhil Feb 22, 2023
00856a4
Fix compilation of `br_on_non_null`.
dhil Feb 22, 2023
41b99b4
Fix ref_as_non_null tests.
dhil Feb 22, 2023
536aed8
Fix a call_ref regression.
dhil Feb 22, 2023
7bc9b38
Fix global tests.
dhil Feb 22, 2023
9f06a5a
Cargo update
dhil Feb 23, 2023
68a85e1
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Feb 23, 2023
ffca326
Update
dhil Feb 23, 2023
b3fad0c
Spell out some cases in match_val
dhil Feb 23, 2023
6b3c469
Disgusting hack to subvert limitations of type reconstruction.
dhil Feb 23, 2023
aa4d5dc
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Feb 23, 2023
ca0e32a
Merge pull request #13 from dhil/function-references-merge-2
dhil Feb 23, 2023
ccba83c
Merge with upstream/main
dhil Feb 27, 2023
cdfb6b1
Address workflows comments.
dhil Feb 27, 2023
94ca0f2
null reference => null_reference for CLIF parsing compliance.
dhil Feb 27, 2023
3372e86
Delete duplicate-loads-dynamic-memory-egraph (again)
dhil Feb 27, 2023
ad2745a
Idiomatic code change.
dhil Feb 27, 2023
f59872a
Nullability subtyping + fix non-null storage check.
dhil Feb 27, 2023
b83cfec
Trigger unimplemented for typed function references. Format values.rs
dhil Feb 27, 2023
55b3e07
run cargo fmt
dhil Feb 27, 2023
104faa4
Merge pull request #14 from dhil/function-references-merge-2
dhil Feb 27, 2023
29f596a
Explicitly match on HeapType::Extern.
dhil Feb 27, 2023
d2c32f1
Address cranelift-related feedback
dhil Mar 1, 2023
63ff410
Remove PartialEq,Eq from ValType, RefType, HeapType.
dhil Mar 1, 2023
6205a01
Pin wasmparser to a fairly recent commit.
dhil Mar 3, 2023
ae88c8c
Merge with upstream
dhil Mar 3, 2023
e2f5aa0
Merge with upstream
dhil Apr 3, 2023
87a2314
Run cargo fmt
dhil Apr 3, 2023
ab5bd54
Merge with upstream
dhil Apr 5, 2023
4a05b7a
Merge with upstream
dhil Apr 10, 2023
b518164
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 13, 2023
231c356
Merge with upstream
dhil Apr 17, 2023
9fb9be1
Ignore tail call tests.
dhil Apr 17, 2023
09007ed
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 18, 2023
0d5f9e3
Remove garbage
dhil Apr 18, 2023
005676b
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 18, 2023
1d39f20
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 19, 2023
f3a19c0
Revert changes to wasmtime public API.
dhil Apr 19, 2023
1e85b66
Run cargo fmt
dhil Apr 19, 2023
196ed98
Get more CI passing (#19)
alexcrichton Apr 20, 2023
7654287
Merge with upstream
dhil Apr 20, 2023
acbbefd
Implement link-time matches relation. Disable tests failing due to la…
dhil Apr 20, 2023
a7c3c62
Run cargo fmt
dhil Apr 20, 2023
2ae2785
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 25, 2023
54fa25f
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil Apr 27, 2023
2e11f0b
Merge with upstream
dhil May 3, 2023
3816390
Run cargo fmt
dhil May 3, 2023
830c7b3
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil May 4, 2023
5de9a24
Initial implementation of eager table initialization
dhil May 5, 2023
6dc3eb7
Merge with upstream
dhil May 16, 2023
ef53563
Merge with upstream
dhil May 17, 2023
0f0d3b2
Tidy up eager table initialisation
dhil May 17, 2023
9943f90
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil May 19, 2023
ef80220
Cargo fmt
dhil May 19, 2023
4e8e510
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil May 22, 2023
fb94ffb
Merge branch 'main' of github.com:bytecodealliance/wasmtime into func…
dhil May 23, 2023
c04a013
Ignore type-equivalence test
dhil May 23, 2023
6f66bb5
Replace TODOs with descriptive comments.
dhil May 23, 2023
26e6d9f
Various changes found during review (#21)
alexcrichton May 24, 2023
0adcec6
Merge remote-tracking branch 'origin/main' into function-references
alexcrichton May 25, 2023
36e9f7e
Merge pull request #22 from alexcrichton/function-references
dhil May 25, 2023
e467bba
Merge with upstream
dhil May 26, 2023
aa4ffdc
Cargo fmt
dhil May 26, 2023
96a9b55
Fix arity mismatch in aarch64/abi
dhil May 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ fn main() -> anyhow::Result<()> {
test_directory_module(out, "tests/misc_testsuite/threads", strategy)?;
test_directory_module(out, "tests/misc_testsuite/memory64", strategy)?;
test_directory_module(out, "tests/misc_testsuite/component-model", strategy)?;
test_directory_module(out, "tests/misc_testsuite/function-references", strategy)?;
Ok(())
})?;

Expand All @@ -39,6 +40,11 @@ fn main() -> anyhow::Result<()> {
// out.
if spec_tests > 0 {
test_directory_module(out, "tests/spec_testsuite/proposals/memory64", strategy)?;
test_directory_module(
out,
"tests/spec_testsuite/proposals/function-references",
strategy,
)?;
test_directory_module(
out,
"tests/spec_testsuite/proposals/multi-memory",
Expand Down Expand Up @@ -187,6 +193,30 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
return true;
}

// Tail calls are not yet implemented.
if testname.contains("return_call") {
return true;
}

if testsuite == "function_references" {
// The following tests fail due to function references not yet
// being exposed in the public API.
if testname == "ref_null" || testname == "local_init" {
return true;
}
// This test fails due to incomplete support for the various
// table/elem syntactic sugar in wasm-tools/wast.
if testname == "br_table" {
return true;
}
// This test fails due to the current implementation of type
// canonicalisation being broken as a result of
// #[derive(hash)] on WasmHeapType.
if testname == "type_equivalence" {
return true;
}
}

match env::var("CARGO_CFG_TARGET_ARCH").unwrap().as_str() {
"s390x" => {
// FIXME: These tests fail under qemu due to a qemu bug.
Expand Down
6 changes: 6 additions & 0 deletions cranelift/codegen/src/ir/trapcode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ pub enum TrapCode {

/// A user-defined trap code.
User(u16),

/// A null reference was encountered which was required to be non-null.
NullReference,
}

impl TrapCode {
Expand All @@ -68,6 +71,7 @@ impl TrapCode {
TrapCode::BadConversionToInteger,
TrapCode::UnreachableCodeReached,
TrapCode::Interrupt,
TrapCode::NullReference,
]
}
}
Expand All @@ -88,6 +92,7 @@ impl Display for TrapCode {
UnreachableCodeReached => "unreachable",
Interrupt => "interrupt",
User(x) => return write!(f, "user{}", x),
NullReference => "null_reference",
};
f.write_str(identifier)
}
Expand All @@ -110,6 +115,7 @@ impl FromStr for TrapCode {
"bad_toint" => Ok(BadConversionToInteger),
"unreachable" => Ok(UnreachableCodeReached),
"interrupt" => Ok(Interrupt),
"null_reference" => Ok(NullReference),
_ if s.starts_with("user") => s[4..].parse().map(User).map_err(|_| ()),
_ => Err(()),
}
Expand Down
5 changes: 4 additions & 1 deletion cranelift/codegen/src/verifier/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1175,7 +1175,10 @@ impl<'a> Verifier<'a> {
errors.report((
inst,
self.context(inst),
format!("has an invalid controlling type {}", ctrl_type),
format!(
"has an invalid controlling type {} (allowed set is {:?})",
ctrl_type, value_typeset
),
));
}

Expand Down
23 changes: 23 additions & 0 deletions cranelift/filetests/src/test_wasm/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use cranelift_codegen::{
};
use cranelift_wasm::{
DummyEnvironment, FuncEnvironment, FuncIndex, ModuleEnvironment, TargetEnvironment,
TypeConvert, TypeIndex, WasmHeapType,
};

pub struct ModuleEnv {
Expand Down Expand Up @@ -235,6 +236,12 @@ impl<'data> ModuleEnvironment<'data> for ModuleEnv {
}
}

impl TypeConvert for ModuleEnv {
fn lookup_heap_type(&self, _index: TypeIndex) -> WasmHeapType {
todo!()
}
}

pub struct FuncEnv<'a> {
pub inner: cranelift_wasm::DummyFuncEnvironment<'a>,
pub config: TestConfig,
Expand All @@ -261,6 +268,12 @@ impl<'a> FuncEnv<'a> {
}
}

impl TypeConvert for FuncEnv<'_> {
fn lookup_heap_type(&self, _index: TypeIndex) -> WasmHeapType {
todo!()
}
}

impl<'a> TargetEnvironment for FuncEnv<'a> {
fn target_config(&self) -> TargetFrontendConfig {
self.inner.target_config()
Expand Down Expand Up @@ -622,4 +635,14 @@ impl<'a> FuncEnvironment for FuncEnv<'a> {
fn is_x86(&self) -> bool {
self.config.target.contains("x86_64")
}

fn translate_call_ref(
&mut self,
_builder: &mut cranelift_frontend::FunctionBuilder<'_>,
_ty: ir::SigRef,
_func: ir::Value,
_args: &[ir::Value],
) -> cranelift_wasm::WasmResult<ir::Inst> {
unimplemented!()
}
}
74 changes: 66 additions & 8 deletions cranelift/wasm/src/code_translator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,6 @@ use crate::translation_utils::{
};
use crate::wasm_unsupported;
use crate::{FuncIndex, GlobalIndex, MemoryIndex, TableIndex, TypeIndex, WasmResult};
use core::convert::TryInto;
use core::{i32, u32};
use cranelift_codegen::ir::condcodes::{FloatCC, IntCC};
use cranelift_codegen::ir::immediates::Offset32;
Expand Down Expand Up @@ -1152,7 +1151,8 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
translate_fcmp(FloatCC::LessThanOrEqual, builder, state)
}
Operator::RefNull { hty } => {
state.push1(environ.translate_ref_null(builder.cursor(), (*hty).try_into()?)?)
let hty = environ.convert_heap_type(*hty);
state.push1(environ.translate_ref_null(builder.cursor(), hty)?)
}
Operator::RefIsNull => {
let value = state.pop1();
Expand Down Expand Up @@ -2337,16 +2337,74 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
state.push1(builder.ins().iadd(dot32, c));
}

Operator::CallRef { .. }
| Operator::ReturnCallRef { .. }
| Operator::BrOnNull { .. }
| Operator::BrOnNonNull { .. }
| Operator::RefAsNonNull => {
Operator::ReturnCallRef { type_index: _ } => {
return Err(wasm_unsupported!(
"proposed function-references operator {:?}",
"proposed tail-call operator for function references {:?}",
op
));
}
Operator::BrOnNull { relative_depth } => {
let r = state.pop1();
let (br_destination, inputs) = translate_br_if_args(*relative_depth, state);
let is_null = environ.translate_ref_is_null(builder.cursor(), r)?;
let else_block = builder.create_block();
canonicalise_brif(builder, is_null, br_destination, inputs, else_block, &[]);

builder.seal_block(else_block); // The only predecessor is the current block.
builder.switch_to_block(else_block);
state.push1(r);
}
Operator::BrOnNonNull { relative_depth } => {
// We write this a bit differently from the spec to avoid an extra
// block/branch and the typed accounting thereof. Instead of the
// spec's approach, it's described as such:
// Peek the value val from the stack.
// If val is ref.null ht, then: pop the value val from the stack.
// Else: Execute the instruction (br relative_depth).
let is_null = environ.translate_ref_is_null(builder.cursor(), state.peek1())?;
let (br_destination, inputs) = translate_br_if_args(*relative_depth, state);
let else_block = builder.create_block();
canonicalise_brif(builder, is_null, else_block, &[], br_destination, inputs);

// In the null case, pop the ref
state.pop1();

builder.seal_block(else_block); // The only predecessor is the current block.

// The rest of the translation operates on our is null case, which is
// currently an empty block
builder.switch_to_block(else_block);
}
Operator::CallRef { type_index } => {
// Get function signature
// `index` is the index of the function's signature and `table_index` is the index of
// the table to search the function in.
let (sigref, num_args) = state.get_indirect_sig(builder.func, *type_index, environ)?;
let callee = state.pop1();

// Bitcast any vector arguments to their default type, I8X16, before calling.
let args = state.peekn_mut(num_args);
bitcast_wasm_params(environ, sigref, args, builder);

let call =
environ.translate_call_ref(builder, sigref, callee, state.peekn(num_args))?;

let inst_results = builder.inst_results(call);
debug_assert_eq!(
inst_results.len(),
builder.func.dfg.signatures[sigref].returns.len(),
"translate_call_ref results should match the call signature"
);
state.popn(num_args);
state.pushn(inst_results);
}
Operator::RefAsNonNull => {
let r = state.pop1();
let is_null = environ.translate_ref_is_null(builder.cursor(), r)?;
builder.ins().trapnz(is_null, ir::TrapCode::NullReference);
state.push1(r);
}

Operator::I31New | Operator::I31GetS | Operator::I31GetU => {
unimplemented!("GC operators not yet implemented")
}
Expand Down
30 changes: 26 additions & 4 deletions cranelift/wasm/src/environ/dummy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ use crate::state::FuncTranslationState;
use crate::WasmType;
use crate::{
DataIndex, DefinedFuncIndex, ElemIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Heap,
HeapData, HeapStyle, Memory, MemoryIndex, Table, TableIndex, TypeIndex, WasmFuncType,
WasmResult,
HeapData, HeapStyle, Memory, MemoryIndex, Table, TableIndex, TypeConvert, TypeIndex,
WasmFuncType, WasmHeapType, WasmResult,
};
use core::convert::TryFrom;
use cranelift_codegen::cursor::FuncCursor;
Expand Down Expand Up @@ -251,6 +251,12 @@ impl<'dummy_environment> DummyFuncEnvironment<'dummy_environment> {
}
}

impl<'dummy_environment> TypeConvert for DummyFuncEnvironment<'dummy_environment> {
fn lookup_heap_type(&self, _index: TypeIndex) -> WasmHeapType {
unimplemented!()
}
}

impl<'dummy_environment> TargetEnvironment for DummyFuncEnvironment<'dummy_environment> {
fn target_config(&self) -> TargetFrontendConfig {
self.mod_info.config
Expand Down Expand Up @@ -279,7 +285,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
WasmType::F32 => ir::types::F32,
WasmType::F64 => ir::types::F64,
WasmType::V128 => ir::types::I8X16,
WasmType::FuncRef | WasmType::ExternRef => ir::types::R64,
WasmType::Ref(_) => ir::types::R64,
},
})
}
Expand Down Expand Up @@ -464,6 +470,16 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
Ok(pos.ins().Call(ir::Opcode::Call, INVALID, callee, args).0)
}

fn translate_call_ref(
&mut self,
_builder: &mut FunctionBuilder,
_sig_ref: ir::SigRef,
_callee: ir::Value,
_call_args: &[ir::Value],
) -> WasmResult<ir::Inst> {
todo!("Implement dummy translate_call_ref")
}

fn translate_memory_grow(
&mut self,
mut pos: FuncCursor,
Expand Down Expand Up @@ -658,6 +674,12 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
}
}

impl TypeConvert for DummyEnvironment {
fn lookup_heap_type(&self, _index: TypeIndex) -> WasmHeapType {
unimplemented!()
}
}

impl TargetEnvironment for DummyEnvironment {
fn target_config(&self) -> TargetFrontendConfig {
self.info.config
Expand All @@ -683,7 +705,7 @@ impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
WasmType::F32 => ir::types::F32,
WasmType::F64 => ir::types::F64,
WasmType::V128 => ir::types::I8X16,
WasmType::FuncRef | WasmType::ExternRef => reference_type,
WasmType::Ref(_) => reference_type,
})
};
sig.params.extend(wasm.params().iter().map(&mut cvt));
Expand Down
32 changes: 26 additions & 6 deletions cranelift/wasm/src/environ/spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
use crate::state::FuncTranslationState;
use crate::{
DataIndex, ElemIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Heap, HeapData, Memory,
MemoryIndex, SignatureIndex, Table, TableIndex, Tag, TagIndex, TypeIndex, WasmError,
WasmFuncType, WasmResult, WasmType,
MemoryIndex, SignatureIndex, Table, TableIndex, Tag, TagIndex, TypeConvert, TypeIndex,
WasmError, WasmFuncType, WasmHeapType, WasmResult,
};
use core::convert::From;
use cranelift_codegen::cursor::FuncCursor;
Expand Down Expand Up @@ -44,7 +44,7 @@ pub enum GlobalVariable {
}

/// Environment affecting the translation of a WebAssembly.
pub trait TargetEnvironment {
pub trait TargetEnvironment: TypeConvert {
/// Get the information needed to produce Cranelift IR for the given target.
fn target_config(&self) -> TargetFrontendConfig;

Expand All @@ -70,7 +70,7 @@ pub trait TargetEnvironment {
/// 32-bit architectures. If you override this, then you should also
/// override `FuncEnvironment::{translate_ref_null, translate_ref_is_null}`
/// as well.
fn reference_type(&self, ty: WasmType) -> ir::Type {
fn reference_type(&self, ty: WasmHeapType) -> ir::Type {
let _ = ty;
match self.pointer_type() {
ir::types::I32 => ir::types::R32,
Expand Down Expand Up @@ -208,6 +208,22 @@ pub trait FuncEnvironment: TargetEnvironment {
Ok(pos.ins().call(callee, call_args))
}

/// Translate a `call_ref` WebAssembly instruction at `pos`.
///
/// Insert instructions at `pos` for an indirect call to the
/// function `callee`. The `callee` value will have type `Ref`.
///
/// The signature `sig_ref` was previously created by `make_indirect_sig()`.
///
/// Return the call instruction whose results are the WebAssembly return values.
fn translate_call_ref(
&mut self,
builder: &mut FunctionBuilder,
sig_ref: ir::SigRef,
callee: ir::Value,
call_args: &[ir::Value],
) -> WasmResult<ir::Inst>;

/// Translate a `memory.grow` WebAssembly instruction.
///
/// The `index` provided identifies the linear memory to grow, and `heap` is the heap reference
Expand Down Expand Up @@ -373,7 +389,11 @@ pub trait FuncEnvironment: TargetEnvironment {
/// null sentinel is not a null reference type pointer for your type. If you
/// override this method, then you should also override
/// `translate_ref_is_null` as well.
fn translate_ref_null(&mut self, mut pos: FuncCursor, ty: WasmType) -> WasmResult<ir::Value> {
fn translate_ref_null(
&mut self,
mut pos: FuncCursor,
ty: WasmHeapType,
) -> WasmResult<ir::Value> {
let _ = ty;
Ok(pos.ins().null(self.reference_type(ty)))
}
Expand Down Expand Up @@ -547,7 +567,7 @@ pub trait FuncEnvironment: TargetEnvironment {
/// An object satisfying the `ModuleEnvironment` trait can be passed as argument to the
/// [`translate_module`](fn.translate_module.html) function. These methods should not be called
/// by the user, they are only for `cranelift-wasm` internal use.
pub trait ModuleEnvironment<'data> {
pub trait ModuleEnvironment<'data>: TypeConvert {
/// Provides the number of types up front. By default this does nothing, but
/// implementations can use this to preallocate memory if desired.
fn reserve_types(&mut self, _num: u32) -> WasmResult<()> {
Expand Down
Loading