Update LLVM backend to wasmparser 0.51.3

This commit is contained in:
Mark McCaskey
2020-02-26 13:07:31 -08:00
parent 21fd95d760
commit 0a92d9c65e
3 changed files with 65 additions and 74 deletions

View File

@ -37,7 +37,7 @@ use wasmer_runtime_core::{
codegen::*, codegen::*,
memory::MemoryType, memory::MemoryType,
module::{ModuleInfo, ModuleInner}, module::{ModuleInfo, ModuleInner},
parse::wp_type_to_type, parse::{wp_type_to_type, LoadError},
structures::{Map, TypedIndex}, structures::{Map, TypedIndex},
types::{ types::{
FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type, FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type,
@ -670,7 +670,7 @@ fn resolve_memory_ptr<'ctx>(
memarg: &MemoryImmediate, memarg: &MemoryImmediate,
ptr_ty: PointerType<'ctx>, ptr_ty: PointerType<'ctx>,
value_size: usize, value_size: usize,
) -> Result<PointerValue<'ctx>, BinaryReaderError> { ) -> Result<PointerValue<'ctx>, CodegenError> {
// Look up the memory base (as pointer) and bounds (as unsigned integer). // Look up the memory base (as pointer) and bounds (as unsigned integer).
let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone()); let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone());
let (mem_base, mem_bound, minimum, _maximum) = match memory_cache { let (mem_base, mem_bound, minimum, _maximum) = match memory_cache {
@ -1200,9 +1200,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions * https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions
***************************/ ***************************/
Operator::Block { ty } => { Operator::Block { ty } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let end_block = context.append_basic_block(function, "end"); let end_block = context.append_basic_block(function, "end");
@ -1276,9 +1275,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::Br { relative_depth } => { Operator::Br { relative_depth } => {
let frame = state.frame_at_depth(relative_depth)?; let frame = state.frame_at_depth(relative_depth)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let value_len = if frame.is_loop() { let value_len = if frame.is_loop() {
@ -1308,9 +1306,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
let cond = state.pop1()?; let cond = state.pop1()?;
let frame = state.frame_at_depth(relative_depth)?; let frame = state.frame_at_depth(relative_depth)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let value_len = if frame.is_loop() { let value_len = if frame.is_loop() {
@ -1340,9 +1337,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
builder.position_at_end(&else_block); builder.position_at_end(&else_block);
} }
Operator::BrTable { ref table } => { Operator::BrTable { ref table } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let (label_depths, default_depth) = table.read_table()?; let (label_depths, default_depth) = table.read_table()?;
@ -1366,7 +1362,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.iter() .iter()
.enumerate() .enumerate()
.map(|(case_index, &depth)| { .map(|(case_index, &depth)| {
let frame_result: Result<&ControlFrame, BinaryReaderError> = let frame_result: Result<&ControlFrame, CodegenError> =
state.frame_at_depth(depth); state.frame_at_depth(depth);
let frame = match frame_result { let frame = match frame_result {
Ok(v) => v, Ok(v) => v,
@ -1390,9 +1386,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
state.reachable = false; state.reachable = false;
} }
Operator::If { ty } => { Operator::If { ty } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let if_then_block = context.append_basic_block(function, "if_then"); let if_then_block = context.append_basic_block(function, "if_then");
let if_else_block = context.append_basic_block(function, "if_else"); let if_else_block = context.append_basic_block(function, "if_else");
@ -1431,9 +1426,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::Else => { Operator::Else => {
if state.reachable { if state.reachable {
let frame = state.frame_at_depth(0)?; let frame = state.frame_at_depth(0)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
for phi in frame.phis().to_vec().iter().rev() { for phi in frame.phis().to_vec().iter().rev() {
@ -1465,9 +1459,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::End => { Operator::End => {
let frame = state.pop_frame()?; let frame = state.pop_frame()?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
if state.reachable { if state.reachable {
@ -1524,9 +1517,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
} }
} }
Operator::Return => { Operator::Return => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError { let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block", message: "not currently in a block".to_string(),
offset: -1isize as usize,
})?; })?;
let frame = state.outermost_frame()?; let frame = state.outermost_frame()?;
@ -8611,6 +8603,14 @@ impl From<BinaryReaderError> for CodegenError {
} }
} }
impl From<LoadError> for CodegenError {
fn from(other: LoadError) -> CodegenError {
CodegenError {
message: format!("{:?}", other),
}
}
}
impl Drop for LLVMModuleCodeGenerator<'_> { impl Drop for LLVMModuleCodeGenerator<'_> {
fn drop(&mut self) { fn drop(&mut self) {
// Ensure that all members of the context are dropped before we drop the context. // Ensure that all members of the context are dropped before we drop the context.

View File

@ -1,15 +1,16 @@
use crate::code::CodegenError;
use wasmer_runtime_core::parse::wp_type_to_type; use wasmer_runtime_core::parse::wp_type_to_type;
use wasmer_runtime_core::types::Type; use wasmer_runtime_core::types::Type;
use wasmparser::{BinaryReaderError, TypeOrFuncType as WpTypeOrFuncType}; use wasmparser::TypeOrFuncType as WpTypeOrFuncType;
pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result<Type, BinaryReaderError> { pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result<Type, CodegenError> {
match ty { match ty {
WpTypeOrFuncType::Type(inner_ty) => wp_type_to_type(inner_ty), WpTypeOrFuncType::Type(inner_ty) => Ok(wp_type_to_type(inner_ty)?),
_ => { _ => {
return Err(BinaryReaderError { return Err(CodegenError {
message: message:
"the wasmer llvm backend does not yet support the multi-value return extension", "the wasmer llvm backend does not yet support the multi-value return extension"
offset: -1isize as usize, .to_string(),
}); });
} }
} }

View File

@ -1,3 +1,4 @@
use crate::code::CodegenError;
use inkwell::{ use inkwell::{
basic_block::BasicBlock, basic_block::BasicBlock,
values::{BasicValue, BasicValueEnum, PhiValue}, values::{BasicValue, BasicValueEnum, PhiValue},
@ -5,7 +6,6 @@ use inkwell::{
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::Cell; use std::cell::Cell;
use std::ops::{BitAnd, BitOr, BitOrAssign}; use std::ops::{BitAnd, BitOr, BitOrAssign};
use wasmparser::BinaryReaderError;
#[derive(Debug)] #[derive(Debug)]
pub enum ControlFrame<'ctx> { pub enum ControlFrame<'ctx> {
@ -229,21 +229,19 @@ impl<'ctx> State<'ctx> {
self.stack.truncate(stack_size_snapshot); self.stack.truncate(stack_size_snapshot);
} }
pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, BinaryReaderError> { pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, CodegenError> {
self.control_stack.get(0).ok_or(BinaryReaderError { self.control_stack.get(0).ok_or(CodegenError {
message: "outermost_frame: invalid control stack depth", message: "outermost_frame: invalid control stack depth".to_string(),
offset: -1isize as usize,
}) })
} }
pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, BinaryReaderError> { pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, CodegenError> {
let index = self let index = self
.control_stack .control_stack
.len() .len()
.checked_sub(1 + (depth as usize)) .checked_sub(1 + (depth as usize))
.ok_or(BinaryReaderError { .ok_or(CodegenError {
message: "frame_at_depth: invalid control stack depth", message: "frame_at_depth: invalid control stack depth".to_string(),
offset: -1isize as usize,
})?; })?;
Ok(&self.control_stack[index]) Ok(&self.control_stack[index])
} }
@ -251,22 +249,20 @@ impl<'ctx> State<'ctx> {
pub fn frame_at_depth_mut( pub fn frame_at_depth_mut(
&mut self, &mut self,
depth: u32, depth: u32,
) -> Result<&mut ControlFrame<'ctx>, BinaryReaderError> { ) -> Result<&mut ControlFrame<'ctx>, CodegenError> {
let index = self let index = self
.control_stack .control_stack
.len() .len()
.checked_sub(1 + (depth as usize)) .checked_sub(1 + (depth as usize))
.ok_or(BinaryReaderError { .ok_or(CodegenError {
message: "frame_at_depth_mut: invalid control stack depth", message: "frame_at_depth_mut: invalid control stack depth".to_string(),
offset: -1isize as usize,
})?; })?;
Ok(&mut self.control_stack[index]) Ok(&mut self.control_stack[index])
} }
pub fn pop_frame(&mut self) -> Result<ControlFrame<'ctx>, BinaryReaderError> { pub fn pop_frame(&mut self) -> Result<ControlFrame<'ctx>, CodegenError> {
self.control_stack.pop().ok_or(BinaryReaderError { self.control_stack.pop().ok_or(CodegenError {
message: "pop_frame: cannot pop from control stack", message: "pop_frame: cannot pop from control stack".to_string(),
offset: -1isize as usize,
}) })
} }
@ -285,20 +281,17 @@ impl<'ctx> State<'ctx> {
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<'ctx>, BinaryReaderError> { pub fn pop1(&mut self) -> Result<BasicValueEnum<'ctx>, CodegenError> {
Ok(self.pop1_extra()?.0) Ok(self.pop1_extra()?.0)
} }
pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> { pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> {
self.stack.pop().ok_or(BinaryReaderError { self.stack.pop().ok_or(CodegenError {
message: "pop1_extra: invalid value stack", message: "pop1_extra: invalid value stack".to_string(),
offset: -1isize as usize,
}) })
} }
pub fn pop2( pub fn pop2(&mut self) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), CodegenError> {
&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))
@ -311,7 +304,7 @@ impl<'ctx> State<'ctx> {
(BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
), ),
BinaryReaderError, CodegenError,
> { > {
let v2 = self.pop1_extra()?; let v2 = self.pop1_extra()?;
let v1 = self.pop1_extra()?; let v1 = self.pop1_extra()?;
@ -326,7 +319,7 @@ impl<'ctx> State<'ctx> {
(BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo), (BasicValueEnum<'ctx>, ExtraInfo),
), ),
BinaryReaderError, CodegenError,
> { > {
let v3 = self.pop1_extra()?; let v3 = self.pop1_extra()?;
let v2 = self.pop1_extra()?; let v2 = self.pop1_extra()?;
@ -334,25 +327,23 @@ impl<'ctx> State<'ctx> {
Ok((v1, v2, v3)) Ok((v1, v2, v3))
} }
pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> { pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> {
let index = self.stack.len().checked_sub(1).ok_or(BinaryReaderError { let index = self.stack.len().checked_sub(1).ok_or(CodegenError {
message: "peek1_extra: invalid value stack", message: "peek1_extra: invalid value stack".to_string(),
offset: -1isize as usize,
})?; })?;
Ok(self.stack[index]) Ok(self.stack[index])
} }
pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum<'ctx>>, BinaryReaderError> { pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum<'ctx>>, CodegenError> {
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<'ctx>, ExtraInfo)], BinaryReaderError> { ) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], CodegenError> {
let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError { let index = self.stack.len().checked_sub(n).ok_or(CodegenError {
message: "peekn_extra: invalid value stack", message: "peekn_extra: invalid value stack".to_string(),
offset: -1isize as usize,
})?; })?;
Ok(&self.stack[index..]) Ok(&self.stack[index..])
@ -361,16 +352,15 @@ impl<'ctx> State<'ctx> {
pub fn popn_save_extra( pub fn popn_save_extra(
&mut self, &mut self,
n: usize, n: usize,
) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, BinaryReaderError> { ) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, CodegenError> {
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)
} }
pub fn popn(&mut self, n: usize) -> Result<(), BinaryReaderError> { pub fn popn(&mut self, n: usize) -> Result<(), CodegenError> {
let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError { let index = self.stack.len().checked_sub(n).ok_or(CodegenError {
message: "popn: invalid value stack", message: "popn: invalid value stack".to_string(),
offset: -1isize as usize,
})?; })?;
self.stack.truncate(index); self.stack.truncate(index);