Update wasmparser to 0.51.3 and clif forks to 0.59

This commit is contained in:
Mark McCaskey 2020-02-26 12:51:56 -08:00
parent 6059c04630
commit 21fd95d760
10 changed files with 188 additions and 84 deletions

72
Cargo.lock generated
View File

@ -221,35 +221,36 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]] [[package]]
name = "cranelift-bforest" name = "cranelift-bforest"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56aa72ef104c5d634f2f9e84ef2c47e116c1d185fae13f196b97ca84b0a514f1" checksum = "45a9c21f8042b9857bda93f6c1910b9f9f24100187a3d3d52f214a34e3dc5818"
dependencies = [ dependencies = [
"cranelift-entity", "cranelift-entity",
] ]
[[package]] [[package]]
name = "cranelift-codegen" name = "cranelift-codegen"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460b9d20793543599308d22f5a1172c196e63a780c4e9aacb0b3f4f63d63ffe1" checksum = "7853f77a6e4a33c67a69c40f5e1bb982bd2dc5c4a22e17e67b65bbccf9b33b2e"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"cranelift-bforest", "cranelift-bforest",
"cranelift-codegen-meta", "cranelift-codegen-meta",
"cranelift-codegen-shared", "cranelift-codegen-shared",
"cranelift-entity", "cranelift-entity",
"gimli",
"log", "log",
"smallvec", "smallvec 1.2.0",
"target-lexicon", "target-lexicon",
"thiserror", "thiserror",
] ]
[[package]] [[package]]
name = "cranelift-codegen-meta" name = "cranelift-codegen-meta"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc70e4e8ccebd53a4f925147def857c9e9f7fe0fdbef4bb645a420473e012f50" checksum = "084cd6d5fb0d1da28acd72c199471bfb09acc703ec8f3bf07b1699584272a3b9"
dependencies = [ dependencies = [
"cranelift-codegen-shared", "cranelift-codegen-shared",
"cranelift-entity", "cranelift-entity",
@ -257,21 +258,21 @@ dependencies = [
[[package]] [[package]]
name = "cranelift-codegen-shared" name = "cranelift-codegen-shared"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3992000be4d18df0fe332b7c42c120de896e8ec54cd7b6cfa050910a8c9f6e2f" checksum = "701b599783305a58c25027a4d73f2d6b599b2d8ef3f26677275f480b4d51e05d"
[[package]] [[package]]
name = "cranelift-entity" name = "cranelift-entity"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "722957e05064d97a3157bf0976deed0f3e8ee4f8a4ce167a7c724ca63a4e8bd9" checksum = "b88e792b28e1ebbc0187b72ba5ba880dad083abe9231a99d19604d10c9e73f38"
[[package]] [[package]]
name = "cranelift-native" name = "cranelift-native"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21398a0bc6ba389ea86964ac4a495426dd61080f2ddd306184777a8560fe9976" checksum = "32daf082da21c0c05d93394ff4842c2ab7c4991b1f3186a1d952f8ac660edd0b"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"raw-cpuid", "raw-cpuid",
@ -537,6 +538,16 @@ dependencies = [
"syn 1.0.14", "syn 1.0.14",
] ]
[[package]]
name = "gimli"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81dd6190aad0f05ddbbf3245c54ed14ca4aa6dd32f22312b70d8f168c3e3e633"
dependencies = [
"byteorder",
"indexmap",
]
[[package]] [[package]]
name = "glob" name = "glob"
version = "0.2.11" version = "0.2.11"
@ -926,7 +937,7 @@ dependencies = [
"cloudabi", "cloudabi",
"libc", "libc",
"redox_syscall", "redox_syscall",
"smallvec", "smallvec 1.2.0",
"winapi", "winapi",
] ]
@ -1414,6 +1425,15 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "smallvec"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
dependencies = [
"maybe-uninit",
]
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.2.0" version = "1.2.0"
@ -1503,9 +1523,9 @@ dependencies = [
[[package]] [[package]]
name = "target-lexicon" name = "target-lexicon"
version = "0.9.0" version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4" checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
[[package]] [[package]]
name = "tempfile" name = "tempfile"
@ -1758,21 +1778,21 @@ dependencies = [
[[package]] [[package]]
name = "wasmer-clif-fork-frontend" name = "wasmer-clif-fork-frontend"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2e13201ef9ef527ad30a6bf1b08e3e024a40cf2731f393d80375dc88506207" checksum = "c23f2824f354a00a77e4b040eef6e1d4c595a8a3e9013bad65199cc8dade9a5a"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"log", "log",
"smallvec", "smallvec 1.2.0",
"target-lexicon", "target-lexicon",
] ]
[[package]] [[package]]
name = "wasmer-clif-fork-wasm" name = "wasmer-clif-fork-wasm"
version = "0.52.0" version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8b09302cc4fdc4efc03823cb3e1880b0fde578ba43f27ddd212811cb28c1530" checksum = "a35e21d3aebc51cc6ebc0e830cf8458a9891c3482fb3c65ad18d408102929ae5"
dependencies = [ dependencies = [
"cranelift-codegen", "cranelift-codegen",
"cranelift-entity", "cranelift-entity",
@ -1846,7 +1866,7 @@ dependencies = [
"regex", "regex",
"rustc_version", "rustc_version",
"semver", "semver",
"smallvec", "smallvec 0.6.13",
"wabt", "wabt",
"wasmer-runtime-core", "wasmer-runtime-core",
"wasmparser", "wasmparser",
@ -1933,7 +1953,7 @@ dependencies = [
"serde-bench", "serde-bench",
"serde_bytes", "serde_bytes",
"serde_derive", "serde_derive",
"smallvec", "smallvec 0.6.13",
"wasmparser", "wasmparser",
"winapi", "winapi",
] ]
@ -1962,7 +1982,7 @@ dependencies = [
"nix", "nix",
"serde", "serde",
"serde_derive", "serde_derive",
"smallvec", "smallvec 0.6.13",
"wasmer-runtime-core", "wasmer-runtime-core",
] ]
@ -2033,9 +2053,9 @@ dependencies = [
[[package]] [[package]]
name = "wasmparser" name = "wasmparser"
version = "0.45.2" version = "0.51.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b4eab1d9971d0803729cba3617b56eb04fcb4bd25361cb63880ed41a42f20d5" checksum = "447465bb5cf5ecd5918919ef3a0002e0839c87fb2a9483d4816d9b2cc36221fa"
[[package]] [[package]]
name = "wast" name = "wast"

View File

@ -12,13 +12,13 @@ readme = "README.md"
[dependencies] [dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
cranelift-native = "0.52.0" cranelift-native = "0.59.0"
cranelift-codegen = "0.52.0" cranelift-codegen = "0.59.0"
cranelift-entity = "0.52.0" cranelift-entity = "0.59.0"
cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.52.0" } cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.59.0" }
cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.52.0" } cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.59.0" }
target-lexicon = "0.9" target-lexicon = "0.10"
wasmparser = "0.45.0" wasmparser = "0.51.3"
byteorder = "1.3.2" byteorder = "1.3.2"
nix = "0.15.0" nix = "0.15.0"
libc = "0.2.60" libc = "0.2.60"

View File

@ -7,13 +7,14 @@ use crate::{
}; };
use cranelift_codegen::entity::EntityRef; use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{self, Ebb, Function, InstBuilder}; use cranelift_codegen::ir::{self, Block, Function, InstBuilder};
use cranelift_codegen::isa::CallConv; use cranelift_codegen::isa::CallConv;
use cranelift_codegen::{cursor::FuncCursor, isa}; use cranelift_codegen::{cursor::FuncCursor, isa};
use cranelift_frontend::{FunctionBuilder, Position, Variable}; use cranelift_frontend::{FunctionBuilder, Position, Variable};
use cranelift_wasm::{self, FuncTranslator, ModuleTranslationState}; use cranelift_wasm::{self, FuncTranslator, ModuleTranslationState};
use cranelift_wasm::{get_vmctx_value_label, translate_operator}; use cranelift_wasm::{get_vmctx_value_label, translate_operator};
use cranelift_wasm::{FuncEnvironment, ReturnMode, TargetEnvironment, WasmError}; use cranelift_wasm::{FuncEnvironment, ReturnMode, TargetEnvironment, WasmError};
use std::mem; use std::mem;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use wasmer_runtime_core::error::CompileError; use wasmer_runtime_core::error::CompileError;
@ -103,7 +104,7 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
}, },
}; };
debug_assert_eq!(func_env.func.dfg.num_ebbs(), 0, "Function must be empty"); debug_assert_eq!(func_env.func.dfg.num_blocks(), 0, "Function must be empty");
debug_assert_eq!(func_env.func.dfg.num_insts(), 0, "Function must be empty"); debug_assert_eq!(func_env.func.dfg.num_insts(), 0, "Function must be empty");
let mut builder = FunctionBuilder::new( let mut builder = FunctionBuilder::new(
@ -115,20 +116,20 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
// TODO srcloc // TODO srcloc
//builder.set_srcloc(cur_srcloc(&reader)); //builder.set_srcloc(cur_srcloc(&reader));
let entry_block = builder.create_ebb(); let entry_block = builder.create_block();
builder.append_ebb_params_for_function_params(entry_block); builder.append_block_params_for_function_params(entry_block);
builder.switch_to_block(entry_block); // This also creates values for the arguments. builder.switch_to_block(entry_block); // This also creates values for the arguments.
builder.seal_block(entry_block); builder.seal_block(entry_block);
// Make sure the entry block is inserted in the layout before we make any callbacks to // Make sure the entry block is inserted in the layout before we make any callbacks to
// `environ`. The callback functions may need to insert things in the entry block. // `environ`. The callback functions may need to insert things in the entry block.
builder.ensure_inserted_ebb(); builder.ensure_inserted_block();
declare_wasm_parameters(&mut builder, entry_block); declare_wasm_parameters(&mut builder, entry_block);
// Set up the translation state with a single pushed control block representing the whole // Set up the translation state with a single pushed control block representing the whole
// function and its return values. // function and its return values.
let exit_block = builder.create_ebb(); let exit_block = builder.create_block();
builder.append_ebb_params_for_function_returns(exit_block); builder.append_block_params_for_function_returns(exit_block);
func_env func_env
.func_translator .func_translator
.state .state
@ -1005,7 +1006,7 @@ impl FuncEnvironment for FunctionEnvironment {
_src: ir::Value, _src: ir::Value,
_len: ir::Value, _len: ir::Value,
) -> cranelift_wasm::WasmResult<()> { ) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.copy yet implemented"); unimplemented!("table.copy not yet implemented");
} }
fn translate_table_init( fn translate_table_init(
@ -1018,7 +1019,7 @@ impl FuncEnvironment for FunctionEnvironment {
_src: ir::Value, _src: ir::Value,
_len: ir::Value, _len: ir::Value,
) -> cranelift_wasm::WasmResult<()> { ) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.init yet implemented"); unimplemented!("table.init not yet implemented");
} }
fn translate_elem_drop( fn translate_elem_drop(
@ -1026,7 +1027,72 @@ impl FuncEnvironment for FunctionEnvironment {
_pos: FuncCursor, _pos: FuncCursor,
_seg_index: u32, _seg_index: u32,
) -> cranelift_wasm::WasmResult<()> { ) -> cranelift_wasm::WasmResult<()> {
unimplemented!("elem.drop yet implemented"); unimplemented!("elem.drop not yet implemented");
}
fn translate_table_grow(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_delta: ir::Value,
_init_value: ir::Value,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("table.grow not yet implemented");
}
fn translate_table_get(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_index: ir::Value,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("table.get not yet implemented");
}
fn translate_table_set(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_value: ir::Value,
_index: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.set not yet implemented");
}
fn translate_table_fill(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_dst: ir::Value,
_val: ir::Value,
_len: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.fill not yet implemented");
}
fn translate_ref_func(
&mut self,
_pos: FuncCursor,
_func_index: u32,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("ref.func not yet implemented");
}
fn translate_custom_global_get(
&mut self,
_pos: FuncCursor,
_global_index: cranelift_wasm::GlobalIndex,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("custom global.get not yet implemented");
}
fn translate_custom_global_set(
&mut self,
_pos: FuncCursor,
_global_index: cranelift_wasm::GlobalIndex,
_val: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("custom global.set not yet implemented");
} }
} }
@ -1215,7 +1281,7 @@ fn pointer_type(mcg: &CraneliftModuleCodeGenerator) -> ir::Type {
/// Declare local variables for the signature parameters that correspond to WebAssembly locals. /// Declare local variables for the signature parameters that correspond to WebAssembly locals.
/// ///
/// Return the number of local variables declared. /// Return the number of local variables declared.
fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> usize { fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Block) -> usize {
let sig_len = builder.func.signature.params.len(); let sig_len = builder.func.signature.params.len();
let mut next_local = 0; let mut next_local = 0;
for i in 0..sig_len { for i in 0..sig_len {
@ -1228,11 +1294,11 @@ fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> u
builder.declare_var(local, param_type.value_type); builder.declare_var(local, param_type.value_type);
next_local += 1; next_local += 1;
let param_value = builder.ebb_params(entry_block)[i]; let param_value = builder.block_params(entry_block)[i];
builder.def_var(local, param_value); builder.def_var(local, param_value);
} }
if param_type.purpose == ir::ArgumentPurpose::VMContext { if param_type.purpose == ir::ArgumentPurpose::VMContext {
let param_value = builder.ebb_params(entry_block)[i]; let param_value = builder.block_params(entry_block)[i];
builder.set_val_label(param_value, get_vmctx_value_label()); builder.set_val_label(param_value, get_vmctx_value_label());
} }
} }

View File

@ -98,7 +98,7 @@ pub struct RelocSink {
} }
impl binemit::RelocSink for RelocSink { impl binemit::RelocSink for RelocSink {
fn reloc_ebb( fn reloc_block(
&mut self, &mut self,
_offset: binemit::CodeOffset, _offset: binemit::CodeOffset,
_reloc: binemit::Reloc, _reloc: binemit::Reloc,

View File

@ -16,7 +16,7 @@ use wasmer_runtime_core::{
struct NullRelocSink {} struct NullRelocSink {}
impl RelocSink for NullRelocSink { impl RelocSink for NullRelocSink {
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {} fn reloc_block(&mut self, _: u32, _: Reloc, _: u32) {}
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {} fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {}
fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) { fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) {
@ -158,12 +158,12 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function {
let export_sig_ref = func.import_signature(generate_export_signature(func_sig)); let export_sig_ref = func.import_signature(generate_export_signature(func_sig));
let entry_ebb = func.dfg.make_ebb(); let entry_ebb = func.dfg.make_block();
let vmctx_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); let vmctx_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let func_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); let func_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let args_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); let args_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let returns_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64); let returns_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
func.layout.append_ebb(entry_ebb); func.layout.append_block(entry_ebb);
let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb); let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb);

View File

@ -11,7 +11,7 @@ readme = "README.md"
[dependencies] [dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" } wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
wasmparser = "0.45.0" wasmparser = "0.51.3"
smallvec = "0.6" smallvec = "0.6"
goblin = "0.0.24" goblin = "0.0.24"
libc = "0.2.60" libc = "0.2.60"

View File

@ -12,7 +12,7 @@ edition = "2018"
[dependencies] [dependencies]
nix = "0.15" nix = "0.15"
page_size = "0.4" page_size = "0.4"
wasmparser = "0.45.0" wasmparser = "0.51.3"
parking_lot = "0.10.0" parking_lot = "0.10.0"
lazy_static = "1.4" lazy_static = "1.4"
errno = "0.2" errno = "0.2"

View File

@ -205,8 +205,8 @@ fn validate_with_features(bytes: &[u8], features: &Features) -> CompileResult<()
let state = parser.read(); let state = parser.read();
match *state { match *state {
wasmparser::ParserState::EndWasm => break Ok(()), wasmparser::ParserState::EndWasm => break Ok(()),
wasmparser::ParserState::Error(err) => Err(CompileError::ValidationError { wasmparser::ParserState::Error(ref err) => Err(CompileError::ValidationError {
msg: err.message.to_string(), msg: err.message().to_string(),
})?, })?,
_ => {} _ => {}
} }

View File

@ -167,7 +167,7 @@ pub fn validate_and_report_errors_with_features(
let state = parser.read(); let state = parser.read();
match *state { match *state {
wasmparser::ParserState::EndWasm => break Ok(()), wasmparser::ParserState::EndWasm => break Ok(()),
wasmparser::ParserState::Error(e) => break Err(format!("{}", e)), wasmparser::ParserState::Error(ref e) => break Err(format!("{}", e)),
_ => {} _ => {}
} }
} }

View File

@ -21,15 +21,15 @@ use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::sync::{Arc, RwLock}; use std::sync::{Arc, RwLock};
use wasmparser::{ use wasmparser::{
BinaryReaderError, ExternalKind, FuncType, ImportSectionEntryType, Operator, Type as WpType, BinaryReaderError, ElemSectionEntryTable, ElementItem, ExternalKind, FuncType,
WasmDecoder, ImportSectionEntryType, Operator, Type as WpType, WasmDecoder,
}; };
/// Kind of load error. /// Kind of load error.
#[derive(Debug)] #[derive(Debug)]
pub enum LoadError { pub enum LoadError {
/// Parse error. /// Parse error.
Parse(BinaryReaderError), Parse(String),
/// Code generation error. /// Code generation error.
Codegen(String), Codegen(String),
} }
@ -44,7 +44,13 @@ impl From<LoadError> for CompileError {
impl From<BinaryReaderError> for LoadError { impl From<BinaryReaderError> for LoadError {
fn from(other: BinaryReaderError) -> LoadError { fn from(other: BinaryReaderError) -> LoadError {
LoadError::Parse(other) LoadError::Parse(format!("{:?}", other))
}
}
impl From<&BinaryReaderError> for LoadError {
fn from(other: &BinaryReaderError) -> LoadError {
LoadError::Parse(format!("{:?}", other))
} }
} }
@ -106,7 +112,7 @@ pub fn read_module<
use wasmparser::ParserState; use wasmparser::ParserState;
let state = parser.read(); let state = parser.read();
match *state { match *state {
ParserState::Error(err) => Err(LoadError::Parse(err))?, ParserState::Error(ref err) => return Err(err.clone().into()),
ParserState::TypeSectionEntry(ref ty) => { ParserState::TypeSectionEntry(ref ty) => {
info.write() info.write()
.unwrap() .unwrap()
@ -253,7 +259,7 @@ pub fn read_module<
loop { loop {
let state = parser.read(); let state = parser.read();
match state { match state {
ParserState::Error(err) => return Err(LoadError::Parse(*err)), ParserState::Error(err) => return Err(err.into()),
ParserState::FunctionBodyLocals { ref locals } => { ParserState::FunctionBodyLocals { ref locals } => {
for &(count, ty) in locals.iter() { for &(count, ty) in locals.iter() {
fcg.feed_local(ty, count as usize) fcg.feed_local(ty, count as usize)
@ -292,15 +298,18 @@ pub fn read_module<
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?; .map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
func_count = func_count.wrapping_add(1); func_count = func_count.wrapping_add(1);
} }
ParserState::BeginActiveElementSectionEntry(table_index) => { ParserState::BeginElementSectionEntry {
let table_index = TableIndex::new(table_index as usize); table: ElemSectionEntryTable::Active(table_index_raw),
ty: WpType::Func,
} => {
let table_index = TableIndex::new(table_index_raw as usize);
let mut elements: Option<Vec<FuncIndex>> = None; let mut elements: Option<Vec<FuncIndex>> = None;
let mut base: Option<Initializer> = None; let mut base: Option<Initializer> = None;
loop { loop {
let state = parser.read(); let state = parser.read();
match *state { match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)), ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => { ParserState::InitExpressionOperator(ref op) => {
base = Some(eval_init_expr(op)?) base = Some(eval_init_expr(op)?)
} }
@ -308,9 +317,11 @@ pub fn read_module<
elements = Some( elements = Some(
_elements _elements
.iter() .iter()
.cloned() .map(|elem_idx| match elem_idx {
.map(|index| FuncIndex::new(index as usize)) ElementItem::Null => Err(LoadError::Parse(format!("Error at table {}: null entries in tables are not yet supported", table_index_raw))),
.collect(), ElementItem::Func(idx) => Ok(FuncIndex::new(*idx as usize)),
})
.collect::<Result<Vec<FuncIndex>, LoadError>>()?,
); );
} }
ParserState::BeginInitExpressionBody ParserState::BeginInitExpressionBody
@ -328,6 +339,15 @@ pub fn read_module<
info.write().unwrap().elem_initializers.push(table_init); info.write().unwrap().elem_initializers.push(table_init);
} }
ParserState::BeginElementSectionEntry {
table: ElemSectionEntryTable::Active(table_index),
ty,
} => {
return Err(LoadError::Parse(format!(
"Error at table {}: type \"{:?}\" is not supported in tables yet",
table_index, ty
)));
}
ParserState::BeginActiveDataSectionEntry(memory_index) => { ParserState::BeginActiveDataSectionEntry(memory_index) => {
let memory_index = MemoryIndex::new(memory_index as usize); let memory_index = MemoryIndex::new(memory_index as usize);
let mut base: Option<Initializer> = None; let mut base: Option<Initializer> = None;
@ -336,7 +356,7 @@ pub fn read_module<
loop { loop {
let state = parser.read(); let state = parser.read();
match *state { match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)), ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => { ParserState::InitExpressionOperator(ref op) => {
base = Some(eval_init_expr(op)?) base = Some(eval_init_expr(op)?)
} }
@ -363,7 +383,7 @@ pub fn read_module<
let init = loop { let init = loop {
let state = parser.read(); let state = parser.read();
match *state { match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)), ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => { ParserState::InitExpressionOperator(ref op) => {
break eval_init_expr(op)?; break eval_init_expr(op)?;
} }
@ -402,7 +422,7 @@ pub fn read_module<
} }
/// Convert given `WpType` to `Type`. /// Convert given `WpType` to `Type`.
pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> { pub fn wp_type_to_type(ty: WpType) -> Result<Type, LoadError> {
match ty { match ty {
WpType::I32 => Ok(Type::I32), WpType::I32 => Ok(Type::I32),
WpType::I64 => Ok(Type::I64), WpType::I64 => Ok(Type::I64),
@ -410,10 +430,9 @@ pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
WpType::F64 => Ok(Type::F64), WpType::F64 => Ok(Type::F64),
WpType::V128 => Ok(Type::V128), WpType::V128 => Ok(Type::V128),
_ => { _ => {
return Err(BinaryReaderError { return Err(LoadError::Parse(
message: "broken invariant, invalid type", "broken invariant, invalid type".to_string(),
offset: -1isize as usize, ));
});
} }
} }
} }
@ -429,7 +448,7 @@ pub fn type_to_wp_type(ty: Type) -> WpType {
} }
} }
fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, BinaryReaderError> { fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, LoadError> {
assert_eq!(func_ty.form, WpType::Func); assert_eq!(func_ty.form, WpType::Func);
Ok(FuncSig::new( Ok(FuncSig::new(
@ -448,7 +467,7 @@ fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, BinaryReaderErro
)) ))
} }
fn eval_init_expr(op: &Operator) -> Result<Initializer, BinaryReaderError> { fn eval_init_expr(op: &Operator) -> Result<Initializer, LoadError> {
Ok(match *op { Ok(match *op {
Operator::GlobalGet { global_index } => { Operator::GlobalGet { global_index } => {
Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize)) Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize))
@ -465,10 +484,9 @@ fn eval_init_expr(op: &Operator) -> Result<Initializer, BinaryReaderError> {
Initializer::Const(Value::V128(u128::from_le_bytes(*value.bytes()))) Initializer::Const(Value::V128(u128::from_le_bytes(*value.bytes())))
} }
_ => { _ => {
return Err(BinaryReaderError { return Err(LoadError::Parse(
message: "init expr evaluation failed: unsupported opcode", "init expr evaluation failed: unsupported opcode".to_string(),
offset: -1isize as usize, ));
});
} }
}) })
} }