From 8f33b67404160ce8cf35a22c0d0993112b5abe9c Mon Sep 17 00:00:00 2001 From: Henry Gressmann Date: Mon, 18 Dec 2023 15:01:30 +0100 Subject: feat: global parsing, improve testsuite Signed-off-by: Henry Gressmann --- crates/parser/src/conversion.rs | 49 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) (limited to 'crates/parser/src/conversion.rs') diff --git a/crates/parser/src/conversion.rs b/crates/parser/src/conversion.rs index 269bb66..9f4930a 100644 --- a/crates/parser/src/conversion.rs +++ b/crates/parser/src/conversion.rs @@ -1,10 +1,43 @@ use alloc::{boxed::Box, format, string::ToString, vec::Vec}; use log::info; -use tinywasm_types::{BlockArgs, Export, ExternalKind, FuncType, Instruction, MemArg, ValType}; +use tinywasm_types::{ + BlockArgs, ConstInstruction, Export, ExternalKind, FuncType, Global, Instruction, MemArg, ValType, +}; use wasmparser::{FuncValidator, ValidatorResources}; use crate::{module::CodeSection, Result}; +pub(crate) fn convert_module_globals<'a, T: IntoIterator>>>( + globals: T, +) -> Result> { + let globals = globals + .into_iter() + .map(|global| { + let global = global?; + let ty = convert_valtype(&global.ty.content_type); + + let ops = global + .init_expr + .get_operators_reader() + .into_iter() + .collect::>>()?; + + // In practice, the len can never be something other than 2, + // but we'll keep this here since it's part of the spec + // Invalid modules will be rejected by the validator anyway (there are also tests for this in the testsuite) + assert!(ops.len() >= 2); + assert!(matches!(ops[ops.len() - 1], wasmparser::Operator::End)); + + Ok(Global { + ty, + init: process_const_operator(ops[ops.len() - 2].clone())?, + mutable: global.ty.mutable, + }) + }) + .collect::>>()?; + Ok(globals) +} + pub(crate) fn convert_module_export(export: wasmparser::Export) -> Result { let kind = match export.kind { wasmparser::ExternalKind::Func => ExternalKind::Func, @@ -105,6 +138,20 @@ pub(crate) fn convert_memarg(memarg: wasmparser::MemArg) -> MemArg { } } +pub fn process_const_operator(op: wasmparser::Operator) -> Result { + match op { + wasmparser::Operator::I32Const { value } => Ok(ConstInstruction::I32Const(value)), + wasmparser::Operator::I64Const { value } => Ok(ConstInstruction::I64Const(value)), + wasmparser::Operator::F32Const { value } => Ok(ConstInstruction::F32Const(f32::from_bits(value.bits()))), // TODO: check if this is correct + wasmparser::Operator::F64Const { value } => Ok(ConstInstruction::F64Const(f64::from_bits(value.bits()))), // TODO: check if this is correct + wasmparser::Operator::GlobalGet { global_index } => Ok(ConstInstruction::GlobalGet(global_index)), + op => Err(crate::ParseError::UnsupportedOperator(format!( + "Unsupported instruction: {:?}", + op + ))), + } +} + pub fn process_operators<'a>( mut offset: usize, ops: impl Iterator, wasmparser::BinaryReaderError>>, -- cgit v1.3.1