我正在尝试使用
no_std
目标构建 wasm32-unknown-unknown
代码:
#[no_mangle]
pub fn test() {
let mut idx: i32 = 10;
let ptr = &mut idx as *mut i32;
let buffer = unsafe { core::slice::from_raw_parts_mut(ptr, 10) };
for pixel in buffer.iter_mut() {
*pixel = 0x7d2b7500;
}
}
构建后,我得到以下 wasm 二进制代码(我使用
wasm2wat
工具):
(module
(type (;0;) (func))
(func (;0;) (type 0)
nop)
(memory (;0;) 16)
(global (;0;) i32 (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "test" (func 0))
(export "__data_end" (global 0))
(export "__heap_base" (global 1)))
我的
test
函数由于某种原因为空(“nop”)。
但是当我从外部传递原始指针
ptr
作为 test
函数参数时:
#[no_mangle]
pub fn test(ptr: *mut i32) {
let buffer = unsafe { core::slice::from_raw_parts_mut(ptr, 10) };
for pixel in buffer.iter_mut() {
*pixel = 0x7d2b7500;
}
}
wasm 代码生成:
(module
(type (;0;) (func (param i32)))
(func (;0;) (type 0) (param i32)
local.get 0
i64.const 9019431323700000000
i64.store offset=32 align=4
local.get 0
i64.const 9019431323700000000
i64.store offset=24 align=4
local.get 0
i64.const 9019431323700000000
i64.store offset=16 align=4
local.get 0
i64.const 9019431323700000000
i64.store offset=8 align=4
local.get 0
i64.const 9019431323700000000
i64.store align=4)
(memory (;0;) 16)
(global (;0;) i32 (i32.const 1048576))
(global (;1;) i32 (i32.const 1048576))
(export "memory" (memory 0))
(export "test" (func 0))
(export "__data_end" (global 0))
(export "__heap_base" (global 1)))
为什么会发生这种情况?
我期待 wasm 生成的代码
您只是修改本地堆栈内存而不返回值,因此它没有副作用并且可以优化掉。您可以使用 write_volatile 来阻止此操作。
您的代码也是 UB,因为您不符合 from_raw_parts_mut 文档中的安全要求。特别是
data must point to len consecutive properly initialized values of type T.