WIP.
This commit is contained in:
parent
15d45e1443
commit
9e5d2fae26
|
@ -43,6 +43,14 @@ impl Module {
|
||||||
Ok(slice.to_vec())
|
Ok(slice.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new() -> Result<Module> {
|
||||||
|
let ptr = unsafe { BinaryenModuleCreate() };
|
||||||
|
if ptr.is_null() {
|
||||||
|
bail!("Failed to allocate module");
|
||||||
|
}
|
||||||
|
Ok(Module(ptr))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn num_funcs(&self) -> usize {
|
pub fn num_funcs(&self) -> usize {
|
||||||
unsafe { BinaryenGetNumFunctions(self.0) as usize }
|
unsafe { BinaryenGetNumFunctions(self.0) as usize }
|
||||||
}
|
}
|
||||||
|
@ -88,6 +96,178 @@ impl Module {
|
||||||
pub fn module(&self) -> BinaryenModule {
|
pub fn module(&self) -> BinaryenModule {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_global(&self, ty: ir::Type, mutable: bool, value: Option<u64>) -> ir::Global {
|
||||||
|
let b_ty = Type::from(ty).to_binaryen();
|
||||||
|
let value = value.unwrap_or(0);
|
||||||
|
let init = match ty {
|
||||||
|
ir::Type::I32 => Expression::const_i32(self, value as i32),
|
||||||
|
ir::Type::I64 => Expression::const_i64(self, value as i64),
|
||||||
|
ir::Type::F32 => Expression::const_f32(self, Ieee32::from_bits(value as u32)),
|
||||||
|
ir::Type::F64 => Expression::const_f64(self, Ieee64::from_bits(value)),
|
||||||
|
_ => panic!("Unsupported type"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let num = unsafe { BinaryenGetNumGlobals(self.0) };
|
||||||
|
let global = unsafe { BinaryenAddGlobal(self.0, std::ptr::null(), b_ty, mutable, init.1) };
|
||||||
|
assert!(!global.is_null());
|
||||||
|
ir::Global::from(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_table(&self, ty: ir::Type, init: usize, max: Option<u32>) -> ir::Table {
|
||||||
|
let ty = Type::from(ty).to_binaryen();
|
||||||
|
let num = unsafe { BinaryenGetNumTables(self.0) };
|
||||||
|
let max = max.unwrap_or(0);
|
||||||
|
let table = unsafe {
|
||||||
|
BinaryenAddTable(
|
||||||
|
self.0,
|
||||||
|
std::ptr::null(),
|
||||||
|
init as BinaryenIndex,
|
||||||
|
max as BinaryenIndex,
|
||||||
|
ty,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
assert!(!table.is_null());
|
||||||
|
ir::Table::from(num)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_table_elem(&self, table: ir::Table, index: usize, elt: ir::Func) {
|
||||||
|
let table_name = unsafe {
|
||||||
|
BinaryenTableGetName(BinaryenGetTableByIndex(
|
||||||
|
self.0,
|
||||||
|
table.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let func_name = unsafe {
|
||||||
|
BinaryenFunctionGetName(BinaryenGetFunctionByIndex(
|
||||||
|
self.0,
|
||||||
|
elt.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let offset = Expression::const_i32(self, index as i32);
|
||||||
|
let seg = unsafe {
|
||||||
|
BinaryenAddActiveElementSegment(
|
||||||
|
self.0,
|
||||||
|
table_name,
|
||||||
|
std::ptr::null(),
|
||||||
|
&func_name as *const *const c_char,
|
||||||
|
1,
|
||||||
|
offset.1,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
assert!(!seg.is_null());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_mem(
|
||||||
|
&self,
|
||||||
|
init_pages: usize,
|
||||||
|
max_pages: Option<usize>,
|
||||||
|
segments: &[ir::MemorySegment],
|
||||||
|
) -> ir::Memory {
|
||||||
|
let seg_passive = vec![false; segments.len()];
|
||||||
|
let seg_offset = segments
|
||||||
|
.iter()
|
||||||
|
.map(|seg| Expression::const_i32(self, seg.offset as i32).1)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let seg_data = segments
|
||||||
|
.iter()
|
||||||
|
.map(|seg| seg.data.as_ptr() as *const c_char)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let seg_size = segments
|
||||||
|
.iter()
|
||||||
|
.map(|seg| seg.data.len() as BinaryenIndex)
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Binaryen does not support multi-memory.
|
||||||
|
unsafe {
|
||||||
|
BinaryenSetMemory(
|
||||||
|
self.0,
|
||||||
|
init_pages as BinaryenIndex,
|
||||||
|
max_pages.unwrap_or(0) as BinaryenIndex,
|
||||||
|
std::ptr::null(),
|
||||||
|
seg_data.as_ptr(),
|
||||||
|
seg_passive.as_ptr(),
|
||||||
|
seg_offset.as_ptr(),
|
||||||
|
seg_size.as_ptr(),
|
||||||
|
segments.len() as BinaryenIndex,
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
ir::Memory::from(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_table_import(&self, table: ir::Table, module: &str, name: &str) {
|
||||||
|
let table_name = unsafe {
|
||||||
|
BinaryenTableGetName(BinaryenGetTableByIndex(
|
||||||
|
self.0,
|
||||||
|
table.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let c_module = std::ffi::CString::new(module).unwrap();
|
||||||
|
let c_name = std::ffi::CString::new(name).unwrap();
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddTableImport(self.0, table_name, c_module.as_ptr(), c_name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_func_import(
|
||||||
|
&self,
|
||||||
|
func: ir::Func,
|
||||||
|
module: &str,
|
||||||
|
name: &str,
|
||||||
|
params: &[ir::Type],
|
||||||
|
results: &[ir::Type],
|
||||||
|
) {
|
||||||
|
let func_name = unsafe {
|
||||||
|
BinaryenFunctionGetName(BinaryenGetFunctionByIndex(
|
||||||
|
self.0,
|
||||||
|
func.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let c_module = std::ffi::CString::new(module).unwrap();
|
||||||
|
let c_name = std::ffi::CString::new(name).unwrap();
|
||||||
|
let params = tys_to_binaryen(params.iter().copied());
|
||||||
|
let results = tys_to_binaryen(results.iter().copied());
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddFunctionImport(
|
||||||
|
self.0,
|
||||||
|
func_name,
|
||||||
|
c_module.as_ptr(),
|
||||||
|
c_name.as_ptr(),
|
||||||
|
params,
|
||||||
|
results,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_global_import(
|
||||||
|
&self,
|
||||||
|
global: ir::Global,
|
||||||
|
module: &str,
|
||||||
|
name: &str,
|
||||||
|
ty: ir::Type,
|
||||||
|
mutable: bool,
|
||||||
|
) {
|
||||||
|
let global_name = unsafe {
|
||||||
|
BinaryenGlobalGetName(BinaryenGetGlobalByIndex(
|
||||||
|
self.0,
|
||||||
|
global.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
let c_module = std::ffi::CString::new(module).unwrap();
|
||||||
|
let c_name = std::ffi::CString::new(name).unwrap();
|
||||||
|
let ty = Type::from(ty).to_binaryen();
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddGlobalImport(
|
||||||
|
self.0,
|
||||||
|
global_name,
|
||||||
|
c_module.as_ptr(),
|
||||||
|
c_name.as_ptr(),
|
||||||
|
ty,
|
||||||
|
mutable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Module {
|
impl Drop for Module {
|
||||||
|
@ -708,6 +888,8 @@ type BinaryenExport = *const c_void;
|
||||||
type BinaryenRelooper = *const c_void;
|
type BinaryenRelooper = *const c_void;
|
||||||
type BinaryenRelooperBlock = *const c_void;
|
type BinaryenRelooperBlock = *const c_void;
|
||||||
type BinaryenTable = *const c_void;
|
type BinaryenTable = *const c_void;
|
||||||
|
type BinaryenGlobal = *const c_void;
|
||||||
|
type BinaryenElementSegment = *const c_void;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct BinaryenModuleAllocateAndWriteResult {
|
struct BinaryenModuleAllocateAndWriteResult {
|
||||||
|
@ -787,6 +969,7 @@ impl Drop for Relooper {
|
||||||
#[link(name = "binaryen")]
|
#[link(name = "binaryen")]
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn BinaryenModuleRead(data: *const u8, len: usize) -> BinaryenModule;
|
fn BinaryenModuleRead(data: *const u8, len: usize) -> BinaryenModule;
|
||||||
|
fn BinaryenModuleCreate() -> BinaryenModule;
|
||||||
fn BinaryenModuleDispose(ptr: BinaryenModule);
|
fn BinaryenModuleDispose(ptr: BinaryenModule);
|
||||||
fn BinaryenModuleAllocateAndWrite(
|
fn BinaryenModuleAllocateAndWrite(
|
||||||
ptr: BinaryenModule,
|
ptr: BinaryenModule,
|
||||||
|
@ -1373,6 +1556,77 @@ extern "C" {
|
||||||
fn BinaryenRefAsData() -> BinaryenOp;
|
fn BinaryenRefAsData() -> BinaryenOp;
|
||||||
fn BinaryenRefAsI31() -> BinaryenOp;
|
fn BinaryenRefAsI31() -> BinaryenOp;
|
||||||
|
|
||||||
|
fn BinaryenAddGlobal(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
ty: BinaryenType,
|
||||||
|
mutable: bool,
|
||||||
|
init: BinaryenExpression,
|
||||||
|
) -> BinaryenGlobal;
|
||||||
|
fn BinaryenGetNumGlobals(module: BinaryenModule) -> BinaryenIndex;
|
||||||
|
|
||||||
|
fn BinaryenAddTable(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
initial: BinaryenIndex,
|
||||||
|
max: BinaryenIndex,
|
||||||
|
ty: BinaryenType,
|
||||||
|
) -> BinaryenTable;
|
||||||
|
fn BinaryenGetNumTables(module: BinaryenModule) -> BinaryenIndex;
|
||||||
|
|
||||||
|
fn BinaryenAddActiveElementSegment(
|
||||||
|
module: BinaryenModule,
|
||||||
|
table: *const c_char,
|
||||||
|
name: *const c_char,
|
||||||
|
func_names: *const *const c_char,
|
||||||
|
num_funcs: BinaryenIndex,
|
||||||
|
offset: BinaryenExpression,
|
||||||
|
) -> BinaryenElementSegment;
|
||||||
|
|
||||||
|
fn BinaryenSetMemory(
|
||||||
|
module: BinaryenModule,
|
||||||
|
init: BinaryenIndex,
|
||||||
|
max: BinaryenIndex,
|
||||||
|
export_name: *const c_char,
|
||||||
|
segments: *const *const c_char,
|
||||||
|
seg_passive: *const bool,
|
||||||
|
seg_offsets: *const BinaryenExpression,
|
||||||
|
sizes: *const BinaryenIndex,
|
||||||
|
n_segments: BinaryenIndex,
|
||||||
|
shared: bool,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn BinaryenAddTableImport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
extern_module: *const c_char,
|
||||||
|
extern_name: *const c_char,
|
||||||
|
);
|
||||||
|
fn BinaryenAddMemoryImport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
extern_module: *const c_char,
|
||||||
|
extern_name: *const c_char,
|
||||||
|
);
|
||||||
|
fn BinaryenAddGlobalImport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
extern_module: *const c_char,
|
||||||
|
extern_name: *const c_char,
|
||||||
|
ty: BinaryenType,
|
||||||
|
mutable: bool,
|
||||||
|
);
|
||||||
|
fn BinaryenAddFunctionImport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
name: *const c_char,
|
||||||
|
extern_module: *const c_char,
|
||||||
|
extern_name: *const c_char,
|
||||||
|
params: BinaryenType,
|
||||||
|
results: BinaryenType,
|
||||||
|
);
|
||||||
|
|
||||||
|
fn BinaryenGlobalGetName(global: BinaryenGlobal) -> *const c_char;
|
||||||
|
fn BinaryenGetGlobalByIndex(module: BinaryenModule, index: BinaryenIndex) -> BinaryenGlobal;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -1,10 +1,84 @@
|
||||||
use crate::backend::binaryen;
|
use crate::backend::binaryen;
|
||||||
use crate::entity::EntityRef;
|
use crate::entity::EntityRef;
|
||||||
|
use crate::ir::ImportKind;
|
||||||
use crate::ir::*;
|
use crate::ir::*;
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
|
use anyhow::Result;
|
||||||
use fxhash::FxHashMap;
|
use fxhash::FxHashMap;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
pub(crate) fn lower(module: &Module) -> Result<binaryen::Module> {
|
||||||
|
let into_mod = binaryen::Module::new()?;
|
||||||
|
|
||||||
|
// Create globals.
|
||||||
|
for (global, data) in module.globals() {
|
||||||
|
let new_global = into_mod.add_global(data.ty, data.mutable, data.value);
|
||||||
|
assert_eq!(new_global, global);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create tables.
|
||||||
|
for (table, data) in module.tables() {
|
||||||
|
let new_table = into_mod.add_table(
|
||||||
|
data.ty,
|
||||||
|
data.func_elements
|
||||||
|
.as_ref()
|
||||||
|
.map(|elems| elems.len())
|
||||||
|
.unwrap_or(0),
|
||||||
|
data.max,
|
||||||
|
);
|
||||||
|
assert_eq!(new_table, table);
|
||||||
|
if let Some(elts) = data.func_elements.as_ref() {
|
||||||
|
for (i, &elt) in elts.iter().enumerate() {
|
||||||
|
if elt.is_valid() {
|
||||||
|
into_mod.add_table_elem(new_table, i, elt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create memories.
|
||||||
|
for (mem, data) in module.memories() {
|
||||||
|
let new_mem = into_mod.add_mem(data.initial_pages, data.maximum_pages, &data.segments[..]);
|
||||||
|
assert_eq!(new_mem, mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create function bodies.
|
||||||
|
|
||||||
|
// Create imports.
|
||||||
|
for import in module.imports() {
|
||||||
|
match &import.kind {
|
||||||
|
&ImportKind::Table(table) => {
|
||||||
|
into_mod.add_table_import(table, &import.module[..], &import.name[..]);
|
||||||
|
}
|
||||||
|
&ImportKind::Func(func) => {
|
||||||
|
let sig = module.func(func).sig();
|
||||||
|
let sigdata = module.signature(sig);
|
||||||
|
into_mod.add_func_import(
|
||||||
|
func,
|
||||||
|
&import.module[..],
|
||||||
|
&import.name[..],
|
||||||
|
&sigdata.params[..],
|
||||||
|
&sigdata.returns[..],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
&ImportKind::Global(global) => {
|
||||||
|
let globdata = module.global(global);
|
||||||
|
into_mod.add_global_import(
|
||||||
|
global,
|
||||||
|
&import.module[..],
|
||||||
|
&import.name[..],
|
||||||
|
globdata.ty,
|
||||||
|
globdata.mutable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create exports.
|
||||||
|
|
||||||
|
Ok(into_mod)
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a body expression for a function. Returns that expression,
|
/// Creates a body expression for a function. Returns that expression,
|
||||||
/// and new locals (as their types) that were created as temporaries
|
/// and new locals (as their types) that were created as temporaries
|
||||||
/// and need to be appended to `body.locals`.
|
/// and need to be appended to `body.locals`.
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
|
|
||||||
pub mod binaryen;
|
pub mod binaryen;
|
||||||
pub mod lower;
|
pub mod lower;
|
||||||
|
|
||||||
|
|
|
@ -78,12 +78,17 @@ fn handle_payload<'a>(
|
||||||
Some(ImportKind::Func(func))
|
Some(ImportKind::Func(func))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Global(ty) => {
|
ImportSectionEntryType::Global(ty) => {
|
||||||
|
let mutable = ty.mutable;
|
||||||
let ty = ty.content_type.into();
|
let ty = ty.content_type.into();
|
||||||
let global = module.frontend_add_global(GlobalData { ty, value: None });
|
let global = module.frontend_add_global(GlobalData {
|
||||||
|
ty,
|
||||||
|
value: None,
|
||||||
|
mutable,
|
||||||
|
});
|
||||||
Some(ImportKind::Global(global))
|
Some(ImportKind::Global(global))
|
||||||
}
|
}
|
||||||
ImportSectionEntryType::Table(ty) => {
|
ImportSectionEntryType::Table(ty) => {
|
||||||
let table = module.frontend_add_table(ty.element_type.into());
|
let table = module.frontend_add_table(ty.element_type.into(), None);
|
||||||
Some(ImportKind::Table(table))
|
Some(ImportKind::Table(table))
|
||||||
}
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -100,18 +105,20 @@ fn handle_payload<'a>(
|
||||||
Payload::GlobalSection(reader) => {
|
Payload::GlobalSection(reader) => {
|
||||||
for global in reader {
|
for global in reader {
|
||||||
let global = global?;
|
let global = global?;
|
||||||
|
let mutable = global.ty.mutable;
|
||||||
let ty = global.ty.content_type.into();
|
let ty = global.ty.content_type.into();
|
||||||
let init_expr = parse_init_expr(&global.init_expr)?;
|
let init_expr = parse_init_expr(&global.init_expr)?;
|
||||||
module.frontend_add_global(GlobalData {
|
module.frontend_add_global(GlobalData {
|
||||||
ty,
|
ty,
|
||||||
value: init_expr,
|
value: init_expr,
|
||||||
|
mutable,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::TableSection(reader) => {
|
Payload::TableSection(reader) => {
|
||||||
for table in reader {
|
for table in reader {
|
||||||
let table = table?;
|
let table = table?;
|
||||||
module.frontend_add_table(table.element_type.into());
|
module.frontend_add_table(table.element_type.into(), table.maximum);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Payload::FunctionSection(reader) => {
|
Payload::FunctionSection(reader) => {
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
use super::{Func, FuncDecl, Global, Memory, ModuleDisplay, Signature, Table, Type};
|
use super::{Func, FuncDecl, Global, Memory, ModuleDisplay, Signature, Table, Type};
|
||||||
use crate::entity::EntityVec;
|
use crate::entity::EntityVec;
|
||||||
use crate::frontend;
|
|
||||||
use crate::ir::FunctionBody;
|
use crate::ir::FunctionBody;
|
||||||
|
use crate::{backend, frontend};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use fxhash::FxHashSet;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct Module<'a> {
|
pub struct Module<'a> {
|
||||||
|
@ -15,8 +14,6 @@ pub struct Module<'a> {
|
||||||
imports: Vec<Import>,
|
imports: Vec<Import>,
|
||||||
exports: Vec<Export>,
|
exports: Vec<Export>,
|
||||||
memories: EntityVec<Memory, MemoryData>,
|
memories: EntityVec<Memory, MemoryData>,
|
||||||
|
|
||||||
dirty_funcs: FxHashSet<Func>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
|
@ -41,6 +38,7 @@ pub struct MemorySegment {
|
||||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
pub struct TableData {
|
pub struct TableData {
|
||||||
pub ty: Type,
|
pub ty: Type,
|
||||||
|
pub max: Option<u32>,
|
||||||
pub func_elements: Option<Vec<Func>>,
|
pub func_elements: Option<Vec<Func>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +46,7 @@ pub struct TableData {
|
||||||
pub struct GlobalData {
|
pub struct GlobalData {
|
||||||
pub ty: Type,
|
pub ty: Type,
|
||||||
pub value: Option<u64>,
|
pub value: Option<u64>,
|
||||||
|
pub mutable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&wasmparser::FuncType> for SignatureData {
|
impl From<&wasmparser::FuncType> for SignatureData {
|
||||||
|
@ -134,7 +133,6 @@ impl<'a> Module<'a> {
|
||||||
imports: vec![],
|
imports: vec![],
|
||||||
exports: vec![],
|
exports: vec![],
|
||||||
memories: EntityVec::default(),
|
memories: EntityVec::default(),
|
||||||
dirty_funcs: FxHashSet::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -144,7 +142,6 @@ impl<'a> Module<'a> {
|
||||||
&self.funcs[id]
|
&self.funcs[id]
|
||||||
}
|
}
|
||||||
pub fn func_mut<'b>(&'b mut self, id: Func) -> &'b mut FuncDecl {
|
pub fn func_mut<'b>(&'b mut self, id: Func) -> &'b mut FuncDecl {
|
||||||
self.dirty_funcs.insert(id);
|
|
||||||
&mut self.funcs[id]
|
&mut self.funcs[id]
|
||||||
}
|
}
|
||||||
pub fn funcs<'b>(&'b self) -> impl Iterator<Item = (Func, &'b FuncDecl)> {
|
pub fn funcs<'b>(&'b self) -> impl Iterator<Item = (Func, &'b FuncDecl)> {
|
||||||
|
@ -190,13 +187,17 @@ impl<'a> Module<'a> {
|
||||||
pub(crate) fn frontend_add_func(&mut self, body: FuncDecl) -> Func {
|
pub(crate) fn frontend_add_func(&mut self, body: FuncDecl) -> Func {
|
||||||
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, max: Option<u32>) -> Table {
|
||||||
let func_elements = if ty == Type::FuncRef {
|
let func_elements = if ty == Type::FuncRef {
|
||||||
Some(vec![])
|
Some(vec![])
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
self.tables.push(TableData { ty, func_elements })
|
self.tables.push(TableData {
|
||||||
|
ty,
|
||||||
|
func_elements,
|
||||||
|
max,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
pub(crate) fn frontend_add_global(&mut self, global: GlobalData) -> Global {
|
pub(crate) fn frontend_add_global(&mut self, global: GlobalData) -> Global {
|
||||||
self.globals.push(global)
|
self.globals.push(global)
|
||||||
|
@ -225,7 +226,8 @@ impl<'a> Module<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> {
|
pub fn to_wasm_bytes(&self) -> Result<Vec<u8>> {
|
||||||
todo!()
|
let module = backend::lower::lower(self)?;
|
||||||
|
module.write()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn display<'b>(&'b self) -> ModuleDisplay<'b>
|
pub fn display<'b>(&'b self) -> ModuleDisplay<'b>
|
||||||
|
|
Loading…
Reference in a new issue