其他 WASM 虚拟机实现

WasmEdge (原 SSVM)

  • 使用 C++ 开发
  • 高性能、轻量级、模块化
  • 支持 WASI、JS API、AOT 编译
  • 支持与 Rust、Go、JavaScript 等语言集成
  • 适合区块链、Serverless、IoT 场景

GitHub: https://github.com/WasmEdge/WasmEdge
文档: https://wasmedge.org

WAVM

  • 使用 C++ 开发
  • 快速、可嵌入、兼容性好
  • 支持 JIT 和解释执行
  • 可用于游戏模拟器、插件系统等

GitHub: https://github.com/WAVM/WAVM

Lucet

  • 使用 Rust 作为开发语言
  • 专为安全沙箱和高性能设计
  • 支持多线程、WASI
  • 曾用于 Compute@Edge 平台
  • 已停止活跃开发(但仍可参考其架构)

GitHub: https://github.com/fastly/lucet

Wasmtime

  • 使用 Rust 作为开发语言,并提供 C API
  • 基于 Cranelift 编译器框架
  • 高性能、内存占用低
  • 支持 WASI、WASI-NN、WASI-Crypto 等扩展
  • 社区活跃,适用于生产环境

GitHub: https://github.com/bytecodealliance/wasmtime
文档: https://wasmtime.dev

Wasmer

  • 多语言支持(Rust、C/C++、Python、Node.js、Go 等)。
  • 支持 JIT/AOT 编译。
  • 提供企业版支持。
  • 相对较重,但可配置性强。

GitHub: https://github.com/wasmerio/wasmer
文档: https://docs.wasmer.io

wasm3

  • 极其轻量,适用于嵌入式设备。
  • 纯 C 实现,跨平台。
  • 性能不如其他高级引擎,但体积小、易于移植。
  • 不支持所有 Wasm 特性(如 SIMD)。

GitHub: https://github.com/wasm3/wasm3

Life

  • 纯 JavaScript 实现,适合浏览器端调试或教学用途。
  • 不适合生产使用。

GitHub: https://github.com/peersky/life

WasmEdge 入门

安装开发工具

安装 Emsdk

通过源码编译方式安装 Emsdk,在 https://github.com/juj/emsdk 下载到源代码后,配置好网络后,便可通过如下命令安装 Emsdk

D:\Apps\emsdk>emsdk install latest
Resolving SDK alias 'latest' to '4.0.10'
Resolving SDK version '4.0.10' to 'sdk-releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'
Installing SDK 'sdk-releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'..
Installing tool 'node-22.16.0-64bit'..
Downloading: D:/Apps/emsdk/downloads/node-v22.16.0-win-x64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v22.16.0-win-x64.zip, 37497627 Bytes
Unpacking 'D:/Apps/emsdk/downloads/node-v22.16.0-win-x64.zip' to 'D:/Apps/emsdk/node/22.16.0_64bit'
Done installing tool 'node-22.16.0-64bit'.
Installing tool 'python-3.13.3-64bit'..
Downloading: D:/Apps/emsdk/downloads/python-3.13.3-0-win-amd64.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/python-3.13.3-0-win-amd64.zip, 29736374 Bytes
Unpacking 'D:/Apps/emsdk/downloads/python-3.13.3-0-win-amd64.zip' to 'D:/Apps/emsdk/python/3.13.3_64bit'
Done installing tool 'python-3.13.3-64bit'.
Installing tool 'releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'..
Downloading: D:/Apps/emsdk/downloads/8103ffedfb0c42d231c6af6859a5a1a832260b43-wasm-binaries.zip from https://storage.googleapis.com/webassembly/emscripten-releases-builds/win/8103ffedfb0c42d231c6af6859a5a1a832260b43/wasm-binaries.zip, 539321345 Bytes
Unpacking 'D:/Apps/emsdk/downloads/8103ffedfb0c42d231c6af6859a5a1a832260b43-wasm-binaries.zip' to 'D:/Apps/emsdk/upstream'
Done installing tool 'releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'.
Done installing SDK 'sdk-releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'.

D:\Apps\emsdk>emsdk activate latest
Resolving SDK alias 'latest' to '4.0.10'
Resolving SDK version '4.0.10' to 'sdk-releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit'
Setting the following tools as active:
   node-22.16.0-64bit
   python-3.13.3-64bit
   releases-8103ffedfb0c42d231c6af6859a5a1a832260b43-64bit

Next steps:
- Consider running `emsdk activate` with --permanent or --system
  to have emsdk settings available on startup.
Adding directories to PATH:
PATH += D:\Apps\emsdk
PATH += D:\Apps\emsdk\upstream\emscripten

Setting environment variables:
PATH = D:\Apps\emsdk;D:\Apps\emsdk\upstream\emscripten;D:\Apps\VulkanSDK\Bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.3\libnvvp;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;D:\Apps\Anaconda\condabin;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\NVIDIA Corporation\Nsight Compute 2021.1.0\;C:\Program Files\dotnet\;D:\Apps\Git\cmd;D:\Apps\JDK\8u202\bin;D:\Apps\go\bin;D:\Apps\node;D:\Apps\BBdown;D:\Apps\flutter\bin;C:\Windows\Microsoft.NET\Framework64\v4.0.30319;D:\Apps\Godot;D:\Apps\mingw64\bin;D:\Apps\python;D:\Apps\python\Scripts;D:\Apps\blender;D:\Apps\sqlite;D:\Apps\gettext-tools-windows\bin;D:\Apps\cmake\bin;D:\Apps\ffmpeg\bin;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit\;D:\Apps\AndroidSdk\tools;D:\Apps\AndroidSdk\platform-tools;D:\Apps\vcpkg;D:\Apps\7-Zip;C:\Program Files\PowerShell\7\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;D:\Apps\WasmEdge\bin;D:\Apps\wabt\bin;C:\Users\Tom\AppData\Local\Microsoft\WindowsApps;C:\Users\Tom\.dotnet\tools;D:\Apps\texlive\2022\bin\win32;D:\Subs\platform-tools;D:\Apps\Microsoft VS Code\bin;
EMSDK = D:/Apps/emsdk
EMSDK_NODE = D:\Apps\emsdk\node\22.16.0_64bit\bin\node.exe
EMSDK_PYTHON = D:\Apps\emsdk\python\3.13.3_64bit\python.exe
Clearing existing environment variable: EMSDK_PY
The changes made to environment variables only apply to the currently running shell instance. Use the 'emsdk_env.bat' to re-enter this environment later, or if you'd like to register this environment permanently, rerun this command with the option --permanent.

D:\Apps\emsdk>

如果没有使用 emsdk activate --permanentemsdk activate --permanent --system 在全局配置 emsdk,每次使用前都需要 emsdk activate 激活 emsdk

安装 WasmEdge

https://github.com/WasmEdge/WasmEdge/releases
安装 WasmEdge-0.15.0-alpha.3-windows 注意后面没有 msvc 也就是使用 MinGW 环境

安装 Wasm Toolkit

https://github.com/WebAssembly/wabt/releases

Helloworld

编写如下 hello.cpp 代码

#include <stdio.h>

int main() 
{
    printf("Hello, WasmEdge!\n");
    return 0;
}
# 激活 emcc
emsdk activate

# 编译为 Wasm
emcc hello.cpp -s WASM=1 -o hello.wasm

# 使用 WasmEdge 运行 Wasm 程序
wasmedge hello.wasm

从 Wat 编译到 Wasm

(module
  (func $add (export "add") (param $a i32) (param $b i32) (result i32)
    local.get $a
    local.get $b
    i32.add))

使用如下 Wasm Toolkit 可以将一个 wat 编译成 wasm 文件

wat2wasm index.wat -o index.wasm
wasm2wat index.wasm -o index2.wat

main.cpp

#include <wasmedge/wasmedge.h>
#include <iostream>
#include <cstring>

int main(int argc, char const *argv[])
{
    // 初始化配置
    WasmEdge_ConfigureContext *conf = WasmEdge_ConfigureCreate();

    // 添加 WASI 插件
    // WasmEdge_ConfigureAddPlugin(conf, "wasmedge_wasi_plugin");

    // 创建虚拟机
    WasmEdge_VMContext *vm = WasmEdge_VMCreate(conf, NULL);

    // 加载 WASM 文件
    WasmEdge_String wasmPath = WasmEdge_StringWrap("add.wasm", strlen("add.wasm"));
    WasmEdge_Result result = WasmEdge_VMLoadWasmFromFile(vm, wasmPath.Buf);
    if (!WasmEdge_ResultOK(result))
    {
        std::cerr << "Failed to load WASM file: " << WasmEdge_ResultGetMessage(result) << std::endl;
        return -1;
    }

    // 验证模块
    result = WasmEdge_VMValidate(vm);
    if (!WasmEdge_ResultOK(result))
    {
        std::cerr << "Validation failed: " << WasmEdge_ResultGetMessage(result) << std::endl;
        return -1;
    }

    // 实例化模块
    result = WasmEdge_VMInstantiate(vm);
    if (!WasmEdge_ResultOK(result))
    {
        std::cerr << "Instantiation failed: " << WasmEdge_ResultGetMessage(result) << std::endl;
        return -1;
    }

    // 调用函数
    WasmEdge_String funcName = WasmEdge_StringWrap("add", strlen("add"));
    WasmEdge_Value params[2] = {WasmEdge_ValueGenI32(3), WasmEdge_ValueGenI32(4)};
    WasmEdge_Value returns[1];

    result = WasmEdge_VMExecute(vm, funcName, params, 2, returns, 1);
    if (!WasmEdge_ResultOK(result))
    {
        std::cerr << "Execution failed: " << WasmEdge_ResultGetMessage(result) << std::endl;
        return -1;
    }

    int32_t sum = WasmEdge_ValueGetI32(returns[0]);
    std::cout << "Result of add(3, 4): " << sum << std::endl;

    // 清理资源
    WasmEdge_VMDelete(vm);
    WasmEdge_ConfigureDelete(conf);

    return 0;
}

配置

c_cpp_properties.json 中配置 includePath

{
  "configurations": [
    {
      "name": "Linux",
      "includePath": [
        "${workspaceFolder}/**",
        "D:/Apps/WasmEdge/include"
      ],
      "defines": [],
      "compilerPath": "D:/Apps/mingw64/bin/g++.exe",
      "cStandard": "c17",
      "cppStandard": "c++17"
    }
  ],
  "version": 4
}

tasks.json 中配置 args 等

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "Build with WasmEdge (MinGW)",
      "type": "cppbuild",
      "command": "g++",
      "args": [
        "${workspaceFolder}/main.cpp",
        "-o",
        "${workspaceFolder}/main.exe",
        "-I\"D:/Apps/WasmEdge/include\"",
        "-L\"D:/Apps/WasmEdge/lib\"",
        "-lWasmEdge",
      ],
      "group": {
        "kind": "build"
      },
      "problemMatcher": [
        "$gcc"
      ],
      "detail": "Compiling C++ file with WasmEdge support"
    },
    {
      "label": "Run WasmEdge Program",
      "type": "shell",
      "command": "${workspaceFolder}/main.exe",
      "group": "none",
      "dependsOn": [
        "Build with WasmEdge"
      ],
      "problemMatcher": []
    }
  ]
}

Wasm3 入门

安装开发工具

#include <iostream>
#include "m3_env.h"
#include "m3_exec_env.h"
#include "m3_module.h"
#include "m3_runtime.h"

int main() {
    // 初始化引擎
    IM3Runtime runtime = m3_NewRuntime(1024 * 1024, 0, NULL); // 1MB 内存
    if (!runtime) {
        std::cerr << "Failed to create runtime" << std::endl;
        return -1;
    }

    // 读取 WASM 文件内容
    FILE* file = fopen("add.wasm", "rb");
    if (!file) {
        std::cerr << "Failed to open add.wasm" << std::endl;
        return -1;
    }

    fseek(file, 0, SEEK_END);
    size_t fileSize = ftell(file);
    rewind(file);

    uint8_t* wasmData = new uint8_t[fileSize];
    fread(wasmData, 1, fileSize, file);
    fclose(file);

    // 加载模块
    IM3Module module;
    M3Result result = m3_ParseModule(runtime->environment, &module, wasmData, fileSize);
    if (result) {
        std::cerr << "Parse module failed: " << result << std::endl;
        return -1;
    }

    result = m3_LoadModule(runtime, module);
    if (result) {
        std::cerr << "Load module failed: " << result << std::endl;
        return -1;
    }

    // 查找导出的函数
    IM3Function function;
    result = m3_FindFunction(&function, runtime, "add");
    if (result) {
        std::cerr << "Function 'add' not found or invalid signature" << std::endl;
        return -1;
    }

    // 准备参数和调用
    uint64_t args[2] = { 3, 4 };
    result = m3_CallV(function, args[0], args[1]);
    if (result) {
        std::cerr << "Execution failed: " << result << std::endl;
        return -1;
    }

    // 获取返回值(i32)
    int32_t resultValue = *(int32_t*)runtime->memories->data + *(uint32_t*)(runtime->stack);
    std::cout << "Result of add(3, 4): " << resultValue << std::endl;

    // 清理资源
    delete[] wasmData;
    m3_FreeRuntime(runtime);

    return 0;
}

引用

https://zhuanlan.zhihu.com/p/699842388