WebGL-Native: 32bit移植
prev: https://zenn.dev/okuoku/scraps/83d06f50d62779
next: https://zenn.dev/okuoku/scraps/d4419915c37216
Raspberry Pi1に移植したい
RPi3までのRaspberry Piは32bitのARMなので、32bitで正常に動作することを確実にしたい。
というわけで、最初はWin32に移植してみることにした。
メモリが全然足りない
そういえば 64bitのネイティブコンパイラでさえコンパイルできない のに、32bitのコンパイラでコンパイルできるはずが無かった。。
FAILED: app2_wasm.bc
cmd.exe /C "cd /D C:\cygwin64\home\oku\repos\cwgl\apps\out\build\x86-Clang-Release && clang -g3 -c -emit-llvm -O0 -Xclang -disable-O0-optnone -DWASM_RT_MEMCHECK_SIGNAL_HANDLER=1 -IC:/cygwin64/home/oku/repos/cwgl/apps/../wasmstub -o C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.bc C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.c"
LLVM ERROR: out of memory
Stack dump:
0. Program arguments: clang -g3 -c -emit-llvm -O0 -Xclang -disable-O0-optnone -DWASM_RT_MEMCHECK_SIGNAL_HANDLER=1 -IC:/cygwin64/home/oku/repos/cwgl/apps/../wasmstub -o C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.bc C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.c
1. <eof> parser at end of file
2. Per-file LLVM IR generation
3. C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.c:7058953:12: Generating code for declaration 'w2c___ZL10domain_getP12Il2CppDomainb'
4. C:/cygwin64/home/oku/repos/cwgl/apps/out/build/x86-Clang-Release/app2_wasm.c:7059038:15: LLVM IR generation of compound statement ('{}')
#0 0x019567f8
#1 0x7584edc2
#2 0x01949aed
#3 0x035a406f
#4 0x00580836
#5 0x014e3d24
#6 0x015240d2
clang: error: clang frontend command failed due to signal (use -v to see invocation)
64bitのclangを使った上で、target tripleである i686-pc-windows-msvc
を手動で設定しないとダメかな。。
MSVCのx64版x86ツールチェーンでビルドする
ややこしいな。。
VisualStudioには64bit版のx86コンパイラが付属してくるので、これを使うことでx86版のコンパイラではビルドできないような大規模なプログラムもビルドできる。
スタートメニューから x64_x86 Cross Tools Command Prompt for VS 2019
を選ぶと該当のツールチェーンが PATH
に入った状態で起動する。 ただしclangはそのままなので 明示的に --target
オプションでターゲットを設定してやる必要がある。
if(BUILD_WIN32)
set(opt_target_triple --target=i686-pc-windows-msvc)
else()
set(opt_target_triple)
endif()
更にVisualStudioでのビルド向けにちょっと微調整をした。
noreturnの対応は↓からcherry-pickしている。
メモリ空間が足りない
Error: alloc failed
at [anon] (C:\cygwin64\home\oku\repos\cwgl32\duktape260\duk_api_stack.c:5502) internal
at Uint8Array () native strict construct preventsyield
at wasmmemory (input:5034) strict construct
at unityFramework (input:879) strict
at boot_unity (input:5794) strict
at boot (input:5891) strict
at [anon] (input:5907) strict
at eval (input:5909) directeval preventsyield
at eval () native strict directeval preventsyield
at eval (C:/cygwin64/home/oku/repos/cwgl32/duk-nccc/bootstrap.js:216) preventsyield
まぁデフォルトで2GiB(現状のWASMが処理できる限界値)取るからな。。32bitプロセスではそんなに取りようがないので、MAX 256MiBくらいにしてみる。
ポインタ = 64bits であることを前提にしたコードがある
function ptrref(addr){
// FIXME: Endian??
return ncccutil.peek_u64(addr);
}
これはWebGL実装のコードの一部だけど、あるアドレス addr
に格納されたポインタ値を読み出している。
... 実際には、ポインタが32bit巾である場合、64bits全体を読んではいけない。(リトルエンディアンの場合、)前半32bitsには正しいポインタが入っているかもしれないが、後半32bitsには未定義値が入っていることになるため、異常値を読む可能性がある。
というわけで、 peek_ptr
というのを足しておいた。
ここまでで、とりあえずWin32では正常に動作するようになった。