1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#![cfg(test)]
use wasmer_runtime::{compile, Func};
use wasmer_runtime_core::vm::Ctx;
use wasmer_wasi::{state::*, *};

use std::ffi::c_void;

#[test]
fn serializing_works() {
    let args = vec![
        b"program_name".into_iter().cloned().collect(),
        b"arg1".into_iter().cloned().collect(),
    ];
    let envs = vec![
        b"PATH=/bin".into_iter().cloned().collect(),
        b"GOROOT=$HOME/.cargo/bin".into_iter().cloned().collect(),
    ];
    let wasm_binary = include_bytes!("../wasitests/fd_read.wasm");
    let import_object = generate_import_object(
        args.clone(),
        envs.clone(),
        vec![],
        vec![(
            ".".to_string(),
            std::path::PathBuf::from("wasitests/test_fs/hamlet"),
        )],
    );
    let module = compile(&wasm_binary[..])
        .map_err(|e| format!("Can't compile module: {:?}", e))
        .unwrap();

    let state_bytes = {
        let instance = module.instantiate(&import_object).unwrap();

        let start: Func<(), ()> = instance.func("_start").unwrap();
        start.call().unwrap();
        let state = get_wasi_state(instance.context());

        assert_eq!(state.args, args);
        assert_eq!(state.envs, envs);
        let bytes = state.freeze().unwrap();

        bytes
    };

    let mut instance = module.instantiate(&import_object).unwrap();

    let wasi_state = Box::new(WasiState::unfreeze(&state_bytes).unwrap());

    instance.context_mut().data = Box::into_raw(wasi_state) as *mut c_void;

    let second_entry: Func<(), i32> = instance.func("second_entry").unwrap();
    let result = second_entry.call().unwrap();
    assert_eq!(result, true as i32);
}

#[allow(clippy::mut_from_ref)]
pub(crate) fn get_wasi_state(ctx: &Ctx) -> &mut WasiState {
    unsafe { state::get_wasi_state(&mut *(ctx as *const Ctx as *mut Ctx)) }
}