最小限のWebAssemblyのバイナリファイルを書く - @ledsun blog でwasmバイナリのプリアンブルの書き出しに成功しました。 続いてセクションを書き出してみます。
Modules — WebAssembly 2.0 (Draft 2023-07-24) によると
ID 0はカスタムセクションというデバッグ情報を埋め込むセクションです。
カスタムセクションはnameと呼ばれるUTF-8文字列を埋め込みます。
ということはnameがhogeなカスタムセクションは0x00 0x04 0x00 0x00 0x00 0x68 0x6f 0x67 0x65
で良さそうです。
File.open("custom_section.wasm", "wb") do # preamble _1.write [0].pack('C') # 0x00 _1.write 'asm'.bytes.pack('C3') # 0x61 0x73 0x6d _1.write [1].pack('I<') # 0x01 0x00 0x00 0x00 # custom section _1.write [0].pack('C') # 0x00 _1.write [4].pack('I<') # 0x04 0x00 0x00 0x00 _1.write 'hoge'.bytes.pack('C4') # 0x68 0x6f 0x67 0x65 end
これをGoogle Chromeでコンパイルします。 実行するためのHTMLです。
<html> <title>Load wasm binary</title> <script> fetch('./custom_section.wasm') .then(response => response.arrayBuffer()) .then(buffer => WebAssembly.compile(buffer)) .then(module => console.log(module)) .catch(e => console.error(e)); </script> </html>
すると次のエラーが起きます。
(インデックス):8 CompileError: WebAssembly.compile(): section (code 111, "
") extends past end of the module (length 103, remaining bytes 1) @+14
理由はよくわかっていません。 結論だけいうと、sizeを7にするとWebAssemblyモジュールとして認識されます。
# custom section _1.write [0].pack('C') _1.write [7].pack('I<') # 4ではなく7 _1.write 'hoge'.bytes.pack('C4')
この3バイトはどこからでてきたのでしょうか? sizeをセクションの頭から数えるなら、7ではなく8や9になりそうなものです。