This commit is contained in:
Chris Fallin 2022-11-29 10:33:06 -08:00
parent 26e7c7a3af
commit 6273e399de
No known key found for this signature in database
GPG key ID: 31649E4FE65EB465
3 changed files with 77 additions and 41 deletions

View file

@ -2,14 +2,11 @@
use crate::cfg::CFGInfo; use crate::cfg::CFGInfo;
use crate::entity::EntityRef; use crate::entity::EntityRef;
use crate::ir::{ use crate::ir::{ExportKind, FuncDecl, FunctionBody, ImportKind, Module, Type, Value, ValueDef};
ExportKind, Func, FuncDecl, FunctionBody, ImportKind, Module, Type, Value, ValueDef,
};
use crate::passes::rpo::RPO; use crate::passes::rpo::RPO;
use crate::Operator; use crate::Operator;
use anyhow::Result; use anyhow::Result;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap;
pub mod stackify; pub mod stackify;
use stackify::{Context as StackifyContext, WasmBlock}; use stackify::{Context as StackifyContext, WasmBlock};
@ -530,34 +527,56 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
into_mod.section(&types); into_mod.section(&types);
let mut imports = wasm_encoder::ImportSection::new(); let mut imports = wasm_encoder::ImportSection::new();
let import_map = module let mut num_func_imports = 0;
.imports() let mut num_table_imports = 0;
.filter_map(|import| match &import.kind { let mut num_global_imports = 0;
&ImportKind::Func(func) => Some((func, (&import.module[..], &import.name[..]))), let mut num_mem_imports = 0;
_ => None, for import in module.imports() {
}) let entity = match &import.kind {
.collect::<HashMap<Func, (&str, &str)>>(); &ImportKind::Func(func) => {
let mut num_imports = 0; num_func_imports += 1;
for (i, (func, func_decl)) in module.funcs().enumerate() { let func = module.func(func);
match func_decl { wasm_encoder::EntityType::Function(func.sig().index() as u32)
FuncDecl::Import(sig) => {
let (module_name, func_name) = import_map.get(&func).unwrap_or(&("", ""));
imports.import(
module_name,
func_name,
wasm_encoder::EntityType::Function(sig.index() as u32),
);
} }
FuncDecl::Body(..) => { &ImportKind::Table(table) => {
num_imports = i; num_table_imports += 1;
break; let table = module.table(table);
wasm_encoder::EntityType::Table(wasm_encoder::TableType {
element_type: wasm_encoder::ValType::from(table.ty),
minimum: table
.func_elements
.as_ref()
.map(|elts| elts.len() as u32)
.unwrap_or(0),
maximum: table.max,
})
} }
} &ImportKind::Global(global) => {
num_global_imports += 1;
let global = module.global(global);
wasm_encoder::EntityType::Global(wasm_encoder::GlobalType {
val_type: wasm_encoder::ValType::from(global.ty),
mutable: global.mutable,
})
}
&ImportKind::Memory(mem) => {
num_mem_imports += 1;
let mem = module.memory(mem);
wasm_encoder::EntityType::Memory(wasm_encoder::MemoryType {
memory64: false,
shared: false,
minimum: mem.initial_pages as u64,
maximum: mem.maximum_pages.map(|val| val as u64),
})
}
};
imports.import(&import.module[..], &import.name[..], entity);
} }
into_mod.section(&imports); into_mod.section(&imports);
let mut funcs = wasm_encoder::FunctionSection::new(); let mut funcs = wasm_encoder::FunctionSection::new();
for (func, func_decl) in module.funcs().skip(num_imports) { for (func, func_decl) in module.funcs().skip(num_func_imports) {
match func_decl { match func_decl {
FuncDecl::Import(_) => anyhow::bail!("Import comes after func with body: {}", func), FuncDecl::Import(_) => anyhow::bail!("Import comes after func with body: {}", func),
FuncDecl::Body(sig, _) => { FuncDecl::Body(sig, _) => {
@ -568,7 +587,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
into_mod.section(&funcs); into_mod.section(&funcs);
let mut tables = wasm_encoder::TableSection::new(); let mut tables = wasm_encoder::TableSection::new();
for (_table, table_data) in module.tables() { for (_table, table_data) in module.tables().skip(num_table_imports) {
tables.table(wasm_encoder::TableType { tables.table(wasm_encoder::TableType {
element_type: wasm_encoder::ValType::from(table_data.ty), element_type: wasm_encoder::ValType::from(table_data.ty),
minimum: table_data minimum: table_data
@ -582,7 +601,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
into_mod.section(&tables); into_mod.section(&tables);
let mut memories = wasm_encoder::MemorySection::new(); let mut memories = wasm_encoder::MemorySection::new();
for (_mem, mem_data) in module.memories() { for (_mem, mem_data) in module.memories().skip(num_mem_imports) {
memories.memory(wasm_encoder::MemoryType { memories.memory(wasm_encoder::MemoryType {
minimum: mem_data.initial_pages as u64, minimum: mem_data.initial_pages as u64,
maximum: mem_data.maximum_pages.map(|val| val as u64), maximum: mem_data.maximum_pages.map(|val| val as u64),
@ -593,7 +612,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
into_mod.section(&memories); into_mod.section(&memories);
let mut globals = wasm_encoder::GlobalSection::new(); let mut globals = wasm_encoder::GlobalSection::new();
for (_global, global_data) in module.globals() { for (_global, global_data) in module.globals().skip(num_global_imports) {
globals.global( globals.global(
wasm_encoder::GlobalType { wasm_encoder::GlobalType {
val_type: wasm_encoder::ValType::from(global_data.ty), val_type: wasm_encoder::ValType::from(global_data.ty),
@ -664,7 +683,7 @@ pub fn compile(module: &Module<'_>) -> anyhow::Result<Vec<u8>> {
into_mod.section(&elem); into_mod.section(&elem);
let mut code = wasm_encoder::CodeSection::new(); let mut code = wasm_encoder::CodeSection::new();
for (_func, func_decl) in module.funcs().skip(num_imports) { for (_func, func_decl) in module.funcs().skip(num_func_imports) {
let body = func_decl.body().unwrap(); let body = func_decl.body().unwrap();
let body = WasmFuncBackend::new(body)?.compile()?; let body = WasmFuncBackend::new(body)?.compile()?;
code.function(&body); code.function(&body);

View file

@ -75,7 +75,7 @@ fn handle_payload<'a>(
let func = let func =
module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx))); module.frontend_add_func(FuncDecl::Import(Signature::from(sig_idx)));
*next_func += 1; *next_func += 1;
Some(ImportKind::Func(func)) ImportKind::Func(func)
} }
TypeRef::Global(ty) => { TypeRef::Global(ty) => {
let mutable = ty.mutable; let mutable = ty.mutable;
@ -85,21 +85,32 @@ fn handle_payload<'a>(
value: None, value: None,
mutable, mutable,
}); });
Some(ImportKind::Global(global)) ImportKind::Global(global)
} }
TypeRef::Table(ty) => { TypeRef::Table(ty) => {
let table = module.frontend_add_table(ty.element_type.into(), None); let table = module.frontend_add_table(ty.element_type.into(), None);
Some(ImportKind::Table(table)) ImportKind::Table(table)
}
TypeRef::Memory(mem) => {
let mem = module.frontend_add_memory(MemoryData {
initial_pages: mem.initial as usize,
maximum_pages: mem.maximum.map(|max| max as usize),
segments: vec![],
});
ImportKind::Memory(mem)
}
t => {
bail!(FrontendError::UnsupportedFeature(format!(
"Unknown import type: {:?}",
t
)));
} }
_ => None,
}; };
if let Some(kind) = kind { module.frontend_add_import(Import {
module.frontend_add_import(Import { module: module_name,
module: module_name, name,
name, kind,
kind, });
});
}
} }
} }
Payload::GlobalSection(reader) => { Payload::GlobalSection(reader) => {

View file

@ -84,6 +84,7 @@ pub enum ImportKind {
Table(Table), Table(Table),
Func(Func), Func(Func),
Global(Global), Global(Global),
Memory(Memory),
} }
impl std::fmt::Display for ImportKind { impl std::fmt::Display for ImportKind {
@ -92,6 +93,7 @@ impl std::fmt::Display for ImportKind {
ImportKind::Table(table) => write!(f, "{}", table)?, ImportKind::Table(table) => write!(f, "{}", table)?,
ImportKind::Func(func) => write!(f, "{}", func)?, ImportKind::Func(func) => write!(f, "{}", func)?,
ImportKind::Global(global) => write!(f, "{}", global)?, ImportKind::Global(global) => write!(f, "{}", global)?,
ImportKind::Memory(mem) => write!(f, "{}", mem)?,
} }
Ok(()) Ok(())
} }
@ -179,6 +181,10 @@ impl<'a> Module<'a> {
pub fn table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData { pub fn table_mut<'b>(&'b mut self, table: Table) -> &'b mut TableData {
&mut self.tables[table] &mut self.tables[table]
} }
pub fn memory<'b>(&'b self, memory: Memory) -> &'b MemoryData {
&self.memories[memory]
}
pub fn memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData { pub fn memory_mut<'b>(&'b mut self, memory: Memory) -> &'b mut MemoryData {
&mut self.memories[memory] &mut self.memories[memory]
} }