WIP.
This commit is contained in:
parent
9e5d2fae26
commit
7b804b02d7
|
@ -51,52 +51,6 @@ impl Module {
|
||||||
Ok(Module(ptr))
|
Ok(Module(ptr))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_funcs(&self) -> usize {
|
|
||||||
unsafe { BinaryenGetNumFunctions(self.0) as usize }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn func(&self, index: usize) -> Function {
|
|
||||||
assert!(index < self.num_funcs());
|
|
||||||
let ptr = unsafe { BinaryenGetFunctionByIndex(self.0, index as u32) };
|
|
||||||
assert!(!ptr.is_null());
|
|
||||||
Function(self.0, ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn func_by_name(&self, name: &str) -> Option<Function> {
|
|
||||||
let c_str = CString::new(name).unwrap();
|
|
||||||
let ptr = unsafe { BinaryenGetFunction(self.0, c_str.as_ptr()) };
|
|
||||||
if !ptr.is_null() {
|
|
||||||
Some(Function(self.0, ptr))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn num_exports(&self) -> usize {
|
|
||||||
unsafe { BinaryenGetNumExports(self.0) as usize }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn export_by_name(&self, name: &str) -> Option<Export> {
|
|
||||||
let c_str = CString::new(name).unwrap();
|
|
||||||
let ptr = unsafe { BinaryenGetExport(self.0, c_str.as_ptr()) };
|
|
||||||
if !ptr.is_null() {
|
|
||||||
Some(Export(self.0, ptr))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn export(&self, index: usize) -> Export {
|
|
||||||
assert!(index < self.num_exports());
|
|
||||||
let ptr = unsafe { BinaryenGetExportByIndex(self.0, index as u32) };
|
|
||||||
assert!(!ptr.is_null());
|
|
||||||
Export(self.0, ptr)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn module(&self) -> BinaryenModule {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn add_global(&self, ty: ir::Type, mutable: bool, value: Option<u64>) -> ir::Global {
|
pub fn add_global(&self, ty: ir::Type, mutable: bool, value: Option<u64>) -> ir::Global {
|
||||||
let b_ty = Type::from(ty).to_binaryen();
|
let b_ty = Type::from(ty).to_binaryen();
|
||||||
let value = value.unwrap_or(0);
|
let value = value.unwrap_or(0);
|
||||||
|
@ -109,7 +63,8 @@ impl Module {
|
||||||
};
|
};
|
||||||
|
|
||||||
let num = unsafe { BinaryenGetNumGlobals(self.0) };
|
let num = unsafe { BinaryenGetNumGlobals(self.0) };
|
||||||
let global = unsafe { BinaryenAddGlobal(self.0, std::ptr::null(), b_ty, mutable, init.1) };
|
let name = CString::new(format!("global{}", num)).unwrap();
|
||||||
|
let global = unsafe { BinaryenAddGlobal(self.0, name.as_ptr(), b_ty, mutable, init.1) };
|
||||||
assert!(!global.is_null());
|
assert!(!global.is_null());
|
||||||
ir::Global::from(num)
|
ir::Global::from(num)
|
||||||
}
|
}
|
||||||
|
@ -118,10 +73,11 @@ impl Module {
|
||||||
let ty = Type::from(ty).to_binaryen();
|
let ty = Type::from(ty).to_binaryen();
|
||||||
let num = unsafe { BinaryenGetNumTables(self.0) };
|
let num = unsafe { BinaryenGetNumTables(self.0) };
|
||||||
let max = max.unwrap_or(0);
|
let max = max.unwrap_or(0);
|
||||||
|
let name = CString::new(format!("table{}", num)).unwrap();
|
||||||
let table = unsafe {
|
let table = unsafe {
|
||||||
BinaryenAddTable(
|
BinaryenAddTable(
|
||||||
self.0,
|
self.0,
|
||||||
std::ptr::null(),
|
name.as_ptr(),
|
||||||
init as BinaryenIndex,
|
init as BinaryenIndex,
|
||||||
max as BinaryenIndex,
|
max as BinaryenIndex,
|
||||||
ty,
|
ty,
|
||||||
|
@ -132,25 +88,23 @@ impl Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_table_elem(&self, table: ir::Table, index: usize, elt: ir::Func) {
|
pub fn add_table_elem(&self, table: ir::Table, index: usize, elt: ir::Func) {
|
||||||
|
log::trace!("add_table_elem: func {}", elt);
|
||||||
let table_name = unsafe {
|
let table_name = unsafe {
|
||||||
BinaryenTableGetName(BinaryenGetTableByIndex(
|
BinaryenTableGetName(BinaryenGetTableByIndex(
|
||||||
self.0,
|
self.0,
|
||||||
table.index() as BinaryenIndex,
|
table.index() as BinaryenIndex,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
let func_name = unsafe {
|
let func_name = compute_func_name(elt);
|
||||||
BinaryenFunctionGetName(BinaryenGetFunctionByIndex(
|
let func_name_ptr = func_name.as_ptr();
|
||||||
self.0,
|
|
||||||
elt.index() as BinaryenIndex,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
let offset = Expression::const_i32(self, index as i32);
|
let offset = Expression::const_i32(self, index as i32);
|
||||||
|
let name = CString::new(format!("seg_{}_{}", table.index(), index)).unwrap();
|
||||||
let seg = unsafe {
|
let seg = unsafe {
|
||||||
BinaryenAddActiveElementSegment(
|
BinaryenAddActiveElementSegment(
|
||||||
self.0,
|
self.0,
|
||||||
table_name,
|
table_name,
|
||||||
std::ptr::null(),
|
name.as_ptr(),
|
||||||
&func_name as *const *const c_char,
|
&func_name_ptr as *const *const c_char,
|
||||||
1,
|
1,
|
||||||
offset.1,
|
offset.1,
|
||||||
)
|
)
|
||||||
|
@ -218,20 +172,17 @@ impl Module {
|
||||||
params: &[ir::Type],
|
params: &[ir::Type],
|
||||||
results: &[ir::Type],
|
results: &[ir::Type],
|
||||||
) {
|
) {
|
||||||
let func_name = unsafe {
|
let num = unsafe { BinaryenGetNumFunctions(self.0) } as usize;
|
||||||
BinaryenFunctionGetName(BinaryenGetFunctionByIndex(
|
assert_eq!(num, func.index());
|
||||||
self.0,
|
|
||||||
func.index() as BinaryenIndex,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
let c_module = std::ffi::CString::new(module).unwrap();
|
let c_module = std::ffi::CString::new(module).unwrap();
|
||||||
let c_name = std::ffi::CString::new(name).unwrap();
|
let c_name = std::ffi::CString::new(name).unwrap();
|
||||||
let params = tys_to_binaryen(params.iter().copied());
|
let params = tys_to_binaryen(params.iter().copied());
|
||||||
let results = tys_to_binaryen(results.iter().copied());
|
let results = tys_to_binaryen(results.iter().copied());
|
||||||
|
let internal_name = compute_func_name(func);
|
||||||
unsafe {
|
unsafe {
|
||||||
BinaryenAddFunctionImport(
|
BinaryenAddFunctionImport(
|
||||||
self.0,
|
self.0,
|
||||||
func_name,
|
internal_name.as_ptr(),
|
||||||
c_module.as_ptr(),
|
c_module.as_ptr(),
|
||||||
c_name.as_ptr(),
|
c_name.as_ptr(),
|
||||||
params,
|
params,
|
||||||
|
@ -268,6 +219,49 @@ impl Module {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_table_export(&self, table: ir::Table, name: &str) {
|
||||||
|
let c_name = CString::new(name).unwrap();
|
||||||
|
let name = unsafe {
|
||||||
|
BinaryenTableGetName(BinaryenGetTableByIndex(
|
||||||
|
self.0,
|
||||||
|
table.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddTableExport(self.0, name, c_name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_func_export(&self, func: ir::Func, name: &str) {
|
||||||
|
log::trace!("add_func_export: func {}", func);
|
||||||
|
let c_name = CString::new(name).unwrap();
|
||||||
|
let name = compute_func_name(func);
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddFunctionExport(self.0, name.as_ptr(), c_name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_global_export(&self, global: ir::Global, name: &str) {
|
||||||
|
let c_name = CString::new(name).unwrap();
|
||||||
|
let name = unsafe {
|
||||||
|
BinaryenGlobalGetName(BinaryenGetGlobalByIndex(
|
||||||
|
self.0,
|
||||||
|
global.index() as BinaryenIndex,
|
||||||
|
))
|
||||||
|
};
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddGlobalExport(self.0, name, c_name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add_memory_export(&self, mem: ir::Memory, name: &str) {
|
||||||
|
assert_eq!(mem.index(), 0);
|
||||||
|
let c_name = CString::new(name).unwrap();
|
||||||
|
unsafe {
|
||||||
|
BinaryenAddMemoryExport(self.0, std::ptr::null(), c_name.as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for Module {
|
impl Drop for Module {
|
||||||
|
@ -278,6 +272,10 @@ impl Drop for Module {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_func_name(func: ir::Func) -> CString {
|
||||||
|
CString::new(format!("func{}", func.index())).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
impl Function {
|
impl Function {
|
||||||
pub fn body(&self) -> Option<Expression> {
|
pub fn body(&self) -> Option<Expression> {
|
||||||
let body = unsafe { BinaryenFunctionGetBody(self.1) };
|
let body = unsafe { BinaryenFunctionGetBody(self.1) };
|
||||||
|
@ -309,10 +307,13 @@ impl Function {
|
||||||
let params = tys_to_binaryen(params);
|
let params = tys_to_binaryen(params);
|
||||||
let results = tys_to_binaryen(results);
|
let results = tys_to_binaryen(results);
|
||||||
let locals: Vec<BinaryenType> = locals.map(|ty| Type::from(ty).to_binaryen()).collect();
|
let locals: Vec<BinaryenType> = locals.map(|ty| Type::from(ty).to_binaryen()).collect();
|
||||||
|
let num = unsafe { BinaryenGetNumFunctions(module.0) };
|
||||||
|
let name = compute_func_name(ir::Func::new(num as usize));
|
||||||
|
log::debug!("creating func {:?}", name);
|
||||||
let ptr = unsafe {
|
let ptr = unsafe {
|
||||||
BinaryenAddFunc(
|
BinaryenAddFunction(
|
||||||
module.0,
|
module.0,
|
||||||
/* name = */ std::ptr::null(),
|
name.as_ptr(),
|
||||||
params,
|
params,
|
||||||
results,
|
results,
|
||||||
locals.as_ptr(),
|
locals.as_ptr(),
|
||||||
|
@ -338,16 +339,6 @@ impl Export {
|
||||||
let s = unsafe { CStr::from_ptr(BinaryenExportGetValue(self.1)) };
|
let s = unsafe { CStr::from_ptr(BinaryenExportGetValue(self.1)) };
|
||||||
s.to_str().unwrap()
|
s.to_str().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn into_function(&self, module: &Module) -> Option<Function> {
|
|
||||||
let kind = unsafe { BinaryenExportGetKind(self.1) };
|
|
||||||
if kind == unsafe { BinaryenExternalFunction() } {
|
|
||||||
let name = self.value();
|
|
||||||
module.func_by_name(name)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TypeIds {
|
struct TypeIds {
|
||||||
|
@ -357,6 +348,7 @@ struct TypeIds {
|
||||||
f32_t: BinaryenType,
|
f32_t: BinaryenType,
|
||||||
f64_t: BinaryenType,
|
f64_t: BinaryenType,
|
||||||
v128_t: BinaryenType,
|
v128_t: BinaryenType,
|
||||||
|
funcref_t: BinaryenType,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TypeIds {
|
impl TypeIds {
|
||||||
|
@ -368,6 +360,7 @@ impl TypeIds {
|
||||||
f32_t: unsafe { BinaryenTypeFloat32() },
|
f32_t: unsafe { BinaryenTypeFloat32() },
|
||||||
f64_t: unsafe { BinaryenTypeFloat64() },
|
f64_t: unsafe { BinaryenTypeFloat64() },
|
||||||
v128_t: unsafe { BinaryenTypeVec128() },
|
v128_t: unsafe { BinaryenTypeVec128() },
|
||||||
|
funcref_t: unsafe { BinaryenTypeFuncref() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -384,26 +377,10 @@ pub enum Type {
|
||||||
F32,
|
F32,
|
||||||
F64,
|
F64,
|
||||||
V128,
|
V128,
|
||||||
|
FuncRef,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
fn from_binaryen(kind: BinaryenType) -> Option<Type> {
|
|
||||||
let tys = &*TYPE_IDS;
|
|
||||||
if kind == tys.none_t {
|
|
||||||
Some(Type::None)
|
|
||||||
} else if kind == tys.i32_t {
|
|
||||||
Some(Type::I32)
|
|
||||||
} else if kind == tys.i64_t {
|
|
||||||
Some(Type::I64)
|
|
||||||
} else if kind == tys.f32_t {
|
|
||||||
Some(Type::F32)
|
|
||||||
} else if kind == tys.f64_t {
|
|
||||||
Some(Type::F64)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn to_binaryen(&self) -> BinaryenType {
|
pub(crate) fn to_binaryen(&self) -> BinaryenType {
|
||||||
let tys = &*TYPE_IDS;
|
let tys = &*TYPE_IDS;
|
||||||
match self {
|
match self {
|
||||||
|
@ -413,6 +390,7 @@ impl Type {
|
||||||
&Type::F32 => tys.f32_t,
|
&Type::F32 => tys.f32_t,
|
||||||
&Type::F64 => tys.f64_t,
|
&Type::F64 => tys.f64_t,
|
||||||
&Type::V128 => tys.v128_t,
|
&Type::V128 => tys.v128_t,
|
||||||
|
&Type::FuncRef => tys.funcref_t,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,7 +403,7 @@ impl From<ir::Type> for Type {
|
||||||
ir::Type::F32 => Type::F32,
|
ir::Type::F32 => Type::F32,
|
||||||
ir::Type::F64 => Type::F64,
|
ir::Type::F64 => Type::F64,
|
||||||
ir::Type::V128 => Type::V128,
|
ir::Type::V128 => Type::V128,
|
||||||
_ => unimplemented!(),
|
ir::Type::FuncRef => Type::FuncRef,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -480,19 +458,14 @@ impl Expression {
|
||||||
tys: &[ir::Type],
|
tys: &[ir::Type],
|
||||||
) -> Expression {
|
) -> Expression {
|
||||||
// Look up the function's name.
|
// Look up the function's name.
|
||||||
let func_name = unsafe {
|
let func_name = compute_func_name(func);
|
||||||
BinaryenFunctionGetName(BinaryenGetFunctionByIndex(
|
|
||||||
module.0,
|
|
||||||
func.index() as BinaryenIndex,
|
|
||||||
))
|
|
||||||
};
|
|
||||||
// Create the appropriate type for return.
|
// Create the appropriate type for return.
|
||||||
let ret_tuple_ty = tys_to_binaryen(tys.iter().copied());
|
let ret_tuple_ty = tys_to_binaryen(tys.iter().copied());
|
||||||
let args = args.iter().map(|expr| expr.1).collect::<Vec<_>>();
|
let args = args.iter().map(|expr| expr.1).collect::<Vec<_>>();
|
||||||
let expr = unsafe {
|
let expr = unsafe {
|
||||||
BinaryenCall(
|
BinaryenCall(
|
||||||
module.0,
|
module.0,
|
||||||
func_name,
|
func_name.as_ptr(),
|
||||||
args.as_ptr(),
|
args.as_ptr(),
|
||||||
args.len() as BinaryenIndex,
|
args.len() as BinaryenIndex,
|
||||||
ret_tuple_ty,
|
ret_tuple_ty,
|
||||||
|
@ -976,7 +949,6 @@ extern "C" {
|
||||||
sourceMapUrl: *const c_char,
|
sourceMapUrl: *const c_char,
|
||||||
) -> BinaryenModuleAllocateAndWriteResult;
|
) -> BinaryenModuleAllocateAndWriteResult;
|
||||||
fn BinaryenGetNumFunctions(ptr: BinaryenModule) -> u32;
|
fn BinaryenGetNumFunctions(ptr: BinaryenModule) -> u32;
|
||||||
fn BinaryenGetFunctionByIndex(ptr: BinaryenModule, index: u32) -> BinaryenFunction;
|
|
||||||
fn BinaryenGetFunction(ptr: BinaryenModule, name: *const c_char) -> BinaryenFunction;
|
fn BinaryenGetFunction(ptr: BinaryenModule, name: *const c_char) -> BinaryenFunction;
|
||||||
fn BinaryenFunctionGetBody(ptr: BinaryenFunction) -> BinaryenExpression;
|
fn BinaryenFunctionGetBody(ptr: BinaryenFunction) -> BinaryenExpression;
|
||||||
fn BinaryenFunctionSetBody(ptr: BinaryenFunction, body: BinaryenExpression);
|
fn BinaryenFunctionSetBody(ptr: BinaryenFunction, body: BinaryenExpression);
|
||||||
|
@ -1010,6 +982,7 @@ extern "C" {
|
||||||
fn BinaryenTypeFloat32() -> BinaryenType;
|
fn BinaryenTypeFloat32() -> BinaryenType;
|
||||||
fn BinaryenTypeFloat64() -> BinaryenType;
|
fn BinaryenTypeFloat64() -> BinaryenType;
|
||||||
fn BinaryenTypeVec128() -> BinaryenType;
|
fn BinaryenTypeVec128() -> BinaryenType;
|
||||||
|
fn BinaryenTypeFuncref() -> BinaryenType;
|
||||||
|
|
||||||
fn BinaryenTypeCreate(tys: *const BinaryenType, n_tys: BinaryenIndex) -> BinaryenType;
|
fn BinaryenTypeCreate(tys: *const BinaryenType, n_tys: BinaryenIndex) -> BinaryenType;
|
||||||
|
|
||||||
|
@ -1130,7 +1103,7 @@ extern "C" {
|
||||||
) -> BinaryenExpression;
|
) -> BinaryenExpression;
|
||||||
fn BinaryenTableSize(module: BinaryenModule, name: *const c_char) -> BinaryenExpression;
|
fn BinaryenTableSize(module: BinaryenModule, name: *const c_char) -> BinaryenExpression;
|
||||||
|
|
||||||
fn BinaryenAddFunc(
|
fn BinaryenAddFunction(
|
||||||
module: BinaryenModule,
|
module: BinaryenModule,
|
||||||
name: *const c_char,
|
name: *const c_char,
|
||||||
params: BinaryenType,
|
params: BinaryenType,
|
||||||
|
@ -1627,6 +1600,27 @@ extern "C" {
|
||||||
|
|
||||||
fn BinaryenGlobalGetName(global: BinaryenGlobal) -> *const c_char;
|
fn BinaryenGlobalGetName(global: BinaryenGlobal) -> *const c_char;
|
||||||
fn BinaryenGetGlobalByIndex(module: BinaryenModule, index: BinaryenIndex) -> BinaryenGlobal;
|
fn BinaryenGetGlobalByIndex(module: BinaryenModule, index: BinaryenIndex) -> BinaryenGlobal;
|
||||||
|
|
||||||
|
fn BinaryenAddTableExport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
internal: *const c_char,
|
||||||
|
external: *const c_char,
|
||||||
|
);
|
||||||
|
fn BinaryenAddFunctionExport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
internal: *const c_char,
|
||||||
|
external: *const c_char,
|
||||||
|
);
|
||||||
|
fn BinaryenAddGlobalExport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
internal: *const c_char,
|
||||||
|
external: *const c_char,
|
||||||
|
);
|
||||||
|
fn BinaryenAddMemoryExport(
|
||||||
|
module: BinaryenModule,
|
||||||
|
internal: *const c_char,
|
||||||
|
external: *const c_char,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
|
@ -1,66 +1,24 @@
|
||||||
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::ir::{ExportKind, FuncDecl, ImportKind};
|
||||||
use crate::Operator;
|
use crate::Operator;
|
||||||
use anyhow::Result;
|
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> {
|
pub(crate) fn lower(module: &Module) -> Result<binaryen::Module> {
|
||||||
let into_mod = binaryen::Module::new()?;
|
let mut into_mod = binaryen::Module::new()?;
|
||||||
|
|
||||||
// Create globals.
|
log::debug!("creating new module");
|
||||||
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.
|
// Create imported tables and globals.
|
||||||
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() {
|
for import in module.imports() {
|
||||||
|
log::debug!("adding import: {:?}", import);
|
||||||
match &import.kind {
|
match &import.kind {
|
||||||
&ImportKind::Table(table) => {
|
&ImportKind::Table(table) => {
|
||||||
into_mod.add_table_import(table, &import.module[..], &import.name[..]);
|
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) => {
|
&ImportKind::Global(global) => {
|
||||||
let globdata = module.global(global);
|
let globdata = module.global(global);
|
||||||
into_mod.add_global_import(
|
into_mod.add_global_import(
|
||||||
|
@ -71,10 +29,100 @@ pub(crate) fn lower(module: &Module) -> Result<binaryen::Module> {
|
||||||
globdata.mutable,
|
globdata.mutable,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create globals.
|
||||||
|
for (global, data) in module.globals() {
|
||||||
|
log::debug!("adding global {}: {:?}", global, data);
|
||||||
|
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() {
|
||||||
|
log::debug!("adding table {}: {:?}", table, data);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create memories.
|
||||||
|
for (mem, data) in module.memories() {
|
||||||
|
log::debug!("adding mem {}", mem);
|
||||||
|
let new_mem = into_mod.add_mem(data.initial_pages, data.maximum_pages, &data.segments[..]);
|
||||||
|
assert_eq!(new_mem, mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create function imports.
|
||||||
|
for import in module.imports() {
|
||||||
|
log::debug!("adding import: {:?}", import);
|
||||||
|
match &import.kind {
|
||||||
|
&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[..],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create function bodies.
|
||||||
|
for (func, decl) in module.funcs() {
|
||||||
|
log::debug!("adding func {}: {:?}", func, decl);
|
||||||
|
match decl {
|
||||||
|
&FuncDecl::Body(sig, ref body) => {
|
||||||
|
let (new_locals, body_expr) = generate_body(module, body, &mut into_mod);
|
||||||
|
let _func =
|
||||||
|
create_new_func(module, sig, body, &mut into_mod, body_expr, new_locals);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create table contents.
|
||||||
|
for (table, data) in module.tables() {
|
||||||
|
if let Some(elts) = data.func_elements.as_ref() {
|
||||||
|
log::debug!("adding elts to table {}: {:?}", table, elts);
|
||||||
|
for (i, &elt) in elts.iter().enumerate() {
|
||||||
|
if elt.is_valid() {
|
||||||
|
into_mod.add_table_elem(table, i, elt);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create exports.
|
// Create exports.
|
||||||
|
for export in module.exports() {
|
||||||
|
log::debug!("adding export {:?}", export);
|
||||||
|
match &export.kind {
|
||||||
|
&ExportKind::Table(table) => {
|
||||||
|
into_mod.add_table_export(table, &export.name[..]);
|
||||||
|
}
|
||||||
|
&ExportKind::Func(func) => {
|
||||||
|
into_mod.add_func_export(func, &export.name[..]);
|
||||||
|
}
|
||||||
|
&ExportKind::Global(global) => {
|
||||||
|
into_mod.add_global_export(global, &export.name[..]);
|
||||||
|
}
|
||||||
|
&ExportKind::Memory(memory) => {
|
||||||
|
into_mod.add_memory_export(memory, &export.name[..]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(into_mod)
|
Ok(into_mod)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue