littlebot
Published on 2025-04-11 / 0 Visits
0

【源码】基于C++20的WebAssembly解释器

项目简介

本项目是一个用C++20编写的可嵌入WebAssembly解释器,目标是创建一个具备简单易用接口的解释器,可作为其他应用程序的脚本引擎。除C++标准模板库(STL)外,项目无其他依赖。

项目的主要特性和功能

  • 代码特性:采用现代、易读的代码编写方式,遵循标准进行代码验证。
  • 性能特性:内存占用适中,启动速度快。
  • 功能特性:支持加载和编译WebAssembly模块,运行模块的启动函数;能运行特定的WebAssembly函数;允许注册宿主模块,实现与WebAssembly代码的交互;支持添加内省功能,方便观察解释器的操作。
  • 附带示例:包含一个Mandelbrot集的演示示例,展示了解释器在实际应用中的嵌入方式。

安装使用步骤

构建项目

项目使用CMake进行构建,基础的CMakeLists.txt添加了三个子目录: - interpreter:实际要链接的解释器库。 - embedder:嵌入解释器的测试应用程序。 - mandelbrot:Mandelbrot集演示的测试应用程序。 只需在interpreter目录中构建静态库并进行链接,可参考测试应用程序的CMake配置。

运行解释器

```C++

include "interpreter/interpreter.h"

include "interpreter/error.h"

int main() { try { WASM::Interpreter interpreter; interpreter.loadModule("path/to/myModule.wasm"); interpreter.compileAndLinkModules();

interpreter.runStartFunctions();

} catch (WASM::Error& e) { std::cerr << "Caught wasm error: " << e << std::endl; } catch (std::exception& e) { std::cerr << "Caught generic error: " << e.what() << std::endl; } } ```

运行特定函数

```C++ int main() { WASM::Interpreter interpreter;

/... Load the WASM modules... /

using WASM::i32; auto addFunc= interpreter.functionByName("myModule", "myAddFunction"); auto result = interpreter.runFunction(addFunc, (i32)123, (i32)234);

result.print(std::cout); } ```

注册宿主模块

```C++ int main() { WASM::Interpreter interpreter;

/... Load the WASM modules... /

using WASM::i32, WASM::f64;

// Define a module with some functions and a memory instance (10 pages) WASM::HostModuleBuilder myModuleBuilder{ "myNativeModule" }; myModuleBuilder .defineFunction("printInt", & { std::cout << x << std::endl; }) .defineFunction("floatSum", & { return x+ y; }) .defineFunction("myLog", & { return std::log(x); }) .defineMemory("memory", 10);

// Register the host module before compilation auto myHostModule = interpreter.registerHostModule(myModuleBuilder);

// Load a wasm module that now can link to the 'myNativeModule' module interpreter.loadModule("path/to/myModule.wasm");

interpreter.compileAndLinkModules(); interpreter.runStartFunctions();

// Access the memory view of the host module auto memory= myHostModule.hostMemoryByName("memory"); auto memoryView= memory->memoryView();

for(auto& data : memoryView) { std::cout << data << std::endl; } } ```

添加内省功能

```C++

include "interpreter/introspection.h"

int main() { WASM::Interpreter interpreter;

// Attach a console logging introspector (very noisy) auto logger = std::make_unique( std::cout ); interpreter.attachIntrospector(std::move(logger));

/... Use the interpreter... / } ```

Mandelbrot集演示

/webassembly/mandelbrot目录下的代码需要使用Assembly Script编译器进行编译。可以在源Mandelbrot目录中使用npm i下载本地安装包。/interpreter/mandelbrot中的C++应用程序展示了解释器如何嵌入到应用中,加载Mandelbrot的WebAssembly模块并执行update函数,最终将生成的图像编码并保存为output.png。此演示需要使用stb_image库,该库已包含在本项目中。

下载地址

点击下载 【提取码: 4003】【解压密码: www.makuang.net】