Bug 1562185: Reorganize code in Cranelift bindings; r=lth
authorBenjamin Bouvier <benj@benj.me>
Thu, 27 Jun 2019 19:18:42 +0200
changeset 543615 f3b972e5914eca062d19dbaaed110e5472b7b612
parent 543614 b684d4532b91357024ec0ac6810565d442bc54f3
child 543616 9d520df46c0b4c716e0b3c27a13acced3765c65a
push id2131
push userffxbld-merge
push dateMon, 26 Aug 2019 18:30:20 +0000
treeherdermozilla-release@b19ffb3ca153 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslth
bugs1562185
milestone69.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1562185: Reorganize code in Cranelift bindings; r=lth This introduces a bindings module in the cranelift bindings directory, to make the roles of different files clearer: - bindings/low_level.rs (formerly known as baldrapi.rs) contains all the bindings automatically generated by bindgen. - bindings/mod.rs (formerly known as baldrdash.rs) contains all the high-level bindings, to be used by the rest of baldrdash. Some code has been moved to match the roles more consistently; in particular, nothing in bindings/low_level should be directly used from outer the bindings directory. Rustfmt has been run too, which explains a few unrelated changes. Differential Revision: https://phabricator.services.mozilla.com/D36319
js/src/wasm/cranelift/baldrapi.h
js/src/wasm/cranelift/build.rs
js/src/wasm/cranelift/src/baldrapi.rs
js/src/wasm/cranelift/src/baldrdash.rs
js/src/wasm/cranelift/src/bindings/low_level.rs
js/src/wasm/cranelift/src/bindings/mod.rs
js/src/wasm/cranelift/src/compile.rs
js/src/wasm/cranelift/src/cpu.rs
js/src/wasm/cranelift/src/lib.rs
js/src/wasm/cranelift/src/wasm2clif.rs
--- a/js/src/wasm/cranelift/baldrapi.h
+++ b/js/src/wasm/cranelift/baldrapi.h
@@ -16,17 +16,17 @@
  * limitations under the License.
  */
 
 // This is an ADT-style C API to the WebAssembly per-function compilation state,
 // allowing Rust to access constant metadata and produce output.
 //
 // This file is input to Rust's bindgen, so as to create primitive APIs for the
 // Cranelift pipeline to access compilation metadata. The actual Rust API then
-// wraps these primitive APIs.  See src/baldrdash.rs.
+// wraps these primitive APIs.  See src/bindings/mod.rs.
 //
 // This file can be included in SpiderMonkey's C++ code, where all the prefixes
 // must be obeyed.  The purpose of the prefixes is to avoid type confusion.  See
 // js/src/wasm/WasmCraneliftCompile.cpp.
 
 #ifndef wasm_cranelift_baldrapi_h
 #define wasm_cranelift_baldrapi_h
 
--- a/js/src/wasm/cranelift/build.rs
+++ b/js/src/wasm/cranelift/build.rs
@@ -12,17 +12,17 @@
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 //! Build script for the Baldr <-> Cranelift bindings.
 //!
 //! This file is executed by cargo when this crate is built. It generates the
-//! `$OUT_DIR/bindings.rs` file which is then included by `src/baldrapi.rs`.
+//! `$OUT_DIR/bindings.rs` file which is then included by `src/bindings/low_level.rs`.
 
 extern crate bindgen;
 
 use std::env;
 use std::fs::File;
 use std::io::prelude::*;
 use std::path::PathBuf;
 
rename from js/src/wasm/cranelift/src/baldrapi.rs
rename to js/src/wasm/cranelift/src/bindings/low_level.rs
--- a/js/src/wasm/cranelift/src/baldrapi.rs
+++ b/js/src/wasm/cranelift/src/bindings/low_level.rs
@@ -15,93 +15,14 @@
 
 //! This module exports the bindings generated by bindgen form the baldrapi.h file.
 //!
 //! The Baldr API consists of a set of C functions and some associated types.
 
 #![allow(non_upper_case_globals)]
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
+
 // We need to allow dead code because the Rustc compiler complains about variants never being
 // constructed in TypeCode, which is true because these values come from C++.
 #![allow(dead_code)]
 
-use cranelift_codegen::binemit::CodeOffset;
-use cranelift_codegen::entity::EntityRef;
-use cranelift_codegen::ir::SourceLoc;
-use cranelift_wasm::FuncIndex;
-
-use compile::CompiledFunc;
-
 include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
-
-impl CraneliftFuncCompileInput {
-    pub fn bytecode(&self) -> &[u8] {
-        use std::slice;
-        unsafe { slice::from_raw_parts(self.bytecode, self.bytecodeSize) }
-    }
-}
-
-impl CraneliftCompiledFunc {
-    pub fn reset(&mut self, compiled_func: &CompiledFunc) {
-        self.numMetadata = compiled_func.metadata.len();
-        self.metadatas = compiled_func.metadata.as_ptr();
-
-        self.framePushed = compiled_func.frame_pushed as usize;
-        self.containsCalls = compiled_func.contains_calls;
-
-        self.code = compiled_func.code_buffer.as_ptr();
-        self.codeSize = compiled_func.code_size as usize;
-        self.jumptablesSize = compiled_func.jumptables_size as usize;
-        self.rodataSize = compiled_func.rodata_size as usize;
-        self.totalSize = compiled_func.code_buffer.len();
-
-        self.numRodataRelocs = compiled_func.rodata_relocs.len();
-        self.rodataRelocs = compiled_func.rodata_relocs.as_ptr();
-    }
-}
-
-impl CraneliftMetadataEntry {
-    pub fn direct_call(code_offset: CodeOffset, func_index: FuncIndex, srcloc: SourceLoc) -> Self {
-        Self {
-            which: CraneliftMetadataEntry_Which_DirectCall,
-            codeOffset: code_offset,
-            moduleBytecodeOffset: srcloc.bits(),
-            extra: func_index.index(),
-        }
-    }
-
-    pub fn indirect_call(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
-        Self {
-            which: CraneliftMetadataEntry_Which_IndirectCall,
-            codeOffset: code_offset,
-            moduleBytecodeOffset: srcloc.bits(),
-            extra: 0,
-        }
-    }
-
-    pub fn trap(code_offset: CodeOffset, srcloc: SourceLoc, which: Trap) -> Self {
-        Self {
-            which: CraneliftMetadataEntry_Which_Trap,
-            codeOffset: code_offset,
-            moduleBytecodeOffset: srcloc.bits(),
-            extra: which as usize,
-        }
-    }
-
-    pub fn memory_access(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
-        Self {
-            which: CraneliftMetadataEntry_Which_MemoryAccess,
-            codeOffset: code_offset,
-            moduleBytecodeOffset: srcloc.bits(),
-            extra: 0,
-        }
-    }
-
-    pub fn symbolic_access(code_offset: CodeOffset, sym: BD_SymbolicAddress) -> Self {
-        Self {
-            which: CraneliftMetadataEntry_Which_SymbolicAccess,
-            codeOffset: code_offset,
-            moduleBytecodeOffset: 0,
-            extra: sym as usize,
-        }
-    }
-}
rename from js/src/wasm/cranelift/src/baldrdash.rs
rename to js/src/wasm/cranelift/src/bindings/mod.rs
--- a/js/src/wasm/cranelift/src/baldrdash.rs
+++ b/js/src/wasm/cranelift/src/bindings/mod.rs
@@ -8,42 +8,43 @@
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
-// Safe wrappers to the low-level ABI.  This re-exports all types in
-// baldrapi but none of the functions.
+// Safe wrappers to the low-level ABI.  This re-exports all types in low_level but none of the
+// functions.
 
+use std::{mem, slice};
+
+use cranelift_codegen::binemit::CodeOffset;
 use cranelift_codegen::cursor::FuncCursor;
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir::immediates::{Ieee32, Ieee64};
-use cranelift_codegen::ir::{self, InstBuilder};
+use cranelift_codegen::ir::{self, InstBuilder, SourceLoc};
 use cranelift_wasm::{FuncIndex, GlobalIndex, SignatureIndex, TableIndex, WasmResult};
 
-use std::mem;
-use std::slice;
-
-use baldrapi;
-use baldrapi::BD_ValType as ValType;
-use baldrapi::CraneliftModuleEnvironment;
-use baldrapi::TypeCode;
-
+use compile;
 use utils::BasicError;
 
-pub use baldrapi::BD_SymbolicAddress as SymbolicAddress;
-pub use baldrapi::CraneliftCompiledFunc as CompiledFunc;
-pub use baldrapi::CraneliftFuncCompileInput as FuncCompileInput;
-pub use baldrapi::CraneliftMetadataEntry as MetadataEntry;
-pub use baldrapi::CraneliftStaticEnvironment as StaticEnvironment;
-pub use baldrapi::FuncTypeIdDescKind;
-pub use baldrapi::Trap;
+use self::low_level::*;
+
+pub use self::low_level::BD_SymbolicAddress as SymbolicAddress;
+pub use self::low_level::CraneliftCompiledFunc as CompiledFunc;
+pub use self::low_level::CraneliftFuncCompileInput as FuncCompileInput;
+pub use self::low_level::CraneliftMetadataEntry as MetadataEntry;
+pub use self::low_level::CraneliftModuleEnvironment as LowLevelModuleEnvironment;
+pub use self::low_level::CraneliftStaticEnvironment as StaticEnvironment;
+pub use self::low_level::FuncTypeIdDescKind;
+pub use self::low_level::Trap;
+
+mod low_level;
 
 /// Converts a `TypeCode` into the equivalent Cranelift type, if it's a known type, or an error
 /// otherwise.
 #[inline]
 fn typecode_to_type(type_code: TypeCode) -> WasmResult<Option<ir::Type>> {
     match type_code {
         TypeCode::I32 => Ok(Some(ir::types::I32)),
         TypeCode::I64 => Ok(Some(ir::types::I64)),
@@ -57,140 +58,214 @@ fn typecode_to_type(type_code: TypeCode)
 /// Convert a non-void `TypeCode` into the equivalent Cranelift type.
 #[inline]
 fn typecode_to_nonvoid_type(type_code: TypeCode) -> WasmResult<ir::Type> {
     Ok(typecode_to_type(type_code)?.expect("unexpected void type"))
 }
 
 /// Convert a `TypeCode` into the equivalent Cranelift type.
 #[inline]
-fn valtype_to_type(val_type: ValType) -> WasmResult<ir::Type> {
-    let type_code = unsafe { baldrapi::env_unpack(val_type) };
+fn valtype_to_type(val_type: BD_ValType) -> WasmResult<ir::Type> {
+    let type_code = unsafe { low_level::env_unpack(val_type) };
     typecode_to_nonvoid_type(type_code)
 }
 
 /// Convert a u32 into a `BD_SymbolicAddress`.
 impl From<u32> for SymbolicAddress {
     fn from(x: u32) -> SymbolicAddress {
         assert!(x < SymbolicAddress::Limit as u32);
         unsafe { mem::transmute(x) }
     }
 }
 
 #[derive(Clone, Copy)]
-pub struct GlobalDesc(*const baldrapi::GlobalDesc);
+pub struct GlobalDesc(*const low_level::GlobalDesc);
 
 impl GlobalDesc {
     pub fn value_type(self) -> WasmResult<ir::Type> {
-        let type_code = unsafe { baldrapi::global_type(self.0) };
+        let type_code = unsafe { low_level::global_type(self.0) };
         typecode_to_nonvoid_type(type_code)
     }
 
     pub fn is_constant(self) -> bool {
-        unsafe { baldrapi::global_isConstant(self.0) }
+        unsafe { low_level::global_isConstant(self.0) }
     }
 
     pub fn is_indirect(self) -> bool {
-        unsafe { baldrapi::global_isIndirect(self.0) }
+        unsafe { low_level::global_isIndirect(self.0) }
     }
 
     /// Insert an instruction at `pos` that materialized the constant value.
     pub fn emit_constant(self, pos: &mut FuncCursor) -> WasmResult<ir::Value> {
         unsafe {
-            let v = baldrapi::global_constantValue(self.0);
+            let v = low_level::global_constantValue(self.0);
             match v.t {
                 TypeCode::I32 => Ok(pos.ins().iconst(ir::types::I32, i64::from(v.u.i32))),
                 TypeCode::I64 => Ok(pos.ins().iconst(ir::types::I64, v.u.i64)),
                 TypeCode::F32 => Ok(pos.ins().f32const(Ieee32::with_bits(v.u.i32 as u32))),
                 TypeCode::F64 => Ok(pos.ins().f64const(Ieee64::with_bits(v.u.i64 as u64))),
                 _ => Err(BasicError::new(format!("unexpected type: {}", v.t as u64)).into()),
             }
         }
     }
 
     /// Get the offset from the `WasmTlsReg` to the memory representing this global variable.
     pub fn tls_offset(self) -> usize {
-        unsafe { baldrapi::global_tlsOffset(self.0) }
+        unsafe { low_level::global_tlsOffset(self.0) }
     }
 }
 
 #[derive(Clone, Copy)]
-pub struct TableDesc(*const baldrapi::TableDesc);
+pub struct TableDesc(*const low_level::TableDesc);
 
 impl TableDesc {
     /// Get the offset from the `WasmTlsReg` to the `wasm::TableTls` representing this table.
     pub fn tls_offset(self) -> usize {
-        unsafe { baldrapi::table_tlsOffset(self.0) }
+        unsafe { low_level::table_tlsOffset(self.0) }
     }
 }
 
 #[derive(Clone, Copy)]
-pub struct FuncTypeWithId(*const baldrapi::FuncTypeWithId);
+pub struct FuncTypeWithId(*const low_level::FuncTypeWithId);
 
 impl FuncTypeWithId {
     pub fn args<'a>(self) -> WasmResult<Vec<ir::Type>> {
-        let num_args = unsafe { baldrapi::funcType_numArgs(self.0) };
+        let num_args = unsafe { low_level::funcType_numArgs(self.0) };
         // The `funcType_args` callback crashes when there are no arguments. Also note that
         // `slice::from_raw_parts()` requires a non-null pointer for empty slices.
         // TODO: We should get all the parts of a signature in a single callback that returns a
         // struct.
         if num_args == 0 {
             Ok(Vec::new())
         } else {
-            let args = unsafe { slice::from_raw_parts(baldrapi::funcType_args(self.0), num_args) };
+            let args = unsafe { slice::from_raw_parts(low_level::funcType_args(self.0), num_args) };
             let mut ret = Vec::new();
             for &arg in args {
                 ret.push(valtype_to_type(arg)?);
             }
             Ok(ret)
         }
     }
 
     pub fn ret_type(self) -> WasmResult<Option<ir::Type>> {
-        let type_code = unsafe { baldrapi::funcType_retType(self.0) };
+        let type_code = unsafe { low_level::funcType_retType(self.0) };
         typecode_to_type(type_code)
     }
 
     pub fn id_kind(self) -> FuncTypeIdDescKind {
-        unsafe { baldrapi::funcType_idKind(self.0) }
+        unsafe { low_level::funcType_idKind(self.0) }
     }
 
     pub fn id_immediate(self) -> usize {
-        unsafe { baldrapi::funcType_idImmediate(self.0) }
+        unsafe { low_level::funcType_idImmediate(self.0) }
     }
 
     pub fn id_tls_offset(self) -> usize {
-        unsafe { baldrapi::funcType_idTlsOffset(self.0) }
+        unsafe { low_level::funcType_idTlsOffset(self.0) }
     }
 }
 
 /// Thin wrapper for the CraneliftModuleEnvironment structure.
 
 pub struct ModuleEnvironment<'a> {
     env: &'a CraneliftModuleEnvironment,
 }
 
 impl<'a> ModuleEnvironment<'a> {
     pub fn new(env: &'a CraneliftModuleEnvironment) -> Self {
         Self { env }
     }
     pub fn function_signature(&self, func_index: FuncIndex) -> FuncTypeWithId {
-        FuncTypeWithId(unsafe { baldrapi::env_function_signature(self.env, func_index.index()) })
+        FuncTypeWithId(unsafe { low_level::env_function_signature(self.env, func_index.index()) })
     }
     pub fn func_import_tls_offset(&self, func_index: FuncIndex) -> usize {
-        unsafe { baldrapi::env_func_import_tls_offset(self.env, func_index.index()) }
+        unsafe { low_level::env_func_import_tls_offset(self.env, func_index.index()) }
     }
     pub fn func_is_import(&self, func_index: FuncIndex) -> bool {
-        unsafe { baldrapi::env_func_is_import(self.env, func_index.index()) }
+        unsafe { low_level::env_func_is_import(self.env, func_index.index()) }
     }
     pub fn signature(&self, sig_index: SignatureIndex) -> FuncTypeWithId {
-        FuncTypeWithId(unsafe { baldrapi::env_signature(self.env, sig_index.index()) })
+        FuncTypeWithId(unsafe { low_level::env_signature(self.env, sig_index.index()) })
     }
     pub fn table(&self, table_index: TableIndex) -> TableDesc {
-        TableDesc(unsafe { baldrapi::env_table(self.env, table_index.index()) })
+        TableDesc(unsafe { low_level::env_table(self.env, table_index.index()) })
     }
     pub fn global(&self, global_index: GlobalIndex) -> GlobalDesc {
-        GlobalDesc(unsafe { baldrapi::env_global(self.env, global_index.index()) })
+        GlobalDesc(unsafe { low_level::env_global(self.env, global_index.index()) })
     }
     pub fn min_memory_length(&self) -> i64 {
         i64::from(self.env.min_memory_length)
     }
 }
+
+/// Extra methods for some C++ wrappers.
+
+impl FuncCompileInput {
+    pub fn bytecode(&self) -> &[u8] {
+        unsafe { slice::from_raw_parts(self.bytecode, self.bytecodeSize) }
+    }
+}
+
+impl CompiledFunc {
+    pub fn reset(&mut self, compiled_func: &compile::CompiledFunc) {
+        self.numMetadata = compiled_func.metadata.len();
+        self.metadatas = compiled_func.metadata.as_ptr();
+
+        self.framePushed = compiled_func.frame_pushed as usize;
+        self.containsCalls = compiled_func.contains_calls;
+
+        self.code = compiled_func.code_buffer.as_ptr();
+        self.codeSize = compiled_func.code_size as usize;
+        self.jumptablesSize = compiled_func.jumptables_size as usize;
+        self.rodataSize = compiled_func.rodata_size as usize;
+        self.totalSize = compiled_func.code_buffer.len();
+
+        self.numRodataRelocs = compiled_func.rodata_relocs.len();
+        self.rodataRelocs = compiled_func.rodata_relocs.as_ptr();
+    }
+}
+
+impl MetadataEntry {
+    pub fn direct_call(code_offset: CodeOffset, func_index: FuncIndex, srcloc: SourceLoc) -> Self {
+        Self {
+            which: CraneliftMetadataEntry_Which_DirectCall,
+            codeOffset: code_offset,
+            moduleBytecodeOffset: srcloc.bits(),
+            extra: func_index.index(),
+        }
+    }
+
+    pub fn indirect_call(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
+        Self {
+            which: CraneliftMetadataEntry_Which_IndirectCall,
+            codeOffset: code_offset,
+            moduleBytecodeOffset: srcloc.bits(),
+            extra: 0,
+        }
+    }
+
+    pub fn trap(code_offset: CodeOffset, srcloc: SourceLoc, which: Trap) -> Self {
+        Self {
+            which: CraneliftMetadataEntry_Which_Trap,
+            codeOffset: code_offset,
+            moduleBytecodeOffset: srcloc.bits(),
+            extra: which as usize,
+        }
+    }
+
+    pub fn memory_access(code_offset: CodeOffset, srcloc: SourceLoc) -> Self {
+        Self {
+            which: CraneliftMetadataEntry_Which_MemoryAccess,
+            codeOffset: code_offset,
+            moduleBytecodeOffset: srcloc.bits(),
+            extra: 0,
+        }
+    }
+
+    pub fn symbolic_access(code_offset: CodeOffset, sym: SymbolicAddress) -> Self {
+        Self {
+            which: CraneliftMetadataEntry_Which_SymbolicAccess,
+            codeOffset: code_offset,
+            moduleBytecodeOffset: 0,
+            extra: sym as usize,
+        }
+    }
+}
--- a/js/src/wasm/cranelift/src/compile.rs
+++ b/js/src/wasm/cranelift/src/compile.rs
@@ -13,42 +13,44 @@
  * limitations under the License.
  */
 
 //! Cranelift WebAssembly function compiler.
 //!
 //! This module defines the `compile()` function which uses Cranelift to compile a single
 //! WebAssembly function.
 
-use baldrdash as bd;
-use cpu::make_isa;
+use std::fmt;
+use std::mem;
+
 use cranelift_codegen::binemit::{Addend, CodeInfo, CodeOffset, NullTrapSink, Reloc, RelocSink};
 use cranelift_codegen::entity::EntityRef;
 use cranelift_codegen::ir;
 use cranelift_codegen::ir::stackslot::StackSize;
 use cranelift_codegen::isa::TargetIsa;
 use cranelift_codegen::CodegenResult;
 use cranelift_codegen::Context;
 use cranelift_wasm::{FuncIndex, FuncTranslator, WasmResult};
-use std::fmt;
-use std::mem;
+
+use bindings;
+use cpu::make_isa;
 use utils::DashResult;
 use wasm2clif::{init_sig, native_pointer_size, TransEnv};
 
 // Namespace for user-defined functions.
 const USER_FUNCTION_NAMESPACE: u32 = 0;
 
 // Namespace for builtins functions that are translated to symbolic accesses in Spidermonkey.
 const SYMBOLIC_FUNCTION_NAMESPACE: u32 = 1;
 
 /// The result of a function's compilation: code + metadata.
 pub struct CompiledFunc {
     pub frame_pushed: StackSize,
     pub contains_calls: bool,
-    pub metadata: Vec<bd::MetadataEntry>,
+    pub metadata: Vec<bindings::MetadataEntry>,
     // rodata_relocs is Vec<CodeOffset>, but u32 is C++-friendlier
     pub rodata_relocs: Vec<u32>,
     // TODO(bbouvier) should just be a pointer into the masm buffer
     pub code_buffer: Vec<u8>,
     pub code_size: CodeOffset,
     pub jumptables_size: CodeOffset,
     pub rodata_size: CodeOffset,
 }
@@ -77,28 +79,28 @@ impl CompiledFunc {
         self.jumptables_size = 0;
         self.rodata_size = 0;
     }
 }
 
 /// A batch compiler holds on to data structures that can be recycled for multiple function
 /// compilations.
 pub struct BatchCompiler<'a, 'b> {
-    static_environ: &'a bd::StaticEnvironment,
-    environ: bd::ModuleEnvironment<'b>,
+    static_environ: &'a bindings::StaticEnvironment,
+    environ: bindings::ModuleEnvironment<'b>,
     isa: Box<dyn TargetIsa>,
     context: Context,
     trans: FuncTranslator,
     pub current_func: CompiledFunc,
 }
 
 impl<'a, 'b> BatchCompiler<'a, 'b> {
     pub fn new(
-        static_environ: &'a bd::StaticEnvironment,
-        environ: bd::ModuleEnvironment<'b>,
+        static_environ: &'a bindings::StaticEnvironment,
+        environ: bindings::ModuleEnvironment<'b>,
     ) -> DashResult<Self> {
         // TODO: The target ISA could be shared by multiple batch compilers across threads.
         Ok(BatchCompiler {
             static_environ,
             environ,
             isa: make_isa(static_environ)?,
             context: Context::new(),
             trans: FuncTranslator::new(),
@@ -110,18 +112,18 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
         let info = self.context.compile(&*self.isa)?;
         debug!("Optimized wasm function IR: {}", self);
         self.binemit(info)
     }
 
     /// Translate the WebAssembly code to Cranelift IR.
     pub fn translate_wasm(
         &mut self,
-        func: &bd::FuncCompileInput,
-    ) -> WasmResult<bd::FuncTypeWithId> {
+        func: &bindings::FuncCompileInput,
+    ) -> WasmResult<bindings::FuncTypeWithId> {
         self.context.clear();
 
         // Set up the signature before translating the WebAssembly byte code.
         // The translator refers to it.
         let index = FuncIndex::new(func.index as usize);
         let wsig = init_sig(&mut self.context.func.signature, &self.environ, index)?;
         self.context.func.name = wasm_function_name(index);
 
@@ -139,17 +141,20 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
     }
 
     /// Emit binary machine code to `emitter`.
     fn binemit(&mut self, info: CodeInfo) -> CodegenResult<()> {
         let total_size = info.total_size as usize;
         let frame_pushed = self.frame_pushed();
         let contains_calls = self.contains_calls();
 
-        info!("Emitting {} bytes, frame_pushed={}\n.", total_size, frame_pushed);
+        info!(
+            "Emitting {} bytes, frame_pushed={}\n.",
+            total_size, frame_pushed
+        );
 
         self.current_func.reset(frame_pushed, contains_calls);
 
         // Generate metadata about function calls and traps now that the emitter knows where the
         // Cranelift code is going to end up.
         let mut metadata = mem::replace(&mut self.current_func.metadata, vec![]);
         self.emit_metadata(&mut metadata);
         mem::swap(&mut metadata, &mut self.current_func.metadata);
@@ -157,23 +162,27 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
         // TODO: If we can get a pointer into `size` pre-allocated bytes of memory, we wouldn't
         // have to allocate and copy here.
         // TODO(bbouvier) try to get this pointer from the C++ caller, with an unlikely callback to
         // C++ if the remaining size is smaller than  needed.
         if self.current_func.code_buffer.len() < total_size {
             let current_size = self.current_func.code_buffer.len();
             // There's no way to do a proper uninitialized reserve, so first reserve and then
             // unsafely set the final size.
-            self.current_func.code_buffer.reserve(total_size - current_size);
+            self.current_func
+                .code_buffer
+                .reserve(total_size - current_size);
             unsafe { self.current_func.code_buffer.set_len(total_size) };
         }
 
         {
-            let emit_env = &mut EmitEnv::new(&mut self.current_func.metadata,
-                                             &mut self.current_func.rodata_relocs);
+            let emit_env = &mut EmitEnv::new(
+                &mut self.current_func.metadata,
+                &mut self.current_func.rodata_relocs,
+            );
             let mut trap_sink = NullTrapSink {};
             unsafe {
                 let code_buffer = &mut self.current_func.code_buffer;
                 self.context.emit_to_memory(
                     &*self.isa,
                     code_buffer.as_mut_ptr(),
                     emit_env,
                     &mut trap_sink,
@@ -224,17 +233,17 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
 
     /// Emit metadata by scanning the compiled function before `emit_to_memory`.
     ///
     /// - All call sites need metadata: direct, indirect, symbolic.
     /// - All explicit traps must be registered.
     ///
     /// We don't get enough callbacks through the `RelocSink` trait to generate all the metadata we
     /// need.
-    fn emit_metadata(&self, metadata: &mut Vec<bd::MetadataEntry>) {
+    fn emit_metadata(&self, metadata: &mut Vec<bindings::MetadataEntry>) {
         let encinfo = self.isa.encoding_info();
         let func = &self.context.func;
         for ebb in func.layout.ebbs() {
             for (offset, inst, inst_size) in func.inst_offsets(ebb, &encinfo) {
                 let opcode = func.dfg[inst].opcode();
                 match opcode {
                     ir::Opcode::Call => self.call_metadata(metadata, inst, offset + inst_size),
                     ir::Opcode::CallIndirect => {
@@ -306,17 +315,17 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
                 .display_inst(inst, Some(self.isa.as_ref()))
         );
         srcloc
     }
 
     /// Emit metadata for direct call `inst`.
     fn call_metadata(
         &self,
-        metadata: &mut Vec<bd::MetadataEntry>,
+        metadata: &mut Vec<bindings::MetadataEntry>,
         inst: ir::Inst,
         ret_addr: CodeOffset,
     ) {
         let func = &self.context.func;
 
         // This is a direct call, so the callee should be a non-imported wasm
         // function. We register both the call site *and* the target for relocation.
         let callee = match func.dfg[inst] {
@@ -327,47 +336,47 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
         let func_index = match *callee {
             ir::ExternalName::User {
                 namespace: USER_FUNCTION_NAMESPACE,
                 index,
             } => FuncIndex::new(index as usize),
             _ => panic!("Direct call to {} unsupported", callee),
         };
 
-        metadata.push(bd::MetadataEntry::direct_call(
+        metadata.push(bindings::MetadataEntry::direct_call(
             ret_addr,
             func_index,
             self.srcloc(inst),
         ));
     }
 
     /// Emit metadata for indirect call `inst`.
     fn indirect_call_metadata(
         &self,
-        metadata: &mut Vec<bd::MetadataEntry>,
+        metadata: &mut Vec<bindings::MetadataEntry>,
         inst: ir::Inst,
         ret_addr: CodeOffset,
     ) {
         // A call_indirect instruction can represent either a table call or a far call to a runtime
         // function. The CallSiteDesc::Kind enum does distinguish between the two, but it is not
         // clear that the information is used anywhere. For now, we won't bother distinguishing
         // them, and mark all calls as `Kind::Dynamic`.
         //
         // If we do need to make a distinction in the future, it is probably easiest to add a
         // `call_far` instruction to Cranelift that encodes like an indirect call, but includes the
         // callee like a direct call.
-        metadata.push(bd::MetadataEntry::indirect_call(
+        metadata.push(bindings::MetadataEntry::indirect_call(
             ret_addr,
             self.srcloc(inst),
         ));
     }
 
     fn trap_metadata(
         &self,
-        metadata: &mut Vec<bd::MetadataEntry>,
+        metadata: &mut Vec<bindings::MetadataEntry>,
         inst: ir::Inst,
         offset: CodeOffset,
     ) {
         let func = &self.context.func;
         let (code, trap_offset) = match func.dfg[inst] {
             ir::InstructionData::Trap { code, .. } => (code, 0),
             ir::InstructionData::IntCondTrap { code, .. }
             | ir::InstructionData::FloatCondTrap { code, .. } => {
@@ -375,40 +384,40 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
                 // The actual trap happens on the ud2 instruction.
                 (code, 2)
             }
             _ => panic!("Bad format for trap"),
         };
 
         // Translate the trap code into one of BaldrMonkey's trap codes.
         let bd_trap = match code {
-            ir::TrapCode::StackOverflow => bd::Trap::StackOverflow,
-            ir::TrapCode::HeapOutOfBounds => bd::Trap::OutOfBounds,
-            ir::TrapCode::OutOfBounds => bd::Trap::OutOfBounds,
-            ir::TrapCode::TableOutOfBounds => bd::Trap::OutOfBounds,
-            ir::TrapCode::IndirectCallToNull => bd::Trap::IndirectCallToNull,
-            ir::TrapCode::BadSignature => bd::Trap::IndirectCallBadSig,
-            ir::TrapCode::IntegerOverflow => bd::Trap::IntegerOverflow,
-            ir::TrapCode::IntegerDivisionByZero => bd::Trap::IntegerDivideByZero,
-            ir::TrapCode::BadConversionToInteger => bd::Trap::InvalidConversionToInteger,
-            ir::TrapCode::Interrupt => bd::Trap::CheckInterrupt,
-            ir::TrapCode::UnreachableCodeReached => bd::Trap::Unreachable,
+            ir::TrapCode::StackOverflow => bindings::Trap::StackOverflow,
+            ir::TrapCode::HeapOutOfBounds => bindings::Trap::OutOfBounds,
+            ir::TrapCode::OutOfBounds => bindings::Trap::OutOfBounds,
+            ir::TrapCode::TableOutOfBounds => bindings::Trap::OutOfBounds,
+            ir::TrapCode::IndirectCallToNull => bindings::Trap::IndirectCallToNull,
+            ir::TrapCode::BadSignature => bindings::Trap::IndirectCallBadSig,
+            ir::TrapCode::IntegerOverflow => bindings::Trap::IntegerOverflow,
+            ir::TrapCode::IntegerDivisionByZero => bindings::Trap::IntegerDivideByZero,
+            ir::TrapCode::BadConversionToInteger => bindings::Trap::InvalidConversionToInteger,
+            ir::TrapCode::Interrupt => bindings::Trap::CheckInterrupt,
+            ir::TrapCode::UnreachableCodeReached => bindings::Trap::Unreachable,
             ir::TrapCode::User(_) => panic!("Uncovered trap code {}", code),
         };
 
-        metadata.push(bd::MetadataEntry::trap(
+        metadata.push(bindings::MetadataEntry::trap(
             offset + trap_offset,
             self.srcloc(inst),
             bd_trap,
         ));
     }
 
     fn memory_metadata(
         &self,
-        metadata: &mut Vec<bd::MetadataEntry>,
+        metadata: &mut Vec<bindings::MetadataEntry>,
         inst: ir::Inst,
         offset: CodeOffset,
     ) {
         let func = &self.context.func;
         let memflags = match func.dfg[inst] {
             ir::InstructionData::Load { flags, .. }
             | ir::InstructionData::LoadComplex { flags, .. }
             | ir::InstructionData::Store { flags, .. }
@@ -418,17 +427,20 @@ impl<'a, 'b> BatchCompiler<'a, 'b> {
 
         // Some load/store instructions may be accessing VM data structures instead of the
         // WebAssembly heap. These are tagged with `notrap` since their trapping is not part of
         // the semantics, i.e. that would be a bug.
         if memflags.notrap() {
             return;
         }
 
-        metadata.push(bd::MetadataEntry::memory_access(offset, self.srcloc(inst)));
+        metadata.push(bindings::MetadataEntry::memory_access(
+            offset,
+            self.srcloc(inst),
+        ));
     }
 }
 
 impl<'a, 'b> fmt::Display for BatchCompiler<'a, 'b> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "{}", self.context.func.display(self.isa.as_ref()))
     }
 }
@@ -437,33 +449,38 @@ impl<'a, 'b> fmt::Display for BatchCompi
 pub fn wasm_function_name(func: FuncIndex) -> ir::ExternalName {
     ir::ExternalName::User {
         namespace: USER_FUNCTION_NAMESPACE,
         index: func.index() as u32,
     }
 }
 
 /// Create a Cranelift function name representing a builtin function.
-pub fn symbolic_function_name(sym: bd::SymbolicAddress) -> ir::ExternalName {
+pub fn symbolic_function_name(sym: bindings::SymbolicAddress) -> ir::ExternalName {
     ir::ExternalName::User {
         namespace: SYMBOLIC_FUNCTION_NAMESPACE,
         index: sym as u32,
     }
 }
 
 /// References joined so we can implement `RelocSink`.
 struct EmitEnv<'a> {
-    metadata: &'a mut Vec<bd::MetadataEntry>,
-    rodata_relocs: &'a mut Vec<CodeOffset>
+    metadata: &'a mut Vec<bindings::MetadataEntry>,
+    rodata_relocs: &'a mut Vec<CodeOffset>,
 }
 
 impl<'a> EmitEnv<'a> {
-    pub fn new(metadata: &'a mut Vec<bd::MetadataEntry>, rodata_relocs: &'a mut Vec<CodeOffset>)
-               -> EmitEnv<'a> {
-        EmitEnv { metadata, rodata_relocs }
+    pub fn new(
+        metadata: &'a mut Vec<bindings::MetadataEntry>,
+        rodata_relocs: &'a mut Vec<CodeOffset>,
+    ) -> EmitEnv<'a> {
+        EmitEnv {
+            metadata,
+            rodata_relocs,
+        }
     }
 }
 
 impl<'a> RelocSink for EmitEnv<'a> {
     fn reloc_ebb(&mut self, _offset: CodeOffset, _reloc: Reloc, _ebb_offset: CodeOffset) {
         unimplemented!();
     }
 
@@ -488,38 +505,38 @@ impl<'a> RelocSink for EmitEnv<'a> {
                 index,
             } => {
                 // This is a symbolic function reference encoded by `symbolic_function_name()`.
                 let sym = index.into();
 
                 // The symbolic access patch address points *after* the stored pointer.
                 let offset = offset + native_pointer_size() as u32;
                 self.metadata
-                    .push(bd::MetadataEntry::symbolic_access(offset, sym));
+                    .push(bindings::MetadataEntry::symbolic_access(offset, sym));
             }
 
             ir::ExternalName::LibCall(call) => {
                 let sym = match call {
-                    ir::LibCall::CeilF32 => bd::SymbolicAddress::CeilF32,
-                    ir::LibCall::CeilF64 => bd::SymbolicAddress::CeilF64,
-                    ir::LibCall::FloorF32 => bd::SymbolicAddress::FloorF32,
-                    ir::LibCall::FloorF64 => bd::SymbolicAddress::FloorF64,
-                    ir::LibCall::NearestF32 => bd::SymbolicAddress::NearestF32,
-                    ir::LibCall::NearestF64 => bd::SymbolicAddress::NearestF64,
-                    ir::LibCall::TruncF32 => bd::SymbolicAddress::TruncF32,
-                    ir::LibCall::TruncF64 => bd::SymbolicAddress::TruncF64,
+                    ir::LibCall::CeilF32 => bindings::SymbolicAddress::CeilF32,
+                    ir::LibCall::CeilF64 => bindings::SymbolicAddress::CeilF64,
+                    ir::LibCall::FloorF32 => bindings::SymbolicAddress::FloorF32,
+                    ir::LibCall::FloorF64 => bindings::SymbolicAddress::FloorF64,
+                    ir::LibCall::NearestF32 => bindings::SymbolicAddress::NearestF32,
+                    ir::LibCall::NearestF64 => bindings::SymbolicAddress::NearestF64,
+                    ir::LibCall::TruncF32 => bindings::SymbolicAddress::TruncF32,
+                    ir::LibCall::TruncF64 => bindings::SymbolicAddress::TruncF64,
                     _ => {
                         panic!("Don't understand external {}", name);
                     }
                 };
 
                 // The symbolic access patch address points *after* the stored pointer.
                 let offset = offset + native_pointer_size() as u32;
                 self.metadata
-                    .push(bd::MetadataEntry::symbolic_access(offset, sym));
+                    .push(bindings::MetadataEntry::symbolic_access(offset, sym));
             }
             _ => {
                 panic!("Don't understand external {}", name);
             }
         }
     }
 
     fn reloc_jt(&mut self, offset: CodeOffset, reloc: Reloc, _jt: ir::JumpTable) {
--- a/js/src/wasm/cranelift/src/cpu.rs
+++ b/js/src/wasm/cranelift/src/cpu.rs
@@ -21,17 +21,17 @@
 //! The main entry point is the `make_isa()` function which allocates a configured `TargetISA`
 //! object.
 
 use cranelift_codegen::isa;
 use cranelift_codegen::settings::{self, Configurable};
 use std::str::FromStr;
 use utils::{BasicError, DashResult};
 
-use baldrdash::StaticEnvironment;
+use bindings::StaticEnvironment;
 
 impl From<isa::LookupError> for BasicError {
     fn from(err: isa::LookupError) -> BasicError {
         BasicError::new(err.to_string())
     }
 }
 
 impl From<settings::SetError> for BasicError {
--- a/js/src/wasm/cranelift/src/lib.rs
+++ b/js/src/wasm/cranelift/src/lib.rs
@@ -16,24 +16,23 @@
 extern crate cranelift_codegen;
 extern crate cranelift_wasm;
 #[macro_use]
 extern crate target_lexicon;
 #[macro_use]
 extern crate log;
 extern crate env_logger;
 
-mod baldrapi; // Low-level C API, ignore this.
-mod baldrdash; // High-level Rust API, use this.
+mod bindings; // High-level bindings for C++ data structures.
 mod compile; // Cranelift function compiler.
 mod cpu; // CPU detection and `TargetISA` configuration.
 mod utils; // Helpers for other source files.
 mod wasm2clif; // WebAssembly to Cranelift translation callbacks.
 
-use baldrdash::{CompiledFunc, FuncCompileInput, ModuleEnvironment, StaticEnvironment};
+use bindings::{CompiledFunc, FuncCompileInput, ModuleEnvironment, StaticEnvironment};
 use compile::BatchCompiler;
 use std::ptr;
 
 #[no_mangle]
 pub extern "C" fn cranelift_initialize() {
     // Gecko might set a logger before we do, which is all fine; try to initialize ours, and reset
     // the FilterLevel env_logger::try_init might have set to what it was in case of initialization
     // failure
@@ -47,17 +46,17 @@ pub extern "C" fn cranelift_initialize()
 }
 
 /// Allocate a compiler for a module environment and return an opaque handle.
 ///
 /// This is declared in `clifapi.h`.
 #[no_mangle]
 pub unsafe extern "C" fn cranelift_compiler_create<'a, 'b>(
     static_env: *const StaticEnvironment,
-    env: *const baldrapi::CraneliftModuleEnvironment,
+    env: *const bindings::LowLevelModuleEnvironment,
 ) -> *mut BatchCompiler<'a, 'b> {
     let env = env.as_ref().unwrap();
     let static_env = static_env.as_ref().unwrap();
     match BatchCompiler::new(static_env, ModuleEnvironment::new(env)) {
         Ok(compiler) => Box::into_raw(Box::new(compiler)),
         Err(err) => {
             error!("When constructing the batch compiler: {}", err);
             ptr::null_mut()
--- a/js/src/wasm/cranelift/src/wasm2clif.rs
+++ b/js/src/wasm/cranelift/src/wasm2clif.rs
@@ -13,30 +13,32 @@
  * limitations under the License.
  */
 
 //! This module deals with the translation of WebAssembly binary functions to Cranelift IR.
 //!
 //! The code here deals with adapting the `cranelift_wasm` module to the specifics of BaldrMonkey's
 //! internal data structures.
 
-use baldrdash as bd;
-use compile::{symbolic_function_name, wasm_function_name};
+use std::collections::HashMap;
+
 use cranelift_codegen::cursor::{Cursor, FuncCursor};
 use cranelift_codegen::entity::{EntityRef, PrimaryMap, SecondaryMap};
 use cranelift_codegen::ir;
 use cranelift_codegen::ir::condcodes::IntCC;
 use cranelift_codegen::ir::InstBuilder;
 use cranelift_codegen::isa::{CallConv, TargetFrontendConfig, TargetIsa};
 use cranelift_codegen::packed_option::PackedOption;
 use cranelift_wasm::{
     FuncEnvironment, FuncIndex, GlobalIndex, GlobalVariable, MemoryIndex, ReturnMode,
     SignatureIndex, TableIndex, WasmResult,
 };
-use std::collections::HashMap;
+
+use bindings;
+use compile::{symbolic_function_name, wasm_function_name};
 
 /// Get the integer type used for representing pointers on this platform.
 fn native_pointer_type() -> ir::Type {
     if cfg!(target_pointer_width = "64") {
         ir::types::I64
     } else {
         ir::types::I32
     }
@@ -63,17 +65,17 @@ fn imm64(offset: usize) -> ir::immediate
 }
 
 /// Convert a usize offset into a `Uimm64`.
 fn uimm64(offset: usize) -> ir::immediates::Uimm64 {
     (offset as u64).into()
 }
 
 /// Initialize a `Signature` from a wasm signature.
-fn init_sig_from_wsig(sig: &mut ir::Signature, wsig: bd::FuncTypeWithId) -> WasmResult<()> {
+fn init_sig_from_wsig(sig: &mut ir::Signature, wsig: bindings::FuncTypeWithId) -> WasmResult<()> {
     sig.clear(CallConv::Baldrdash);
     for arg in wsig.args()? {
         sig.params.push(ir::AbiParam::new(arg));
     }
 
     if let Some(ret_type) = wsig.ret_type()? {
         let ret = match ret_type {
             // Spidermonkey requires i32 returns to have their high 32 bits
@@ -92,29 +94,29 @@ fn init_sig_from_wsig(sig: &mut ir::Sign
     ));
 
     Ok(())
 }
 
 /// Initialize the signature `sig` to match the function with `index` in `env`.
 pub fn init_sig(
     sig: &mut ir::Signature,
-    env: &bd::ModuleEnvironment,
+    env: &bindings::ModuleEnvironment,
     func_index: FuncIndex,
-) -> WasmResult<bd::FuncTypeWithId> {
+) -> WasmResult<bindings::FuncTypeWithId> {
     let wsig = env.function_signature(func_index);
     init_sig_from_wsig(sig, wsig)?;
     Ok(wsig)
 }
 
 /// A `TargetIsa` and `ModuleEnvironment` joined so we can implement `FuncEnvironment`.
 pub struct TransEnv<'a, 'b, 'c> {
     isa: &'a dyn TargetIsa,
-    env: &'b bd::ModuleEnvironment<'b>,
-    static_env: &'c bd::StaticEnvironment,
+    env: &'b bindings::ModuleEnvironment<'b>,
+    static_env: &'c bindings::StaticEnvironment,
 
     /// Information about the function pointer tables `self.env` knowns about. Indexed by table
     /// index.
     tables: PrimaryMap<TableIndex, TableInfo>,
 
     /// For those signatures whose ID is stored in a global, keep track of the globals we have
     /// created so far.
     ///
@@ -151,18 +153,18 @@ pub struct TransEnv<'a, 'b, 'c> {
 
     /// The address of the `realm` field in the `wasm::TlsData` struct.
     realm_addr: PackedOption<ir::GlobalValue>,
 }
 
 impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
     pub fn new(
         isa: &'a dyn TargetIsa,
-        env: &'b bd::ModuleEnvironment,
-        static_env: &'c bd::StaticEnvironment,
+        env: &'b bindings::ModuleEnvironment,
+        static_env: &'c bindings::StaticEnvironment,
     ) -> Self {
         TransEnv {
             isa,
             env,
             static_env,
             tables: PrimaryMap::new(),
             signatures: HashMap::new(),
             func_gvs: SecondaryMap::new(),
@@ -271,17 +273,17 @@ impl<'a, 'b, 'c> TransEnv<'a, 'b, 'c> {
         pos.ins().load(ir::types::I32, ir::MemFlags::new(), ga, 0)
     }
 
     /// Get a `FuncRef` for the given symbolic address.
     /// Uses the closure to create the signature if necessary.
     fn symbolic_funcref<MKSIG: FnOnce() -> ir::Signature>(
         &mut self,
         func: &mut ir::Function,
-        sym: bd::SymbolicAddress,
+        sym: bindings::SymbolicAddress,
         make_sig: MKSIG,
     ) -> (ir::FuncRef, ir::SigRef) {
         let symidx = sym as usize;
         if let Some(fnref) = self.symbolic[symidx].expand() {
             return (fnref, func.dfg.ext_funcs[fnref].signature);
         }
 
         // We need to allocate a signature and func-ref.
@@ -477,17 +479,17 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
         &mut self,
         func: &mut ir::Function,
         index: SignatureIndex,
     ) -> WasmResult<ir::SigRef> {
         let mut sigdata = ir::Signature::new(CallConv::Baldrdash);
         let wsig = self.env.signature(index);
         init_sig_from_wsig(&mut sigdata, wsig)?;
 
-        if wsig.id_kind() != bd::FuncTypeIdDescKind::None {
+        if wsig.id_kind() != bindings::FuncTypeIdDescKind::None {
             // A signature to be used for an indirect call also takes a signature id.
             sigdata.params.push(ir::AbiParam::special(
                 native_pointer_type(),
                 ir::ArgumentPurpose::SignatureId,
             ));
         }
 
         Ok(func.import_signature(sigdata))
@@ -553,23 +555,23 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
         // Currently, WebAssembly doesn't support multiple tables. That may change.
         assert_eq!(table_index.index(), 0);
         let wtable = self.get_table(pos.func, table_index);
 
         // Follows `MacroAssembler::wasmCallIndirect`:
 
         // 1. Materialize the signature ID.
         let sigid_value = match wsig.id_kind() {
-            bd::FuncTypeIdDescKind::None => None,
-            bd::FuncTypeIdDescKind::Immediate => {
+            bindings::FuncTypeIdDescKind::None => None,
+            bindings::FuncTypeIdDescKind::Immediate => {
                 // The signature is represented as an immediate pointer-sized value.
                 let imm = wsig.id_immediate() as i64;
                 Some(pos.ins().iconst(native_pointer_type(), imm))
             }
-            bd::FuncTypeIdDescKind::Global => {
+            bindings::FuncTypeIdDescKind::Global => {
                 let gv = self.sig_global(pos.func, wsig.id_tls_offset());
                 let addr = pos.ins().global_value(native_pointer_type(), gv);
                 Some(
                     pos.ins()
                         .load(native_pointer_type(), ir::MemFlags::new(), addr, 0),
                 )
             }
         };
@@ -705,17 +707,17 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
         mut pos: FuncCursor,
         _index: MemoryIndex,
         _heap: ir::Heap,
         val: ir::Value,
     ) -> WasmResult<ir::Value> {
         // We emit a call to `uint32_t memoryGrow_i32(Instance* instance, uint32_t delta)` via a
         // stub.
         let (fnref, sigref) =
-            self.symbolic_funcref(pos.func, bd::SymbolicAddress::MemoryGrow, || {
+            self.symbolic_funcref(pos.func, bindings::SymbolicAddress::MemoryGrow, || {
                 let mut sig = ir::Signature::new(CallConv::Baldrdash);
                 sig.params.push(ir::AbiParam::new(native_pointer_type()));
                 sig.params.push(ir::AbiParam::new(ir::types::I32).uext());
                 sig.params.push(ir::AbiParam::special(
                     native_pointer_type(),
                     ir::ArgumentPurpose::VMContext,
                 ));
                 sig.returns.push(ir::AbiParam::new(ir::types::I32).uext());
@@ -741,17 +743,17 @@ impl<'a, 'b, 'c> FuncEnvironment for Tra
     fn translate_memory_size(
         &mut self,
         mut pos: FuncCursor,
         _index: MemoryIndex,
         _heap: ir::Heap,
     ) -> WasmResult<ir::Value> {
         // We emit a call to `uint32_t memorySize_i32(Instance* instance)` via a stub.
         let (fnref, sigref) =
-            self.symbolic_funcref(pos.func, bd::SymbolicAddress::MemorySize, || {
+            self.symbolic_funcref(pos.func, bindings::SymbolicAddress::MemorySize, || {
                 let mut sig = ir::Signature::new(CallConv::Baldrdash);
                 sig.params.push(ir::AbiParam::new(native_pointer_type()));
                 sig.params.push(ir::AbiParam::special(
                     native_pointer_type(),
                     ir::ArgumentPurpose::VMContext,
                 ));
                 sig.returns.push(ir::AbiParam::new(ir::types::I32).uext());
                 sig
@@ -789,17 +791,21 @@ struct TableInfo {
     ///
     /// 0: Unsigned 32-bit table length.
     /// n: Pointer to table (n = sizeof(void*))
     pub global: ir::GlobalValue,
 }
 
 impl TableInfo {
     /// Create a TableInfo and its global variable in `func`.
-    pub fn new(wtab: bd::TableDesc, func: &mut ir::Function, vmctx: ir::GlobalValue) -> TableInfo {
+    pub fn new(
+        wtab: bindings::TableDesc,
+        func: &mut ir::Function,
+        vmctx: ir::GlobalValue,
+    ) -> TableInfo {
         // Create the global variable.
         let offset = wtab.tls_offset();
         assert!(offset < i32::max_value() as usize);
         let offset = imm64(offset);
         let global = func.create_global_value(ir::GlobalValueData::IAddImm {
             base: vmctx,
             offset,
             global_type: native_pointer_type(),