标签: wasi

为什么此 wasm 模块中有“wasi_snapshot_preview_1”导入?

最近,我尝试使用尽可能少的助手来尝试 WebAssembly。

所以我创建了 ac 项目,包含一些库(stb_image.h)并尝试编译它。

这是一个简短的可重现示例:

#include <emscripten.h>
#define STBI_NO_STDIO
#define STBI_NO_FAILURE_STRINGS
#define STB_IMAGE_IMPLEMENTATION

#include "stb_image.h"

EMSCRIPTEN_KEEPALIVE
void test(){
    stbi_load_from_memory(NULL, 0, NULL, NULL, NULL, 0);
}

Run Code Online (Sandbox Code Playgroud)

这是我使用的命令:

emcc converter.c -s STANDALONE_WASM -o converter.wasm --no-entry

这工作正常并给了我一个有效的 wasm 文件。

但后来我尝试使用 javascript 在浏览器中实例化它,而不使用其他任何东西:

let wasm = await Webassembly.instantiateStreaming(fetch('converter.wasm'), {});
Run Code Online (Sandbox Code Playgroud)

但我收到这个错误:

未捕获(承诺中) TypeError: WebAssembly.instantiate(): Import #0 module="wasi_snapshot_preview1" 错误:模块不是对象或函数

我检查了 WebAssembly,确实我的 WebAssembly 需要这些功能:

  (func $wasi_snapshot_preview1.fd_close (;0;) (import "wasi_snapshot_preview1" "fd_close") (param i32) (result i32))
  (func $wasi_snapshot_preview1.fd_seek (;1;) (import "wasi_snapshot_preview1" "fd_seek") (param i32 i64 i32 …
Run Code Online (Sandbox Code Playgroud)

c import emscripten webassembly wasi

7
推荐指数
1
解决办法
7712
查看次数

为什么 WebAssembly 是安全的以及什么是线性内存模型?

(1) 我听说 WebAssembly 通过提供线性内存而安全。我想知道这个线性存储器包含什么?wasm栈和堆是否位于这个内存空间?如果是的话,我认为 wasm 堆栈和粘合代码堆栈(例如 JavaScript、Python 等)是分开的,对吧?

(2)我可以通过使用导入表来了解wasm的内存安全性。换句话说,wasm函数不能调用线性内存之外的任何函数,因为它只能使用索引来调用导入的函数。除此之外,wasm 还提供哪些其他安全功能?可能是上面的堆栈问题。

(3) 看起来wasm中也有控制流完整性。也就是说每个函数的返回地址都是固定的,不能在函数内部修改。这是正确的理解吗?

emscripten asm.js webassembly wasi wasmtime

5
推荐指数
1
解决办法
1666
查看次数

如何在 WASI 中使用 Rust 的 async/await 语法

我想用Cargo-wasi编译以下代码。

// reqwest = { version = "0.11", features = ["json"] }
// tokio = { version = "1", features = ["full"] }

use std::collections::HashMap;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let resp = reqwest::get("https://httpbin.org/ip")
        .await?
        .json::<HashMap<String, String>>()
        .await?;
    println!("{:#?}", resp);
    Ok(())
}
Run Code Online (Sandbox Code Playgroud)

尝试编译后,出现以下错误,因为mio 目前不支持 WASI

$ cargo wasi run
   Compiling mio v0.7.9
   Compiling parking_lot v0.11.1
   Compiling serde_json v1.0.64
   Compiling idna v0.2.2
error[E0432]: unresolved import `crate::sys::IoSourceState`
  --> /home/ducaale/.cargo/registry/src/github.com-1ecc6299db9ec823/mio-0.7.9/src/io_source.rs:12:5
   |
12 | use crate::sys::IoSourceState;
   | …
Run Code Online (Sandbox Code Playgroud)

rust wasi

5
推荐指数
1
解决办法
2127
查看次数

如何减小 WASM 二进制文件的大小?

我有一个用 C++ 编写的项目,要部署的平台有 256KB 二进制大小的限制。

工具链是wasi-sdk-16.0 clang++,我们使用这个编译器将源代码编译成WASM格式的二进制文件。在此步骤中,我们使用以下 CXX_FLAGS 编译源代码。

-fstack-protector-strong -Os -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security -Wl,-z,relro,-z,now -Wno-psabi
Run Code Online (Sandbox Code Playgroud)

然后我们将strip二进制文件与

strip -s output_binary.wasm
Run Code Online (Sandbox Code Playgroud)

经过上述步骤后,这一步编译出来的二进制文件大小为254KB。

然后我们wamrc在 WAMR 中使用 AOT 运行时编译 WASM 二进制文件,命令如下所示。

wamrc --enable-indirect-mode --disable-llvm-intrinsics -o output.aot output.wasm
Run Code Online (Sandbox Code Playgroud)

输出二进制大小变为 428KB,远大于限制(256KB)。


谷歌搜索后,我用来wasm-opt缩小尺寸,

wasm-opt -Oz output.wasm -o output.wasm
Run Code Online (Sandbox Code Playgroud)

大小变小 4KB。(几乎没用)


我试图确认我的代码对二进制大小的影响有多大,所以我编写了简单的最小示例代码,称为标准 C++ 库,如下所示,

-fstack-protector-strong -Os -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security -Wl,-z,relro,-z,now -Wno-psabi
Run Code Online (Sandbox Code Playgroud)

编译后的二进制大小已经变成了205KB。


我还尝试使用二进制大小分析器 ( twiggy) 来跟踪二进制文件每个部分的大小,但该工具无法打开该二进制文件。


所以我想问一下

  1. 虽然仅包含两个标准 C++ 头文件会使二进制大小达到大小限制,但如何使用我真正使用的函数剥离 C++ 标准库(我不能使用剥离未使用的函数标志,因为我的项目是提供给其他人的库),或者C++ 标准库真的影响了二进制大小吗?

  2. 是否有任何其他编译器标志,或剥离标志,或任何其他优化工具可以显着减少二进制大小?

c++ compiler-optimization webassembly wasi

5
推荐指数
1
解决办法
1345
查看次数

Emscripten 和 Clang 在 WebAssembly 编译方面有什么区别

我知道 clang(通过使用 target=wasm32)和 emscripten 都可以将 C 代码编译成 webassembly,但它们有什么不同?

看起来他们都使用 LLVM 作为后端。其实,我什至不太明白 llvm 和 clang 之间的关系......

我已经阅读了一段时间的 WebAssembly,但我对它缺乏低级理解。非常感谢您的参与!!

llvm clang emscripten webassembly wasi

2
推荐指数
1
解决办法
500
查看次数

从 rust wasm32-wasi 调用 console.log,无需 ssvm/ssvmup

我想使用 console.log 的消息进行调试。

我们有一个 rust wasm32-wasi 函数从在 Nodejs 中运行的 JavaScript 调用。由于其他限制,我们无法使用 ssvm/ssvmup。

我们可以做些什么来在控制台中查看来自 wasm 代码的消息吗?

node.js rust wasi

1
推荐指数
1
解决办法
3761
查看次数