当我在编译时创建原始指针并在缓冲区中使用它时,为什么 wasm 二进制代码为空?

问题描述 投票:0回答:1

我正在尝试使用

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 生成的代码

rust webassembly
1个回答
3
投票

您只是修改本地堆栈内存而不返回值,因此它没有副作用并且可以优化掉。您可以使用 write_volatile 来阻止此操作。

您的代码也是 UB,因为您不符合 from_raw_parts_mut 文档中的安全要求。特别是

data must point to len consecutive properly initialized values of type T.
© www.soinside.com 2019 - 2024. All rights reserved.