Path: blob/main/tests/all/module_serialize.rs
1692 views
use anyhow::bail;1use std::fs::{self, OpenOptions};2use wasmtime::*;34fn serialize(engine: &Engine, wat: &str) -> Result<Vec<u8>> {5let module = Module::new(&engine, wat)?;6Ok(module.serialize()?)7}89unsafe fn deserialize_and_instantiate(store: &mut Store<()>, buffer: &[u8]) -> Result<Instance> {10let module = unsafe { Module::deserialize(store.engine(), buffer)? };11Ok(Instance::new(store, &module, &[])?)12}1314#[test]15fn test_version_mismatch() -> Result<()> {16let engine = Engine::default();17let buffer = serialize(&engine, "(module)")?;1819let mut config = Config::new();20config21.module_version(ModuleVersionStrategy::Custom("custom!".to_owned()))22.unwrap();23let custom_version_engine = Engine::new(&config).unwrap();24match unsafe { Module::deserialize(&custom_version_engine, &buffer) } {25Ok(_) => bail!("expected deserialization to fail"),26Err(e) => assert!(27e.to_string()28.starts_with("Module was compiled with incompatible version")29),30}3132let mut config = Config::new();33config.module_version(ModuleVersionStrategy::None).unwrap();34let none_version_engine = Engine::new(&config).unwrap();35unsafe { Module::deserialize(&none_version_engine, &buffer) }36.expect("accepts the wasmtime versioned module");3738let buffer = serialize(&custom_version_engine, "(module)")?;39unsafe { Module::deserialize(&none_version_engine, &buffer) }40.expect("accepts the custom versioned module");4142Ok(())43}4445#[test]46#[cfg_attr(miri, ignore)]47fn test_module_serialize_simple() -> Result<()> {48let buffer = serialize(49&Engine::default(),50"(module (func (export \"run\") (result i32) i32.const 42))",51)?;5253let mut store = Store::default();54let instance = unsafe { deserialize_and_instantiate(&mut store, &buffer)? };55let run = instance.get_typed_func::<(), i32>(&mut store, "run")?;56let result = run.call(&mut store, ())?;5758assert_eq!(42, result);59Ok(())60}6162#[test]63#[cfg_attr(miri, ignore)]64fn test_module_serialize_fail() -> Result<()> {65let buffer = serialize(66&Engine::default(),67"(module (func (export \"run\") (result i32) i32.const 42))",68)?;6970let mut config = Config::new();71config.memory_reservation(0);72let mut store = Store::new(&Engine::new(&config)?, ());73match unsafe { deserialize_and_instantiate(&mut store, &buffer) } {74Ok(_) => bail!("expected failure at deserialization"),75Err(_) => (),76}77Ok(())78}7980#[test]81#[cfg_attr(miri, ignore)]82fn test_deserialize_from_file() -> Result<()> {83serialize_and_call("(module (func (export \"run\") (result i32) i32.const 42))")?;84serialize_and_call(85"(module86(func (export \"run\") (result i32)87call $answer)8889(func $answer (result i32)90i32.const 42))91",92)?;93return Ok(());9495fn serialize_and_call(wat: &str) -> Result<()> {96let mut store = Store::<()>::default();97let td = tempfile::TempDir::new()?;98let buffer = serialize(store.engine(), wat)?;99100let path = td.path().join("module.bin");101fs::write(&path, &buffer)?;102let module = unsafe { Module::deserialize_file(store.engine(), &path)? };103let instance = Instance::new(&mut store, &module, &[])?;104let func = instance.get_typed_func::<(), i32>(&mut store, "run")?;105assert_eq!(func.call(&mut store, ())?, 42);106107// Try an already opened file as well.108let mut open_options = OpenOptions::new();109open_options.read(true);110#[cfg(target_os = "windows")]111{112use std::os::windows::prelude::*;113use windows_sys::Win32::Storage::FileSystem::*;114open_options.access_mode(FILE_GENERIC_READ | FILE_GENERIC_EXECUTE);115}116117let file = open_options.open(&path)?;118let module = unsafe { Module::deserialize_open_file(store.engine(), file)? };119let instance = Instance::new(&mut store, &module, &[])?;120let func = instance.get_typed_func::<(), i32>(&mut store, "run")?;121assert_eq!(func.call(&mut store, ())?, 42);122123Ok(())124}125}126127#[test]128#[cfg_attr(miri, ignore)]129fn deserialize_from_serialized() -> Result<()> {130let engine = Engine::default();131let buffer1 = serialize(132&engine,133"(module (func (export \"run\") (result i32) i32.const 42))",134)?;135let buffer2 = unsafe { Module::deserialize(&engine, &buffer1)?.serialize()? };136assert!(buffer1 == buffer2);137Ok(())138}139140#[test]141#[cfg_attr(miri, ignore)]142fn detect_precompiled() -> Result<()> {143let engine = Engine::default();144let buffer = serialize(145&engine,146"(module (func (export \"run\") (result i32) i32.const 42))",147)?;148assert_eq!(Engine::detect_precompiled(&[]), None);149assert_eq!(Engine::detect_precompiled(&buffer[..5]), None);150assert_eq!(151Engine::detect_precompiled(&buffer),152Some(Precompiled::Module)153);154Ok(())155}156157158