wasmi 0.36.0

WebAssembly interpreter
Documentation
use super::*;
use crate::core::ValType;

fn test_reg(ty: ValType) {
    let display_ty = DisplayValueType::from(ty);
    let wasm = format!(
        r"
        (module
            (table $t 10 {display_ty})
            (func (param $value {display_ty}) (param $index i32) (result i32)
                (local.get $value)
                (local.get $index)
                (table.grow $t)
            )
        )",
    );
    TranslationTest::from_wat(&wasm)
        .expect_func_instrs([
            Instruction::table_grow(
                Register::from_i16(2),
                Register::from_i16(1),
                Register::from_i16(0),
            ),
            Instruction::table_idx(0),
            Instruction::return_reg(Register::from_i16(2)),
        ])
        .run();
}

#[test]
#[cfg_attr(miri, ignore)]
fn reg() {
    test_reg(ValType::FuncRef);
    test_reg(ValType::ExternRef);
}

fn test_imm16(ty: ValType, delta: u32) {
    let display_ty = DisplayValueType::from(ty);
    let wasm = format!(
        r"
        (module
            (table $t 10 {display_ty})
            (func (param $value {display_ty}) (result i32)
                (local.get $value)
                (i32.const {delta})
                (table.grow $t)
            )
        )",
    );
    TranslationTest::from_wat(&wasm)
        .expect_func_instrs([
            Instruction::table_grow_imm(
                Register::from_i16(1),
                u32imm16(delta),
                Register::from_i16(0),
            ),
            Instruction::table_idx(0),
            Instruction::return_reg(Register::from_i16(1)),
        ])
        .run();
}

#[test]
#[cfg_attr(miri, ignore)]
fn imm16() {
    fn test_for(delta: u32) {
        test_imm16(ValType::FuncRef, delta);
        test_imm16(ValType::ExternRef, delta);
    }
    test_for(1);
    test_for(42);
    test_for(u32::from(u16::MAX) - 1);
    test_for(u32::from(u16::MAX));
}

fn test_imm_zero(ty: ValType) {
    let display_ty = DisplayValueType::from(ty);
    let wasm = format!(
        r"
        (module
            (table $t 10 {display_ty})
            (func (param $value {display_ty}) (result i32)
                (local.get $value)
                (i32.const 0)
                (table.grow $t)
            )
        )",
    );
    TranslationTest::from_wat(&wasm)
        .expect_func_instrs([
            Instruction::table_size(Register::from_i16(1), 0),
            Instruction::return_reg(Register::from_i16(1)),
        ])
        .run();
}

#[test]
#[cfg_attr(miri, ignore)]
fn imm_zero() {
    test_imm_zero(ValType::FuncRef);
    test_imm_zero(ValType::ExternRef);
}

fn test_imm_value_and_zero(ty: ValType) {
    let display_ty: DisplayValueType = DisplayValueType::from(ty);
    let ref_ty = match ty {
        ValType::FuncRef => "func",
        ValType::ExternRef => "extern",
        _ => panic!("invalid Wasm reftype"),
    };
    let wasm = format!(
        r"
        (module
            (table $t 10 {display_ty})
            (func (param $value {display_ty}) (result i32)
                (ref.null {ref_ty})
                (i32.const 0)
                (table.grow $t)
            )
        )",
    );
    TranslationTest::from_wat(&wasm)
        .expect_func_instrs([
            Instruction::table_size(Register::from_i16(1), 0),
            Instruction::return_reg(Register::from_i16(1)),
        ])
        .run();
}

#[test]
#[cfg_attr(miri, ignore)]
fn imm_value_and_zero() {
    test_imm_value_and_zero(ValType::FuncRef);
    test_imm_value_and_zero(ValType::ExternRef);
}

fn test_imm(ty: ValType, delta: u32) {
    let display_ty = DisplayValueType::from(ty);
    let wasm = format!(
        r"
        (module
            (table $t 10 {display_ty})
            (func (param $value {display_ty}) (result i32)
                (local.get $value)
                (i32.const {delta})
                (table.grow $t)
            )
        )",
    );
    TranslationTest::from_wat(&wasm)
        .expect_func(
            ExpectedFunc::new([
                Instruction::table_grow(
                    Register::from_i16(1),
                    Register::from_i16(-1),
                    Register::from_i16(0),
                ),
                Instruction::table_idx(0),
                Instruction::return_reg(Register::from_i16(1)),
            ])
            .consts([delta]),
        )
        .run();
}

#[test]
#[cfg_attr(miri, ignore)]
fn imm() {
    fn test_for(delta: u32) {
        test_imm(ValType::FuncRef, delta);
        test_imm(ValType::ExternRef, delta);
    }
    test_for(u32::from(u16::MAX) + 1);
    test_for(u32::MAX - 1);
    test_for(u32::MAX);
}