Merge pull request #1781 from fitzgen/externref

Initial, partial support for `externref`
This commit is contained in:
Nick Fitzgerald
2020-06-02 09:47:49 -07:00
committed by GitHub
69 changed files with 1144 additions and 490 deletions

0
cranelift/peepmatic/crates/runtime/src/lib.rs Executable file → Normal file
View File

0
cranelift/peepmatic/src/lib.rs Executable file → Normal file
View File

0
cranelift/src/clif-util.rs Executable file → Normal file
View File

View File

@@ -12,7 +12,7 @@ keywords = ["webassembly", "wasm"]
edition = "2018"
[dependencies]
wasmparser = { version = "0.55.0", default-features = false }
wasmparser = { version = "0.57.0", default-features = false }
cranelift-codegen = { path = "../codegen", version = "0.63.0", default-features = false }
cranelift-entity = { path = "../entity", version = "0.63.0" }
cranelift-frontend = { path = "../frontend", version = "0.63.0", default-features = false }

View File

@@ -1171,23 +1171,26 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
)?);
}
Operator::TableGrow { table } => {
let table_index = TableIndex::from_u32(*table);
let delta = state.pop1();
let init_value = state.pop1();
state.push1(environ.translate_table_grow(
builder.cursor(),
*table,
table_index,
delta,
init_value,
)?);
}
Operator::TableGet { table } => {
let table_index = TableIndex::from_u32(*table);
let index = state.pop1();
state.push1(environ.translate_table_get(builder.cursor(), *table, index)?);
state.push1(environ.translate_table_get(builder.cursor(), table_index, index)?);
}
Operator::TableSet { table } => {
let table_index = TableIndex::from_u32(*table);
let value = state.pop1();
let index = state.pop1();
environ.translate_table_set(builder.cursor(), *table, value, index)?;
environ.translate_table_set(builder.cursor(), table_index, value, index)?;
}
Operator::TableCopy {
dst_table: dst_table_index,
@@ -1210,10 +1213,11 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
)?;
}
Operator::TableFill { table } => {
let table_index = TableIndex::from_u32(*table);
let len = state.pop1();
let val = state.pop1();
let dest = state.pop1();
environ.translate_table_fill(builder.cursor(), *table, dest, val, len)?;
environ.translate_table_fill(builder.cursor(), table_index, dest, val, len)?;
}
Operator::TableInit {
segment,
@@ -1561,6 +1565,10 @@ pub fn translate_operator<FE: FuncEnvironment + ?Sized>(
| Operator::I32x4WidenHighI16x8U { .. } => {
return Err(wasm_unsupported!("proposed SIMD operator {:?}", op));
}
Operator::ReturnCall { .. } | Operator::ReturnCallIndirect { .. } => {
return Err(wasm_unsupported!("proposed tail-call operator {:?}", op));
}
};
Ok(())
}

View File

@@ -6,7 +6,8 @@
//! [Wasmtime]: https://github.com/bytecodealliance/wasmtime
use crate::environ::{
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmResult,
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment,
WasmFuncType, WasmResult,
};
use crate::func_translator::FuncTranslator;
use crate::state::ModuleTranslationState;
@@ -433,7 +434,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn translate_table_grow(
&mut self,
mut pos: FuncCursor,
_table_index: u32,
_table_index: TableIndex,
_delta: ir::Value,
_init_value: ir::Value,
) -> WasmResult<ir::Value> {
@@ -443,7 +444,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn translate_table_get(
&mut self,
mut pos: FuncCursor,
_table_index: u32,
_table_index: TableIndex,
_index: ir::Value,
) -> WasmResult<ir::Value> {
Ok(pos.ins().null(self.reference_type()))
@@ -452,7 +453,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn translate_table_set(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_table_index: TableIndex,
_value: ir::Value,
_index: ir::Value,
) -> WasmResult<()> {
@@ -476,7 +477,7 @@ impl<'dummy_environment> FuncEnvironment for DummyFuncEnvironment<'dummy_environ
fn translate_table_fill(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_table_index: TableIndex,
_dst: ir::Value,
_val: ir::Value,
_len: ir::Value,
@@ -534,7 +535,7 @@ impl TargetEnvironment for DummyEnvironment {
}
impl<'data> ModuleEnvironment<'data> for DummyEnvironment {
fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()> {
fn declare_signature(&mut self, _wasm: &WasmFuncType, sig: ir::Signature) -> WasmResult<()> {
self.info.signatures.push(sig);
Ok(())
}

View File

@@ -7,5 +7,5 @@ mod spec;
pub use crate::environ::dummy::DummyEnvironment;
pub use crate::environ::spec::{
FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode, TargetEnvironment, WasmError,
WasmResult,
WasmFuncType, WasmResult, WasmType,
};

View File

@@ -22,6 +22,13 @@ use thiserror::Error;
use wasmparser::BinaryReaderError;
use wasmparser::Operator;
// Re-export `wasmparser`'s function and value types so that consumers can
// associate this the original Wasm signature with each compiled function. This
// is often necessary because while each Wasm signature gets compiled down into
// a single native signature, multiple Wasm signatures might compile down into
// the same native signature.
pub use wasmparser::{FuncType as WasmFuncType, Type as WasmType};
/// The value of a WebAssembly global variable.
#[derive(Clone, Copy)]
pub enum GlobalVariable {
@@ -347,7 +354,7 @@ pub trait FuncEnvironment: TargetEnvironment {
fn translate_table_grow(
&mut self,
pos: FuncCursor,
table_index: u32,
table_index: TableIndex,
delta: ir::Value,
init_value: ir::Value,
) -> WasmResult<ir::Value>;
@@ -356,7 +363,7 @@ pub trait FuncEnvironment: TargetEnvironment {
fn translate_table_get(
&mut self,
pos: FuncCursor,
table_index: u32,
table_index: TableIndex,
index: ir::Value,
) -> WasmResult<ir::Value>;
@@ -364,7 +371,7 @@ pub trait FuncEnvironment: TargetEnvironment {
fn translate_table_set(
&mut self,
pos: FuncCursor,
table_index: u32,
table_index: TableIndex,
value: ir::Value,
index: ir::Value,
) -> WasmResult<()>;
@@ -387,7 +394,7 @@ pub trait FuncEnvironment: TargetEnvironment {
fn translate_table_fill(
&mut self,
pos: FuncCursor,
table_index: u32,
table_index: TableIndex,
dst: ir::Value,
val: ir::Value,
len: ir::Value,
@@ -472,7 +479,11 @@ pub trait ModuleEnvironment<'data>: TargetEnvironment {
}
/// Declares a function signature to the environment.
fn declare_signature(&mut self, sig: ir::Signature) -> WasmResult<()>;
fn declare_signature(
&mut self,
wasm_func_type: &WasmFuncType,
sig: ir::Signature,
) -> WasmResult<()>;
/// Provides the number of imports up front. By default this does nothing, but
/// implementations can use this to preallocate memory if desired.

View File

@@ -59,7 +59,7 @@ mod translation_utils;
pub use crate::environ::{
DummyEnvironment, FuncEnvironment, GlobalVariable, ModuleEnvironment, ReturnMode,
TargetEnvironment, WasmError, WasmResult,
TargetEnvironment, WasmError, WasmFuncType, WasmResult, WasmType,
};
pub use crate::func_translator::FuncTranslator;
pub use crate::module_translator::translate_module;

View File

@@ -23,7 +23,7 @@ use std::boxed::Box;
use std::vec::Vec;
use wasmparser::{
self, CodeSectionReader, Data, DataKind, DataSectionReader, Element, ElementItem, ElementItems,
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind, FuncType,
ElementKind, ElementSectionReader, Export, ExportSectionReader, ExternalKind,
FunctionSectionReader, GlobalSectionReader, GlobalType, ImportSectionEntryType,
ImportSectionReader, MemorySectionReader, MemoryType, NameSectionReader, Naming, NamingReader,
Operator, TableSectionReader, Type, TypeSectionReader,
@@ -40,34 +40,22 @@ pub fn parse_type_section(
environ.reserve_signatures(count)?;
for entry in types {
match entry? {
FuncType {
form: wasmparser::Type::Func,
params,
returns,
} => {
let mut sig =
Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
sig.params.extend(params.iter().map(|ty| {
let cret_arg: ir::Type = type_to_type(*ty, environ)
.expect("only numeric types are supported in function signatures");
AbiParam::new(cret_arg)
}));
sig.returns.extend(returns.iter().map(|ty| {
let cret_arg: ir::Type = type_to_type(*ty, environ)
.expect("only numeric types are supported in function signatures");
AbiParam::new(cret_arg)
}));
environ.declare_signature(sig)?;
module_translation_state.wasm_types.push((params, returns));
}
ty => {
return Err(wasm_unsupported!(
"unsupported type in type section: {:?}",
ty
))
}
}
let wasm_func_ty = entry?;
let mut sig = Signature::new(ModuleEnvironment::target_config(environ).default_call_conv);
sig.params.extend(wasm_func_ty.params.iter().map(|ty| {
let cret_arg: ir::Type = type_to_type(*ty, environ)
.expect("only numeric types are supported in function signatures");
AbiParam::new(cret_arg)
}));
sig.returns.extend(wasm_func_ty.returns.iter().map(|ty| {
let cret_arg: ir::Type = type_to_type(*ty, environ)
.expect("only numeric types are supported in function signatures");
AbiParam::new(cret_arg)
}));
environ.declare_signature(&wasm_func_ty, sig)?;
module_translation_state
.wasm_types
.push((wasm_func_ty.params, wasm_func_ty.returns));
}
Ok(())
}