WIP.
This commit is contained in:
parent
754492c860
commit
71bd0b399d
|
@ -27,11 +27,14 @@ 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> {
|
fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<Option<u64>> {
|
||||||
let operators = init_expr
|
let operators = init_expr
|
||||||
.get_operators_reader()
|
.get_operators_reader()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.collect::<Result<Vec<wasmparser::Operator>, _>>()?;
|
.collect::<Result<Vec<wasmparser::Operator>, _>>()?;
|
||||||
|
if operators.len() == 1 && matches!(&operators[0], &wasmparser::Operator::End) {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
if operators.len() != 2 || !matches!(&operators[1], &wasmparser::Operator::End) {
|
if operators.len() != 2 || !matches!(&operators[1], &wasmparser::Operator::End) {
|
||||||
anyhow::bail!(
|
anyhow::bail!(
|
||||||
"Unsupported operator seq in base-address expr: {:?}",
|
"Unsupported operator seq in base-address expr: {:?}",
|
||||||
|
@ -39,8 +42,10 @@ fn parse_init_expr<'a>(init_expr: &wasmparser::InitExpr<'a>) -> Result<usize> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
Ok(match &operators[0] {
|
Ok(match &operators[0] {
|
||||||
&wasmparser::Operator::I32Const { value } => value as usize,
|
&wasmparser::Operator::I32Const { value } => Some(value as u64),
|
||||||
&wasmparser::Operator::I64Const { value } => value as usize,
|
&wasmparser::Operator::I64Const { value } => Some(value as u64),
|
||||||
|
&wasmparser::Operator::F32Const { value } => Some(value.bits() as u64),
|
||||||
|
&wasmparser::Operator::F64Const { value } => Some(value.bits()),
|
||||||
op => anyhow::bail!("Unsupported data segment base-address operator: {:?}", op),
|
op => anyhow::bail!("Unsupported data segment base-address operator: {:?}", op),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -73,7 +78,8 @@ fn handle_payload<'a>(
|
||||||
Some(ImportKind::Func(func))
|
Some(ImportKind::Func(func))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Global(ty) => {
|
ImportSectionEntryType::Global(ty) => {
|
||||||
let global = module.frontend_add_global(ty.content_type.into());
|
let ty = ty.content_type.into();
|
||||||
|
let global = module.frontend_add_global(GlobalData { ty, value: None });
|
||||||
Some(ImportKind::Global(global))
|
Some(ImportKind::Global(global))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Table(ty) => {
|
ImportSectionEntryType::Table(ty) => {
|
||||||
|
@ -94,7 +100,12 @@ fn handle_payload<'a>(
|
||||||
Payload::GlobalSection(reader) => {
|
Payload::GlobalSection(reader) => {
|
||||||
for global in reader {
|
for global in reader {
|
||||||
let global = global?;
|
let global = global?;
|
||||||
module.frontend_add_global(global.ty.content_type.into());
|
let ty = global.ty.content_type.into();
|
||||||
|
let init_expr = parse_init_expr(&global.init_expr)?;
|
||||||
|
module.frontend_add_global(GlobalData {
|
||||||
|
ty,
|
||||||
|
value: init_expr,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::TableSection(reader) => {
|
Payload::TableSection(reader) => {
|
||||||
|
@ -156,9 +167,9 @@ 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 offset = parse_init_expr(init_expr)?;
|
let offset = parse_init_expr(init_expr)?.unwrap_or(0) as usize;
|
||||||
module
|
module
|
||||||
.frontend_memory_mut(memory)
|
.memory_mut(memory)
|
||||||
.segments
|
.segments
|
||||||
.push(MemorySegment { offset, data });
|
.push(MemorySegment { offset, data });
|
||||||
}
|
}
|
||||||
|
@ -182,7 +193,7 @@ fn handle_payload<'a>(
|
||||||
init_expr,
|
init_expr,
|
||||||
} => {
|
} => {
|
||||||
let table = Table::from(*table_index);
|
let table = Table::from(*table_index);
|
||||||
let offset = parse_init_expr(&init_expr)?;
|
let offset = parse_init_expr(&init_expr)?.unwrap_or(0) as usize;
|
||||||
let items = element
|
let items = element
|
||||||
.items
|
.items
|
||||||
.get_items_reader()?
|
.get_items_reader()?
|
||||||
|
@ -197,11 +208,7 @@ fn handle_payload<'a>(
|
||||||
funcs.push(func);
|
funcs.push(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
let table_items = module
|
let table_items = module.table_mut(table).func_elements.as_mut().unwrap();
|
||||||
.frontend_table_mut(table)
|
|
||||||
.func_elements
|
|
||||||
.as_mut()
|
|
||||||
.unwrap();
|
|
||||||
if (offset + funcs.len()) > table_items.len() {
|
if (offset + funcs.len()) > table_items.len() {
|
||||||
table_items.resize(offset + funcs.len(), Func::invalid());
|
table_items.resize(offset + funcs.len(), Func::invalid());
|
||||||
}
|
}
|
||||||
|
|
|
@ -155,8 +155,12 @@ impl<'a> Display for ModuleDisplay<'a> {
|
||||||
sig_strs.insert(sig, sig_str.clone());
|
sig_strs.insert(sig, sig_str.clone());
|
||||||
writeln!(f, " {}: {}", sig, sig_str)?;
|
writeln!(f, " {}: {}", sig, sig_str)?;
|
||||||
}
|
}
|
||||||
for (global, global_ty) in self.0.globals() {
|
for (global, global_data) in self.0.globals() {
|
||||||
writeln!(f, " {}: {}", global, global_ty)?;
|
writeln!(
|
||||||
|
f,
|
||||||
|
" {}: {:?} # {}",
|
||||||
|
global, global_data.value, global_data.ty
|
||||||
|
)?;
|
||||||
}
|
}
|
||||||
for (table, table_data) in self.0.tables() {
|
for (table, table_data) in self.0.tables() {
|
||||||
writeln!(f, " {}: {}", table, table_data.ty)?;
|
writeln!(f, " {}: {}", table, table_data.ty)?;
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub struct Module<'a> {
|
||||||
orig_bytes: &'a [u8],
|
orig_bytes: &'a [u8],
|
||||||
funcs: EntityVec<Func, FuncDecl>,
|
funcs: EntityVec<Func, FuncDecl>,
|
||||||
signatures: EntityVec<Signature, SignatureData>,
|
signatures: EntityVec<Signature, SignatureData>,
|
||||||
globals: EntityVec<Global, Type>,
|
globals: EntityVec<Global, GlobalData>,
|
||||||
tables: EntityVec<Table, TableData>,
|
tables: EntityVec<Table, TableData>,
|
||||||
imports: Vec<Import>,
|
imports: Vec<Import>,
|
||||||
exports: Vec<Export>,
|
exports: Vec<Export>,
|
||||||
|
@ -43,6 +43,12 @@ pub struct TableData {
|
||||||
pub func_elements: Option<Vec<Func>>,
|
pub func_elements: Option<Vec<Func>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
pub struct GlobalData {
|
||||||
|
pub ty: Type,
|
||||||
|
pub value: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
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 signatures<'b>(&'b self) -> impl Iterator<Item = (Signature, &'b SignatureData)> {
|
pub fn signatures<'b>(&'b self) -> impl Iterator<Item = (Signature, &'b SignatureData)> {
|
||||||
self.signatures.entries()
|
self.signatures.entries()
|
||||||
}
|
}
|
||||||
pub fn global_ty(&self, id: Global) -> Type {
|
pub fn global<'b>(&'b self, id: Global) -> &'b GlobalData {
|
||||||
self.globals[id]
|
&self.globals[id]
|
||||||
}
|
}
|
||||||
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, Type)> + 'b {
|
pub fn globals<'b>(&'b self) -> impl Iterator<Item = (Global, &'b GlobalData)> + 'b {
|
||||||
self.globals.entries().map(|(id, ty)| (id, *ty))
|
self.globals.entries()
|
||||||
}
|
}
|
||||||
pub fn table<'b>(&'b self, id: Table) -> &'b TableData {
|
pub fn table<'b>(&'b self, id: Table) -> &'b TableData {
|
||||||
&self.tables[id]
|
&self.tables[id]
|
||||||
|
@ -170,6 +176,12 @@ impl<'a> Module<'a> {
|
||||||
pub fn exports<'b>(&'b self) -> impl Iterator<Item = &'b Export> + 'b {
|
pub fn exports<'b>(&'b self) -> impl Iterator<Item = &'b Export> + 'b {
|
||||||
self.exports.iter()
|
self.exports.iter()
|
||||||
}
|
}
|
||||||
|
pub(crate) fn table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
|
||||||
|
&mut self.tables[table]
|
||||||
|
}
|
||||||
|
pub(crate) fn memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData {
|
||||||
|
&mut self.memories[memory]
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn frontend_add_signature(&mut self, ty: SignatureData) {
|
pub(crate) fn frontend_add_signature(&mut self, ty: SignatureData) {
|
||||||
self.signatures.push(ty);
|
self.signatures.push(ty);
|
||||||
|
@ -185,11 +197,8 @@ impl<'a> Module<'a> {
|
||||||
};
|
};
|
||||||
self.tables.push(TableData { ty, func_elements })
|
self.tables.push(TableData { ty, func_elements })
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
|
pub(crate) fn frontend_add_global(&mut self, global: GlobalData) -> Global {
|
||||||
&mut self.tables[table]
|
self.globals.push(global)
|
||||||
}
|
|
||||||
pub(crate) fn frontend_add_global(&mut self, ty: Type) -> Global {
|
|
||||||
self.globals.push(ty)
|
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_add_import(&mut self, import: Import) {
|
pub(crate) fn frontend_add_import(&mut self, import: Import) {
|
||||||
self.imports.push(import);
|
self.imports.push(import);
|
||||||
|
@ -200,9 +209,6 @@ impl<'a> Module<'a> {
|
||||||
pub(crate) fn frontend_add_memory(&mut self, memory: MemoryData) -> Memory {
|
pub(crate) fn frontend_add_memory(&mut self, memory: MemoryData) -> Memory {
|
||||||
self.memories.push(memory)
|
self.memories.push(memory)
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData {
|
|
||||||
&mut self.memories[memory]
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result<Self> {
|
pub fn from_wasm_bytes(bytes: &'a [u8]) -> Result<Self> {
|
||||||
let mut module = frontend::wasm_to_ir(bytes)?;
|
let mut module = frontend::wasm_to_ir(bytes)?;
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub fn op_inputs(
|
||||||
&Operator::TypedSelect { ty } => Ok(vec![ty, ty, Type::I32].into()),
|
&Operator::TypedSelect { ty } => Ok(vec![ty, ty, Type::I32].into()),
|
||||||
|
|
||||||
&Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])),
|
&Operator::GlobalGet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
&Operator::GlobalSet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
|
&Operator::GlobalSet { global_index } => Ok(vec![module.global(global_index).ty].into()),
|
||||||
|
|
||||||
Operator::I32Load { .. }
|
Operator::I32Load { .. }
|
||||||
| Operator::I64Load { .. }
|
| Operator::I64Load { .. }
|
||||||
|
@ -258,7 +258,7 @@ pub fn op_outputs(
|
||||||
Ok(vec![val_ty].into())
|
Ok(vec![val_ty].into())
|
||||||
}
|
}
|
||||||
&Operator::TypedSelect { ty } => Ok(vec![ty].into()),
|
&Operator::TypedSelect { ty } => Ok(vec![ty].into()),
|
||||||
&Operator::GlobalGet { global_index } => Ok(vec![module.global_ty(global_index)].into()),
|
&Operator::GlobalGet { global_index } => Ok(vec![module.global(global_index).ty].into()),
|
||||||
&Operator::GlobalSet { .. } => Ok(Cow::Borrowed(&[])),
|
&Operator::GlobalSet { .. } => Ok(Cow::Borrowed(&[])),
|
||||||
|
|
||||||
Operator::I32Load { .. }
|
Operator::I32Load { .. }
|
||||||
|
|
Loading…
Reference in a new issue