javascript - Clang 是否为 WebAssembly 的 memory.fill 和 memory.copy 提供内在函数?

标签 javascript c clang llvm webassembly

我正在用 C 语言开发 WebAssembly 模块,并一直在尝试利用 WebAssembly spec 中定义的 memory.fillmemory.copy 指令。 .

我知道 Clang (v11.1.0) 已经 supports other memory-related wasm intrinsics__builtin_wasm_memory_size__builtin_wasm_memory_grow,但如果它支持 memory.fillmemory 的内在函数,我一直在努力解决.复制.

我不太熟悉 Clang/LLVM 的内部工作原理,但在一些地方似乎暗示了对这些说明的引用 [1] [2] (除非我误解了什么)。

我尝试使用 __builtin_memcpy__builtin_memset:

__attribute__((export_name("memcpy")))
void memcpy_test(void* mem_dst, void* mem_src) {
    __builtin_memcpy(mem_dst, mem_src, 128);
}

__attribute__((export_name("memset")))
void memset_test(void* mem_src) {
    __builtin_memset(mem_src, 0, 128);
}

可以编译,但是对 __builtin_memcpy__builtin_memset 的调用将替换为程序集中的导入函数:

...
  (import "env" "memcpy" (func $memcpy (type $t0)))
  (import "env" "memset" (func $memset (type $t0)))
  (func $__wasm_call_ctors (type $t1))
  (func $memcpy_test (type $t2) (param $p0 i32) (param $p1 i32)
    local.get $p0
    local.get $p1
    i32.const 128
    call $memcpy
    drop)
  (func $memset_test (type $t3) (param $p0 i32)
    local.get $p0
    i32.const 0
    i32.const 128
    call $memset
    drop)
...

此时我有点卡住了,似乎这些内在函数还不可用,但我对此并不肯定。

如果能得到任何帮助,我将不胜感激!

[快速说明:我目前对使用 emscripten 不感兴趣,因为我试图避免它附带的大量粘合代码。]

最佳答案

but the calls to __builtin_memcpy and __builtin_memset are replaced with imported functions in the assembly:

原因是这些指令不是核心 (MVP) WebAssembly 指令集的一部分,而是稍后在 bulk-memory proposal 中添加的.

那些后来的提案需要明确选择加入,因为存在您可能针对的给定 WebAssembly 引擎尚不支持它们的风险。可以肯定的是,您可以检查my support table on webassembly.org .

最后,如果您已经选中此项,则可以通过 -mbulk-memory 标志在 Clang 中选择启用此功能。例如,启用此标志和优化

clang temp.c -mbulk-memory -O -c -o temp.wasm

这是我从上面的示例中得到的:

(module
  (type $t0 (func (param i32 i32)))
  (type $t1 (func (param i32)))
  (import "env" "__linear_memory" (memory $env.__linear_memory 0))
  (import "env" "__indirect_function_table" (table $env.__indirect_function_table 0 funcref))
  (func $memcpy_test (type $t0) (param $p0 i32) (param $p1 i32)
    (memory.copy
      (local.get $p0)
      (local.get $p1)
      (i32.const 128)))
  (func $memset_test (type $t1) (param $p0 i32)
    (memory.fill
      (local.get $p0)
      (i32.const 0)
      (i32.const 128)))
  (export "memcpy" (func $memcpy_test))
  (export "memset" (func $memset_test)))

这似乎是预期的结果。

关于javascript - Clang 是否为 WebAssembly 的 memory.fill 和 memory.copy 提供内在函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67068195/

相关文章:

javascript - 什么是 'global symbol registry' ?

c - 如何从 C 中的现有变量创建位域

Clang 优化破坏代码?

c++ - 为什么 gcc 和 clang 允许我构造一个抽象类?

c++ - Linux下如何将ARM和Flash组装到STM32?

c++ - 可以在 Windows 中使用 clang-cl 标志 -fprofile-instr-generate -fcoverage-mapping

Javascript - requestAnimationFrame 帧速率

javascript - 如何对对象的属性值求和?

javascript - ReactJS:如果变量更改值则重新加载组件

c - 有没有办法初始化一个尚未在c中读取的文件