tinywasm 0.9.0-alpha.0

A tiny WebAssembly interpreter
Documentation
use eyre::Result;
use tinywasm::types::WasmType;
use tinywasm_types::{ExportType, ImportType};

#[test]
fn module_descriptors_resolve_imported_and_local_export_types() -> Result<()> {
    let wasm = wat::parse_str(
        r#"
        (module
          (type $t0 (func (param i32) (result i32)))
          (import "host" "ifunc" (func $ifunc (type $t0)))
          (import "host" "iglobal" (global $iglobal (mut i32)))

          (func $lfunc (param i64) (result i64)
            local.get 0)
          (global $lglobal i64 (i64.const 9))

          (export "ifunc_export" (func $ifunc))
          (export "iglobal_export" (global $iglobal))
          (export "lfunc_export" (func $lfunc))
          (export "lglobal_export" (global $lglobal))
        )
        "#,
    )?;

    let module = tinywasm::parse_bytes(&wasm)?;

    let imports: Vec<_> = module.imports().collect();
    assert_eq!(imports.len(), 2);

    let ifunc_import = imports.iter().find(|import| import.name == "ifunc").expect("ifunc import not found");
    match ifunc_import.ty {
        ImportType::Func(ty) => {
            assert_eq!(ty.params(), &[WasmType::I32]);
            assert_eq!(ty.results(), &[WasmType::I32]);
        }
        _ => panic!("ifunc import should be a function type"),
    }

    let iglobal_import = imports.iter().find(|import| import.name == "iglobal").expect("iglobal import not found");
    match iglobal_import.ty {
        ImportType::Global(ty) => {
            assert!(ty.mutable);
            assert_eq!(ty.ty, WasmType::I32);
        }
        _ => panic!("iglobal import should be a global type"),
    }

    let exports: Vec<_> = module.exports().collect();
    assert_eq!(exports.len(), 4);

    let ifunc_export = exports.iter().find(|export| export.name == "ifunc_export").expect("ifunc export not found");
    match ifunc_export.ty {
        ExportType::Func(ty) => {
            assert_eq!(ty.params(), &[WasmType::I32]);
            assert_eq!(ty.results(), &[WasmType::I32]);
        }
        _ => panic!("ifunc export should resolve to imported function type"),
    }

    let iglobal_export =
        exports.iter().find(|export| export.name == "iglobal_export").expect("iglobal export not found");
    match iglobal_export.ty {
        ExportType::Global(ty) => {
            assert!(ty.mutable);
            assert_eq!(ty.ty, WasmType::I32);
        }
        _ => panic!("iglobal export should resolve to imported global type"),
    }

    let lfunc_export = exports.iter().find(|export| export.name == "lfunc_export").expect("lfunc export not found");
    match lfunc_export.ty {
        ExportType::Func(ty) => {
            assert_eq!(ty.params(), &[WasmType::I64]);
            assert_eq!(ty.results(), &[WasmType::I64]);
        }
        _ => panic!("lfunc export should resolve to local function type"),
    }

    let lglobal_export =
        exports.iter().find(|export| export.name == "lglobal_export").expect("lglobal export not found");
    match lglobal_export.ty {
        ExportType::Global(ty) => {
            assert!(!ty.mutable);
            assert_eq!(ty.ty, WasmType::I64);
        }
        _ => panic!("lglobal export should resolve to local global type"),
    }

    Ok(())
}