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"
[dependencies.inkwell]
git = "https://github.com/wasmerio/inkwell"
branch = "llvm8-0"
git = "https://github.com/TheDan64/inkwell"
rev = "781620e9fa30e51a6e03bd0d49b5f5bb7a782520"
default-features = false
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::collections::HashMap;
use std::marker::PhantomData;
use std::rc::Rc;
use wasmer_runtime_core::{
memory::MemoryType,
@ -25,7 +24,7 @@ use wasmer_runtime_core::{
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 {
Type::I32 => intrinsics.i32_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 ctlz_i32: FunctionValue,
pub ctlz_i64: FunctionValue,
pub struct Intrinsics<'ctx> {
pub ctlz_i32: FunctionValue<'ctx>,
pub ctlz_i64: FunctionValue<'ctx>,
pub cttz_i32: FunctionValue,
pub cttz_i64: FunctionValue,
pub cttz_i32: FunctionValue<'ctx>,
pub cttz_i64: FunctionValue<'ctx>,
pub ctpop_i32: FunctionValue,
pub ctpop_i64: FunctionValue,
pub ctpop_i32: FunctionValue<'ctx>,
pub ctpop_i64: FunctionValue<'ctx>,
pub sqrt_f32: FunctionValue,
pub sqrt_f64: FunctionValue,
pub sqrt_f32x4: FunctionValue,
pub sqrt_f64x2: FunctionValue,
pub sqrt_f32: FunctionValue<'ctx>,
pub sqrt_f64: FunctionValue<'ctx>,
pub sqrt_f32x4: FunctionValue<'ctx>,
pub sqrt_f64x2: FunctionValue<'ctx>,
pub ceil_f32: FunctionValue,
pub ceil_f64: FunctionValue,
pub ceil_f32: FunctionValue<'ctx>,
pub ceil_f64: FunctionValue<'ctx>,
pub floor_f32: FunctionValue,
pub floor_f64: FunctionValue,
pub floor_f32: FunctionValue<'ctx>,
pub floor_f64: FunctionValue<'ctx>,
pub trunc_f32: FunctionValue,
pub trunc_f64: FunctionValue,
pub trunc_f32: FunctionValue<'ctx>,
pub trunc_f64: FunctionValue<'ctx>,
pub nearbyint_f32: FunctionValue,
pub nearbyint_f64: FunctionValue,
pub nearbyint_f32: FunctionValue<'ctx>,
pub nearbyint_f64: FunctionValue<'ctx>,
pub fabs_f32: FunctionValue,
pub fabs_f64: FunctionValue,
pub fabs_f32x4: FunctionValue,
pub fabs_f64x2: FunctionValue,
pub fabs_f32: FunctionValue<'ctx>,
pub fabs_f64: FunctionValue<'ctx>,
pub fabs_f32x4: FunctionValue<'ctx>,
pub fabs_f64x2: FunctionValue<'ctx>,
pub copysign_f32: FunctionValue,
pub copysign_f64: FunctionValue,
pub copysign_f32: FunctionValue<'ctx>,
pub copysign_f64: FunctionValue<'ctx>,
pub sadd_sat_i8x16: FunctionValue,
pub sadd_sat_i16x8: FunctionValue,
pub uadd_sat_i8x16: FunctionValue,
pub uadd_sat_i16x8: FunctionValue,
pub sadd_sat_i8x16: FunctionValue<'ctx>,
pub sadd_sat_i16x8: FunctionValue<'ctx>,
pub uadd_sat_i8x16: FunctionValue<'ctx>,
pub uadd_sat_i16x8: FunctionValue<'ctx>,
pub ssub_sat_i8x16: FunctionValue,
pub ssub_sat_i16x8: FunctionValue,
pub usub_sat_i8x16: FunctionValue,
pub usub_sat_i16x8: FunctionValue,
pub ssub_sat_i8x16: FunctionValue<'ctx>,
pub ssub_sat_i16x8: FunctionValue<'ctx>,
pub usub_sat_i8x16: FunctionValue<'ctx>,
pub usub_sat_i16x8: FunctionValue<'ctx>,
pub expect_i1: FunctionValue,
pub trap: FunctionValue,
pub expect_i1: FunctionValue<'ctx>,
pub trap: FunctionValue<'ctx>,
pub void_ty: VoidType,
pub i1_ty: IntType,
pub i8_ty: IntType,
pub i16_ty: IntType,
pub i32_ty: IntType,
pub i64_ty: IntType,
pub i128_ty: IntType,
pub f32_ty: FloatType,
pub f64_ty: FloatType,
pub void_ty: VoidType<'ctx>,
pub i1_ty: IntType<'ctx>,
pub i8_ty: IntType<'ctx>,
pub i16_ty: IntType<'ctx>,
pub i32_ty: IntType<'ctx>,
pub i64_ty: IntType<'ctx>,
pub i128_ty: IntType<'ctx>,
pub f32_ty: FloatType<'ctx>,
pub f64_ty: FloatType<'ctx>,
pub i1x128_ty: VectorType,
pub i8x16_ty: VectorType,
pub i16x8_ty: VectorType,
pub i32x4_ty: VectorType,
pub i64x2_ty: VectorType,
pub f32x4_ty: VectorType,
pub f64x2_ty: VectorType,
pub i1x128_ty: VectorType<'ctx>,
pub i8x16_ty: VectorType<'ctx>,
pub i16x8_ty: VectorType<'ctx>,
pub i32x4_ty: VectorType<'ctx>,
pub i64x2_ty: VectorType<'ctx>,
pub f32x4_ty: VectorType<'ctx>,
pub f64x2_ty: VectorType<'ctx>,
pub i8_ptr_ty: PointerType,
pub i16_ptr_ty: PointerType,
pub i32_ptr_ty: PointerType,
pub i64_ptr_ty: PointerType,
pub i128_ptr_ty: PointerType,
pub f32_ptr_ty: PointerType,
pub f64_ptr_ty: PointerType,
pub i8_ptr_ty: PointerType<'ctx>,
pub i16_ptr_ty: PointerType<'ctx>,
pub i32_ptr_ty: PointerType<'ctx>,
pub i64_ptr_ty: PointerType<'ctx>,
pub i128_ptr_ty: PointerType<'ctx>,
pub f32_ptr_ty: PointerType<'ctx>,
pub f64_ptr_ty: PointerType<'ctx>,
pub anyfunc_ty: StructType,
pub anyfunc_ty: StructType<'ctx>,
pub i1_zero: IntValue,
pub i8_zero: IntValue,
pub i32_zero: IntValue,
pub i64_zero: IntValue,
pub i128_zero: IntValue,
pub f32_zero: FloatValue,
pub f64_zero: FloatValue,
pub f32x4_zero: VectorValue,
pub f64x2_zero: VectorValue,
pub i1_zero: IntValue<'ctx>,
pub i8_zero: IntValue<'ctx>,
pub i32_zero: IntValue<'ctx>,
pub i64_zero: IntValue<'ctx>,
pub i128_zero: IntValue<'ctx>,
pub f32_zero: FloatValue<'ctx>,
pub f64_zero: FloatValue<'ctx>,
pub f32x4_zero: VectorValue<'ctx>,
pub f64x2_zero: VectorValue<'ctx>,
pub trap_unreachable: BasicValueEnum,
pub trap_call_indirect_sig: BasicValueEnum,
pub trap_call_indirect_oob: BasicValueEnum,
pub trap_memory_oob: BasicValueEnum,
pub trap_illegal_arithmetic: BasicValueEnum,
pub trap_misaligned_atomic: BasicValueEnum,
pub trap_unreachable: BasicValueEnum<'ctx>,
pub trap_call_indirect_sig: BasicValueEnum<'ctx>,
pub trap_call_indirect_oob: BasicValueEnum<'ctx>,
pub trap_memory_oob: BasicValueEnum<'ctx>,
pub trap_illegal_arithmetic: BasicValueEnum<'ctx>,
pub trap_misaligned_atomic: BasicValueEnum<'ctx>,
// VM intrinsics.
pub memory_grow_dynamic_local: FunctionValue,
pub memory_grow_static_local: FunctionValue,
pub memory_grow_shared_local: FunctionValue,
pub memory_grow_dynamic_import: FunctionValue,
pub memory_grow_static_import: FunctionValue,
pub memory_grow_shared_import: FunctionValue,
pub memory_grow_dynamic_local: FunctionValue<'ctx>,
pub memory_grow_static_local: FunctionValue<'ctx>,
pub memory_grow_shared_local: FunctionValue<'ctx>,
pub memory_grow_dynamic_import: FunctionValue<'ctx>,
pub memory_grow_static_import: FunctionValue<'ctx>,
pub memory_grow_shared_import: FunctionValue<'ctx>,
pub memory_size_dynamic_local: FunctionValue,
pub memory_size_static_local: FunctionValue,
pub memory_size_shared_local: FunctionValue,
pub memory_size_dynamic_import: FunctionValue,
pub memory_size_static_import: FunctionValue,
pub memory_size_shared_import: FunctionValue,
pub memory_size_dynamic_local: FunctionValue<'ctx>,
pub memory_size_static_local: FunctionValue<'ctx>,
pub memory_size_shared_local: FunctionValue<'ctx>,
pub memory_size_dynamic_import: FunctionValue<'ctx>,
pub memory_size_static_import: FunctionValue<'ctx>,
pub memory_size_shared_import: FunctionValue<'ctx>,
pub throw_trap: FunctionValue,
pub throw_breakpoint: FunctionValue,
pub throw_trap: FunctionValue<'ctx>,
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 {
pub fn declare(module: &Module, context: &Context) -> Self {
impl<'ctx> Intrinsics<'ctx> {
pub fn declare(module: &Module<'ctx>, context: &'ctx Context) -> Self {
let void_ty = context.void_type();
let i1_ty = context.bool_type();
let i8_ty = context.i8_type();
@ -560,66 +559,64 @@ impl Intrinsics {
}
#[derive(Clone, Copy)]
pub enum MemoryCache {
pub enum MemoryCache<'ctx> {
/// The memory moves around.
Dynamic {
ptr_to_base_ptr: PointerValue,
ptr_to_bounds: PointerValue,
ptr_to_base_ptr: PointerValue<'ctx>,
ptr_to_bounds: PointerValue<'ctx>,
minimum: Pages,
maximum: Option<Pages>,
},
/// The memory is always in the same place.
Static {
base_ptr: PointerValue,
bounds: IntValue,
base_ptr: PointerValue<'ctx>,
bounds: IntValue<'ctx>,
minimum: Pages,
maximum: Option<Pages>,
},
}
struct TableCache {
ptr_to_base_ptr: PointerValue,
ptr_to_bounds: PointerValue,
struct TableCache<'ctx> {
ptr_to_base_ptr: PointerValue<'ctx>,
ptr_to_bounds: PointerValue<'ctx>,
}
#[derive(Clone, Copy)]
pub enum GlobalCache {
Mut { ptr_to_value: PointerValue },
Const { value: BasicValueEnum },
pub enum GlobalCache<'ctx> {
Mut { ptr_to_value: PointerValue<'ctx> },
Const { value: BasicValueEnum<'ctx> },
}
struct ImportedFuncCache {
func_ptr: PointerValue,
ctx_ptr: PointerValue,
struct ImportedFuncCache<'ctx> {
func_ptr: PointerValue<'ctx>,
ctx_ptr: PointerValue<'ctx>,
}
pub struct CtxType<'a> {
ctx_ptr_value: PointerValue,
pub struct CtxType<'a, 'ctx> {
ctx_ptr_value: PointerValue<'ctx>,
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_tables: HashMap<TableIndex, TableCache>,
cached_sigindices: HashMap<SigIndex, IntValue>,
cached_globals: HashMap<GlobalIndex, GlobalCache>,
cached_imported_functions: HashMap<ImportedFuncIndex, ImportedFuncCache>,
_phantom: PhantomData<&'a FunctionValue>,
cached_memories: HashMap<MemoryIndex, MemoryCache<'ctx>>,
cached_tables: HashMap<TableIndex, TableCache<'ctx>>,
cached_sigindices: HashMap<SigIndex, IntValue<'ctx>>,
cached_globals: HashMap<GlobalIndex, GlobalCache<'ctx>>,
cached_imported_functions: HashMap<ImportedFuncIndex, ImportedFuncCache<'ctx>>,
}
fn offset_to_index(offset: u8) -> u32 {
(offset as usize / ::std::mem::size_of::<usize>()) as u32
}
impl<'a> CtxType<'a> {
impl<'a, 'ctx> CtxType<'a, 'ctx> {
pub fn new(
info: &'a ModuleInfo,
func_value: &'a FunctionValue,
cache_builder: Builder,
) -> CtxType<'a> {
func_value: &FunctionValue<'ctx>,
cache_builder: Builder<'ctx>,
) -> CtxType<'a, 'ctx> {
CtxType {
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_globals: 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()
}
pub fn signal_mem(&mut self) -> PointerValue {
pub fn signal_mem(&mut self) -> PointerValue<'ctx> {
if let Some(x) = self.cached_signal_mem {
return x;
}
@ -666,9 +661,9 @@ impl<'a> CtxType<'a> {
pub fn memory(
&mut self,
index: MemoryIndex,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
) -> MemoryCache {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
) -> MemoryCache<'ctx> {
let (cached_memories, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_memories,
self.info,
@ -713,7 +708,7 @@ impl<'a> CtxType<'a> {
.build_load(memory_array_ptr_ptr, "memory_array_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
field_name,
memory_array_ptr.as_instruction_value().unwrap(),
@ -731,7 +726,7 @@ impl<'a> CtxType<'a> {
.build_load(memory_ptr_ptr, "memory_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"memory_ptr",
memory_ptr.as_instruction_value().unwrap(),
@ -760,14 +755,14 @@ impl<'a> CtxType<'a> {
.build_load(ptr_to_bounds, "bounds")
.into_int_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"static_memory_base",
base_ptr.as_instruction_value().unwrap(),
Some(index as u32),
);
tbaa_label(
module.clone(),
&module,
intrinsics,
"static_memory_bounds",
bounds.as_instruction_value().unwrap(),
@ -787,9 +782,9 @@ impl<'a> CtxType<'a> {
pub fn table_prepare(
&mut self,
index: TableIndex,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
) -> (PointerValue, PointerValue) {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
) -> (PointerValue<'ctx>, PointerValue<'ctx>) {
let (cached_tables, info, ctx_ptr_value, cache_builder) = (
&mut self.cached_tables,
self.info,
@ -830,7 +825,7 @@ impl<'a> CtxType<'a> {
.build_load(table_array_ptr_ptr, "table_array_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
field_name,
table_array_ptr.as_instruction_value().unwrap(),
@ -844,7 +839,7 @@ impl<'a> CtxType<'a> {
.build_load(table_ptr_ptr, "table_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"table_ptr",
table_array_ptr.as_instruction_value().unwrap(),
@ -870,10 +865,10 @@ impl<'a> CtxType<'a> {
pub fn table(
&mut self,
index: TableIndex,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
builder: &Builder,
) -> (PointerValue, IntValue) {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
builder: &Builder<'ctx>,
) -> (PointerValue<'ctx>, IntValue<'ctx>) {
let (ptr_to_base_ptr, ptr_to_bounds) =
self.table_prepare(index, intrinsics, module.clone());
let base_ptr = builder
@ -881,14 +876,14 @@ impl<'a> CtxType<'a> {
.into_pointer_value();
let bounds = builder.build_load(ptr_to_bounds, "bounds").into_int_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"table_base_ptr",
base_ptr.as_instruction_value().unwrap(),
Some(index.index() as u32),
);
tbaa_label(
module.clone(),
&module,
intrinsics,
"table_bounds",
bounds.as_instruction_value().unwrap(),
@ -897,7 +892,11 @@ impl<'a> CtxType<'a> {
(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) = (
&mut self.cached_sigindices,
self.ctx_ptr_value,
@ -934,9 +933,9 @@ impl<'a> CtxType<'a> {
pub fn global_cache(
&mut self,
index: GlobalIndex,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
) -> GlobalCache {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
) -> GlobalCache<'ctx> {
let (cached_globals, ctx_ptr_value, info, cache_builder) = (
&mut self.cached_globals,
self.ctx_ptr_value,
@ -987,7 +986,7 @@ impl<'a> CtxType<'a> {
.build_load(globals_array_ptr_ptr, "global_array_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
field_name,
global_array_ptr.as_instruction_value().unwrap(),
@ -1005,7 +1004,7 @@ impl<'a> CtxType<'a> {
.build_load(global_ptr_ptr, "global_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"global_ptr",
global_ptr.as_instruction_value().unwrap(),
@ -1022,7 +1021,7 @@ impl<'a> CtxType<'a> {
} else {
let value = cache_builder.build_load(global_ptr_typed, "global_value");
tbaa_label(
module.clone(),
&module,
intrinsics,
"global",
value.as_instruction_value().unwrap(),
@ -1036,9 +1035,9 @@ impl<'a> CtxType<'a> {
pub fn imported_func(
&mut self,
index: ImportedFuncIndex,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
) -> (PointerValue, PointerValue) {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
) -> (PointerValue<'ctx>, PointerValue<'ctx>) {
let (cached_imported_functions, ctx_ptr_value, cache_builder) = (
&mut self.cached_imported_functions,
self.ctx_ptr_value,
@ -1057,7 +1056,7 @@ impl<'a> CtxType<'a> {
.build_load(func_array_ptr_ptr, "func_array_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"context_field_ptr_to_imported_funcs",
func_array_ptr.as_instruction_value().unwrap(),
@ -1089,14 +1088,14 @@ impl<'a> CtxType<'a> {
.build_load(ctx_ptr_ptr, "ctx_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"imported_func_ptr",
func_ptr.as_instruction_value().unwrap(),
Some(index.index() as u32),
);
tbaa_label(
module.clone(),
&module,
intrinsics,
"imported_func_ctx_ptr",
ctx_ptr.as_instruction_value().unwrap(),
@ -1112,10 +1111,10 @@ impl<'a> CtxType<'a> {
pub fn internal_field(
&mut self,
index: usize,
intrinsics: &Intrinsics,
module: Rc<RefCell<Module>>,
builder: &Builder,
) -> PointerValue {
intrinsics: &Intrinsics<'ctx>,
module: Rc<RefCell<Module<'ctx>>>,
builder: &Builder<'ctx>,
) -> PointerValue<'ctx> {
assert!(index < INTERNALS_SIZE);
let local_internals_ptr_ptr = unsafe {
@ -1129,7 +1128,7 @@ impl<'a> CtxType<'a> {
.build_load(local_internals_ptr_ptr, "local_internals_ptr")
.into_pointer_value();
tbaa_label(
module.clone(),
&module,
intrinsics,
"context_field_ptr_to_internals",
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
// other memory accesses which have a different (label, index) pair.
pub fn tbaa_label(
module: Rc<RefCell<Module>>,
intrinsics: &Intrinsics,
pub fn tbaa_label<'ctx>(
module: &Rc<RefCell<Module<'ctx>>>,
intrinsics: &Intrinsics<'ctx>,
label: &str,
instruction: InstructionValue,
instruction: InstructionValue<'ctx>,
index: Option<u32>,
) {
// 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 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.
let tbaa_root = module
.get_global_metadata("wasmer_tbaa_root")

View File

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

View File

@ -8,23 +8,23 @@ use std::ops::{BitAnd, BitOr, BitOrAssign};
use wasmparser::BinaryReaderError;
#[derive(Debug)]
pub enum ControlFrame {
pub enum ControlFrame<'ctx> {
Block {
next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>,
phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize,
},
Loop {
body: BasicBlock,
next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>,
phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize,
},
IfElse {
if_then: BasicBlock,
if_else: BasicBlock,
next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>,
phis: SmallVec<[PhiValue<'ctx>; 1]>,
stack_size_snapshot: usize,
if_else_state: IfElseState,
},
@ -36,7 +36,7 @@ pub enum IfElseState {
Else,
}
impl ControlFrame {
impl<'ctx> ControlFrame<'ctx> {
pub fn code_after(&self) -> &BasicBlock {
match self {
ControlFrame::Block { ref next, .. }
@ -52,7 +52,7 @@ impl ControlFrame {
}
}
pub fn phis(&self) -> &[PhiValue] {
pub fn phis(&self) -> &[PhiValue<'ctx>] {
match self {
ControlFrame::Block { ref phis, .. }
| ControlFrame::Loop { ref phis, .. }
@ -193,15 +193,15 @@ impl BitAnd for ExtraInfo {
}
#[derive(Debug)]
pub struct State {
pub stack: Vec<(BasicValueEnum, ExtraInfo)>,
control_stack: Vec<ControlFrame>,
pub struct State<'ctx> {
pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
control_stack: Vec<ControlFrame<'ctx>>,
value_counter: Cell<usize>,
pub reachable: bool,
}
impl State {
impl<'ctx> State<'ctx> {
pub fn new() -> Self {
Self {
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 {
ControlFrame::Block {
stack_size_snapshot,
@ -229,14 +229,14 @@ impl State {
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 {
message: "invalid control stack depth",
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);
self.control_stack.get(index).ok_or(BinaryReaderError {
message: "invalid control stack depth",
@ -247,7 +247,7 @@ impl State {
pub fn frame_at_depth_mut(
&mut self,
depth: u32,
) -> Result<&mut ControlFrame, BinaryReaderError> {
) -> Result<&mut ControlFrame<'ctx>, BinaryReaderError> {
let index = self.control_stack.len() - 1 - (depth as usize);
self.control_stack.get_mut(index).ok_or(BinaryReaderError {
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 {
message: "cannot pop from control stack",
offset: -1isize as usize,
@ -269,26 +269,28 @@ impl State {
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());
}
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));
}
pub fn pop1(&mut self) -> Result<BasicValueEnum, BinaryReaderError> {
pub fn pop1(&mut self) -> Result<BasicValueEnum<'ctx>, BinaryReaderError> {
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 {
message: "invalid value stack",
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 v1 = self.pop1()?;
Ok((v1, v2))
@ -296,7 +298,13 @@ impl State {
pub fn pop2_extra(
&mut self,
) -> Result<((BasicValueEnum, ExtraInfo), (BasicValueEnum, ExtraInfo)), BinaryReaderError> {
) -> Result<
(
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
),
BinaryReaderError,
> {
let v2 = self.pop1_extra()?;
let v1 = self.pop1_extra()?;
Ok((v1, v2))
@ -306,9 +314,9 @@ impl State {
&mut self,
) -> Result<
(
(BasicValueEnum, ExtraInfo),
(BasicValueEnum, ExtraInfo),
(BasicValueEnum, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
),
BinaryReaderError,
> {
@ -318,7 +326,7 @@ impl State {
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
.get(self.stack.len() - 1)
.ok_or(BinaryReaderError {
@ -328,14 +336,14 @@ impl State {
.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())
}
pub fn peekn_extra(
&self,
n: usize,
) -> Result<&[(BasicValueEnum, ExtraInfo)], BinaryReaderError> {
) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], BinaryReaderError> {
let new_len = self.stack.len().checked_sub(n).ok_or(BinaryReaderError {
message: "invalid value stack",
offset: -1isize as usize,
@ -347,7 +355,7 @@ impl State {
pub fn popn_save_extra(
&mut self,
n: usize,
) -> Result<Vec<(BasicValueEnum, ExtraInfo)>, BinaryReaderError> {
) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, BinaryReaderError> {
let v = self.peekn_extra(n)?.to_vec();
self.popn(n)?;
Ok(v)
@ -366,7 +374,7 @@ impl State {
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 {
next,
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 {
body,
next,
@ -388,7 +401,7 @@ impl State {
if_then: BasicBlock,
if_else: BasicBlock,
next: BasicBlock,
phis: SmallVec<[PhiValue; 1]>,
phis: SmallVec<[PhiValue<'ctx>; 1]>,
) {
self.control_stack.push(ControlFrame::IfElse {
if_then,

View File

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