Fix llvm backend to work with latest inkwell.

cargo update to pick up latest inkwell branch commit.

Add lifetime annotations to Module which now takes a lifetime, and more lifetime annotations across intrinsics.rs.

Add <'ctx> to missing places in CtxType and Intrinsics. Remove it from reference bindings.

Use ManuallyDrop to ensure that context's members are dropped before the Context.

Co-authored-by: Mark McCaskey <mark@wasmer.io>
This commit is contained in:
Nick Lewycky 2019-11-04 18:12:32 -08:00
parent dfc7163b71
commit 31a77b0eb7
7 changed files with 1528 additions and 629 deletions

1149
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@ libc = "0.2.60"
byteorder = "1" byteorder = "1"
[dependencies.inkwell] [dependencies.inkwell]
git = "https://github.com/wasmerio/inkwell" git = "https://github.com/TheDan64/inkwell"
branch = "llvm8-0" rev = "781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
default-features = false default-features = false
features = ["llvm8-0", "target-x86"] features = ["llvm8-0", "target-x86"]

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,6 @@ use inkwell::{
}; };
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use wasmer_runtime_core::{ use wasmer_runtime_core::{
memory::MemoryType, memory::MemoryType,
@ -25,7 +24,7 @@ use wasmer_runtime_core::{
vm::{Ctx, INTERNALS_SIZE}, vm::{Ctx, INTERNALS_SIZE},
}; };
fn type_to_llvm_ptr(intrinsics: &Intrinsics, ty: Type) -> PointerType { fn type_to_llvm_ptr<'ctx>(intrinsics: &Intrinsics<'ctx>, ty: Type) -> PointerType<'ctx> {
match ty { match ty {
Type::I32 => intrinsics.i32_ptr_ty, Type::I32 => intrinsics.i32_ptr_ty,
Type::I64 => intrinsics.i64_ptr_ty, Type::I64 => intrinsics.i64_ptr_ty,
@ -35,124 +34,124 @@ fn type_to_llvm_ptr(intrinsics: &Intrinsics, ty: Type) -> PointerType {
} }
} }
pub struct Intrinsics { pub struct Intrinsics<'ctx> {
pub ctlz_i32: FunctionValue, pub ctlz_i32: FunctionValue<'ctx>,
pub ctlz_i64: FunctionValue, pub ctlz_i64: FunctionValue<'ctx>,
pub cttz_i32: FunctionValue, pub cttz_i32: FunctionValue<'ctx>,
pub cttz_i64: FunctionValue, pub cttz_i64: FunctionValue<'ctx>,
pub ctpop_i32: FunctionValue, pub ctpop_i32: FunctionValue<'ctx>,
pub ctpop_i64: FunctionValue, pub ctpop_i64: FunctionValue<'ctx>,
pub sqrt_f32: FunctionValue, pub sqrt_f32: FunctionValue<'ctx>,
pub sqrt_f64: FunctionValue, pub sqrt_f64: FunctionValue<'ctx>,
pub sqrt_f32x4: FunctionValue, pub sqrt_f32x4: FunctionValue<'ctx>,
pub sqrt_f64x2: FunctionValue, pub sqrt_f64x2: FunctionValue<'ctx>,
pub ceil_f32: FunctionValue, pub ceil_f32: FunctionValue<'ctx>,
pub ceil_f64: FunctionValue, pub ceil_f64: FunctionValue<'ctx>,
pub floor_f32: FunctionValue, pub floor_f32: FunctionValue<'ctx>,
pub floor_f64: FunctionValue, pub floor_f64: FunctionValue<'ctx>,
pub trunc_f32: FunctionValue, pub trunc_f32: FunctionValue<'ctx>,
pub trunc_f64: FunctionValue, pub trunc_f64: FunctionValue<'ctx>,
pub nearbyint_f32: FunctionValue, pub nearbyint_f32: FunctionValue<'ctx>,
pub nearbyint_f64: FunctionValue, pub nearbyint_f64: FunctionValue<'ctx>,
pub fabs_f32: FunctionValue, pub fabs_f32: FunctionValue<'ctx>,
pub fabs_f64: FunctionValue, pub fabs_f64: FunctionValue<'ctx>,
pub fabs_f32x4: FunctionValue, pub fabs_f32x4: FunctionValue<'ctx>,
pub fabs_f64x2: FunctionValue, pub fabs_f64x2: FunctionValue<'ctx>,
pub copysign_f32: FunctionValue, pub copysign_f32: FunctionValue<'ctx>,
pub copysign_f64: FunctionValue, pub copysign_f64: FunctionValue<'ctx>,
pub sadd_sat_i8x16: FunctionValue, pub sadd_sat_i8x16: FunctionValue<'ctx>,
pub sadd_sat_i16x8: FunctionValue, pub sadd_sat_i16x8: FunctionValue<'ctx>,
pub uadd_sat_i8x16: FunctionValue, pub uadd_sat_i8x16: FunctionValue<'ctx>,
pub uadd_sat_i16x8: FunctionValue, pub uadd_sat_i16x8: FunctionValue<'ctx>,
pub ssub_sat_i8x16: FunctionValue, pub ssub_sat_i8x16: FunctionValue<'ctx>,
pub ssub_sat_i16x8: FunctionValue, pub ssub_sat_i16x8: FunctionValue<'ctx>,
pub usub_sat_i8x16: FunctionValue, pub usub_sat_i8x16: FunctionValue<'ctx>,
pub usub_sat_i16x8: FunctionValue, pub usub_sat_i16x8: FunctionValue<'ctx>,
pub expect_i1: FunctionValue, pub expect_i1: FunctionValue<'ctx>,
pub trap: FunctionValue, pub trap: FunctionValue<'ctx>,
pub void_ty: VoidType, pub void_ty: VoidType<'ctx>,
pub i1_ty: IntType, pub i1_ty: IntType<'ctx>,
pub i8_ty: IntType, pub i8_ty: IntType<'ctx>,
pub i16_ty: IntType, pub i16_ty: IntType<'ctx>,
pub i32_ty: IntType, pub i32_ty: IntType<'ctx>,
pub i64_ty: IntType, pub i64_ty: IntType<'ctx>,
pub i128_ty: IntType, pub i128_ty: IntType<'ctx>,
pub f32_ty: FloatType, pub f32_ty: FloatType<'ctx>,
pub f64_ty: FloatType, pub f64_ty: FloatType<'ctx>,
pub i1x128_ty: VectorType, pub i1x128_ty: VectorType<'ctx>,
pub i8x16_ty: VectorType, pub i8x16_ty: VectorType<'ctx>,
pub i16x8_ty: VectorType, pub i16x8_ty: VectorType<'ctx>,
pub i32x4_ty: VectorType, pub i32x4_ty: VectorType<'ctx>,
pub i64x2_ty: VectorType, pub i64x2_ty: VectorType<'ctx>,
pub f32x4_ty: VectorType, pub f32x4_ty: VectorType<'ctx>,
pub f64x2_ty: VectorType, pub f64x2_ty: VectorType<'ctx>,
pub i8_ptr_ty: PointerType, pub i8_ptr_ty: PointerType<'ctx>,
pub i16_ptr_ty: PointerType, pub i16_ptr_ty: PointerType<'ctx>,
pub i32_ptr_ty: PointerType, pub i32_ptr_ty: PointerType<'ctx>,
pub i64_ptr_ty: PointerType, pub i64_ptr_ty: PointerType<'ctx>,
pub i128_ptr_ty: PointerType, pub i128_ptr_ty: PointerType<'ctx>,
pub f32_ptr_ty: PointerType, pub f32_ptr_ty: PointerType<'ctx>,
pub f64_ptr_ty: PointerType, pub f64_ptr_ty: PointerType<'ctx>,
pub anyfunc_ty: StructType, pub anyfunc_ty: StructType<'ctx>,
pub i1_zero: IntValue, pub i1_zero: IntValue<'ctx>,
pub i8_zero: IntValue, pub i8_zero: IntValue<'ctx>,
pub i32_zero: IntValue, pub i32_zero: IntValue<'ctx>,
pub i64_zero: IntValue, pub i64_zero: IntValue<'ctx>,
pub i128_zero: IntValue, pub i128_zero: IntValue<'ctx>,
pub f32_zero: FloatValue, pub f32_zero: FloatValue<'ctx>,
pub f64_zero: FloatValue, pub f64_zero: FloatValue<'ctx>,
pub f32x4_zero: VectorValue, pub f32x4_zero: VectorValue<'ctx>,
pub f64x2_zero: VectorValue, pub f64x2_zero: VectorValue<'ctx>,
pub trap_unreachable: BasicValueEnum, pub trap_unreachable: BasicValueEnum<'ctx>,
pub trap_call_indirect_sig: BasicValueEnum, pub trap_call_indirect_sig: BasicValueEnum<'ctx>,
pub trap_call_indirect_oob: BasicValueEnum, pub trap_call_indirect_oob: BasicValueEnum<'ctx>,
pub trap_memory_oob: BasicValueEnum, pub trap_memory_oob: BasicValueEnum<'ctx>,
pub trap_illegal_arithmetic: BasicValueEnum, pub trap_illegal_arithmetic: BasicValueEnum<'ctx>,
pub trap_misaligned_atomic: BasicValueEnum, pub trap_misaligned_atomic: BasicValueEnum<'ctx>,
// VM intrinsics. // VM intrinsics.
pub memory_grow_dynamic_local: FunctionValue, pub memory_grow_dynamic_local: FunctionValue<'ctx>,
pub memory_grow_static_local: FunctionValue, pub memory_grow_static_local: FunctionValue<'ctx>,
pub memory_grow_shared_local: FunctionValue, pub memory_grow_shared_local: FunctionValue<'ctx>,
pub memory_grow_dynamic_import: FunctionValue, pub memory_grow_dynamic_import: FunctionValue<'ctx>,
pub memory_grow_static_import: FunctionValue, pub memory_grow_static_import: FunctionValue<'ctx>,
pub memory_grow_shared_import: FunctionValue, pub memory_grow_shared_import: FunctionValue<'ctx>,
pub memory_size_dynamic_local: FunctionValue, pub memory_size_dynamic_local: FunctionValue<'ctx>,
pub memory_size_static_local: FunctionValue, pub memory_size_static_local: FunctionValue<'ctx>,
pub memory_size_shared_local: FunctionValue, pub memory_size_shared_local: FunctionValue<'ctx>,
pub memory_size_dynamic_import: FunctionValue, pub memory_size_dynamic_import: FunctionValue<'ctx>,
pub memory_size_static_import: FunctionValue, pub memory_size_static_import: FunctionValue<'ctx>,
pub memory_size_shared_import: FunctionValue, pub memory_size_shared_import: FunctionValue<'ctx>,
pub throw_trap: FunctionValue, pub throw_trap: FunctionValue<'ctx>,
pub throw_breakpoint: FunctionValue, pub throw_breakpoint: FunctionValue<'ctx>,
pub experimental_stackmap: FunctionValue, pub experimental_stackmap: FunctionValue<'ctx>,
pub ctx_ptr_ty: PointerType, pub ctx_ptr_ty: PointerType<'ctx>,
} }
impl Intrinsics { impl<'ctx> Intrinsics<'ctx> {
pub fn declare(module: &Module, context: &Context) -> Self { pub fn declare(module: &Module<'ctx>, context: &'ctx Context) -> Self {
let void_ty = context.void_type(); let void_ty = context.void_type();
let i1_ty = context.bool_type(); let i1_ty = context.bool_type();
let i8_ty = context.i8_type(); let i8_ty = context.i8_type();
@ -560,66 +559,64 @@ impl Intrinsics {
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum MemoryCache { pub enum MemoryCache<'ctx> {
/// The memory moves around. /// The memory moves around.
Dynamic { Dynamic {
ptr_to_base_ptr: PointerValue, ptr_to_base_ptr: PointerValue<'ctx>,
ptr_to_bounds: PointerValue, ptr_to_bounds: PointerValue<'ctx>,
minimum: Pages, minimum: Pages,
maximum: Option<Pages>, maximum: Option<Pages>,
}, },
/// The memory is always in the same place. /// The memory is always in the same place.
Static { Static {
base_ptr: PointerValue, base_ptr: PointerValue<'ctx>,
bounds: IntValue, bounds: IntValue<'ctx>,
minimum: Pages, minimum: Pages,
maximum: Option<Pages>, maximum: Option<Pages>,
}, },
} }
struct TableCache { struct TableCache<'ctx> {
ptr_to_base_ptr: PointerValue, ptr_to_base_ptr: PointerValue<'ctx>,
ptr_to_bounds: PointerValue, ptr_to_bounds: PointerValue<'ctx>,
} }
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub enum GlobalCache { pub enum GlobalCache<'ctx> {
Mut { ptr_to_value: PointerValue }, Mut { ptr_to_value: PointerValue<'ctx> },
Const { value: BasicValueEnum }, Const { value: BasicValueEnum<'ctx> },
} }
struct ImportedFuncCache { struct ImportedFuncCache<'ctx> {
func_ptr: PointerValue, func_ptr: PointerValue<'ctx>,
ctx_ptr: PointerValue, ctx_ptr: PointerValue<'ctx>,
} }
pub struct CtxType<'a> { pub struct CtxType<'a, 'ctx> {
ctx_ptr_value: PointerValue, ctx_ptr_value: PointerValue<'ctx>,
info: &'a ModuleInfo, info: &'a ModuleInfo,
cache_builder: Builder, cache_builder: Builder<'ctx>,
cached_signal_mem: Option<PointerValue>, cached_signal_mem: Option<PointerValue<'ctx>>,
cached_memories: HashMap<MemoryIndex, MemoryCache>, cached_memories: HashMap<MemoryIndex, MemoryCache<'ctx>>,
cached_tables: HashMap<TableIndex, TableCache>, cached_tables: HashMap<TableIndex, TableCache<'ctx>>,
cached_sigindices: HashMap<SigIndex, IntValue>, cached_sigindices: HashMap<SigIndex, IntValue<'ctx>>,
cached_globals: HashMap<GlobalIndex, GlobalCache>, cached_globals: HashMap<GlobalIndex, GlobalCache<'ctx>>,
cached_imported_functions: HashMap<ImportedFuncIndex, ImportedFuncCache>, cached_imported_functions: HashMap<ImportedFuncIndex, ImportedFuncCache<'ctx>>,
_phantom: PhantomData<&'a FunctionValue>,
} }
fn offset_to_index(offset: u8) -> u32 { fn offset_to_index(offset: u8) -> u32 {
(offset as usize / ::std::mem::size_of::<usize>()) as u32 (offset as usize / ::std::mem::size_of::<usize>()) as u32
} }
impl<'a> CtxType<'a> { impl<'a, 'ctx> CtxType<'a, 'ctx> {
pub fn new( pub fn new(
info: &'a ModuleInfo, info: &'a ModuleInfo,
func_value: &'a FunctionValue, func_value: &FunctionValue<'ctx>,
cache_builder: Builder, cache_builder: Builder<'ctx>,
) -> CtxType<'a> { ) -> CtxType<'a, 'ctx> {
CtxType { CtxType {
ctx_ptr_value: func_value.get_nth_param(0).unwrap().into_pointer_value(), ctx_ptr_value: func_value.get_nth_param(0).unwrap().into_pointer_value(),
@ -633,16 +630,14 @@ impl<'a> CtxType<'a> {
cached_sigindices: HashMap::new(), cached_sigindices: HashMap::new(),
cached_globals: HashMap::new(), cached_globals: HashMap::new(),
cached_imported_functions: HashMap::new(), cached_imported_functions: HashMap::new(),
_phantom: PhantomData,
} }
} }
pub fn basic(&self) -> BasicValueEnum { pub fn basic(&self) -> BasicValueEnum<'ctx> {
self.ctx_ptr_value.as_basic_value_enum() self.ctx_ptr_value.as_basic_value_enum()
} }
pub fn signal_mem(&mut self) -> PointerValue { pub fn signal_mem(&mut self) -> PointerValue<'ctx> {
if let Some(x) = self.cached_signal_mem { if let Some(x) = self.cached_signal_mem {
return x; return x;
} }
@ -666,9 +661,9 @@ impl<'a> CtxType<'a> {
pub fn memory( pub fn memory(
&mut self, &mut self,
index: MemoryIndex, index: MemoryIndex,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
) -> MemoryCache { ) -> MemoryCache<'ctx> {
let (cached_memories, info, ctx_ptr_value, cache_builder) = ( let (cached_memories, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_memories, &mut self.cached_memories,
self.info, self.info,
@ -713,7 +708,7 @@ impl<'a> CtxType<'a> {
.build_load(memory_array_ptr_ptr, "memory_array_ptr") .build_load(memory_array_ptr_ptr, "memory_array_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
field_name, field_name,
memory_array_ptr.as_instruction_value().unwrap(), memory_array_ptr.as_instruction_value().unwrap(),
@ -731,7 +726,7 @@ impl<'a> CtxType<'a> {
.build_load(memory_ptr_ptr, "memory_ptr") .build_load(memory_ptr_ptr, "memory_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"memory_ptr", "memory_ptr",
memory_ptr.as_instruction_value().unwrap(), memory_ptr.as_instruction_value().unwrap(),
@ -760,14 +755,14 @@ impl<'a> CtxType<'a> {
.build_load(ptr_to_bounds, "bounds") .build_load(ptr_to_bounds, "bounds")
.into_int_value(); .into_int_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"static_memory_base", "static_memory_base",
base_ptr.as_instruction_value().unwrap(), base_ptr.as_instruction_value().unwrap(),
Some(index as u32), Some(index as u32),
); );
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"static_memory_bounds", "static_memory_bounds",
bounds.as_instruction_value().unwrap(), bounds.as_instruction_value().unwrap(),
@ -787,9 +782,9 @@ impl<'a> CtxType<'a> {
pub fn table_prepare( pub fn table_prepare(
&mut self, &mut self,
index: TableIndex, index: TableIndex,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
) -> (PointerValue, PointerValue) { ) -> (PointerValue<'ctx>, PointerValue<'ctx>) {
let (cached_tables, info, ctx_ptr_value, cache_builder) = ( let (cached_tables, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_tables, &mut self.cached_tables,
self.info, self.info,
@ -830,7 +825,7 @@ impl<'a> CtxType<'a> {
.build_load(table_array_ptr_ptr, "table_array_ptr") .build_load(table_array_ptr_ptr, "table_array_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
field_name, field_name,
table_array_ptr.as_instruction_value().unwrap(), table_array_ptr.as_instruction_value().unwrap(),
@ -844,7 +839,7 @@ impl<'a> CtxType<'a> {
.build_load(table_ptr_ptr, "table_ptr") .build_load(table_ptr_ptr, "table_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"table_ptr", "table_ptr",
table_array_ptr.as_instruction_value().unwrap(), table_array_ptr.as_instruction_value().unwrap(),
@ -870,10 +865,10 @@ impl<'a> CtxType<'a> {
pub fn table( pub fn table(
&mut self, &mut self,
index: TableIndex, index: TableIndex,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
builder: &Builder, builder: &Builder<'ctx>,
) -> (PointerValue, IntValue) { ) -> (PointerValue<'ctx>, IntValue<'ctx>) {
let (ptr_to_base_ptr, ptr_to_bounds) = let (ptr_to_base_ptr, ptr_to_bounds) =
self.table_prepare(index, intrinsics, module.clone()); self.table_prepare(index, intrinsics, module.clone());
let base_ptr = builder let base_ptr = builder
@ -881,14 +876,14 @@ impl<'a> CtxType<'a> {
.into_pointer_value(); .into_pointer_value();
let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value(); let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"table_base_ptr", "table_base_ptr",
base_ptr.as_instruction_value().unwrap(), base_ptr.as_instruction_value().unwrap(),
Some(index.index() as u32), Some(index.index() as u32),
); );
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"table_bounds", "table_bounds",
bounds.as_instruction_value().unwrap(), bounds.as_instruction_value().unwrap(),
@ -897,7 +892,11 @@ impl<'a> CtxType<'a> {
(base_ptr, bounds) (base_ptr, bounds)
} }
pub fn dynamic_sigindex(&mut self, index: SigIndex, intrinsics: &Intrinsics) -> IntValue { pub fn dynamic_sigindex(
&mut self,
index: SigIndex,
intrinsics: &Intrinsics<'ctx>,
) -> IntValue<'ctx> {
let (cached_sigindices, ctx_ptr_value, cache_builder) = ( let (cached_sigindices, ctx_ptr_value, cache_builder) = (
&mut self.cached_sigindices, &mut self.cached_sigindices,
self.ctx_ptr_value, self.ctx_ptr_value,
@ -934,9 +933,9 @@ impl<'a> CtxType<'a> {
pub fn global_cache( pub fn global_cache(
&mut self, &mut self,
index: GlobalIndex, index: GlobalIndex,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
) -> GlobalCache { ) -> GlobalCache<'ctx> {
let (cached_globals, ctx_ptr_value, info, cache_builder) = ( let (cached_globals, ctx_ptr_value, info, cache_builder) = (
&mut self.cached_globals, &mut self.cached_globals,
self.ctx_ptr_value, self.ctx_ptr_value,
@ -987,7 +986,7 @@ impl<'a> CtxType<'a> {
.build_load(globals_array_ptr_ptr, "global_array_ptr") .build_load(globals_array_ptr_ptr, "global_array_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
field_name, field_name,
global_array_ptr.as_instruction_value().unwrap(), global_array_ptr.as_instruction_value().unwrap(),
@ -1005,7 +1004,7 @@ impl<'a> CtxType<'a> {
.build_load(global_ptr_ptr, "global_ptr") .build_load(global_ptr_ptr, "global_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"global_ptr", "global_ptr",
global_ptr.as_instruction_value().unwrap(), global_ptr.as_instruction_value().unwrap(),
@ -1022,7 +1021,7 @@ impl<'a> CtxType<'a> {
} else { } else {
let value = cache_builder.build_load(global_ptr_typed, "global_value"); let value = cache_builder.build_load(global_ptr_typed, "global_value");
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"global", "global",
value.as_instruction_value().unwrap(), value.as_instruction_value().unwrap(),
@ -1036,9 +1035,9 @@ impl<'a> CtxType<'a> {
pub fn imported_func( pub fn imported_func(
&mut self, &mut self,
index: ImportedFuncIndex, index: ImportedFuncIndex,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
) -> (PointerValue, PointerValue) { ) -> (PointerValue<'ctx>, PointerValue<'ctx>) {
let (cached_imported_functions, ctx_ptr_value, cache_builder) = ( let (cached_imported_functions, ctx_ptr_value, cache_builder) = (
&mut self.cached_imported_functions, &mut self.cached_imported_functions,
self.ctx_ptr_value, self.ctx_ptr_value,
@ -1057,7 +1056,7 @@ impl<'a> CtxType<'a> {
.build_load(func_array_ptr_ptr, "func_array_ptr") .build_load(func_array_ptr_ptr, "func_array_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"context_field_ptr_to_imported_funcs", "context_field_ptr_to_imported_funcs",
func_array_ptr.as_instruction_value().unwrap(), func_array_ptr.as_instruction_value().unwrap(),
@ -1089,14 +1088,14 @@ impl<'a> CtxType<'a> {
.build_load(ctx_ptr_ptr, "ctx_ptr") .build_load(ctx_ptr_ptr, "ctx_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"imported_func_ptr", "imported_func_ptr",
func_ptr.as_instruction_value().unwrap(), func_ptr.as_instruction_value().unwrap(),
Some(index.index() as u32), Some(index.index() as u32),
); );
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"imported_func_ctx_ptr", "imported_func_ctx_ptr",
ctx_ptr.as_instruction_value().unwrap(), ctx_ptr.as_instruction_value().unwrap(),
@ -1112,10 +1111,10 @@ impl<'a> CtxType<'a> {
pub fn internal_field( pub fn internal_field(
&mut self, &mut self,
index: usize, index: usize,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module>>, module: Rc<RefCell<Module<'ctx>>>,
builder: &Builder, builder: &Builder<'ctx>,
) -> PointerValue { ) -> PointerValue<'ctx> {
assert!(index < INTERNALS_SIZE); assert!(index < INTERNALS_SIZE);
let local_internals_ptr_ptr = unsafe { let local_internals_ptr_ptr = unsafe {
@ -1129,7 +1128,7 @@ impl<'a> CtxType<'a> {
.build_load(local_internals_ptr_ptr, "local_internals_ptr") .build_load(local_internals_ptr_ptr, "local_internals_ptr")
.into_pointer_value(); .into_pointer_value();
tbaa_label( tbaa_label(
module.clone(), &module,
intrinsics, intrinsics,
"context_field_ptr_to_internals", "context_field_ptr_to_internals",
local_internals_ptr.as_instruction_value().unwrap(), local_internals_ptr.as_instruction_value().unwrap(),
@ -1147,11 +1146,11 @@ impl<'a> CtxType<'a> {
// Given an instruction that operates on memory, mark the access as not aliasing // Given an instruction that operates on memory, mark the access as not aliasing
// other memory accesses which have a different (label, index) pair. // other memory accesses which have a different (label, index) pair.
pub fn tbaa_label( pub fn tbaa_label<'ctx>(
module: Rc<RefCell<Module>>, module: &Rc<RefCell<Module<'ctx>>>,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
label: &str, label: &str,
instruction: InstructionValue, instruction: InstructionValue<'ctx>,
index: Option<u32>, index: Option<u32>,
) { ) {
// To convey to LLVM that two pointers must be pointing to distinct memory, // To convey to LLVM that two pointers must be pointing to distinct memory,
@ -1170,6 +1169,12 @@ pub fn tbaa_label(
let module = module.borrow_mut(); let module = module.borrow_mut();
let context = module.get_context(); let context = module.get_context();
// TODO: ContextRef can't return us the lifetime from module through Deref.
// This could be fixed once generic_associated_types is stable.
let context2 = &*context;
let context = unsafe { std::mem::transmute::<&Context, &'ctx Context>(context2) };
std::mem::forget(context2);
// `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer. // `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer.
let tbaa_root = module let tbaa_root = module
.get_global_metadata("wasmer_tbaa_root") .get_global_metadata("wasmer_tbaa_root")

View File

@ -29,8 +29,8 @@ pub use code::LLVMModuleCodeGenerator as ModuleCodeGenerator;
use wasmer_runtime_core::codegen::SimpleStreamingCompilerGen; use wasmer_runtime_core::codegen::SimpleStreamingCompilerGen;
pub type LLVMCompiler = SimpleStreamingCompilerGen< pub type LLVMCompiler = SimpleStreamingCompilerGen<
code::LLVMModuleCodeGenerator, code::LLVMModuleCodeGenerator<'static>,
code::LLVMFunctionCodeGenerator, code::LLVMFunctionCodeGenerator<'static>,
backend::LLVMBackend, backend::LLVMBackend,
code::CodegenError, code::CodegenError,
>; >;

View File

@ -8,23 +8,23 @@ use std::ops::{BitAnd, BitOr, BitOrAssign};
use wasmparser::BinaryReaderError; use wasmparser::BinaryReaderError;
#[derive(Debug)] #[derive(Debug)]
pub enum ControlFrame { pub enum ControlFrame<'ctx> {
Block { Block {
next: BasicBlock, next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>, phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize, stack_size_snapshot: usize,
}, },
Loop { Loop {
body: BasicBlock, body: BasicBlock,
next: BasicBlock, next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>, phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize, stack_size_snapshot: usize,
}, },
IfElse { IfElse {
if_then: BasicBlock, if_then: BasicBlock,
if_else: BasicBlock, if_else: BasicBlock,
next: BasicBlock, next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>, phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize, stack_size_snapshot: usize,
if_else_state: IfElseState, if_else_state: IfElseState,
}, },
@ -36,7 +36,7 @@ pub enum IfElseState {
Else, Else,
} }
impl ControlFrame { impl<'ctx> ControlFrame<'ctx> {
pub fn code_after(&self) -> &BasicBlock { pub fn code_after(&self) -> &BasicBlock {
match self { match self {
ControlFrame::Block { ref next, .. } ControlFrame::Block { ref next, .. }
@ -52,7 +52,7 @@ impl ControlFrame {
} }
} }
pub fn phis(&self) -> &[PhiValue] { pub fn phis(&self) -> &[PhiValue<'ctx>] {
match self { match self {
ControlFrame::Block { ref phis, .. } ControlFrame::Block { ref phis, .. }
| ControlFrame::Loop { ref phis, .. } | ControlFrame::Loop { ref phis, .. }
@ -193,15 +193,15 @@ impl BitAnd for ExtraInfo {
} }
#[derive(Debug)] #[derive(Debug)]
pub struct State { pub struct State<'ctx> {
pub stack: Vec<(BasicValueEnum, ExtraInfo)>, pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
control_stack: Vec<ControlFrame>, control_stack: Vec<ControlFrame<'ctx>>,
value_counter: Cell<usize>, value_counter: Cell<usize>,
pub reachable: bool, pub reachable: bool,
} }
impl State { impl<'ctx> State<'ctx> {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
stack: vec![], stack: vec![],
@ -211,7 +211,7 @@ impl State {
} }
} }
pub fn reset_stack(&mut self, frame: &ControlFrame) { pub fn reset_stack(&mut self, frame: &ControlFrame<'ctx>) {
let stack_size_snapshot = match frame { let stack_size_snapshot = match frame {
ControlFrame::Block { ControlFrame::Block {
stack_size_snapshot, stack_size_snapshot,
@ -229,14 +229,14 @@ impl State {
self.stack.truncate(stack_size_snapshot); self.stack.truncate(stack_size_snapshot);
} }
pub fn outermost_frame(&self) -> Result<&ControlFrame, BinaryReaderError> { pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, BinaryReaderError> {
self.control_stack.get(0).ok_or(BinaryReaderError { self.control_stack.get(0).ok_or(BinaryReaderError {
message: "invalid control stack depth", message: "invalid control stack depth",
offset: -1isize as usize, offset: -1isize as usize,
}) })
} }
pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame, BinaryReaderError> { pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, BinaryReaderError> {
let index = self.control_stack.len() - 1 - (depth as usize); let index = self.control_stack.len() - 1 - (depth as usize);
self.control_stack.get(index).ok_or(BinaryReaderError { self.control_stack.get(index).ok_or(BinaryReaderError {
message: "invalid control stack depth", message: "invalid control stack depth",
@ -247,7 +247,7 @@ impl State {
pub fn frame_at_depth_mut( pub fn frame_at_depth_mut(
&mut self, &mut self,
depth: u32, depth: u32,
) -> Result<&mut ControlFrame, BinaryReaderError> { ) -> Result<&mut ControlFrame<'ctx>, BinaryReaderError> {
let index = self.control_stack.len() - 1 - (depth as usize); let index = self.control_stack.len() - 1 - (depth as usize);
self.control_stack.get_mut(index).ok_or(BinaryReaderError { self.control_stack.get_mut(index).ok_or(BinaryReaderError {
message: "invalid control stack depth", message: "invalid control stack depth",
@ -255,7 +255,7 @@ impl State {
}) })
} }
pub fn pop_frame(&mut self) -> Result<ControlFrame, BinaryReaderError> { pub fn pop_frame(&mut self) -> Result<ControlFrame<'ctx>, BinaryReaderError> {
self.control_stack.pop().ok_or(BinaryReaderError { self.control_stack.pop().ok_or(BinaryReaderError {
message: "cannot pop from control stack", message: "cannot pop from control stack",
offset: -1isize as usize, offset: -1isize as usize,
@ -269,26 +269,28 @@ impl State {
s s
} }
pub fn push1<T: BasicValue>(&mut self, value: T) { pub fn push1<T: BasicValue<'ctx>>(&mut self, value: T) {
self.push1_extra(value, Default::default()); self.push1_extra(value, Default::default());
} }
pub fn push1_extra<T: BasicValue>(&mut self, value: T, info: ExtraInfo) { pub fn push1_extra<T: BasicValue<'ctx>>(&mut self, value: T, info: ExtraInfo) {
self.stack.push((value.as_basic_value_enum(), info)); self.stack.push((value.as_basic_value_enum(), info));
} }
pub fn pop1(&mut self) -> Result<BasicValueEnum, BinaryReaderError> { pub fn pop1(&mut self) -> Result<BasicValueEnum<'ctx>, BinaryReaderError> {
Ok(self.pop1_extra()?.0) Ok(self.pop1_extra()?.0)
} }
pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum, ExtraInfo), BinaryReaderError> { pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> {
self.stack.pop().ok_or(BinaryReaderError { self.stack.pop().ok_or(BinaryReaderError {
message: "invalid value stack", message: "invalid value stack",
offset: -1isize as usize, offset: -1isize as usize,
}) })
} }
pub fn pop2(&mut self) -> Result<(BasicValueEnum, BasicValueEnum), BinaryReaderError> { pub fn pop2(
&mut self,
) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), BinaryReaderError> {
let v2 = self.pop1()?; let v2 = self.pop1()?;
let v1 = self.pop1()?; let v1 = self.pop1()?;
Ok((v1, v2)) Ok((v1, v2))
@ -296,7 +298,13 @@ impl State {
pub fn pop2_extra( pub fn pop2_extra(
&mut self, &mut self,
) -> Result<((BasicValueEnum, ExtraInfo), (BasicValueEnum, ExtraInfo)), BinaryReaderError> { ) -> Result<
(
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
),
BinaryReaderError,
> {
let v2 = self.pop1_extra()?; let v2 = self.pop1_extra()?;
let v1 = self.pop1_extra()?; let v1 = self.pop1_extra()?;
Ok((v1, v2)) Ok((v1, v2))
@ -306,9 +314,9 @@ impl State {
&mut self, &mut self,
) -> Result< ) -> Result<
( (
(BasicValueEnum, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
), ),
BinaryReaderError, BinaryReaderError,
> { > {
@ -318,7 +326,7 @@ impl State {
Ok((v1, v2, v3)) Ok((v1, v2, v3))
} }
pub fn peek1_extra(&self) -> Result<(BasicValueEnum, ExtraInfo), BinaryReaderError> { pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> {
self.stack self.stack
.get(self.stack.len() - 1) .get(self.stack.len() - 1)
.ok_or(BinaryReaderError { .ok_or(BinaryReaderError {
@ -328,14 +336,14 @@ impl State {
.map(|v| *v) .map(|v| *v)
} }
pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum>, BinaryReaderError> { pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum<'ctx>>, BinaryReaderError> {
Ok(self.peekn_extra(n)?.iter().map(|x| x.0).collect()) Ok(self.peekn_extra(n)?.iter().map(|x| x.0).collect())
} }
pub fn peekn_extra( pub fn peekn_extra(
&self, &self,
n: usize, n: usize,
) -> Result<&[(BasicValueEnum, ExtraInfo)], BinaryReaderError> { ) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], BinaryReaderError> {
let new_len = self.stack.len().checked_sub(n).ok_or(BinaryReaderError { let new_len = self.stack.len().checked_sub(n).ok_or(BinaryReaderError {
message: "invalid value stack", message: "invalid value stack",
offset: -1isize as usize, offset: -1isize as usize,
@ -347,7 +355,7 @@ impl State {
pub fn popn_save_extra( pub fn popn_save_extra(
&mut self, &mut self,
n: usize, n: usize,
) -> Result<Vec<(BasicValueEnum, ExtraInfo)>, BinaryReaderError> { ) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, BinaryReaderError> {
let v = self.peekn_extra(n)?.to_vec(); let v = self.peekn_extra(n)?.to_vec();
self.popn(n)?; self.popn(n)?;
Ok(v) Ok(v)
@ -366,7 +374,7 @@ impl State {
Ok(()) Ok(())
} }
pub fn push_block(&mut self, next: BasicBlock, phis: SmallVec<[PhiValue; 1]>) { pub fn push_block(&mut self, next: BasicBlock, phis: SmallVec<[PhiValue<'ctx>; 1]>) {
self.control_stack.push(ControlFrame::Block { self.control_stack.push(ControlFrame::Block {
next, next,
phis, phis,
@ -374,7 +382,12 @@ impl State {
}); });
} }
pub fn push_loop(&mut self, body: BasicBlock, next: BasicBlock, phis: SmallVec<[PhiValue; 1]>) { pub fn push_loop(
&mut self,
body: BasicBlock,
next: BasicBlock,
phis: SmallVec<[PhiValue<'ctx>; 1]>,
) {
self.control_stack.push(ControlFrame::Loop { self.control_stack.push(ControlFrame::Loop {
body, body,
next, next,
@ -388,7 +401,7 @@ impl State {
if_then: BasicBlock, if_then: BasicBlock,
if_else: BasicBlock, if_else: BasicBlock,
next: BasicBlock, next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>, phis: SmallVec<[PhiValue<'ctx>; 1]>,
) { ) {
self.control_stack.push(ControlFrame::IfElse { self.control_stack.push(ControlFrame::IfElse {
if_then, if_then,

View File

@ -13,13 +13,13 @@ use wasmer_runtime_core::{
types::{FuncSig, SigIndex, Type}, types::{FuncSig, SigIndex, Type},
}; };
pub fn generate_trampolines( pub fn generate_trampolines<'ctx>(
info: &ModuleInfo, info: &ModuleInfo,
signatures: &SliceMap<SigIndex, FunctionType>, signatures: &SliceMap<SigIndex, FunctionType<'ctx>>,
module: &Module, module: &Module<'ctx>,
context: &Context, context: &'ctx Context,
builder: &Builder, builder: &Builder<'ctx>,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
) -> Result<(), String> { ) -> Result<(), String> {
for (sig_index, sig) in info.signatures.iter() { for (sig_index, sig) in info.signatures.iter() {
let func_type = signatures[sig_index]; let func_type = signatures[sig_index];
@ -47,14 +47,14 @@ pub fn generate_trampolines(
Ok(()) Ok(())
} }
fn generate_trampoline( fn generate_trampoline<'ctx>(
trampoline_func: FunctionValue, trampoline_func: FunctionValue,
func_sig: &FuncSig, func_sig: &FuncSig,
context: &Context, context: &'ctx Context,
builder: &Builder, builder: &Builder<'ctx>,
intrinsics: &Intrinsics, intrinsics: &Intrinsics<'ctx>,
) -> Result<(), String> { ) -> Result<(), String> {
let entry_block = context.append_basic_block(&trampoline_func, "entry"); let entry_block = context.append_basic_block(trampoline_func, "entry");
builder.position_at_end(&entry_block); builder.position_at_end(&entry_block);
let (vmctx_ptr, func_ptr, args_ptr, returns_ptr) = match trampoline_func.get_params().as_slice() let (vmctx_ptr, func_ptr, args_ptr, returns_ptr) = match trampoline_func.get_params().as_slice()