summaryrefslogtreecommitdiff
path: root/crates/parser/src/conversion.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/parser/src/conversion.rs')
-rw-r--r--crates/parser/src/conversion.rs336
1 files changed, 8 insertions, 328 deletions
diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs
index f81b9e7..03b5f82 100644
--- a/crates/parser/src/conversion.rs
+++ b/crates/parser/src/conversion.rs
@@ -1,10 +1,9 @@
-use crate::log;
+use crate::visit::process_operators;
+use crate::Result;
use alloc::{boxed::Box, format, string::ToString, vec::Vec};
use tinywasm_types::*;
use wasmparser::{FuncValidator, OperatorsReader, ValidatorResources};
-use crate::{module::CodeSection, Result};
-
pub(crate) fn convert_module_elements<'a, T: IntoIterator<Item = wasmparser::Result<wasmparser::Element<'a>>>>(
elements: T,
) -> Result<Vec<tinywasm_types::Element>> {
@@ -160,12 +159,12 @@ pub(crate) fn convert_module_export(export: wasmparser::Export<'_>) -> Result<Ex
pub(crate) fn convert_module_code(
func: wasmparser::FunctionBody<'_>,
mut validator: FuncValidator<ValidatorResources>,
-) -> Result<CodeSection> {
+) -> Result<(Box<[Instruction]>, Box<[ValType]>)> {
let locals_reader = func.get_locals_reader()?;
let count = locals_reader.get_count();
let pos = locals_reader.original_position();
- let mut locals = Vec::with_capacity(count as usize);
+ let mut locals = Vec::with_capacity(count as usize);
for (i, local) in locals_reader.into_iter().enumerate() {
let local = local?;
validator.define_locals(pos + i, local.0, local.1)?;
@@ -174,10 +173,9 @@ pub(crate) fn convert_module_code(
}
}
- let body_reader = func.get_operators_reader()?;
- let body = process_operators(body_reader, validator)?;
-
- Ok(CodeSection { locals: locals.into_boxed_slice(), body })
+ let body = process_operators(&mut validator, &func)?;
+ let locals = locals.into_boxed_slice();
+ Ok((body, locals))
}
pub(crate) fn convert_module_type(ty: wasmparser::RecGroup) -> Result<FuncType> {
@@ -254,328 +252,10 @@ pub(crate) fn process_const_operator(op: wasmparser::Operator<'_>) -> Result<Con
}
}
-fn convert_heaptype(heap: wasmparser::HeapType) -> ValType {
+pub(crate) fn convert_heaptype(heap: wasmparser::HeapType) -> ValType {
match heap {
wasmparser::HeapType::Func => ValType::RefFunc,
wasmparser::HeapType::Extern => ValType::RefExtern,
_ => unimplemented!("Unsupported heap type: {:?}", heap),
}
}
-
-pub(crate) fn process_operators(
- ops: OperatorsReader<'_>,
- mut validator: FuncValidator<ValidatorResources>,
-) -> Result<Box<[Instruction]>> {
- let mut instructions = Vec::with_capacity(1024);
- let mut labels_ptrs = Vec::with_capacity(32);
- // indexes into the instructions array
- let mut offset = ops.original_position();
-
- for op in ops {
- let op = match op {
- Ok(op) => op,
- Err(e) => {
- cold();
- log::error!("Error while processing operators: {:?}", e);
- return Err(crate::ParseError::UnsupportedOperator("Error while processing operators".to_string()));
- }
- };
-
- match validator.op(offset, &op) {
- Ok(_) => (),
- Err(e) => {
- cold();
- log::error!("Error while processing operators: {:?}", e);
- return Err(crate::ParseError::UnsupportedOperator("Error while processing operators".to_string()));
- }
- }
- offset += 1;
-
- use wasmparser::Operator::*;
- let res = match op {
- BrTable { targets } => {
- let def = targets.default();
-
- let instrs = targets
- .targets()
- .map(|t| t.map(Instruction::BrLabel))
- .collect::<Result<Vec<Instruction>, wasmparser::BinaryReaderError>>()?;
-
- instructions.push(Instruction::BrTable(def, instrs.len()));
- instructions.extend(instrs);
- continue;
- }
- Unreachable => Instruction::Unreachable,
- Nop => Instruction::Nop,
- Block { blockty } => {
- labels_ptrs.push(instructions.len());
- Instruction::Block(convert_blocktype(blockty), 0)
- }
- Loop { blockty } => {
- labels_ptrs.push(instructions.len());
- Instruction::Loop(convert_blocktype(blockty), 0)
- }
- If { blockty } => {
- labels_ptrs.push(instructions.len());
- Instruction::If(convert_blocktype(blockty), None, 0)
- }
- Else => {
- labels_ptrs.push(instructions.len());
- Instruction::Else(0)
- }
- End => {
- if let Some(label_pointer) = labels_ptrs.pop() {
- let current_instr_ptr = instructions.len();
-
- // last_label_pointer is Some if we're ending a block
- match instructions[label_pointer] {
- Instruction::Else(ref mut else_instr_end_offset) => {
- *else_instr_end_offset = current_instr_ptr - label_pointer;
-
- // since we're ending an else block, we need to end the if block as well
- let if_label_pointer = labels_ptrs.pop().ok_or(crate::ParseError::UnsupportedOperator(
- "Expected to end an if block, but the last label was not an if".to_string(),
- ))?;
-
- let if_instruction = &mut instructions[if_label_pointer];
- let Instruction::If(_, ref mut else_offset, ref mut end_offset) = if_instruction else {
- return Err(crate::ParseError::UnsupportedOperator(
- "Expected to end an if block, but the last label was not an if".to_string(),
- ));
- };
-
- *else_offset = Some(label_pointer - if_label_pointer);
- *end_offset = current_instr_ptr - if_label_pointer;
- }
- Instruction::Block(_, ref mut end_offset)
- | Instruction::Loop(_, ref mut end_offset)
- | Instruction::If(_, _, ref mut end_offset) => {
- *end_offset = current_instr_ptr - label_pointer;
- }
- _ => {
- return Err(crate::ParseError::UnsupportedOperator(
- "Expected to end a block, but the last label was not a block".to_string(),
- ))
- }
- }
-
- Instruction::EndBlockFrame
- } else {
- // last_label_pointer is None if we're ending the function
- Instruction::EndFunc
- }
- }
-
- Br { relative_depth } => Instruction::Br(relative_depth),
- BrIf { relative_depth } => Instruction::BrIf(relative_depth),
- Return => Instruction::Return,
- Call { function_index } => Instruction::Call(function_index),
- CallIndirect { type_index, table_index, .. } => Instruction::CallIndirect(type_index, table_index),
- Drop => Instruction::Drop,
- Select => Instruction::Select(None),
- TypedSelect { ty } => Instruction::Select(Some(convert_valtype(&ty))),
- LocalGet { local_index } => Instruction::LocalGet(local_index),
- LocalSet { local_index } => Instruction::LocalSet(local_index),
- LocalTee { local_index } => Instruction::LocalTee(local_index),
- GlobalGet { global_index } => Instruction::GlobalGet(global_index),
- GlobalSet { global_index } => Instruction::GlobalSet(global_index),
- MemorySize { mem, mem_byte } => Instruction::MemorySize(mem, mem_byte),
- MemoryGrow { mem, mem_byte } => Instruction::MemoryGrow(mem, mem_byte),
-
- MemoryCopy { dst_mem, src_mem } => Instruction::MemoryCopy(src_mem, dst_mem),
- MemoryFill { mem } => Instruction::MemoryFill(mem),
- MemoryInit { data_index, mem } => Instruction::MemoryInit(data_index, mem),
- DataDrop { data_index } => Instruction::DataDrop(data_index),
-
- I32Const { value } => Instruction::I32Const(value),
- I64Const { value } => Instruction::I64Const(value),
- F32Const { value } => Instruction::F32Const(f32::from_bits(value.bits())),
- F64Const { value } => Instruction::F64Const(f64::from_bits(value.bits())),
- RefNull { hty } => Instruction::RefNull(convert_heaptype(hty)),
- RefIsNull => Instruction::RefIsNull,
- RefFunc { function_index } => Instruction::RefFunc(function_index),
- I32Load { memarg } => Instruction::I32Load(convert_memarg(memarg)),
- I64Load { memarg } => Instruction::I64Load(convert_memarg(memarg)),
- F32Load { memarg } => Instruction::F32Load(convert_memarg(memarg)),
- F64Load { memarg } => Instruction::F64Load(convert_memarg(memarg)),
- I32Load8S { memarg } => Instruction::I32Load8S(convert_memarg(memarg)),
- I32Load8U { memarg } => Instruction::I32Load8U(convert_memarg(memarg)),
- I32Load16S { memarg } => Instruction::I32Load16S(convert_memarg(memarg)),
- I32Load16U { memarg } => Instruction::I32Load16U(convert_memarg(memarg)),
- I64Load8S { memarg } => Instruction::I64Load8S(convert_memarg(memarg)),
- I64Load8U { memarg } => Instruction::I64Load8U(convert_memarg(memarg)),
- I64Load16S { memarg } => Instruction::I64Load16S(convert_memarg(memarg)),
- I64Load16U { memarg } => Instruction::I64Load16U(convert_memarg(memarg)),
- I64Load32S { memarg } => Instruction::I64Load32S(convert_memarg(memarg)),
- I64Load32U { memarg } => Instruction::I64Load32U(convert_memarg(memarg)),
- I32Store { memarg } => Instruction::I32Store(convert_memarg(memarg)),
- I64Store { memarg } => Instruction::I64Store(convert_memarg(memarg)),
- F32Store { memarg } => Instruction::F32Store(convert_memarg(memarg)),
- F64Store { memarg } => Instruction::F64Store(convert_memarg(memarg)),
- I32Store8 { memarg } => Instruction::I32Store8(convert_memarg(memarg)),
- I32Store16 { memarg } => Instruction::I32Store16(convert_memarg(memarg)),
- I64Store8 { memarg } => Instruction::I64Store8(convert_memarg(memarg)),
- I64Store16 { memarg } => Instruction::I64Store16(convert_memarg(memarg)),
- I64Store32 { memarg } => Instruction::I64Store32(convert_memarg(memarg)),
- I32Eqz => Instruction::I32Eqz,
- I32Eq => Instruction::I32Eq,
- I32Ne => Instruction::I32Ne,
- I32LtS => Instruction::I32LtS,
- I32LtU => Instruction::I32LtU,
- I32GtS => Instruction::I32GtS,
- I32GtU => Instruction::I32GtU,
- I32LeS => Instruction::I32LeS,
- I32LeU => Instruction::I32LeU,
- I32GeS => Instruction::I32GeS,
- I32GeU => Instruction::I32GeU,
- I64Eqz => Instruction::I64Eqz,
- I64Eq => Instruction::I64Eq,
- I64Ne => Instruction::I64Ne,
- I64LtS => Instruction::I64LtS,
- I64LtU => Instruction::I64LtU,
- I64GtS => Instruction::I64GtS,
- I64GtU => Instruction::I64GtU,
- I64LeS => Instruction::I64LeS,
- I64LeU => Instruction::I64LeU,
- I64GeS => Instruction::I64GeS,
- I64GeU => Instruction::I64GeU,
- F32Eq => Instruction::F32Eq,
- F32Ne => Instruction::F32Ne,
- F32Lt => Instruction::F32Lt,
- F32Gt => Instruction::F32Gt,
- F32Le => Instruction::F32Le,
- F32Ge => Instruction::F32Ge,
- F64Eq => Instruction::F64Eq,
- F64Ne => Instruction::F64Ne,
- F64Lt => Instruction::F64Lt,
- F64Gt => Instruction::F64Gt,
- F64Le => Instruction::F64Le,
- F64Ge => Instruction::F64Ge,
- I32Clz => Instruction::I32Clz,
- I32Ctz => Instruction::I32Ctz,
- I32Popcnt => Instruction::I32Popcnt,
- I32Add => Instruction::I32Add,
- I32Sub => Instruction::I32Sub,
- I32Mul => Instruction::I32Mul,
- I32DivS => Instruction::I32DivS,
- I32DivU => Instruction::I32DivU,
- I32RemS => Instruction::I32RemS,
- I32RemU => Instruction::I32RemU,
- I32And => Instruction::I32And,
- I32Or => Instruction::I32Or,
- I32Xor => Instruction::I32Xor,
- I32Shl => Instruction::I32Shl,
- I32ShrS => Instruction::I32ShrS,
- I32ShrU => Instruction::I32ShrU,
- I32Rotl => Instruction::I32Rotl,
- I32Rotr => Instruction::I32Rotr,
- I64Clz => Instruction::I64Clz,
- I64Ctz => Instruction::I64Ctz,
- I64Popcnt => Instruction::I64Popcnt,
- I64Add => Instruction::I64Add,
- I64Sub => Instruction::I64Sub,
- I64Mul => Instruction::I64Mul,
- I64DivS => Instruction::I64DivS,
- I64DivU => Instruction::I64DivU,
- I64RemS => Instruction::I64RemS,
- I64RemU => Instruction::I64RemU,
- I64And => Instruction::I64And,
- I64Or => Instruction::I64Or,
- I64Xor => Instruction::I64Xor,
- I64Shl => Instruction::I64Shl,
- I64ShrS => Instruction::I64ShrS,
- I64ShrU => Instruction::I64ShrU,
- I64Rotl => Instruction::I64Rotl,
- I64Rotr => Instruction::I64Rotr,
- F32Abs => Instruction::F32Abs,
- F32Neg => Instruction::F32Neg,
- F32Ceil => Instruction::F32Ceil,
- F32Floor => Instruction::F32Floor,
- F32Trunc => Instruction::F32Trunc,
- F32Nearest => Instruction::F32Nearest,
- F32Sqrt => Instruction::F32Sqrt,
- F32Add => Instruction::F32Add,
- F32Sub => Instruction::F32Sub,
- F32Mul => Instruction::F32Mul,
- F32Div => Instruction::F32Div,
- F32Min => Instruction::F32Min,
- F32Max => Instruction::F32Max,
- F32Copysign => Instruction::F32Copysign,
- F64Abs => Instruction::F64Abs,
- F64Neg => Instruction::F64Neg,
- F64Ceil => Instruction::F64Ceil,
- F64Floor => Instruction::F64Floor,
- F64Trunc => Instruction::F64Trunc,
- F64Nearest => Instruction::F64Nearest,
- F64Sqrt => Instruction::F64Sqrt,
- F64Add => Instruction::F64Add,
- F64Sub => Instruction::F64Sub,
- F64Mul => Instruction::F64Mul,
- F64Div => Instruction::F64Div,
- F64Min => Instruction::F64Min,
- F64Max => Instruction::F64Max,
- F64Copysign => Instruction::F64Copysign,
- I32WrapI64 => Instruction::I32WrapI64,
- I32TruncF32S => Instruction::I32TruncF32S,
- I32TruncF32U => Instruction::I32TruncF32U,
- I32TruncF64S => Instruction::I32TruncF64S,
- I32TruncF64U => Instruction::I32TruncF64U,
- I64Extend8S => Instruction::I64Extend8S,
- I64Extend16S => Instruction::I64Extend16S,
- I64Extend32S => Instruction::I64Extend32S,
- I64ExtendI32S => Instruction::I64ExtendI32S,
- I64ExtendI32U => Instruction::I64ExtendI32U,
- I32Extend8S => Instruction::I32Extend8S,
- I32Extend16S => Instruction::I32Extend16S,
- I64TruncF32S => Instruction::I64TruncF32S,
- I64TruncF32U => Instruction::I64TruncF32U,
- I64TruncF64S => Instruction::I64TruncF64S,
- I64TruncF64U => Instruction::I64TruncF64U,
- F32ConvertI32S => Instruction::F32ConvertI32S,
- F32ConvertI32U => Instruction::F32ConvertI32U,
- F32ConvertI64S => Instruction::F32ConvertI64S,
- F32ConvertI64U => Instruction::F32ConvertI64U,
- F32DemoteF64 => Instruction::F32DemoteF64,
- F64ConvertI32S => Instruction::F64ConvertI32S,
- F64ConvertI32U => Instruction::F64ConvertI32U,
- F64ConvertI64S => Instruction::F64ConvertI64S,
- F64ConvertI64U => Instruction::F64ConvertI64U,
- F64PromoteF32 => Instruction::F64PromoteF32,
- I32ReinterpretF32 => Instruction::I32ReinterpretF32,
- I64ReinterpretF64 => Instruction::I64ReinterpretF64,
- F32ReinterpretI32 => Instruction::F32ReinterpretI32,
- F64ReinterpretI64 => Instruction::F64ReinterpretI64,
- I32TruncSatF32S => Instruction::I32TruncSatF32S,
- I32TruncSatF32U => Instruction::I32TruncSatF32U,
- I32TruncSatF64S => Instruction::I32TruncSatF64S,
- I32TruncSatF64U => Instruction::I32TruncSatF64U,
- I64TruncSatF32S => Instruction::I64TruncSatF32S,
- I64TruncSatF32U => Instruction::I64TruncSatF32U,
- I64TruncSatF64S => Instruction::I64TruncSatF64S,
- I64TruncSatF64U => Instruction::I64TruncSatF64U,
- TableGet { table } => Instruction::TableGet(table),
- TableSet { table } => Instruction::TableSet(table),
- TableInit { table, elem_index } => Instruction::TableInit(table, elem_index),
- TableCopy { src_table, dst_table } => Instruction::TableCopy { from: src_table, to: dst_table },
- TableGrow { table } => Instruction::TableGrow(table),
- TableSize { table } => Instruction::TableSize(table),
- TableFill { table } => Instruction::TableFill(table),
- op => {
- cold();
- log::error!("Unsupported instruction: {:?}", op);
- return Err(crate::ParseError::UnsupportedOperator(format!("Unsupported instruction: {:?}", op)));
- }
- };
- instructions.push(res);
- }
-
- if !labels_ptrs.is_empty() {
- panic!("last_label_pointer should be None after processing all instructions: {:?}", labels_ptrs);
- }
-
- validator.finish(offset)?;
- Ok(instructions.into_boxed_slice())
-}
-
-#[cold]
-fn cold() {}