WIP.
This commit is contained in:
parent
86454940af
commit
e04a4113a2
|
@ -27,6 +27,24 @@ pub fn wasm_to_ir(bytes: &[u8]) -> Result<Module<'_>> {
|
||||||
Ok(module)
|
Ok(module)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<usize> {
|
||||||
|
let operators = init_expr
|
||||||
|
.get_operators_reader()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Result<Vec<wasmparser::Operator>, _>>()?;
|
||||||
|
if operators.len() != 2 || !matches!(&operators[1], &wasmparser::Operator::End) {
|
||||||
|
anyhow::bail!(
|
||||||
|
"Unsupported operator seq in base-address expr: {:?}",
|
||||||
|
operators
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Ok(match &operators[0] {
|
||||||
|
&wasmparser::Operator::I32Const { value } => value as usize,
|
||||||
|
&wasmparser::Operator::I64Const { value } => value as usize,
|
||||||
|
op => anyhow::bail!("Unsupported data segment base-address operator: {:?}", op),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn handle_payload<'a>(
|
fn handle_payload<'a>(
|
||||||
module: &mut Module<'a>,
|
module: &mut Module<'a>,
|
||||||
payload: Payload<'a>,
|
payload: Payload<'a>,
|
||||||
|
@ -138,26 +156,7 @@ fn handle_payload<'a>(
|
||||||
} => {
|
} => {
|
||||||
let data = segment.data.to_vec();
|
let data = segment.data.to_vec();
|
||||||
let memory = Memory::from(*memory_index);
|
let memory = Memory::from(*memory_index);
|
||||||
let operators = init_expr
|
let offset = parse_init_expr(init_expr)?;
|
||||||
.get_operators_reader()
|
|
||||||
.into_iter()
|
|
||||||
.collect::<Result<Vec<wasmparser::Operator>, _>>()?;
|
|
||||||
if operators.len() != 2
|
|
||||||
|| !matches!(&operators[1], &wasmparser::Operator::End)
|
|
||||||
{
|
|
||||||
anyhow::bail!(
|
|
||||||
"Unsupported operator seq in base-address expr: {:?}",
|
|
||||||
operators
|
|
||||||
);
|
|
||||||
}
|
|
||||||
let offset = match &operators[0] {
|
|
||||||
&wasmparser::Operator::I32Const { value } => value as usize,
|
|
||||||
&wasmparser::Operator::I64Const { value } => value as usize,
|
|
||||||
op => anyhow::bail!(
|
|
||||||
"Unsupported data segment base-address operator: {:?}",
|
|
||||||
op
|
|
||||||
),
|
|
||||||
};
|
|
||||||
module
|
module
|
||||||
.frontend_memory_mut(memory)
|
.frontend_memory_mut(memory)
|
||||||
.segments
|
.segments
|
||||||
|
@ -166,7 +165,54 @@ fn handle_payload<'a>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
Payload::CustomSection { .. } => {}
|
||||||
|
Payload::CodeSectionStart { .. } => {}
|
||||||
|
Payload::Version { .. } => {}
|
||||||
|
Payload::ElementSection(reader) => {
|
||||||
|
for element in reader {
|
||||||
|
let element = element?;
|
||||||
|
if element.ty != wasmparser::Type::FuncRef {
|
||||||
|
anyhow::bail!("Unsupported table type: {:?}", element.ty);
|
||||||
|
}
|
||||||
|
match &element.kind {
|
||||||
|
wasmparser::ElementKind::Passive => {}
|
||||||
|
wasmparser::ElementKind::Declared => {}
|
||||||
|
wasmparser::ElementKind::Active {
|
||||||
|
table_index,
|
||||||
|
init_expr,
|
||||||
|
} => {
|
||||||
|
let table = Table::from(*table_index);
|
||||||
|
let offset = parse_init_expr(&init_expr)?;
|
||||||
|
let items = element
|
||||||
|
.items
|
||||||
|
.get_items_reader()?
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let mut funcs = vec![];
|
||||||
|
for item in items {
|
||||||
|
let func = match item {
|
||||||
|
wasmparser::ElementItem::Func(func_idx) => Func::from(func_idx),
|
||||||
|
_ => anyhow::bail!("Unsupported element item: {:?}", item),
|
||||||
|
};
|
||||||
|
funcs.push(func);
|
||||||
|
}
|
||||||
|
|
||||||
|
let table_items = module
|
||||||
|
.frontend_table_mut(table)
|
||||||
|
.func_elements
|
||||||
|
.as_mut()
|
||||||
|
.unwrap();
|
||||||
|
if (offset + funcs.len()) > table_items.len() {
|
||||||
|
table_items.resize(offset + funcs.len(), Func::invalid());
|
||||||
|
}
|
||||||
|
table_items[offset..(offset + funcs.len())].copy_from_slice(&funcs[..]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
payload => {
|
||||||
|
log::warn!("Skipping section: {:?}", payload);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -155,8 +155,13 @@ impl<'a> Display for ModuleDisplay<'a> {
|
||||||
for (global, global_ty) in self.0.globals() {
|
for (global, global_ty) in self.0.globals() {
|
||||||
writeln!(f, " {}: {}", global, global_ty)?;
|
writeln!(f, " {}: {}", global, global_ty)?;
|
||||||
}
|
}
|
||||||
for (table, table_ty) in self.0.tables() {
|
for (table, table_data) in self.0.tables() {
|
||||||
writeln!(f, " {}: {}", table, table_ty)?;
|
writeln!(f, " {}: {}", table, table_data.ty)?;
|
||||||
|
if let Some(funcs) = &table_data.func_elements {
|
||||||
|
for (i, &func) in funcs.iter().enumerate() {
|
||||||
|
writeln!(f, " {}[{}]: {}", table, i, func)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (memory, memory_data) in self.0.memories() {
|
for (memory, memory_data) in self.0.memories() {
|
||||||
writeln!(
|
writeln!(
|
||||||
|
|
|
@ -10,7 +10,7 @@ pub struct Module<'a> {
|
||||||
funcs: EntityVec<Func, FuncDecl>,
|
funcs: EntityVec<Func, FuncDecl>,
|
||||||
signatures: EntityVec<Signature, SignatureData>,
|
signatures: EntityVec<Signature, SignatureData>,
|
||||||
globals: EntityVec<Global, Type>,
|
globals: EntityVec<Global, Type>,
|
||||||
tables: EntityVec<Table, Type>,
|
tables: EntityVec<Table, TableData>,
|
||||||
imports: Vec<Import>,
|
imports: Vec<Import>,
|
||||||
exports: Vec<Export>,
|
exports: Vec<Export>,
|
||||||
memories: EntityVec<Memory, MemoryData>,
|
memories: EntityVec<Memory, MemoryData>,
|
||||||
|
@ -37,6 +37,12 @@ pub struct MemorySegment {
|
||||||
pub data: Vec<u8>,
|
pub data: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct TableData {
|
||||||
|
pub ty: Type,
|
||||||
|
pub func_elements: Option<Vec<Func>>,
|
||||||
|
}
|
||||||
|
|
||||||
impl From<&wasmparser::FuncType> for SignatureData {
|
impl From<&wasmparser::FuncType> for SignatureData {
|
||||||
fn from(fty: &wasmparser::FuncType) -> Self {
|
fn from(fty: &wasmparser::FuncType) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -149,11 +155,11 @@ impl<'a> Module<'a> {
|
||||||
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, Type)> + 'b {
|
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, Type)> + 'b {
|
||||||
self.globals.entries().map(|(id, ty)| (id, *ty))
|
self.globals.entries().map(|(id, ty)| (id, *ty))
|
||||||
}
|
}
|
||||||
pub fn table_ty(&self, id: Table) -> Type {
|
pub fn table<'b>(&'b self, id: Table) -> &'b TableData {
|
||||||
self.tables[id]
|
&self.tables[id]
|
||||||
}
|
}
|
||||||
pub fn tables<'b>(&'b self) -> impl Iterator<Item = (Table, Type)> + 'b {
|
pub fn tables<'b>(&'b self) -> impl Iterator<Item = (Table, &'b TableData)> + 'b {
|
||||||
self.tables.entries().map(|(id, ty)| (id, *ty))
|
self.tables.entries()
|
||||||
}
|
}
|
||||||
pub fn memories<'b>(&'b self) -> impl Iterator<Item = (Memory, &'b MemoryData)> + 'b {
|
pub fn memories<'b>(&'b self) -> impl Iterator<Item = (Memory, &'b MemoryData)> + 'b {
|
||||||
self.memories.entries()
|
self.memories.entries()
|
||||||
|
@ -172,7 +178,15 @@ impl<'a> Module<'a> {
|
||||||
self.funcs.push(body)
|
self.funcs.push(body)
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_add_table(&mut self, ty: Type) -> Table {
|
pub(crate) fn frontend_add_table(&mut self, ty: Type) -> Table {
|
||||||
self.tables.push(ty)
|
let func_elements = if ty == Type::FuncRef {
|
||||||
|
Some(vec![])
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
self.tables.push(TableData { ty, func_elements })
|
||||||
|
}
|
||||||
|
pub(crate) fn frontend_table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
|
||||||
|
&mut self.tables[table]
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_add_global(&mut self, ty: Type) -> Global {
|
pub(crate) fn frontend_add_global(&mut self, ty: Type) -> Global {
|
||||||
self.globals.push(ty)
|
self.globals.push(ty)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! Metadata on operators.
|
//! Metadata on operators.
|
||||||
|
|
||||||
use crate::entity::EntityVec;
|
use crate::entity::EntityVec;
|
||||||
use crate::ir::{Global, Local, Module, Signature, Table, Value, Type};
|
use crate::ir::{Global, Local, Module, Signature, Table, Type, Value};
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
|
|
||||||
|
@ -216,7 +216,7 @@ pub fn op_inputs(
|
||||||
Operator::I32ReinterpretF32 => Ok(vec![Type::F32]),
|
Operator::I32ReinterpretF32 => Ok(vec![Type::F32]),
|
||||||
Operator::I64ReinterpretF64 => Ok(vec![Type::F64]),
|
Operator::I64ReinterpretF64 => Ok(vec![Type::F64]),
|
||||||
Operator::TableGet { .. } => Ok(vec![Type::I32]),
|
Operator::TableGet { .. } => Ok(vec![Type::I32]),
|
||||||
Operator::TableSet { table_index } => Ok(vec![Type::I32, module.table_ty(*table_index)]),
|
Operator::TableSet { table_index } => Ok(vec![Type::I32, module.table(*table_index).ty]),
|
||||||
Operator::TableGrow { .. } => Ok(vec![Type::I32]),
|
Operator::TableGrow { .. } => Ok(vec![Type::I32]),
|
||||||
Operator::TableSize { .. } => Ok(vec![]),
|
Operator::TableSize { .. } => Ok(vec![]),
|
||||||
Operator::MemorySize { .. } => Ok(vec![]),
|
Operator::MemorySize { .. } => Ok(vec![]),
|
||||||
|
@ -425,7 +425,7 @@ pub fn op_outputs(
|
||||||
Operator::F64ReinterpretI64 => Ok(vec![Type::F64]),
|
Operator::F64ReinterpretI64 => Ok(vec![Type::F64]),
|
||||||
Operator::I32ReinterpretF32 => Ok(vec![Type::I32]),
|
Operator::I32ReinterpretF32 => Ok(vec![Type::I32]),
|
||||||
Operator::I64ReinterpretF64 => Ok(vec![Type::I64]),
|
Operator::I64ReinterpretF64 => Ok(vec![Type::I64]),
|
||||||
Operator::TableGet { table_index } => Ok(vec![module.table_ty(*table_index)]),
|
Operator::TableGet { table_index } => Ok(vec![module.table(*table_index).ty]),
|
||||||
Operator::TableSet { .. } => Ok(vec![]),
|
Operator::TableSet { .. } => Ok(vec![]),
|
||||||
Operator::TableGrow { .. } => Ok(vec![]),
|
Operator::TableGrow { .. } => Ok(vec![]),
|
||||||
Operator::TableSize { .. } => Ok(vec![Type::I32]),
|
Operator::TableSize { .. } => Ok(vec![Type::I32]),
|
||||||
|
|
Loading…
Reference in a new issue