Ale*_*her 7 rust webassembly rust-wasm
嘿@all,我正在使用WebAssembly Studio并创建了一个空的 Rust 项目。
在我的 Rust 代码中,我返回“Hello World”字符串的指针和长度。编译工作正常,但我期望生成的 WASM 有一个返回两个 i32 的函数。但我发现一个函数接受一个 i32 并且没有返回任何内容。
为什么该函数没有签名 fn () -> (i32,i32) ?
我该如何从 WASM 模块中提取这两个值?(使用 Rust- wasmtime)
您可以在下面找到我正在讨论的代码片段。提前致谢!
#[no_mangle]
pub extern "C" fn say() -> (*const u8,i32) {
let pointcut = "Hello World";
(pointcut.as_ptr(),11)
}
Run Code Online (Sandbox Code Playgroud)
(module
(type $t0 (func (param i32)))
(func $say (export "say") (type $t0) (param $p0 i32)
get_local $p0
i32.const 11
i32.store offset=4
get_local $p0
i32.const 1024
i32.store)
(table $T0 1 1 anyfunc)
(memory $memory (export "memory") 17)
(data (i32.const 1024) "Hello World"))
Run Code Online (Sandbox Code Playgroud)
WebAssembly最近才获得了返回多个值的能力。使用的编译器似乎还不支持此功能,或者出于兼容性原因而不使用它,即尚不知道此功能的运行时。
因此,编译器将代码重写如下:
#[no_mangle]
pub extern "C" fn say(output: &mut (*const u8, i32)) {
let pointcut = "Hello World";
output.1 = 11;
output.0 = pointcut.as_ptr();
}
Run Code Online (Sandbox Code Playgroud)
至少这会导致与您的代码相同的 WebAssembly 代码。该参数output对应于$p0WebAssembly 代码中的参数。
WebAssembly 代码现在执行以下操作:
首先,数字 11 被写入元组中的第二项,因此位于 的内存地址处output + 4。偏移量为 4 个字节,因为i32元组的第一个有 4 个字节。
其次,将字符串的内存地址pointcut写入元组的第一个值。正如您在生成的 WebAssembly 代码的数据部分中看到的,该字符串被放入内存地址 1024 处的线性内存中。注意:pointcut是一个字符串文字,因此是静态的,因此它不存在于堆栈中,这是非法的(正如Coder-256已经评论的那样)并且会导致编译器错误。编辑:由于原始指针而没有编译错误。寿命检查仅供参考。
因此,要获取这两个值,您必须i32在线性内存中分配 8 个字节的内存(对于这两个值),使用指向该内存区域的指针调用该函数,然后读取这两个值。将函数拆分为两个单独的函数可能更方便,其中一个返回指针,另一个返回长度。至少,这将使提取值变得更容易,因为两个函数都会返回一个i32.
编辑:我发现Mozilla 的一篇文章也解释了我在“wasm-bindgen”部分的想法。
| 归档时间: |
|
| 查看次数: |
1067 次 |
| 最近记录: |