Update rustfmt to 0.9.0.

This commit is contained in:
Dan Gohman
2017-08-31 10:44:59 -07:00
parent 46fb64cbb4
commit 2efdc0ed37
111 changed files with 4692 additions and 3379 deletions

View File

@@ -135,7 +135,7 @@ struct TranslationState {
/// Holds mappings between the function and signatures indexes in the Wasm module and their
/// references as imports of the Cretonne IL function.
#[derive(Clone,Debug)]
#[derive(Clone, Debug)]
pub struct FunctionImports {
/// Mappings index in function index space -> index in function local imports
pub functions: HashMap<FunctionIndex, FuncRef>,
@@ -153,16 +153,17 @@ impl FunctionImports {
}
/// Returns a well-formed Cretonne IL function from a wasm function body and a signature.
pub fn translate_function_body(parser: &mut Parser,
function_index: FunctionIndex,
sig: Signature,
locals: &[(usize, Type)],
exports: &Option<HashMap<FunctionIndex, String>>,
signatures: &[Signature],
functions: &[SignatureIndex],
il_builder: &mut ILBuilder<Local>,
runtime: &mut WasmRuntime)
-> Result<(Function, FunctionImports), String> {
pub fn translate_function_body(
parser: &mut Parser,
function_index: FunctionIndex,
sig: Signature,
locals: &[(usize, Type)],
exports: &Option<HashMap<FunctionIndex, String>>,
signatures: &[Signature],
functions: &[SignatureIndex],
il_builder: &mut ILBuilder<Local>,
runtime: &mut WasmRuntime,
) -> Result<(Function, FunctionImports), String> {
runtime.next_function();
// First we build the Function object with its name and signature
let mut func = Function::new();
@@ -216,39 +217,45 @@ pub fn translate_function_body(parser: &mut Parser,
// We initialize the control stack with the implicit function block
let end_ebb = builder.create_ebb();
control_stack.push(ControlStackFrame::Block {
destination: end_ebb,
original_stack_size: 0,
return_values: sig.return_types
.iter()
.map(|argty| argty.value_type)
.collect(),
reachable: false,
});
destination: end_ebb,
original_stack_size: 0,
return_values: sig.return_types
.iter()
.map(|argty| argty.value_type)
.collect(),
reachable: false,
});
// Now the main loop that reads every wasm instruction and translates it
loop {
let parser_state = parser.read();
match *parser_state {
ParserState::CodeOperator(ref op) => {
debug_assert!(state.phantom_unreachable_stack_depth == 0 ||
state.real_unreachable_stack_depth > 0);
debug_assert!(
state.phantom_unreachable_stack_depth == 0 ||
state.real_unreachable_stack_depth > 0
);
if state.real_unreachable_stack_depth > 0 {
translate_unreachable_operator(op,
&mut builder,
&mut stack,
&mut control_stack,
&mut state)
translate_unreachable_operator(
op,
&mut builder,
&mut stack,
&mut control_stack,
&mut state,
)
} else {
translate_operator(op,
&mut builder,
runtime,
&mut stack,
&mut control_stack,
&mut state,
&sig,
&functions,
&signatures,
&exports,
&mut func_imports)
translate_operator(
op,
&mut builder,
runtime,
&mut stack,
&mut control_stack,
&mut state,
&sig,
&functions,
&signatures,
&exports,
&mut func_imports,
)
}
}
@@ -281,17 +288,19 @@ pub fn translate_function_body(parser: &mut Parser,
/// Translates wasm operators into Cretonne IL instructions. Returns `true` if it inserted
/// a return.
fn translate_operator(op: &Operator,
builder: &mut FunctionBuilder<Local>,
runtime: &mut WasmRuntime,
stack: &mut Vec<Value>,
control_stack: &mut Vec<ControlStackFrame>,
state: &mut TranslationState,
sig: &Signature,
functions: &[SignatureIndex],
signatures: &[Signature],
exports: &Option<HashMap<FunctionIndex, String>>,
func_imports: &mut FunctionImports) {
fn translate_operator(
op: &Operator,
builder: &mut FunctionBuilder<Local>,
runtime: &mut WasmRuntime,
stack: &mut Vec<Value>,
control_stack: &mut Vec<ControlStackFrame>,
state: &mut TranslationState,
sig: &Signature,
functions: &[SignatureIndex],
signatures: &[Signature],
exports: &Option<HashMap<FunctionIndex, String>>,
func_imports: &mut FunctionImports,
) {
// This big match treats all Wasm code operators.
match *op {
/********************************** Locals ****************************************
@@ -357,11 +366,11 @@ fn translate_operator(op: &Operator,
Err(_) => {}
}
control_stack.push(ControlStackFrame::Block {
destination: next,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
destination: next,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
}
Operator::Loop { ty } => {
let loop_body = builder.create_ebb();
@@ -374,12 +383,12 @@ fn translate_operator(op: &Operator,
}
builder.ins().jump(loop_body, &[]);
control_stack.push(ControlStackFrame::Loop {
destination: next,
header: loop_body,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
destination: next,
header: loop_body,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
builder.switch_to_block(loop_body, &[]);
}
Operator::If { ty } => {
@@ -399,12 +408,12 @@ fn translate_operator(op: &Operator,
Err(_) => {}
}
control_stack.push(ControlStackFrame::If {
destination: if_not,
branch_inst: jump_inst,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
destination: if_not,
branch_inst: jump_inst,
return_values: translate_type(ty).unwrap(),
original_stack_size: stack.len(),
reachable: false,
});
}
Operator::Else => {
// We take the control frame pushed by the if, use its ebb as the else body
@@ -434,9 +443,10 @@ fn translate_operator(op: &Operator,
if !builder.is_unreachable() || !builder.is_pristine() {
let cut_index = stack.len() - frame.return_values().len();
let jump_args = stack.split_off(cut_index);
builder
.ins()
.jump(frame.following_code(), jump_args.as_slice());
builder.ins().jump(
frame.following_code(),
jump_args.as_slice(),
);
}
builder.switch_to_block(frame.following_code(), frame.return_values());
builder.seal_block(frame.following_code());
@@ -478,9 +488,10 @@ fn translate_operator(op: &Operator,
let cut_index = stack.len() - frame.return_values().len();
stack.split_off(cut_index)
};
builder
.ins()
.jump(frame.br_destination(), jump_args.as_slice());
builder.ins().jump(
frame.br_destination(),
jump_args.as_slice(),
);
// We signal that all the code that follows until the next End is unreachable
frame.set_reachable();
state.real_unreachable_stack_depth = 1 + relative_depth as usize;
@@ -495,9 +506,11 @@ fn translate_operator(op: &Operator,
let cut_index = stack.len() - frame.return_values().len();
stack.split_off(cut_index)
};
builder
.ins()
.brnz(val, frame.br_destination(), jump_args.as_slice());
builder.ins().brnz(
val,
frame.br_destination(),
jump_args.as_slice(),
);
// The values returned by the branch are still available for the reachable
// code that comes after it
frame.set_reachable();
@@ -545,10 +558,9 @@ fn translate_operator(op: &Operator,
let cut_index = stack.len() - jump_args_count;
let jump_args = stack.split_off(cut_index);
let jt = builder.create_jump_table();
let dest_ebbs: HashMap<usize, Ebb> = depths
.iter()
.enumerate()
.fold(HashMap::new(), |mut acc, (index, &depth)| {
let dest_ebbs: HashMap<usize, Ebb> =
depths.iter().enumerate().fold(HashMap::new(), |mut acc,
(index, &depth)| {
if acc.get(&(depth as usize)).is_none() {
let branch_ebb = builder.create_ebb();
builder.insert_jump_table_entry(jt, index, branch_ebb);
@@ -592,15 +604,18 @@ fn translate_operator(op: &Operator,
let args_num = args_count(function_index as usize, functions, signatures);
let cut_index = stack.len() - args_num;
let call_args = stack.split_off(cut_index);
let internal_function_index = find_function_import(function_index as usize,
builder,
func_imports,
functions,
exports,
signatures);
let call_inst = builder
.ins()
.call(internal_function_index, call_args.as_slice());
let internal_function_index = find_function_import(
function_index as usize,
builder,
func_imports,
functions,
exports,
signatures,
);
let call_inst = builder.ins().call(
internal_function_index,
call_args.as_slice(),
);
let ret_values = builder.inst_results(call_inst);
for val in ret_values {
stack.push(*val);
@@ -1107,9 +1122,11 @@ fn translate_operator(op: &Operator,
Operator::I32LeU | Operator::I64LeU => {
let arg2 = stack.pop().unwrap();
let arg1 = stack.pop().unwrap();
let val = builder
.ins()
.icmp(IntCC::UnsignedLessThanOrEqual, arg1, arg2);
let val = builder.ins().icmp(
IntCC::UnsignedLessThanOrEqual,
arg1,
arg2,
);
stack.push(builder.ins().bint(I32, val));
}
Operator::I32GtS | Operator::I64GtS => {
@@ -1127,17 +1144,21 @@ fn translate_operator(op: &Operator,
Operator::I32GeS | Operator::I64GeS => {
let arg2 = stack.pop().unwrap();
let arg1 = stack.pop().unwrap();
let val = builder
.ins()
.icmp(IntCC::SignedGreaterThanOrEqual, arg1, arg2);
let val = builder.ins().icmp(
IntCC::SignedGreaterThanOrEqual,
arg1,
arg2,
);
stack.push(builder.ins().bint(I32, val));
}
Operator::I32GeU | Operator::I64GeU => {
let arg2 = stack.pop().unwrap();
let arg1 = stack.pop().unwrap();
let val = builder
.ins()
.icmp(IntCC::UnsignedGreaterThanOrEqual, arg1, arg2);
let val = builder.ins().icmp(
IntCC::UnsignedGreaterThanOrEqual,
arg1,
arg2,
);
stack.push(builder.ins().bint(I32, val));
}
Operator::I32Eqz | Operator::I64Eqz => {
@@ -1199,11 +1220,13 @@ fn translate_operator(op: &Operator,
/// Deals with a Wasm instruction located in an unreachable portion of the code. Most of them
/// are dropped but special ones like `End` or `Else` signal the potential end of the unreachable
/// portion so the translation state muts be updated accordingly.
fn translate_unreachable_operator(op: &Operator,
builder: &mut FunctionBuilder<Local>,
stack: &mut Vec<Value>,
control_stack: &mut Vec<ControlStackFrame>,
state: &mut TranslationState) {
fn translate_unreachable_operator(
op: &Operator,
builder: &mut FunctionBuilder<Local>,
stack: &mut Vec<Value>,
control_stack: &mut Vec<ControlStackFrame>,
state: &mut TranslationState,
) {
// We don't translate because the code is unreachable
// Nevertheless we have to record a phantom stack for this code
// to know when the unreachable code ends
@@ -1253,15 +1276,15 @@ fn translate_unreachable_operator(op: &Operator,
} else {
// Encountering an real else means that the code in the else
// clause is reachable again
let (branch_inst, original_stack_size) = match &control_stack[control_stack.len() -
1] {
&ControlStackFrame::If {
branch_inst,
original_stack_size,
..
} => (branch_inst, original_stack_size),
_ => panic!("should not happen"),
};
let (branch_inst, original_stack_size) =
match &control_stack[control_stack.len() - 1] {
&ControlStackFrame::If {
branch_inst,
original_stack_size,
..
} => (branch_inst, original_stack_size),
_ => panic!("should not happen"),
};
// We change the target of the branch instruction
let else_ebb = builder.create_ebb();
builder.change_jump_destination(branch_inst, else_ebb);
@@ -1279,22 +1302,24 @@ fn translate_unreachable_operator(op: &Operator,
}
}
fn args_count(index: FunctionIndex,
functions: &[SignatureIndex],
signatures: &[Signature])
-> usize {
fn args_count(
index: FunctionIndex,
functions: &[SignatureIndex],
signatures: &[Signature],
) -> usize {
signatures[functions[index] as usize].argument_types.len()
}
// Given a index in the function index space, search for it in the function imports and if it is
// not there add it to the function imports.
fn find_function_import(index: FunctionIndex,
builder: &mut FunctionBuilder<Local>,
func_imports: &mut FunctionImports,
functions: &[SignatureIndex],
exports: &Option<HashMap<FunctionIndex, String>>,
signatures: &[Signature])
-> FuncRef {
fn find_function_import(
index: FunctionIndex,
builder: &mut FunctionBuilder<Local>,
func_imports: &mut FunctionImports,
functions: &[SignatureIndex],
exports: &Option<HashMap<FunctionIndex, String>>,
signatures: &[Signature],
) -> FuncRef {
match func_imports.functions.get(&index) {
Some(local_index) => return *local_index,
None => {}
@@ -1303,21 +1328,18 @@ fn find_function_import(index: FunctionIndex,
let sig_index = functions[index];
match func_imports.signatures.get(&(sig_index as usize)) {
Some(local_sig_index) => {
let local_func_index =
builder.import_function(ExtFuncData {
name: match exports {
&None => FunctionName::new(""),
&Some(ref exports) => {
match exports.get(&index) {
None => FunctionName::new(""),
Some(name) => {
FunctionName::new(name.clone())
}
}
}
},
signature: *local_sig_index,
});
let local_func_index = builder.import_function(ExtFuncData {
name: match exports {
&None => FunctionName::new(""),
&Some(ref exports) => {
match exports.get(&index) {
None => FunctionName::new(""),
Some(name) => FunctionName::new(name.clone()),
}
}
},
signature: *local_sig_index,
});
func_imports.functions.insert(index, local_func_index);
return local_func_index;
}
@@ -1325,38 +1347,40 @@ fn find_function_import(index: FunctionIndex,
};
// We have to import the signature
let sig_local_index = builder.import_signature(signatures[sig_index as usize].clone());
func_imports
.signatures
.insert(sig_index as usize, sig_local_index);
let local_func_index =
builder.import_function(ExtFuncData {
name: match exports {
&None => FunctionName::new(""),
&Some(ref exports) => {
match exports.get(&index) {
None => FunctionName::new(""),
Some(name) => FunctionName::new(name.clone()),
}
}
},
signature: sig_local_index,
});
func_imports.signatures.insert(
sig_index as usize,
sig_local_index,
);
let local_func_index = builder.import_function(ExtFuncData {
name: match exports {
&None => FunctionName::new(""),
&Some(ref exports) => {
match exports.get(&index) {
None => FunctionName::new(""),
Some(name) => FunctionName::new(name.clone()),
}
}
},
signature: sig_local_index,
});
func_imports.functions.insert(index, local_func_index);
local_func_index
}
fn find_signature_import(sig_index: SignatureIndex,
builder: &mut FunctionBuilder<Local>,
func_imports: &mut FunctionImports,
signatures: &[Signature])
-> SigRef {
fn find_signature_import(
sig_index: SignatureIndex,
builder: &mut FunctionBuilder<Local>,
func_imports: &mut FunctionImports,
signatures: &[Signature],
) -> SigRef {
match func_imports.signatures.get(&(sig_index as usize)) {
Some(local_sig_index) => return *local_sig_index,
None => {}
}
let sig_local_index = builder.import_signature(signatures[sig_index as usize].clone());
func_imports
.signatures
.insert(sig_index as usize, sig_local_index);
func_imports.signatures.insert(
sig_index as usize,
sig_local_index,
);
sig_local_index
}

View File

@@ -34,7 +34,7 @@ pub enum FunctionTranslation {
Import(),
}
#[derive(Clone,Debug)]
#[derive(Clone, Debug)]
/// Mappings describing the relations between imports of the Cretonne IL functions and the
/// functions in the WebAssembly module.
pub struct ImportMappings {
@@ -58,9 +58,10 @@ impl ImportMappings {
/// [`Function`](../cretonne/ir/function/struct.Function.html).
/// Returns the functions and also the mappings for imported functions and signature between the
/// indexes in the wasm module and the indexes inside each functions.
pub fn translate_module(data: &[u8],
runtime: &mut WasmRuntime)
-> Result<TranslationResult, String> {
pub fn translate_module(
data: &[u8],
runtime: &mut WasmRuntime,
) -> Result<TranslationResult, String> {
let mut parser = Parser::new(data);
match *parser.read() {
ParserState::BeginWasm { .. } => {}
@@ -207,9 +208,9 @@ pub fn translate_module(data: &[u8],
}
ParserState::EndWasm => {
return Ok(TranslationResult {
functions: Vec::new(),
start_index: None,
})
functions: Vec::new(),
start_index: None,
})
}
ParserState::BeginSection { code: SectionCode::Data, .. } => {
match parse_data_section(&mut parser, runtime, &globals) {
@@ -242,32 +243,36 @@ pub fn translate_module(data: &[u8],
locals
.iter()
.map(|&(index, ref ty)| {
(index as usize,
match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("unsupported type for local variable"),
})
})
(
index as usize,
match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("unsupported type for local variable"),
},
)
})
.collect()
}
ParserState::EndSection => break,
_ => return Err(String::from(format!("wrong content in code section"))),
};
let signature = signatures[functions[function_index as usize] as usize].clone();
match translate_function_body(&mut parser,
function_index,
signature,
&locals,
&exports,
&signatures,
&functions,
&mut il_builder,
runtime) {
match translate_function_body(
&mut parser,
function_index,
signature,
&locals,
&exports,
&signatures,
&functions,
&mut il_builder,
runtime,
) {
Ok((il_func, imports)) => {
il_functions.push(FunctionTranslation::Code {
il: il_func,
imports: invert_hashmaps(imports),
})
il: il_func,
imports: invert_hashmaps(imports),
})
}
Err(s) => return Err(s),
}
@@ -285,9 +290,9 @@ pub fn translate_module(data: &[u8],
}
ParserState::EndWasm => {
return Ok(TranslationResult {
functions: il_functions,
start_index,
})
functions: il_functions,
start_index,
})
}
_ => (),
}

View File

@@ -21,19 +21,20 @@ impl DummyRuntime {
}
impl WasmRuntime for DummyRuntime {
fn translate_get_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex)
-> Value {
fn translate_get_global(
&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex,
) -> Value {
let ref glob = self.globals.get(global_index as usize).unwrap();
match glob.ty {
I32 => builder.ins().iconst(glob.ty, -1),
I64 => builder.ins().iconst(glob.ty, -1),
F32 => builder.ins().f32const(Ieee32::with_bits(0xbf800000)), // -1.0
F64 => {
builder
.ins()
.f64const(Ieee64::with_bits(0xbff0000000000000))
builder.ins().f64const(
Ieee64::with_bits(0xbff0000000000000),
)
} // -1.0
_ => panic!("should not happen"),
}
@@ -48,19 +49,21 @@ impl WasmRuntime for DummyRuntime {
fn translate_current_memory(&mut self, builder: &mut FunctionBuilder<Local>) -> Value {
builder.ins().iconst(I32, -1)
}
fn translate_call_indirect<'a>(&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value])
-> &'a [Value] {
fn translate_call_indirect<'a>(
&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value],
) -> &'a [Value] {
let call_inst = builder.ins().call_indirect(sig_ref, index_val, call_args);
builder.inst_results(call_inst)
}
fn translate_memory_base_address(&self,
builder: &mut FunctionBuilder<Local>,
_: MemoryIndex)
-> Value {
fn translate_memory_base_address(
&self,
builder: &mut FunctionBuilder<Local>,
_: MemoryIndex,
) -> Value {
builder.ins().iconst(I64, 0)
}
fn declare_global(&mut self, global: Global) {
@@ -75,11 +78,12 @@ impl WasmRuntime for DummyRuntime {
fn declare_memory(&mut self, _: Memory) {
//We do nothing
}
fn declare_data_initialization(&mut self,
_: MemoryIndex,
_: usize,
_: &[u8])
-> Result<(), String> {
fn declare_data_initialization(
&mut self,
_: MemoryIndex,
_: usize,
_: &[u8],
) -> Result<(), String> {
// We do nothing
Ok(())
}

View File

@@ -14,48 +14,56 @@ pub trait WasmRuntime {
/// Declares a table to the runtime.
fn declare_table(&mut self, table: Table);
/// Fills a declared table with references to functions in the module.
fn declare_table_elements(&mut self,
table_index: TableIndex,
offset: usize,
elements: &[FunctionIndex]);
fn declare_table_elements(
&mut self,
table_index: TableIndex,
offset: usize,
elements: &[FunctionIndex],
);
/// Declares a memory to the runtime
fn declare_memory(&mut self, memory: Memory);
/// Fills a declared memory with bytes at module instantiation.
fn declare_data_initialization(&mut self,
memory_index: MemoryIndex,
offset: usize,
data: &[u8])
-> Result<(), String>;
fn declare_data_initialization(
&mut self,
memory_index: MemoryIndex,
offset: usize,
data: &[u8],
) -> Result<(), String>;
/// Call this function after having declared all the runtime elements but prior to the
/// function body translation.
fn begin_translation(&mut self);
/// Call this function between each function body translation.
fn next_function(&mut self);
/// Translates a `get_global` wasm instruction.
fn translate_get_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex)
-> Value;
fn translate_get_global(
&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex,
) -> Value;
/// Translates a `set_global` wasm instruction.
fn translate_set_global(&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex,
val: Value);
fn translate_set_global(
&self,
builder: &mut FunctionBuilder<Local>,
global_index: GlobalIndex,
val: Value,
);
/// Translates a `grow_memory` wasm instruction. Returns the old size (in pages) of the memory.
fn translate_grow_memory(&mut self, builder: &mut FunctionBuilder<Local>, val: Value) -> Value;
/// Translates a `current_memory` wasm instruction. Returns the size in pages of the memory.
fn translate_current_memory(&mut self, builder: &mut FunctionBuilder<Local>) -> Value;
/// Returns the base address of a wasm memory as a Cretonne `Value`.
fn translate_memory_base_address(&self,
builder: &mut FunctionBuilder<Local>,
index: MemoryIndex)
-> Value;
fn translate_memory_base_address(
&self,
builder: &mut FunctionBuilder<Local>,
index: MemoryIndex,
) -> Value;
/// Translates a `call_indirect` wasm instruction. It involves looking up the value contained
/// it the table at location `index_val` and calling the corresponding function.
fn translate_call_indirect<'a>(&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value])
-> &'a [Value];
fn translate_call_indirect<'a>(
&self,
builder: &'a mut FunctionBuilder<Local>,
sig_ref: SigRef,
index_val: Value,
call_args: &[Value],
) -> &'a [Value];
}

View File

@@ -24,8 +24,9 @@ pub enum SectionParsingError {
}
/// Reads the Type Section of the wasm module and returns the corresponding function signatures.
pub fn parse_function_signatures(parser: &mut Parser)
-> Result<Vec<Signature>, SectionParsingError> {
pub fn parse_function_signatures(
parser: &mut Parser,
) -> Result<Vec<Signature>, SectionParsingError> {
let mut signatures: Vec<Signature> = Vec::new();
loop {
match *parser.read() {
@@ -36,28 +37,22 @@ pub fn parse_function_signatures(parser: &mut Parser)
ref returns,
}) => {
let mut sig = Signature::new(CallConv::Native);
sig.argument_types
.extend(params
.iter()
.map(|ty| {
let cret_arg: cretonne::ir::Type = match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("only numeric types are supported in\
sig.argument_types.extend(params.iter().map(|ty| {
let cret_arg: cretonne::ir::Type = match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("only numeric types are supported in\
function signatures"),
};
ArgumentType::new(cret_arg)
}));
sig.return_types
.extend(returns
.iter()
.map(|ty| {
let cret_arg: cretonne::ir::Type = match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("only numeric types are supported in\
};
ArgumentType::new(cret_arg)
}));
sig.return_types.extend(returns.iter().map(|ty| {
let cret_arg: cretonne::ir::Type = match type_to_type(ty) {
Ok(ty) => ty,
Err(()) => panic!("only numeric types are supported in\
function signatures"),
};
ArgumentType::new(cret_arg)
}));
};
ArgumentType::new(cret_arg)
}));
signatures.push(sig);
}
ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
@@ -78,30 +73,30 @@ pub fn parse_import_section(parser: &mut Parser) -> Result<Vec<Import>, SectionP
ty: ImportSectionEntryType::Memory(MemoryType { limits: ref memlimits }), ..
} => {
imports.push(Import::Memory(Memory {
pages_count: memlimits.initial as usize,
maximum: memlimits.maximum.map(|x| x as usize),
}))
pages_count: memlimits.initial as usize,
maximum: memlimits.maximum.map(|x| x as usize),
}))
}
ParserState::ImportSectionEntry {
ty: ImportSectionEntryType::Global(ref ty), ..
} => {
imports.push(Import::Global(Global {
ty: type_to_type(&ty.content_type).unwrap(),
mutability: ty.mutability != 0,
initializer: GlobalInit::Import(),
}));
ty: type_to_type(&ty.content_type).unwrap(),
mutability: ty.mutability != 0,
initializer: GlobalInit::Import(),
}));
}
ParserState::ImportSectionEntry {
ty: ImportSectionEntryType::Table(ref tab), ..
} => {
imports.push(Import::Table(Table {
ty: match type_to_type(&tab.element_type) {
Ok(t) => TableElementType::Val(t),
Err(()) => TableElementType::Func(),
},
size: tab.limits.initial as usize,
maximum: tab.limits.maximum.map(|x| x as usize),
}));
ty: match type_to_type(&tab.element_type) {
Ok(t) => TableElementType::Val(t),
Err(()) => TableElementType::Func(),
},
size: tab.limits.initial as usize,
maximum: tab.limits.maximum.map(|x| x as usize),
}));
}
ParserState::EndSection => break,
ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
@@ -111,8 +106,9 @@ pub fn parse_import_section(parser: &mut Parser) -> Result<Vec<Import>, SectionP
}
/// Retrieves the correspondances between functions and signatures from the function section
pub fn parse_function_section(parser: &mut Parser)
-> Result<Vec<SignatureIndex>, SectionParsingError> {
pub fn parse_function_section(
parser: &mut Parser,
) -> Result<Vec<SignatureIndex>, SectionParsingError> {
let mut funcs = Vec::new();
loop {
match *parser.read() {
@@ -125,8 +121,9 @@ pub fn parse_function_section(parser: &mut Parser)
}
/// Retrieves the names of the functions from the export section
pub fn parse_export_section(parser: &mut Parser)
-> Result<HashMap<FunctionIndex, String>, SectionParsingError> {
pub fn parse_export_section(
parser: &mut Parser,
) -> Result<HashMap<FunctionIndex, String>, SectionParsingError> {
let mut exports: HashMap<FunctionIndex, String> = HashMap::new();
loop {
match *parser.read() {
@@ -137,8 +134,10 @@ pub fn parse_export_section(parser: &mut Parser)
} => {
match kind {
&ExternalKind::Function => {
exports.insert(index as FunctionIndex,
String::from(from_utf8(field).unwrap()));
exports.insert(
index as FunctionIndex,
String::from(from_utf8(field).unwrap()),
);
}
_ => (),//TODO: deal with other kind of exports
}
@@ -157,9 +156,9 @@ pub fn parse_memory_section(parser: &mut Parser) -> Result<Vec<Memory>, SectionP
match *parser.read() {
ParserState::MemorySectionEntry(ref ty) => {
memories.push(Memory {
pages_count: ty.limits.initial as usize,
maximum: ty.limits.maximum.map(|x| x as usize),
})
pages_count: ty.limits.initial as usize,
maximum: ty.limits.maximum.map(|x| x as usize),
})
}
ParserState::EndSection => break,
ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
@@ -169,9 +168,10 @@ pub fn parse_memory_section(parser: &mut Parser) -> Result<Vec<Memory>, SectionP
}
/// Retrieves the size and maximum fields of memories from the memory section
pub fn parse_global_section(parser: &mut Parser,
runtime: &mut WasmRuntime)
-> Result<Vec<Global>, SectionParsingError> {
pub fn parse_global_section(
parser: &mut Parser,
runtime: &mut WasmRuntime,
) -> Result<Vec<Global>, SectionParsingError> {
let mut globals = Vec::new();
loop {
let (content_type, mutability) = match *parser.read() {
@@ -221,10 +221,11 @@ pub fn parse_global_section(parser: &mut Parser,
Ok(globals)
}
pub fn parse_data_section(parser: &mut Parser,
runtime: &mut WasmRuntime,
globals: &[Global])
-> Result<(), SectionParsingError> {
pub fn parse_data_section(
parser: &mut Parser,
runtime: &mut WasmRuntime,
globals: &[Global],
) -> Result<(), SectionParsingError> {
loop {
let memory_index = match *parser.read() {
ParserState::BeginDataSectionEntry(memory_index) => memory_index,
@@ -238,8 +239,10 @@ pub fn parse_data_section(parser: &mut Parser,
let offset = match *parser.read() {
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from("negative \
offset value")));
return Err(SectionParsingError::WrongSectionContent(String::from(
"negative \
offset value",
)));
} else {
value as usize
}
@@ -248,15 +251,19 @@ pub fn parse_data_section(parser: &mut Parser,
match globals[global_index as usize].initializer {
GlobalInit::I32Const(value) => {
if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from("\
negative offset value")));
return Err(SectionParsingError::WrongSectionContent(String::from(
"\
negative offset value",
)));
} else {
value as usize
}
}
GlobalInit::Import() => {
return Err(SectionParsingError::WrongSectionContent(String::from("\
imported globals not supported")))
return Err(SectionParsingError::WrongSectionContent(String::from(
"\
imported globals not supported",
)))
} // TODO: add runtime support
_ => panic!("should not happen"),
}
@@ -288,20 +295,21 @@ pub fn parse_data_section(parser: &mut Parser,
}
/// Retrieves the tables from the table section
pub fn parse_table_section(parser: &mut Parser,
runtime: &mut WasmRuntime)
-> Result<(), SectionParsingError> {
pub fn parse_table_section(
parser: &mut Parser,
runtime: &mut WasmRuntime,
) -> Result<(), SectionParsingError> {
loop {
match *parser.read() {
ParserState::TableSectionEntry(ref table) => {
runtime.declare_table(Table {
ty: match type_to_type(&table.element_type) {
Ok(t) => TableElementType::Val(t),
Err(()) => TableElementType::Func(),
},
size: table.limits.initial as usize,
maximum: table.limits.maximum.map(|x| x as usize),
})
ty: match type_to_type(&table.element_type) {
Ok(t) => TableElementType::Val(t),
Err(()) => TableElementType::Func(),
},
size: table.limits.initial as usize,
maximum: table.limits.maximum.map(|x| x as usize),
})
}
ParserState::EndSection => break,
ref s @ _ => return Err(SectionParsingError::WrongSectionContent(format!("{:?}", s))),
@@ -311,10 +319,11 @@ pub fn parse_table_section(parser: &mut Parser,
}
/// Retrieves the tables from the table section
pub fn parse_elements_section(parser: &mut Parser,
runtime: &mut WasmRuntime,
globals: &[Global])
-> Result<(), SectionParsingError> {
pub fn parse_elements_section(
parser: &mut Parser,
runtime: &mut WasmRuntime,
globals: &[Global],
) -> Result<(), SectionParsingError> {
loop {
let table_index = match *parser.read() {
ParserState::BeginElementSectionEntry(ref table_index) => *table_index as TableIndex,
@@ -328,8 +337,10 @@ pub fn parse_elements_section(parser: &mut Parser,
let offset = match *parser.read() {
ParserState::InitExpressionOperator(Operator::I32Const { value }) => {
if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from("negative \
offset value")));
return Err(SectionParsingError::WrongSectionContent(String::from(
"negative \
offset value",
)));
} else {
value as usize
}
@@ -338,8 +349,10 @@ pub fn parse_elements_section(parser: &mut Parser,
match globals[global_index as usize].initializer {
GlobalInit::I32Const(value) => {
if value < 0 {
return Err(SectionParsingError::WrongSectionContent(String::from("\
negative offset value")));
return Err(SectionParsingError::WrongSectionContent(String::from(
"\
negative offset value",
)));
} else {
value as usize
}

View File

@@ -21,7 +21,7 @@ pub type RawByte = u8;
pub type MemoryAddress = usize;
/// WebAssembly import.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub enum Import {
Function { sig_index: u32 },
Memory(Memory),
@@ -30,7 +30,7 @@ pub enum Import {
}
/// WebAssembly global.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub struct Global {
/// The type of the value stored in the global.
pub ty: cretonne::ir::Type,
@@ -41,7 +41,7 @@ pub struct Global {
}
/// Globals are initialized via the four `const` operators or by referring to another import.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub enum GlobalInit {
/// An `i32.const`.
I32Const(i32),
@@ -58,7 +58,7 @@ pub enum GlobalInit {
}
/// WebAssembly table.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub struct Table {
/// The type of data stored in elements of the table.
pub ty: TableElementType,
@@ -69,14 +69,14 @@ pub struct Table {
}
/// WebAssembly table element. Can be a function or a scalar type.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub enum TableElementType {
Val(cretonne::ir::Type),
Func(),
}
/// WebAssembly linear memory.
#[derive(Debug,Clone,Copy)]
#[derive(Debug, Clone, Copy)]
pub struct Memory {
/// The minimum number of pages in the memory.
pub pages_count: usize,
@@ -139,8 +139,9 @@ pub fn translate_type(ty: wasmparser::Type) -> Result<Vec<cretonne::ir::Type>, (
/// Inverts the key-value relation in the imports hashmap. Indeed, these hashmaps are built by
/// feeding the function indexes in the module but are used by the runtime with the `FuncRef` as
/// keys.
pub fn invert_hashmaps(imports: code_translator::FunctionImports)
-> module_translator::ImportMappings {
pub fn invert_hashmaps(
imports: code_translator::FunctionImports,
) -> module_translator::ImportMappings {
let mut new_imports = module_translator::ImportMappings::new();
for (func_index, func_ref) in &imports.functions {
new_imports.functions.insert(*func_ref, *func_index);