为什么 clang 在以 wasm32 为目标时发出 i64 指令?
Why does clang emit i64 instructions when targeting wasm32?
我使用 clang --target=wasm32-unknown-wasi ...
将一个 Hello World C 程序编译成 WebAssembly。一切顺利,.wasm
文件可以在 运行 时间内像 wasmer 一样正确地 运行。
但是当我检查 .wasm
文件(.wat
格式)时,我发现了一些 i64 指令,例如:
(func $__lseek (type $t1) (param $p0 i32) (param $p1 i64) (param $p2 i32) (result i64)
(local $l3 i32)
global.get $g0
i32.const 16
i32.sub
local.tee $l3
global.set $g0
block $B0
block $B1
local.get $p0
local.get $p1
local.get $p2
i32.const 255
i32.and
local.get $l3
i32.const 8
i32.add
call $__wasi_fd_seek
local.tee $p0
i32.eqz
br_if $B1
i32.const 0
i32.const 70
local.get $p0
local.get $p0
i32.const 76
i32.eq
select
i32.store offset=3696
i64.const -1
local.set $p1
br $B0
end
local.get $l3
i64.load offset=8
local.set $p1
end
local.get $l3
i32.const 16
i32.add
global.set $g0
local.get $p1)
看起来很奇怪:为什么 clang 在以 wasm32 为目标时会发出 i64 指令?
根据https://github.com/WebAssembly/wasi-libc/issues/158中的讨论,我认为这可能是因为在link期间引入了一些包含i64指令的wasi API。
我说的对吗?
感谢您的关注!
我看不出有什么不妥。 Targeting 32bits 意味着内存 addressing 是 32bits。由于这个原因,在内存存储指令之前,你只有 32 位指令(即偏移量和值是 i32)你在某个时候有这个:
i32.store offset=3696
这是隐式内存索引 0 中的存储(今天唯一可用的)。存储的值是 32 位整数,偏移量为 i32(在此之前计算 + 3696)。在这种情况下,偏移量 是您关心的,即 i32,它 是 。 首先计算偏移量,然后计算值。
WebAssembly 的 MVP 支持“开箱即用”的 64 位整数。这意味着您可以自由使用这些值,以及 f32 和 f64。然而,这是您程序中的值,MVP 仅支持 i32 内存寻址。就在最近 BitInt
成为 WebAssembly 中匹配 i64
的 JS 类型, memory64
post-MVP 正准备进入生产系统。
详细信息你有这个:
(; push 0 (i32 type) ;)
i32.const 0
(; stack depth from here = 1 ;)
(; push 70 (i32 type) ;)
i32.const 70
(; stack depth from here = 2 ;)
(; push the first parameter two times (that is of i32 type) ;)
local.get $p0
local.get $p0
(; stack depth from here = 4 ;)
(; push 76 (i32 type))
i32.const 76
(; stack depth from here = 5 ;)
(; check is 76 equal to $p0, pop 2, push 1 all i32 types ;)
i32.eq
(; stack depth from here = 4 ;)
(; [t t i32] -> [t], i.e. pop 3, push 1, all i32 types ;)
select
(; stack depth from here = 2 ;)
(; [offset i32, value i32] -> [], pop 2, push zero ;)
i32.store offset=3696
(; stack depth 0 ;)
立即数 offset=3696
是一个偏移量,它将添加到堆栈的计算偏移量以接收 effective address
值将被准确写入的位置。
我使用 clang --target=wasm32-unknown-wasi ...
将一个 Hello World C 程序编译成 WebAssembly。一切顺利,.wasm
文件可以在 运行 时间内像 wasmer 一样正确地 运行。
但是当我检查 .wasm
文件(.wat
格式)时,我发现了一些 i64 指令,例如:
(func $__lseek (type $t1) (param $p0 i32) (param $p1 i64) (param $p2 i32) (result i64)
(local $l3 i32)
global.get $g0
i32.const 16
i32.sub
local.tee $l3
global.set $g0
block $B0
block $B1
local.get $p0
local.get $p1
local.get $p2
i32.const 255
i32.and
local.get $l3
i32.const 8
i32.add
call $__wasi_fd_seek
local.tee $p0
i32.eqz
br_if $B1
i32.const 0
i32.const 70
local.get $p0
local.get $p0
i32.const 76
i32.eq
select
i32.store offset=3696
i64.const -1
local.set $p1
br $B0
end
local.get $l3
i64.load offset=8
local.set $p1
end
local.get $l3
i32.const 16
i32.add
global.set $g0
local.get $p1)
看起来很奇怪:为什么 clang 在以 wasm32 为目标时会发出 i64 指令?
根据https://github.com/WebAssembly/wasi-libc/issues/158中的讨论,我认为这可能是因为在link期间引入了一些包含i64指令的wasi API。 我说的对吗?
感谢您的关注!
我看不出有什么不妥。 Targeting 32bits 意味着内存 addressing 是 32bits。由于这个原因,在内存存储指令之前,你只有 32 位指令(即偏移量和值是 i32)你在某个时候有这个:
i32.store offset=3696
这是隐式内存索引 0 中的存储(今天唯一可用的)。存储的值是 32 位整数,偏移量为 i32(在此之前计算 + 3696)。在这种情况下,偏移量 是您关心的,即 i32,它 是 。 首先计算偏移量,然后计算值。
WebAssembly 的 MVP 支持“开箱即用”的 64 位整数。这意味着您可以自由使用这些值,以及 f32 和 f64。然而,这是您程序中的值,MVP 仅支持 i32 内存寻址。就在最近 BitInt
成为 WebAssembly 中匹配 i64
的 JS 类型, memory64
post-MVP 正准备进入生产系统。
详细信息你有这个:
(; push 0 (i32 type) ;)
i32.const 0
(; stack depth from here = 1 ;)
(; push 70 (i32 type) ;)
i32.const 70
(; stack depth from here = 2 ;)
(; push the first parameter two times (that is of i32 type) ;)
local.get $p0
local.get $p0
(; stack depth from here = 4 ;)
(; push 76 (i32 type))
i32.const 76
(; stack depth from here = 5 ;)
(; check is 76 equal to $p0, pop 2, push 1 all i32 types ;)
i32.eq
(; stack depth from here = 4 ;)
(; [t t i32] -> [t], i.e. pop 3, push 1, all i32 types ;)
select
(; stack depth from here = 2 ;)
(; [offset i32, value i32] -> [], pop 2, push zero ;)
i32.store offset=3696
(; stack depth 0 ;)
立即数 offset=3696
是一个偏移量,它将添加到堆栈的计算偏移量以接收 effective address
值将被准确写入的位置。