前回の続き。
構造体は静的初期化にしたらうまくいくかも?と思い以下のようにコードを変更してみた。
extern (C): nothrow: @nogc: struct TwoI32 { int aa; int bb; }; export TwoI32 return_two_i32() { TwoI32 s = { aa: 1, bb: 2 }; return s; }
が結果は変わらず。
$ wasm-validate multivalue.wasm 000000e: error: invalid function result count 2, only 1 bytes left in section
このエラーメッセージだけだとちょっとわかりにくいが、型定義の部分がおかしいようだ。
$ wasm-objdump -x -j Type multivalue.wasm multivalue.wasm: file format wasm 0x1 000000e: error: invalid function result count 2, only 1 bytes left in section Section Details: Type[1]:
本来であれば
() -> (i32, i32)
のような型が出現してほしい。
スタック参照してるのが悪いのかな?と思い、-Ozで最適化+ついでにコードサイズ小さくしてみる。
ldc2 -mtriple=wasm32-unknown-unknown \ -mattr=+multivalue \ -betterC \ -fvisibility=hidden \ --frame-pointer=none \ -L=-no-entry \ -Oz \ --output-ll \ -vv \ multivalue.d
LLVM IRもなんか小奇麗になった。
(...) %multivalue.TwoI32 = type { i32, i32 } ; [#uses = 0] ; Function Attrs: norecurse nounwind readnone define %multivalue.TwoI32 @return_two_i32() local_unnamed_addr #0 { ret %multivalue.TwoI32 { i32 1, i32 2 } } attributes #0 = { norecurse nounwind readnone "frame-pointer"="none" "target-cpu"="generic" "target-features"="+multivalue" } (...)
しかし--output-ll外してwasm生成すると同じエラーになる。
$ wasm-validate multivalue.wasm 000000e: error: invalid function result count 2, only 1 bytes left in section
同じようにTypeが壊れているということのはずなので、%multivalue.TwoI32ではだめということか。
本体が
ret { i32, i32 } { i32 1, i32 2 }
のようになる必要がある?
ただLDC側でArgInfo::getDirect()のような新し目のAPIを使えるようにするのは今の時点だとなかなか大変な作業なので、なんか簡単に試せる方法がないか考えよう。