Fix constant generation
This commit is contained in:
@@ -7,7 +7,7 @@ use wasm_ast::node::{
|
||||
|
||||
use crate::analyzer::operator::bin_symbol_of;
|
||||
|
||||
use super::manager::{write_f32, write_f64, write_separated, write_variable, Driver, Manager};
|
||||
use super::manager::{write_separated, write_variable, Driver, Manager};
|
||||
|
||||
impl Driver for Recall {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
@@ -66,6 +66,30 @@ impl Driver for MemoryGrow {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_f32(number: f32, w: &mut dyn Write) -> Result<()> {
|
||||
let sign = if number.is_sign_negative() { "-" } else { "" };
|
||||
|
||||
if number.is_infinite() {
|
||||
write!(w, "{sign}math.huge ")
|
||||
} else if number.is_nan() {
|
||||
write!(w, "{sign}0/0 ")
|
||||
} else {
|
||||
write!(w, "{number:e} ")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_f64(number: f64, w: &mut dyn Write) -> Result<()> {
|
||||
let sign = if number.is_sign_negative() { "-" } else { "" };
|
||||
|
||||
if number.is_infinite() {
|
||||
write!(w, "{sign}math.huge ")
|
||||
} else if number.is_nan() {
|
||||
write!(w, "{sign}0/0 ")
|
||||
} else {
|
||||
write!(w, "{number:e} ")
|
||||
}
|
||||
}
|
||||
|
||||
impl Driver for Value {
|
||||
fn write(&self, _: &mut Manager, w: &mut dyn Write) -> Result<()> {
|
||||
match self {
|
||||
|
||||
@@ -56,30 +56,6 @@ pub fn write_ascending(prefix: &str, range: Range<usize>, w: &mut dyn Write) ->
|
||||
write_separated(range, |i, w| write!(w, "{prefix}_{i}"), w)
|
||||
}
|
||||
|
||||
pub fn write_f32(number: f32, w: &mut dyn Write) -> Result<()> {
|
||||
let sign = if number.is_sign_negative() { "-" } else { "" };
|
||||
|
||||
if number.is_infinite() {
|
||||
write!(w, "{sign}math.huge ")
|
||||
} else if number.is_nan() {
|
||||
write!(w, "{sign}0/0 ")
|
||||
} else {
|
||||
write!(w, "{number:e} ")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_f64(number: f64, w: &mut dyn Write) -> Result<()> {
|
||||
let sign = if number.is_sign_negative() { "-" } else { "" };
|
||||
|
||||
if number.is_infinite() {
|
||||
write!(w, "{sign}math.huge ")
|
||||
} else if number.is_nan() {
|
||||
write!(w, "{sign}0/0 ")
|
||||
} else {
|
||||
write!(w, "{number:e} ")
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_variable(var: usize, mng: &Manager, w: &mut dyn Write) -> Result<()> {
|
||||
if let Some(rem) = var.checked_sub(mng.num_param) {
|
||||
write!(w, "loc_{rem} ")
|
||||
|
||||
@@ -14,7 +14,7 @@ use wasm_ast::{
|
||||
|
||||
use crate::{
|
||||
analyzer::localize,
|
||||
backend::manager::{write_f32, write_f64, Driver, Manager},
|
||||
backend::manager::{Driver, Manager},
|
||||
};
|
||||
|
||||
fn aux_internal_index(internal: Internal) -> u32 {
|
||||
@@ -47,24 +47,12 @@ fn write_named_array(name: &str, len: usize, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "local {name} = table.create({len})")
|
||||
}
|
||||
|
||||
fn write_constant(code: &[Instruction], w: &mut dyn Write) -> Result<()> {
|
||||
// FIXME: Badly generated WASM will produce the wrong constant.
|
||||
for inst in code {
|
||||
let result = match *inst {
|
||||
Instruction::I32Const(v) => write!(w, "{v} "),
|
||||
Instruction::I64Const(v) => write!(w, "{v} "),
|
||||
Instruction::F32Const(v) => write_f32(f32::from_bits(v), w),
|
||||
Instruction::F64Const(v) => write_f64(f64::from_bits(v), w),
|
||||
Instruction::GetGlobal(i) => write!(w, "GLOBAL_LIST[{i}].value "),
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
fn write_constant(code: &[Instruction], type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
|
||||
let func = Builder::new(type_info).with_anon(code);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
write!(w, "error(\"mundane expression\")")
|
||||
write!(w, "(")?;
|
||||
func.write(&mut Manager::default(), w)?;
|
||||
write!(w, ")()")
|
||||
}
|
||||
|
||||
fn write_import_of<T>(wasm: &Module, lower: &str, cond: T, w: &mut dyn Write) -> Result<()>
|
||||
@@ -153,7 +141,7 @@ fn write_memory_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_global_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
fn write_global_list(wasm: &Module, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
|
||||
let global = match wasm.global_section() {
|
||||
Some(v) => v,
|
||||
None => return Ok(()),
|
||||
@@ -162,25 +150,27 @@ fn write_global_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
|
||||
for (i, v) in global.entries().iter().enumerate() {
|
||||
write!(w, "GLOBAL_LIST[{}] = {{ value =", i + offset)?;
|
||||
write_constant(v.init_expr().code(), w)?;
|
||||
write_constant(v.init_expr().code(), type_info, w)?;
|
||||
write!(w, "}}")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_element_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
fn write_element_list(wasm: &Module, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
|
||||
let element = match wasm.elements_section() {
|
||||
Some(v) => v.entries(),
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
for v in element {
|
||||
let code = v.offset().as_ref().unwrap().code();
|
||||
|
||||
write!(w, "do ")?;
|
||||
write!(w, "local target = TABLE_LIST[{}].data ", v.index())?;
|
||||
write!(w, "local offset =")?;
|
||||
|
||||
write_constant(v.offset().as_ref().unwrap().code(), w)?;
|
||||
write_constant(code, type_info, w)?;
|
||||
|
||||
write!(w, "local data = {{")?;
|
||||
|
||||
@@ -198,18 +188,20 @@ fn write_element_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_data_list(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
fn write_data_list(wasm: &Module, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
|
||||
let data = match wasm.data_section() {
|
||||
Some(v) => v.entries(),
|
||||
None => return Ok(()),
|
||||
};
|
||||
|
||||
for v in data {
|
||||
let code = v.offset().as_ref().unwrap().code();
|
||||
|
||||
write!(w, "do ")?;
|
||||
write!(w, "local target = MEMORY_LIST[{}]", v.index())?;
|
||||
write!(w, "local offset =")?;
|
||||
|
||||
write_constant(v.offset().as_ref().unwrap().code(), w)?;
|
||||
write_constant(code, type_info, w)?;
|
||||
|
||||
write!(w, "local data = \"")?;
|
||||
|
||||
@@ -233,7 +225,7 @@ fn build_func_list(wasm: &Module, type_info: &TypeInfo) -> Vec<Intermediate> {
|
||||
|
||||
let iter = list.iter().enumerate();
|
||||
|
||||
iter.map(|f| Builder::new(type_info).consume(f.0, f.1))
|
||||
iter.map(|f| Builder::new(type_info).with_index(f.0, f.1))
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -279,13 +271,13 @@ fn write_func_list(
|
||||
})
|
||||
}
|
||||
|
||||
fn write_module_start(wasm: &Module, w: &mut dyn Write) -> Result<()> {
|
||||
fn write_module_start(wasm: &Module, type_info: &TypeInfo, w: &mut dyn Write) -> Result<()> {
|
||||
write!(w, "local function run_init_code()")?;
|
||||
write_table_list(wasm, w)?;
|
||||
write_memory_list(wasm, w)?;
|
||||
write_global_list(wasm, w)?;
|
||||
write_element_list(wasm, w)?;
|
||||
write_data_list(wasm, w)?;
|
||||
write_global_list(wasm, type_info, w)?;
|
||||
write_element_list(wasm, type_info, w)?;
|
||||
write_data_list(wasm, type_info, w)?;
|
||||
write!(w, "end ")?;
|
||||
|
||||
write!(w, "return function(wasm)")?;
|
||||
@@ -314,5 +306,5 @@ pub fn translate(wasm: &Module, type_info: &TypeInfo, w: &mut dyn Write) -> Resu
|
||||
write_named_array("GLOBAL_LIST", wasm.globals_space(), w)?;
|
||||
|
||||
write_func_list(wasm, type_info, &func_list, w)?;
|
||||
write_module_start(wasm, w)
|
||||
write_module_start(wasm, type_info, w)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user