[wasmtime-api] Collect and wrap cranelift dependencies (#623)
* Collect and wrap cranelift dependencies * rename all _cranelift_ named methods
This commit is contained in:
@@ -1,10 +1,10 @@
|
|||||||
|
use crate::data_structures::ir;
|
||||||
use crate::r#ref::HostRef;
|
use crate::r#ref::HostRef;
|
||||||
use crate::runtime::Store;
|
use crate::runtime::Store;
|
||||||
use crate::trampoline::generate_func_export;
|
use crate::trampoline::generate_func_export;
|
||||||
use crate::trap::Trap;
|
use crate::trap::Trap;
|
||||||
use crate::types::FuncType;
|
use crate::types::FuncType;
|
||||||
use crate::values::Val;
|
use crate::values::Val;
|
||||||
use cranelift_codegen::ir;
|
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use wasmtime_jit::InstanceHandle;
|
use wasmtime_jit::InstanceHandle;
|
||||||
use wasmtime_runtime::Export;
|
use wasmtime_runtime::Export;
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::data_structures::native_isa_builder;
|
||||||
use crate::Config;
|
use crate::Config;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
@@ -13,8 +14,7 @@ pub struct Context {
|
|||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
pub fn new(config: &Config) -> Context {
|
pub fn new(config: &Config) -> Context {
|
||||||
let isa_builder =
|
let isa_builder = native_isa_builder();
|
||||||
cranelift_native::builder().expect("host machine is not a supported target");
|
|
||||||
let isa = isa_builder.finish(config.flags.clone());
|
let isa = isa_builder.finish(config.flags.clone());
|
||||||
Context::new_with_compiler(config, Compiler::new(isa, config.strategy))
|
Context::new_with_compiler(config, Compiler::new(isa, config.strategy))
|
||||||
}
|
}
|
||||||
|
|||||||
26
crates/api/src/data_structures.rs
Normal file
26
crates/api/src/data_structures.rs
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
pub(crate) mod ir {
|
||||||
|
pub(crate) use cranelift_codegen::ir::{types, AbiParam, ArgumentPurpose, Signature, Type};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) mod settings {
|
||||||
|
pub(crate) use cranelift_codegen::settings::{builder, Flags};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) use cranelift_codegen::isa::CallConv;
|
||||||
|
pub(crate) use cranelift_entity::{EntityRef, PrimaryMap};
|
||||||
|
|
||||||
|
pub(crate) mod wasm {
|
||||||
|
pub(crate) use cranelift_wasm::{
|
||||||
|
DefinedFuncIndex, DefinedTableIndex, FuncIndex, Global, GlobalInit, Memory, Table,
|
||||||
|
TableElementType,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn native_isa_builder() -> cranelift_codegen::isa::Builder {
|
||||||
|
cranelift_native::builder().expect("host machine is not a supported target")
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) fn native_isa_call_conv() -> CallConv {
|
||||||
|
use target_lexicon::HOST;
|
||||||
|
CallConv::triple_default(&HOST)
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::callable::{Callable, NativeCallable, WasmtimeFn, WrappedCallable};
|
use crate::callable::{Callable, NativeCallable, WasmtimeFn, WrappedCallable};
|
||||||
|
use crate::data_structures::wasm;
|
||||||
use crate::r#ref::{AnyRef, HostRef};
|
use crate::r#ref::{AnyRef, HostRef};
|
||||||
use crate::runtime::Store;
|
use crate::runtime::Store;
|
||||||
use crate::trampoline::{generate_global_export, generate_memory_export, generate_table_export};
|
use crate::trampoline::{generate_global_export, generate_memory_export, generate_table_export};
|
||||||
@@ -162,7 +163,7 @@ impl Func {
|
|||||||
instance_handle: InstanceHandle,
|
instance_handle: InstanceHandle,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export {
|
let ty = if let wasmtime_runtime::Export::Function { signature, .. } = &export {
|
||||||
FuncType::from_cranelift_signature(signature.clone())
|
FuncType::from_wasmtime_signature(signature.clone())
|
||||||
} else {
|
} else {
|
||||||
panic!("expected function export")
|
panic!("expected function export")
|
||||||
};
|
};
|
||||||
@@ -254,7 +255,7 @@ impl Global {
|
|||||||
} else {
|
} else {
|
||||||
panic!("wasmtime export is not memory")
|
panic!("wasmtime export is not memory")
|
||||||
};
|
};
|
||||||
let ty = GlobalType::from_cranelift_global(&global);
|
let ty = GlobalType::from_wasmtime_global(&global);
|
||||||
Global {
|
Global {
|
||||||
_store: store.clone(),
|
_store: store.clone(),
|
||||||
r#type: ty,
|
r#type: ty,
|
||||||
@@ -274,7 +275,7 @@ pub struct Table {
|
|||||||
fn get_table_item(
|
fn get_table_item(
|
||||||
handle: &InstanceHandle,
|
handle: &InstanceHandle,
|
||||||
store: &HostRef<Store>,
|
store: &HostRef<Store>,
|
||||||
table_index: cranelift_wasm::DefinedTableIndex,
|
table_index: wasm::DefinedTableIndex,
|
||||||
item_index: u32,
|
item_index: u32,
|
||||||
) -> Val {
|
) -> Val {
|
||||||
if let Some(item) = handle.table_get(table_index, item_index) {
|
if let Some(item) = handle.table_get(table_index, item_index) {
|
||||||
@@ -287,7 +288,7 @@ fn get_table_item(
|
|||||||
fn set_table_item(
|
fn set_table_item(
|
||||||
handle: &mut InstanceHandle,
|
handle: &mut InstanceHandle,
|
||||||
store: &HostRef<Store>,
|
store: &HostRef<Store>,
|
||||||
table_index: cranelift_wasm::DefinedTableIndex,
|
table_index: wasm::DefinedTableIndex,
|
||||||
item_index: u32,
|
item_index: u32,
|
||||||
val: Val,
|
val: Val,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
@@ -335,7 +336,7 @@ impl Table {
|
|||||||
&self.r#type
|
&self.r#type
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wasmtime_table_index(&self) -> cranelift_wasm::DefinedTableIndex {
|
fn wasmtime_table_index(&self) -> wasm::DefinedTableIndex {
|
||||||
match self.wasmtime_export {
|
match self.wasmtime_export {
|
||||||
wasmtime_runtime::Export::Table { definition, .. } => {
|
wasmtime_runtime::Export::Table { definition, .. } => {
|
||||||
self.wasmtime_handle.table_index(unsafe { &*definition })
|
self.wasmtime_handle.table_index(unsafe { &*definition })
|
||||||
@@ -394,7 +395,7 @@ impl Table {
|
|||||||
} else {
|
} else {
|
||||||
panic!("wasmtime export is not table")
|
panic!("wasmtime export is not table")
|
||||||
};
|
};
|
||||||
let ty = TableType::from_cranelift_table(&table.table);
|
let ty = TableType::from_wasmtime_table(&table.table);
|
||||||
Table {
|
Table {
|
||||||
store: store.clone(),
|
store: store.clone(),
|
||||||
r#type: ty,
|
r#type: ty,
|
||||||
@@ -478,7 +479,7 @@ impl Memory {
|
|||||||
} else {
|
} else {
|
||||||
panic!("wasmtime export is not memory")
|
panic!("wasmtime export is not memory")
|
||||||
};
|
};
|
||||||
let ty = MemoryType::from_cranelift_memory(&memory.memory);
|
let ty = MemoryType::from_wasmtime_memory(&memory.memory);
|
||||||
Memory {
|
Memory {
|
||||||
_store: store.clone(),
|
_store: store.clone(),
|
||||||
r#type: ty,
|
r#type: ty,
|
||||||
|
|||||||
@@ -132,7 +132,7 @@ impl Instance {
|
|||||||
// HACK ensure all handles, instantiated outside Store, present in
|
// HACK ensure all handles, instantiated outside Store, present in
|
||||||
// the store's SignatureRegistry, e.g. WASI instances that are
|
// the store's SignatureRegistry, e.g. WASI instances that are
|
||||||
// imported into this store using the from_handle() method.
|
// imported into this store using the from_handle() method.
|
||||||
let _ = store.borrow_mut().register_cranelift_signature(signature);
|
let _ = store.borrow_mut().register_wasmtime_signature(signature);
|
||||||
}
|
}
|
||||||
let extern_type = ExternType::from_wasmtime_export(&export);
|
let extern_type = ExternType::from_wasmtime_export(&export);
|
||||||
exports_types.push(ExportType::new(Name::new(name), extern_type));
|
exports_types.push(ExportType::new(Name::new(name), extern_type));
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
mod callable;
|
mod callable;
|
||||||
mod context;
|
mod context;
|
||||||
|
mod data_structures;
|
||||||
mod externals;
|
mod externals;
|
||||||
mod instance;
|
mod instance;
|
||||||
mod module;
|
mod module;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::data_structures::{ir, settings};
|
||||||
use crate::r#ref::HostRef;
|
use crate::r#ref::HostRef;
|
||||||
use cranelift_codegen::{ir, settings};
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@@ -139,7 +139,7 @@ impl Store {
|
|||||||
&self.global_exports
|
&self.global_exports
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn register_cranelift_signature(
|
pub(crate) fn register_wasmtime_signature(
|
||||||
&mut self,
|
&mut self,
|
||||||
signature: &ir::Signature,
|
signature: &ir::Signature,
|
||||||
) -> wasmtime_runtime::VMSharedSignatureIndex {
|
) -> wasmtime_runtime::VMSharedSignatureIndex {
|
||||||
@@ -154,7 +154,7 @@ impl Store {
|
|||||||
index
|
index
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn lookup_cranelift_signature(
|
pub(crate) fn lookup_wasmtime_signature(
|
||||||
&self,
|
&self,
|
||||||
type_index: wasmtime_runtime::VMSharedSignatureIndex,
|
type_index: wasmtime_runtime::VMSharedSignatureIndex,
|
||||||
) -> Option<&ir::Signature> {
|
) -> Option<&ir::Signature> {
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
//! Support for a calling of an imported function.
|
//! Support for a calling of an imported function.
|
||||||
|
|
||||||
|
use crate::data_structures::wasm::DefinedFuncIndex;
|
||||||
|
use crate::data_structures::PrimaryMap;
|
||||||
use crate::runtime::Store;
|
use crate::runtime::Store;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_entity::PrimaryMap;
|
|
||||||
use cranelift_wasm::DefinedFuncIndex;
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
use std::collections::{HashMap, HashSet};
|
use std::collections::{HashMap, HashSet};
|
||||||
@@ -36,7 +36,7 @@ pub(crate) fn create_handle(
|
|||||||
module
|
module
|
||||||
.signatures
|
.signatures
|
||||||
.values()
|
.values()
|
||||||
.map(|sig| signature_registry.register_cranelift_signature(sig))
|
.map(|sig| signature_registry.register_wasmtime_signature(sig))
|
||||||
.collect::<PrimaryMap<_, _>>(),
|
.collect::<PrimaryMap<_, _>>(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
//! Support for a calling of an imported function.
|
//! Support for a calling of an imported function.
|
||||||
|
|
||||||
use super::create_handle::create_handle;
|
use super::create_handle::create_handle;
|
||||||
|
use super::ir::{
|
||||||
|
ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind, TrapCode,
|
||||||
|
};
|
||||||
|
use super::{binemit, pretty_error, TargetIsa};
|
||||||
|
use super::{Context, FunctionBuilder, FunctionBuilderContext};
|
||||||
|
use crate::data_structures::ir::{self, types};
|
||||||
|
use crate::data_structures::wasm::{DefinedFuncIndex, FuncIndex};
|
||||||
|
use crate::data_structures::{native_isa_builder, settings, EntityRef, PrimaryMap};
|
||||||
use crate::r#ref::HostRef;
|
use crate::r#ref::HostRef;
|
||||||
use crate::{Callable, FuncType, Store, Trap, Val};
|
use crate::{Callable, FuncType, Store, Trap, Val};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_codegen::ir::{types, InstBuilder, StackSlotData, StackSlotKind, TrapCode};
|
|
||||||
use cranelift_codegen::print_errors::pretty_error;
|
|
||||||
use cranelift_codegen::{binemit, ir, isa, Context};
|
|
||||||
use cranelift_entity::{EntityRef, PrimaryMap};
|
|
||||||
use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
|
||||||
use cranelift_wasm::{DefinedFuncIndex, FuncIndex};
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
use wasmtime_environ::{CompiledFunction, Export, Module};
|
use wasmtime_environ::{CompiledFunction, Export, Module};
|
||||||
@@ -69,7 +71,7 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m
|
|||||||
|
|
||||||
/// Create a trampoline for invoking a Callable.
|
/// Create a trampoline for invoking a Callable.
|
||||||
fn make_trampoline(
|
fn make_trampoline(
|
||||||
isa: &dyn isa::TargetIsa,
|
isa: &dyn TargetIsa,
|
||||||
code_memory: &mut CodeMemory,
|
code_memory: &mut CodeMemory,
|
||||||
fn_builder_ctx: &mut FunctionBuilderContext,
|
fn_builder_ctx: &mut FunctionBuilderContext,
|
||||||
call_id: u32,
|
call_id: u32,
|
||||||
@@ -98,8 +100,7 @@ fn make_trampoline(
|
|||||||
let values_vec_len = 8 * cmp::max(signature.params.len() - 1, signature.returns.len()) as u32;
|
let values_vec_len = 8 * cmp::max(signature.params.len() - 1, signature.returns.len()) as u32;
|
||||||
|
|
||||||
let mut context = Context::new();
|
let mut context = Context::new();
|
||||||
context.func =
|
context.func = Function::with_name_signature(ExternalName::user(0, 0), signature.clone());
|
||||||
ir::Function::with_name_signature(ir::ExternalName::user(0, 0), signature.clone());
|
|
||||||
|
|
||||||
let ss = context.func.create_stack_slot(StackSlotData::new(
|
let ss = context.func.create_stack_slot(StackSlotData::new(
|
||||||
StackSlotKind::ExplicitSlot,
|
StackSlotKind::ExplicitSlot,
|
||||||
@@ -116,7 +117,7 @@ fn make_trampoline(
|
|||||||
builder.seal_block(block0);
|
builder.seal_block(block0);
|
||||||
|
|
||||||
let values_vec_ptr_val = builder.ins().stack_addr(pointer_type, ss, 0);
|
let values_vec_ptr_val = builder.ins().stack_addr(pointer_type, ss, 0);
|
||||||
let mflags = ir::MemFlags::trusted();
|
let mflags = MemFlags::trusted();
|
||||||
for i in 1..signature.params.len() {
|
for i in 1..signature.params.len() {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
continue;
|
continue;
|
||||||
@@ -148,7 +149,7 @@ fn make_trampoline(
|
|||||||
let call_result = builder.func.dfg.inst_results(call)[0];
|
let call_result = builder.func.dfg.inst_results(call)[0];
|
||||||
builder.ins().trapnz(call_result, TrapCode::User(0));
|
builder.ins().trapnz(call_result, TrapCode::User(0));
|
||||||
|
|
||||||
let mflags = ir::MemFlags::trusted();
|
let mflags = MemFlags::trusted();
|
||||||
let mut results = Vec::new();
|
let mut results = Vec::new();
|
||||||
for (i, r) in signature.returns.iter().enumerate() {
|
for (i, r) in signature.returns.iter().enumerate() {
|
||||||
let load = builder.ins().load(
|
let load = builder.ins().load(
|
||||||
@@ -164,7 +165,7 @@ fn make_trampoline(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut code_buf: Vec<u8> = Vec::new();
|
let mut code_buf: Vec<u8> = Vec::new();
|
||||||
let mut reloc_sink = RelocSink {};
|
let mut reloc_sink = binemit::TrampolineRelocSink {};
|
||||||
let mut trap_sink = binemit::NullTrapSink {};
|
let mut trap_sink = binemit::NullTrapSink {};
|
||||||
let mut stackmap_sink = binemit::NullStackmapSink {};
|
let mut stackmap_sink = binemit::NullStackmapSink {};
|
||||||
context
|
context
|
||||||
@@ -196,13 +197,12 @@ pub fn create_handle_with_function(
|
|||||||
func: &Rc<dyn Callable + 'static>,
|
func: &Rc<dyn Callable + 'static>,
|
||||||
store: &HostRef<Store>,
|
store: &HostRef<Store>,
|
||||||
) -> Result<InstanceHandle> {
|
) -> Result<InstanceHandle> {
|
||||||
let sig = ft.get_cranelift_signature().clone();
|
let sig = ft.get_wasmtime_signature().clone();
|
||||||
|
|
||||||
let isa = {
|
let isa = {
|
||||||
let isa_builder =
|
let isa_builder = native_isa_builder();
|
||||||
cranelift_native::builder().expect("host machine is not a supported target");
|
let flag_builder = settings::builder();
|
||||||
let flag_builder = cranelift_codegen::settings::builder();
|
isa_builder.finish(settings::Flags::new(flag_builder))
|
||||||
isa_builder.finish(cranelift_codegen::settings::Flags::new(flag_builder))
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut fn_builder_ctx = FunctionBuilderContext::new();
|
let mut fn_builder_ctx = FunctionBuilderContext::new();
|
||||||
@@ -211,9 +211,6 @@ pub fn create_handle_with_function(
|
|||||||
PrimaryMap::new();
|
PrimaryMap::new();
|
||||||
let mut code_memory = CodeMemory::new();
|
let mut code_memory = CodeMemory::new();
|
||||||
|
|
||||||
//let pointer_type = types::Type::triple_pointer_type(&HOST);
|
|
||||||
//let call_conv = isa::CallConv::triple_default(&HOST);
|
|
||||||
|
|
||||||
let sig_id = module.signatures.push(sig.clone());
|
let sig_id = module.signatures.push(sig.clone());
|
||||||
let func_id = module.functions.push(sig_id);
|
let func_id = module.functions.push(sig_id);
|
||||||
module
|
module
|
||||||
@@ -243,43 +240,3 @@ pub fn create_handle_with_function(
|
|||||||
Box::new(trampoline_state),
|
Box::new(trampoline_state),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We don't expect trampoline compilation to produce any relocations, so
|
|
||||||
/// this `RelocSink` just asserts that it doesn't recieve any.
|
|
||||||
struct RelocSink {}
|
|
||||||
|
|
||||||
impl binemit::RelocSink for RelocSink {
|
|
||||||
fn reloc_ebb(
|
|
||||||
&mut self,
|
|
||||||
_offset: binemit::CodeOffset,
|
|
||||||
_reloc: binemit::Reloc,
|
|
||||||
_ebb_offset: binemit::CodeOffset,
|
|
||||||
) {
|
|
||||||
panic!("trampoline compilation should not produce ebb relocs");
|
|
||||||
}
|
|
||||||
fn reloc_external(
|
|
||||||
&mut self,
|
|
||||||
_offset: binemit::CodeOffset,
|
|
||||||
_reloc: binemit::Reloc,
|
|
||||||
_name: &ir::ExternalName,
|
|
||||||
_addend: binemit::Addend,
|
|
||||||
) {
|
|
||||||
panic!("trampoline compilation should not produce external symbol relocs");
|
|
||||||
}
|
|
||||||
fn reloc_constant(
|
|
||||||
&mut self,
|
|
||||||
_code_offset: binemit::CodeOffset,
|
|
||||||
_reloc: binemit::Reloc,
|
|
||||||
_constant_offset: ir::ConstantOffset,
|
|
||||||
) {
|
|
||||||
panic!("trampoline compilation should not produce constant relocs");
|
|
||||||
}
|
|
||||||
fn reloc_jt(
|
|
||||||
&mut self,
|
|
||||||
_offset: binemit::CodeOffset,
|
|
||||||
_reloc: binemit::Reloc,
|
|
||||||
_jt: ir::JumpTable,
|
|
||||||
) {
|
|
||||||
panic!("trampoline compilation should not produce jump table relocs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::create_handle::create_handle;
|
use super::create_handle::create_handle;
|
||||||
|
use crate::data_structures::{wasm, PrimaryMap};
|
||||||
use crate::{GlobalType, Mutability, Val};
|
use crate::{GlobalType, Mutability, Val};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_entity::PrimaryMap;
|
|
||||||
use wasmtime_environ::Module;
|
use wasmtime_environ::Module;
|
||||||
use wasmtime_runtime::{InstanceHandle, VMGlobalDefinition};
|
use wasmtime_runtime::{InstanceHandle, VMGlobalDefinition};
|
||||||
|
|
||||||
@@ -23,13 +23,13 @@ pub fn create_global(gt: &GlobalType, val: Val) -> Result<(wasmtime_runtime::Exp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let global = cranelift_wasm::Global {
|
let global = wasm::Global {
|
||||||
ty: gt.content().get_cranelift_type(),
|
ty: gt.content().get_wasmtime_type(),
|
||||||
mutability: match gt.mutability() {
|
mutability: match gt.mutability() {
|
||||||
Mutability::Const => false,
|
Mutability::Const => false,
|
||||||
Mutability::Var => true,
|
Mutability::Var => true,
|
||||||
},
|
},
|
||||||
initializer: cranelift_wasm::GlobalInit::Import, // TODO is it right?
|
initializer: wasm::GlobalInit::Import, // TODO is it right?
|
||||||
};
|
};
|
||||||
let mut handle =
|
let mut handle =
|
||||||
create_handle(Module::new(), None, PrimaryMap::new(), Box::new(())).expect("handle");
|
create_handle(Module::new(), None, PrimaryMap::new(), Box::new(())).expect("handle");
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::create_handle::create_handle;
|
use super::create_handle::create_handle;
|
||||||
|
use crate::data_structures::{wasm, PrimaryMap};
|
||||||
use crate::MemoryType;
|
use crate::MemoryType;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_entity::PrimaryMap;
|
|
||||||
use wasmtime_environ::Module;
|
use wasmtime_environ::Module;
|
||||||
use wasmtime_runtime::InstanceHandle;
|
use wasmtime_runtime::InstanceHandle;
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ use wasmtime_runtime::InstanceHandle;
|
|||||||
pub fn create_handle_with_memory(memory: &MemoryType) -> Result<InstanceHandle> {
|
pub fn create_handle_with_memory(memory: &MemoryType) -> Result<InstanceHandle> {
|
||||||
let mut module = Module::new();
|
let mut module = Module::new();
|
||||||
|
|
||||||
let memory = cranelift_wasm::Memory {
|
let memory = wasm::Memory {
|
||||||
minimum: memory.limits().min(),
|
minimum: memory.limits().min(),
|
||||||
maximum: if memory.limits().max() == std::u32::MAX {
|
maximum: if memory.limits().max() == std::u32::MAX {
|
||||||
None
|
None
|
||||||
|
|||||||
@@ -49,3 +49,60 @@ pub fn generate_table_export(
|
|||||||
let export = instance.lookup("table").expect("table export");
|
let export = instance.lookup("table").expect("table export");
|
||||||
Ok((instance, export))
|
Ok((instance, export))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) use cranelift_codegen::print_errors::pretty_error;
|
||||||
|
|
||||||
|
pub(crate) mod binemit {
|
||||||
|
pub(crate) use cranelift_codegen::binemit::{NullStackmapSink, NullTrapSink};
|
||||||
|
|
||||||
|
pub use cranelift_codegen::{binemit, ir};
|
||||||
|
|
||||||
|
/// We don't expect trampoline compilation to produce any relocations, so
|
||||||
|
/// this `RelocSink` just asserts that it doesn't recieve any.
|
||||||
|
pub(crate) struct TrampolineRelocSink {}
|
||||||
|
|
||||||
|
impl binemit::RelocSink for TrampolineRelocSink {
|
||||||
|
fn reloc_ebb(
|
||||||
|
&mut self,
|
||||||
|
_offset: binemit::CodeOffset,
|
||||||
|
_reloc: binemit::Reloc,
|
||||||
|
_ebb_offset: binemit::CodeOffset,
|
||||||
|
) {
|
||||||
|
panic!("trampoline compilation should not produce ebb relocs");
|
||||||
|
}
|
||||||
|
fn reloc_external(
|
||||||
|
&mut self,
|
||||||
|
_offset: binemit::CodeOffset,
|
||||||
|
_reloc: binemit::Reloc,
|
||||||
|
_name: &ir::ExternalName,
|
||||||
|
_addend: binemit::Addend,
|
||||||
|
) {
|
||||||
|
panic!("trampoline compilation should not produce external symbol relocs");
|
||||||
|
}
|
||||||
|
fn reloc_constant(
|
||||||
|
&mut self,
|
||||||
|
_code_offset: binemit::CodeOffset,
|
||||||
|
_reloc: binemit::Reloc,
|
||||||
|
_constant_offset: ir::ConstantOffset,
|
||||||
|
) {
|
||||||
|
panic!("trampoline compilation should not produce constant relocs");
|
||||||
|
}
|
||||||
|
fn reloc_jt(
|
||||||
|
&mut self,
|
||||||
|
_offset: binemit::CodeOffset,
|
||||||
|
_reloc: binemit::Reloc,
|
||||||
|
_jt: ir::JumpTable,
|
||||||
|
) {
|
||||||
|
panic!("trampoline compilation should not produce jump table relocs");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) mod ir {
|
||||||
|
pub(crate) use cranelift_codegen::ir::{
|
||||||
|
ExternalName, Function, InstBuilder, MemFlags, StackSlotData, StackSlotKind, TrapCode,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
pub(crate) use cranelift_codegen::isa::TargetIsa;
|
||||||
|
pub(crate) use cranelift_codegen::Context;
|
||||||
|
pub(crate) use cranelift_frontend::{FunctionBuilder, FunctionBuilderContext};
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
use super::create_handle::create_handle;
|
use super::create_handle::create_handle;
|
||||||
|
use crate::data_structures::{wasm, PrimaryMap};
|
||||||
use crate::{TableType, ValType};
|
use crate::{TableType, ValType};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use cranelift_entity::PrimaryMap;
|
|
||||||
use cranelift_wasm::TableElementType;
|
|
||||||
use wasmtime_environ::Module;
|
use wasmtime_environ::Module;
|
||||||
use wasmtime_runtime::InstanceHandle;
|
use wasmtime_runtime::InstanceHandle;
|
||||||
|
|
||||||
pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle> {
|
pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle> {
|
||||||
let mut module = Module::new();
|
let mut module = Module::new();
|
||||||
|
|
||||||
let table = cranelift_wasm::Table {
|
let table = wasm::Table {
|
||||||
minimum: table.limits().min(),
|
minimum: table.limits().min(),
|
||||||
maximum: if table.limits().max() == std::u32::MAX {
|
maximum: if table.limits().max() == std::u32::MAX {
|
||||||
None
|
None
|
||||||
@@ -17,8 +16,8 @@ pub fn create_handle_with_table(table: &TableType) -> Result<InstanceHandle> {
|
|||||||
Some(table.limits().max())
|
Some(table.limits().max())
|
||||||
},
|
},
|
||||||
ty: match table.element() {
|
ty: match table.element() {
|
||||||
ValType::FuncRef => TableElementType::Func,
|
ValType::FuncRef => wasm::TableElementType::Func,
|
||||||
_ => TableElementType::Val(table.element().get_cranelift_type()),
|
_ => wasm::TableElementType::Val(table.element().get_wasmtime_type()),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let tunable = Default::default();
|
let tunable = Default::default();
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use cranelift_codegen::ir;
|
use crate::data_structures::{ir, wasm};
|
||||||
|
|
||||||
// Type Representations
|
// Type Representations
|
||||||
|
|
||||||
@@ -65,25 +65,25 @@ impl ValType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_cranelift_type(&self) -> ir::Type {
|
pub(crate) fn get_wasmtime_type(&self) -> ir::Type {
|
||||||
match self {
|
match self {
|
||||||
ValType::I32 => ir::types::I32,
|
ValType::I32 => ir::types::I32,
|
||||||
ValType::I64 => ir::types::I64,
|
ValType::I64 => ir::types::I64,
|
||||||
ValType::F32 => ir::types::F32,
|
ValType::F32 => ir::types::F32,
|
||||||
ValType::F64 => ir::types::F64,
|
ValType::F64 => ir::types::F64,
|
||||||
ValType::V128 => ir::types::I8X16,
|
ValType::V128 => ir::types::I8X16,
|
||||||
_ => unimplemented!("get_cranelift_type other"),
|
_ => unimplemented!("get_wasmtime_type other"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_cranelift_type(ty: ir::Type) -> ValType {
|
pub(crate) fn from_wasmtime_type(ty: ir::Type) -> ValType {
|
||||||
match ty {
|
match ty {
|
||||||
ir::types::I32 => ValType::I32,
|
ir::types::I32 => ValType::I32,
|
||||||
ir::types::I64 => ValType::I64,
|
ir::types::I64 => ValType::I64,
|
||||||
ir::types::F32 => ValType::F32,
|
ir::types::F32 => ValType::F32,
|
||||||
ir::types::F64 => ValType::F64,
|
ir::types::F64 => ValType::F64,
|
||||||
ir::types::I8X16 => ValType::V128,
|
ir::types::I8X16 => ValType::V128,
|
||||||
_ => unimplemented!("from_cranelift_type other"),
|
_ => unimplemented!("from_wasmtime_type other"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,25 +126,25 @@ impl ExternType {
|
|||||||
pub(crate) fn from_wasmtime_export(export: &wasmtime_runtime::Export) -> Self {
|
pub(crate) fn from_wasmtime_export(export: &wasmtime_runtime::Export) -> Self {
|
||||||
match export {
|
match export {
|
||||||
wasmtime_runtime::Export::Function { signature, .. } => {
|
wasmtime_runtime::Export::Function { signature, .. } => {
|
||||||
ExternType::ExternFunc(FuncType::from_cranelift_signature(signature.clone()))
|
ExternType::ExternFunc(FuncType::from_wasmtime_signature(signature.clone()))
|
||||||
}
|
}
|
||||||
wasmtime_runtime::Export::Memory { memory, .. } => {
|
wasmtime_runtime::Export::Memory { memory, .. } => {
|
||||||
ExternType::ExternMemory(MemoryType::from_cranelift_memory(&memory.memory))
|
ExternType::ExternMemory(MemoryType::from_wasmtime_memory(&memory.memory))
|
||||||
}
|
}
|
||||||
wasmtime_runtime::Export::Global { global, .. } => {
|
wasmtime_runtime::Export::Global { global, .. } => {
|
||||||
ExternType::ExternGlobal(GlobalType::from_cranelift_global(&global))
|
ExternType::ExternGlobal(GlobalType::from_wasmtime_global(&global))
|
||||||
}
|
}
|
||||||
wasmtime_runtime::Export::Table { table, .. } => {
|
wasmtime_runtime::Export::Table { table, .. } => {
|
||||||
ExternType::ExternTable(TableType::from_cranelift_table(&table.table))
|
ExternType::ExternTable(TableType::from_wasmtime_table(&table.table))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Function Types
|
// Function Types
|
||||||
fn from_cranelift_abiparam(param: &ir::AbiParam) -> ValType {
|
fn from_wasmtime_abiparam(param: &ir::AbiParam) -> ValType {
|
||||||
assert_eq!(param.purpose, ir::ArgumentPurpose::Normal);
|
assert_eq!(param.purpose, ir::ArgumentPurpose::Normal);
|
||||||
ValType::from_cranelift_type(param.value_type)
|
ValType::from_wasmtime_type(param.value_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -156,18 +156,17 @@ pub struct FuncType {
|
|||||||
|
|
||||||
impl FuncType {
|
impl FuncType {
|
||||||
pub fn new(params: Box<[ValType]>, results: Box<[ValType]>) -> FuncType {
|
pub fn new(params: Box<[ValType]>, results: Box<[ValType]>) -> FuncType {
|
||||||
use cranelift_codegen::ir::*;
|
use crate::data_structures::ir::{types, AbiParam, ArgumentPurpose, Signature};
|
||||||
use cranelift_codegen::isa::CallConv;
|
use crate::data_structures::native_isa_call_conv;
|
||||||
use target_lexicon::HOST;
|
let call_conv = native_isa_call_conv();
|
||||||
let call_conv = CallConv::triple_default(&HOST);
|
|
||||||
let signature: Signature = {
|
let signature: Signature = {
|
||||||
let mut params = params
|
let mut params = params
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| AbiParam::new(p.get_cranelift_type()))
|
.map(|p| AbiParam::new(p.get_wasmtime_type()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let returns = results
|
let returns = results
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| AbiParam::new(p.get_cranelift_type()))
|
.map(|p| AbiParam::new(p.get_wasmtime_type()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
params.insert(0, AbiParam::special(types::I64, ArgumentPurpose::VMContext));
|
params.insert(0, AbiParam::special(types::I64, ArgumentPurpose::VMContext));
|
||||||
|
|
||||||
@@ -190,21 +189,21 @@ impl FuncType {
|
|||||||
&self.results
|
&self.results
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn get_cranelift_signature(&self) -> &ir::Signature {
|
pub(crate) fn get_wasmtime_signature(&self) -> &ir::Signature {
|
||||||
&self.signature
|
&self.signature
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_cranelift_signature(signature: ir::Signature) -> FuncType {
|
pub(crate) fn from_wasmtime_signature(signature: ir::Signature) -> FuncType {
|
||||||
let params = signature
|
let params = signature
|
||||||
.params
|
.params
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| p.purpose == ir::ArgumentPurpose::Normal)
|
.filter(|p| p.purpose == ir::ArgumentPurpose::Normal)
|
||||||
.map(|p| from_cranelift_abiparam(p))
|
.map(|p| from_wasmtime_abiparam(p))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let results = signature
|
let results = signature
|
||||||
.returns
|
.returns
|
||||||
.iter()
|
.iter()
|
||||||
.map(|p| from_cranelift_abiparam(p))
|
.map(|p| from_wasmtime_abiparam(p))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
FuncType {
|
FuncType {
|
||||||
params: params.into_boxed_slice(),
|
params: params.into_boxed_slice(),
|
||||||
@@ -236,8 +235,8 @@ impl GlobalType {
|
|||||||
self.mutability
|
self.mutability
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_cranelift_global(global: &cranelift_wasm::Global) -> GlobalType {
|
pub(crate) fn from_wasmtime_global(global: &wasm::Global) -> GlobalType {
|
||||||
let ty = ValType::from_cranelift_type(global.ty);
|
let ty = ValType::from_wasmtime_type(global.ty);
|
||||||
let mutability = if global.mutability {
|
let mutability = if global.mutability {
|
||||||
Mutability::Var
|
Mutability::Var
|
||||||
} else {
|
} else {
|
||||||
@@ -266,8 +265,8 @@ impl TableType {
|
|||||||
&self.limits
|
&self.limits
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_cranelift_table(table: &cranelift_wasm::Table) -> TableType {
|
pub(crate) fn from_wasmtime_table(table: &wasm::Table) -> TableType {
|
||||||
assert!(if let cranelift_wasm::TableElementType::Func = table.ty {
|
assert!(if let wasm::TableElementType::Func = table.ty {
|
||||||
true
|
true
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
@@ -293,7 +292,7 @@ impl MemoryType {
|
|||||||
&self.limits
|
&self.limits
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_cranelift_memory(memory: &cranelift_wasm::Memory) -> MemoryType {
|
pub(crate) fn from_wasmtime_memory(memory: &wasm::Memory) -> MemoryType {
|
||||||
MemoryType::new(Limits::new(
|
MemoryType::new(Limits::new(
|
||||||
memory.minimum,
|
memory.minimum,
|
||||||
memory.maximum.unwrap_or(::std::u32::MAX),
|
memory.maximum.unwrap_or(::std::u32::MAX),
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
use crate::data_structures::ir;
|
||||||
use crate::externals::Func;
|
use crate::externals::Func;
|
||||||
use crate::r#ref::{AnyRef, HostRef};
|
use crate::r#ref::{AnyRef, HostRef};
|
||||||
use crate::runtime::Store;
|
use crate::runtime::Store;
|
||||||
use crate::types::ValType;
|
use crate::types::ValType;
|
||||||
use cranelift_codegen::ir;
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use wasmtime_jit::RuntimeValue;
|
use wasmtime_jit::RuntimeValue;
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ pub(crate) fn into_checked_anyfunc(
|
|||||||
} => (*vmctx, *address, signature),
|
} => (*vmctx, *address, signature),
|
||||||
_ => panic!("expected function export"),
|
_ => panic!("expected function export"),
|
||||||
};
|
};
|
||||||
let type_index = store.borrow_mut().register_cranelift_signature(signature);
|
let type_index = store.borrow_mut().register_wasmtime_signature(signature);
|
||||||
wasmtime_runtime::VMCallerCheckedAnyfunc {
|
wasmtime_runtime::VMCallerCheckedAnyfunc {
|
||||||
func_ptr,
|
func_ptr,
|
||||||
type_index,
|
type_index,
|
||||||
@@ -248,7 +248,7 @@ pub(crate) fn from_checked_anyfunc(
|
|||||||
}
|
}
|
||||||
let signature = store
|
let signature = store
|
||||||
.borrow()
|
.borrow()
|
||||||
.lookup_cranelift_signature(item.type_index)
|
.lookup_wasmtime_signature(item.type_index)
|
||||||
.expect("signature")
|
.expect("signature")
|
||||||
.clone();
|
.clone();
|
||||||
let instance_handle = unsafe { wasmtime_runtime::InstanceHandle::from_vmctx(item.vmctx) };
|
let instance_handle = unsafe { wasmtime_runtime::InstanceHandle::from_vmctx(item.vmctx) };
|
||||||
|
|||||||
Reference in New Issue
Block a user