#wasm-module #resources #limit #execution #deterministic #space

finite-wasm

以运行时无关的方式保证对WebAssembly程序提供的执行时间和空间资源的确定性限制

6个版本 (重大更新)

0.5.0 2023年5月31日
0.4.0 2023年5月10日
0.3.1 2023年3月15日
0.3.0 2023年1月31日
0.1.0 2023年1月16日

#156WebAssembly

Download history 3433/week @ 2024-03-13 2835/week @ 2024-03-20 1909/week @ 2024-03-27 4237/week @ 2024-04-03 3156/week @ 2024-04-10 2930/week @ 2024-04-17 2814/week @ 2024-04-24 3156/week @ 2024-05-01 2964/week @ 2024-05-08 3134/week @ 2024-05-15 3030/week @ 2024-05-22 4722/week @ 2024-05-29 4446/week @ 2024-06-05 3632/week @ 2024-06-12 3755/week @ 2024-06-19 2276/week @ 2024-06-26

15,305 每月下载量
30 包中使用(直接使用11个)

MIT/Apache

625KB
14K SLoC

OCaml 11K SLoC // 0.0% comments Rust 3.5K SLoC // 0.1% comments Batch 75 SLoC

finite-wasm

通过一点欺骗来解决大规模的停机问题

以运行时无关的方式保证对WebAssembly程序提供的执行时间和空间资源的确定性限制。

内容

此项目提供了一些东西

  • 对WebAssembly核心模块规范的补充,描述了执行模型的更改,以便跟踪资源使用情况并强制执行限制;
  • 分析,检查给定的WebAssembly模块,并生成基于修订后的执行模型强制执行限制所需的信息;
  • 测试套件,验证分析实现与修改后的参考WebAssembly解释器的兼容性。

提供的分析结果可以非常灵活地使用:用于对WASM代码进行仪器化;在WASM代码编译期间增加机器代码;在解释器运行时强制执行资源限制;或其他方式,从而实现本项目的可移植性属性。

使用finite-wasm

测试套件实现了一个基本的WebAssembly模块转换过程。意图是使其仅足够验证分析对参考解释器的属性,但它肯定可以作为基础并适应为完整的生产级转换。这可能是一个最佳的开始方式。

然而,这种方法可能在性能方面并不令人满意。转换WASM模块需要解析它、修改它,然后再重新序列化它。尽管至少需要解析WASM模块两次可能是不可避免的,但分析被构建得使得不需要修改和重新序列化模块。

示例

use finite_wasm::{wasmparser as wp, prefix_sum_vec};

struct MySizeConfig;
impl finite_wasm::max_stack::SizeConfig for MySizeConfig {
    fn size_of_value(&self, ty: wp::ValType) -> u8 {
        use wp::ValType::*;
        match ty {
            I32 => 4,
            I64 => 8,
            F32 => 4,
            F64 => 8,
            V128 => 16,
            FuncRef => 32,
            ExternRef => 32,
        }
    }

    fn size_of_function_activation(
        &self,
        locals: &prefix_sum_vec::PrefixSumVec<wp::ValType, u32>,
    ) -> u64 {
        u64::from(locals.max_index().map(|&v| v + 1).unwrap_or(0))
    }
}

macro_rules! define_fee {
    ($(@$proposal:ident $op:ident $({ $($arg:ident: $argty:ty),* })? => $visit:ident)*) => {
        $(
            fn $visit(&mut self $($(,$arg: $argty)*)?) -> Self::Output { 1 }
        )*
    }
}

struct MyGasConfig;
impl<'a> wp::VisitOperator<'a> for MyGasConfig {
    type Output = u64;
    wp::for_each_operator!(define_fee);
}

fn analyze_module(wasm_code: &[u8]) -> finite_wasm::AnalysisOutcome {
    finite_wasm::Analysis::new()
        .with_stack(MySizeConfig)
        .with_gas(MyGasConfig)
        .analyze(wasm_code)
        .expect("something went wrong!")
}

许可证

此项目受MIT或Apache-2.0许可证的许可。

依赖关系

~5–15MB
~221K SLoC