mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-03 08:21:04 +00:00
Cleanup & add imports.
This commit is contained in:
parent
bbb27bedbe
commit
ffc1bde3d8
@ -1,302 +1,11 @@
|
|||||||
use std::ptr::NonNull;
|
#![feature(proc_macro_hygiene)]
|
||||||
use std::sync::Arc;
|
|
||||||
use wasmer_runtime_core::{
|
|
||||||
backend::{Backend, Compiler, FuncResolver, ProtectedCaller, Token},
|
|
||||||
error::{CompileError, CompileResult, RuntimeResult},
|
|
||||||
module::{
|
|
||||||
DataInitializer, ExportIndex, ImportName, ModuleInfo, ModuleInner, StringTable,
|
|
||||||
TableInitializer,
|
|
||||||
},
|
|
||||||
structures::{Map, TypedIndex},
|
|
||||||
types::{
|
|
||||||
ElementType, FuncIndex, FuncSig, GlobalDescriptor, GlobalIndex, GlobalInit,
|
|
||||||
ImportedGlobalIndex, Initializer, LocalFuncIndex, MemoryDescriptor, MemoryIndex,
|
|
||||||
TableDescriptor, TableIndex, Type as CoreType, Value,
|
|
||||||
},
|
|
||||||
units::Pages,
|
|
||||||
vm::{self, ImportBacking},
|
|
||||||
};
|
|
||||||
use wasmparser::{
|
|
||||||
self, ExternalKind, FuncType, ImportSectionEntryType, InitExpr, MemoryType, ModuleReader,
|
|
||||||
Operator, SectionCode, TableType, Type, WasmDecoder,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Placeholder;
|
#[macro_use]
|
||||||
|
extern crate dynasmrt;
|
||||||
|
|
||||||
impl FuncResolver for Placeholder {
|
#[macro_use]
|
||||||
fn get(
|
extern crate dynasm;
|
||||||
&self,
|
|
||||||
_module: &ModuleInner,
|
|
||||||
_local_func_index: LocalFuncIndex,
|
|
||||||
) -> Option<NonNull<vm::Func>> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ProtectedCaller for Placeholder {
|
mod codegen;
|
||||||
fn call(
|
mod codegen_x64;
|
||||||
&self,
|
mod parse;
|
||||||
_module: &ModuleInner,
|
|
||||||
_func_index: FuncIndex,
|
|
||||||
_params: &[Value],
|
|
||||||
_import_backing: &ImportBacking,
|
|
||||||
_vmctx: *mut vm::Ctx,
|
|
||||||
_: Token,
|
|
||||||
) -> RuntimeResult<Vec<Value>> {
|
|
||||||
Ok(vec![])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct DynasmCompiler {}
|
|
||||||
|
|
||||||
impl DynasmCompiler {
|
|
||||||
pub fn new() -> DynasmCompiler {
|
|
||||||
DynasmCompiler {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Compiler for DynasmCompiler {
|
|
||||||
fn compile(&self, wasm: &[u8], _: Token) -> CompileResult<ModuleInner> {
|
|
||||||
validate(wasm)?;
|
|
||||||
|
|
||||||
let mut reader = ModuleReader::new(wasm)?;
|
|
||||||
let mut m = ModuleInner {
|
|
||||||
// this is a placeholder
|
|
||||||
func_resolver: Box::new(Placeholder),
|
|
||||||
protected_caller: Box::new(Placeholder),
|
|
||||||
|
|
||||||
info: ModuleInfo {
|
|
||||||
memories: Map::new(),
|
|
||||||
globals: Map::new(),
|
|
||||||
tables: Map::new(),
|
|
||||||
|
|
||||||
imported_functions: Map::new(),
|
|
||||||
imported_memories: Map::new(),
|
|
||||||
imported_tables: Map::new(),
|
|
||||||
imported_globals: Map::new(),
|
|
||||||
|
|
||||||
exports: Default::default(),
|
|
||||||
|
|
||||||
data_initializers: Vec::new(),
|
|
||||||
elem_initializers: Vec::new(),
|
|
||||||
|
|
||||||
start_func: None,
|
|
||||||
|
|
||||||
func_assoc: Map::new(),
|
|
||||||
signatures: Map::new(),
|
|
||||||
backend: Backend::Cranelift,
|
|
||||||
|
|
||||||
namespace_table: StringTable::new(),
|
|
||||||
name_table: StringTable::new(),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let mut types: Vec<FuncType> = Vec::new();
|
|
||||||
|
|
||||||
loop {
|
|
||||||
if reader.eof() {
|
|
||||||
return Ok(m);
|
|
||||||
}
|
|
||||||
let section = reader.read()?;
|
|
||||||
match section.code {
|
|
||||||
SectionCode::Custom { .. } => {}
|
|
||||||
SectionCode::Type => {
|
|
||||||
let mut ty_reader = section.get_type_section_reader()?;
|
|
||||||
let count = ty_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
types.push(ty_reader.read()?);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Import => {
|
|
||||||
let mut imp_reader = section.get_import_section_reader()?;
|
|
||||||
let count = imp_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let imp = imp_reader.read()?;
|
|
||||||
// FIXME: not implemented
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Function => {
|
|
||||||
let mut func_reader = section.get_function_section_reader()?;
|
|
||||||
let count = func_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let ty_id = func_reader.read()? as usize;
|
|
||||||
m.info.signatures.push(Arc::new(FuncSig::new(
|
|
||||||
types[ty_id]
|
|
||||||
.params
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(CoreType::from_wasmparser_type)
|
|
||||||
.collect::<CompileResult<Vec<CoreType>>>()?,
|
|
||||||
types[ty_id]
|
|
||||||
.returns
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.map(CoreType::from_wasmparser_type)
|
|
||||||
.collect::<CompileResult<Vec<CoreType>>>()?,
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Table => {
|
|
||||||
let mut table_reader = section.get_table_section_reader()?;
|
|
||||||
let count = table_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let tt = table_reader.read()?;
|
|
||||||
if tt.element_type != Type::AnyFunc {
|
|
||||||
return Err(CompileError::InternalError {
|
|
||||||
msg: "unsupported table element type".into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
m.info.tables.push(TableDescriptor {
|
|
||||||
element: ElementType::Anyfunc,
|
|
||||||
minimum: tt.limits.initial,
|
|
||||||
maximum: tt.limits.maximum,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Memory => {
|
|
||||||
let mut mem_reader = section.get_memory_section_reader()?;
|
|
||||||
let count = mem_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let mem_info = mem_reader.read()?;
|
|
||||||
m.info.memories.push(MemoryDescriptor {
|
|
||||||
minimum: Pages(mem_info.limits.initial),
|
|
||||||
maximum: mem_info.limits.maximum.map(Pages),
|
|
||||||
shared: mem_info.shared,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Global => {
|
|
||||||
let mut global_reader = section.get_global_section_reader()?;
|
|
||||||
let count = global_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let info = global_reader.read()?;
|
|
||||||
m.info.globals.push(GlobalInit {
|
|
||||||
desc: GlobalDescriptor {
|
|
||||||
mutable: info.ty.mutable,
|
|
||||||
ty: CoreType::from_wasmparser_type(info.ty.content_type)?,
|
|
||||||
},
|
|
||||||
init: eval_init_expr(&info.init_expr)?,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Export => {
|
|
||||||
let mut export_reader = section.get_export_section_reader()?;
|
|
||||||
let count = export_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let v = export_reader.read()?;
|
|
||||||
m.info.exports.insert(
|
|
||||||
match ::std::str::from_utf8(v.field) {
|
|
||||||
Ok(x) => x.to_string(),
|
|
||||||
Err(_) => {
|
|
||||||
return Err(CompileError::InternalError {
|
|
||||||
msg: "field name not in utf-8".into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
match v.kind {
|
|
||||||
ExternalKind::Function => {
|
|
||||||
ExportIndex::Func(FuncIndex::new(v.index as usize))
|
|
||||||
}
|
|
||||||
ExternalKind::Global => {
|
|
||||||
ExportIndex::Global(GlobalIndex::new(v.index as usize))
|
|
||||||
}
|
|
||||||
ExternalKind::Memory => {
|
|
||||||
ExportIndex::Memory(MemoryIndex::new(v.index as usize))
|
|
||||||
}
|
|
||||||
ExternalKind::Table => {
|
|
||||||
ExportIndex::Table(TableIndex::new(v.index as usize))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Start => {
|
|
||||||
m.info.start_func =
|
|
||||||
Some(FuncIndex::new(section.get_start_section_content()? as usize));
|
|
||||||
}
|
|
||||||
SectionCode::Element => {
|
|
||||||
let mut element_reader = section.get_element_section_reader()?;
|
|
||||||
let count = element_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let elem = element_reader.read()?;
|
|
||||||
let table_index = elem.table_index as usize;
|
|
||||||
|
|
||||||
let mut item_reader = elem.items.get_items_reader()?;
|
|
||||||
let item_count = item_reader.get_count() as usize;
|
|
||||||
|
|
||||||
m.info.elem_initializers.push(TableInitializer {
|
|
||||||
table_index: TableIndex::new(table_index),
|
|
||||||
base: eval_init_expr(&elem.init_expr)?,
|
|
||||||
elements: (0..item_count)
|
|
||||||
.map(|_| Ok(FuncIndex::new(item_reader.read()? as usize)))
|
|
||||||
.collect::<CompileResult<_>>()?,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Code => {
|
|
||||||
let mut code_reader = section.get_code_section_reader()?;
|
|
||||||
let count = code_reader.get_count() as usize;
|
|
||||||
|
|
||||||
if count != m.info.signatures.len() {
|
|
||||||
return Err(CompileError::InternalError {
|
|
||||||
msg: "len(function_bodies) != len(functions)".into(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for i in 0..count {
|
|
||||||
let body = code_reader.read()?;
|
|
||||||
// FIXME: not implemented
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SectionCode::Data => {
|
|
||||||
let mut data_reader = section.get_data_section_reader()?;
|
|
||||||
let count = data_reader.get_count();
|
|
||||||
for _ in 0..count {
|
|
||||||
let initializer = data_reader.read()?;
|
|
||||||
m.info.data_initializers.push(DataInitializer {
|
|
||||||
memory_index: MemoryIndex::new(initializer.memory_index as usize),
|
|
||||||
base: eval_init_expr(&initializer.init_expr)?,
|
|
||||||
data: initializer.data.to_vec(),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate(bytes: &[u8]) -> CompileResult<()> {
|
|
||||||
let mut parser = wasmparser::ValidatingParser::new(bytes, None);
|
|
||||||
loop {
|
|
||||||
let state = parser.read();
|
|
||||||
match *state {
|
|
||||||
wasmparser::ParserState::EndWasm => break Ok(()),
|
|
||||||
wasmparser::ParserState::Error(err) => Err(CompileError::ValidationError {
|
|
||||||
msg: err.message.to_string(),
|
|
||||||
})?,
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn eval_init_expr(expr: &InitExpr) -> CompileResult<Initializer> {
|
|
||||||
let mut reader = expr.get_operators_reader();
|
|
||||||
let op = reader.read()?;
|
|
||||||
Ok(match op {
|
|
||||||
Operator::GetGlobal { global_index } => {
|
|
||||||
Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize))
|
|
||||||
}
|
|
||||||
Operator::I32Const { value } => Initializer::Const(Value::I32(value)),
|
|
||||||
Operator::I64Const { value } => Initializer::Const(Value::I64(value)),
|
|
||||||
Operator::F32Const { value } => {
|
|
||||||
Initializer::Const(Value::F32(unsafe { ::std::mem::transmute(value.bits()) }))
|
|
||||||
}
|
|
||||||
Operator::F64Const { value } => {
|
|
||||||
Initializer::Const(Value::F64(unsafe { ::std::mem::transmute(value.bits()) }))
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return Err(CompileError::InternalError {
|
|
||||||
msg: "init expr evaluation failed: unsupported opcode".into(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user