グルーコードから発生するイベントのフック
Module の特定の関数を実装することでグルーコードの状態変化時の追加処理を記述することができる。
これまでは wasm のインスタンス準備が完了したことを示す onRuntimeInitialized() のみを利用していたが、以下ではそれ以外のものも記述している。
C:\wasm\project\07-hook-module\.vscode\launch.json
{
"version": "0.2.0",
"configurations": [
{
"type": "chrome",
"request": "launch",
"name": "localhost:8080",
"url": "http://localhost:8080/",
}
]
}
C:\wasm\project\07-hook-module\CMakePresets.json
{
"version": 5,
"cmakeMinimumRequired": {
"major": 3,
"minor": 20,
"patch": 0
},
"configurePresets": [
{
"name": "wasm-config-debug",
"generator": "Ninja",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_CXX_STANDARD": "17",
"CMAKE_CXX_STANDARD_REQUIRED": "ON",
"CMAKE_CXX_EXTENSIONS": "OFF",
"CMAKE_TOOLCHAIN_FILE": "$env{EMSDK}/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON",
"CMAKE_BUILD_TYPE": "Debug"
}
}
],
"buildPresets": [
{
"name": "wasm-build-debug",
"configurePreset": "wasm-config-debug",
"verbose": true
}
]
}
C:\wasm\project\07-hook-module\CMakeLists.txt
- --extern-pre-js 指定したファイルをグルーコードの先頭に挿入する
- --pre-js 指定したファイルを Module 変数確定後の位置に挿入する
- 上記以外にも --post-js, --extern-post-js などがある
cmake_minimum_required(VERSION 3.20)
project(07_hook_module LANGUAGES CXX)
add_executable(07_hook_module main.cpp)
target_link_options(07_hook_module PRIVATE
"-gsource-map"
"-sASSERTIONS=1"
"-sSAFE_HEAP=1"
"--extern-pre-js=${CMAKE_SOURCE_DIR}/extern-pre.js"
"--pre-js=${CMAKE_SOURCE_DIR}/pre.js"
)
C:\wasm\project\07-hook-module\index.html
- arguments C++ の main() 関数の引数を設定できる
- locateFile ロードする wasm の URL を変更することが可能
- monitorRunDependencies addRunDependency/removeRunDependency を使うことで、依存関係の解決状況を監視したいときに利用できる
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8"/>
<script src="build/07_hook_module.js"></script>
<script>
Module.arguments.push('WORLD');
Module.monitorRunDependencies = runDependencies => {
console.log(`monitorRunDependencies(${runDependencies})`);
};
Module.preInit = [
() => { console.log('preInit'); },
]
Module.preRun = [
mod => { console.log('preRun'); },
];
Module.setStatus = msg => {
console.log(`setStatus(${msg})`);
};
Module.onRuntimeInitialized = () => {
console.log('onRuntimeInitialized');
};
Module.postRun = [
mod => { console.log('postRun'); },
];
</script>
</head>
<body>
</body>
</html>
C:\wasm\project\07-hook-module\extern-pre.js
// グルーコードの先頭に転記される
var Module = {
preInit: [
() => { console.log('preInit'); },
],
locateFile: (path, scriptDirectory) =>
{
console.log(`locateFile('${path}','${scriptDirectory}')`);
return scriptDirectory + path;
},
arguments: ['HELLO'],
};
// <<== extern-pre.js
C:\wasm\project\07-hook-module\pre.js
// グルーコードの Module 変数確定後の位置に転記される
Module.arguments.push('WASM');
// <<== pre.js
C:\wasm\project\07-hook-module\main.cpp
// UTF-8N CRLF
#include <cstdio>
int main(int argc, char** argv)
{
printf("C++ main(argc=%d, argv=[", argc);
for (int i=0; i<argc; ++i)
{
if (i) {
printf(",");
}
printf("'%s'", argv[i]);
}
puts("])");
return 0;
}
// EOF
実行結果
js や html などに書かれた console.log() により以下のような順番で関数が呼ばれていることを確認できる。
preInit
locateFile('07_hook_module.wasm','http://localhost:8080/build/')
monitorRunDependencies(0)
preRun
setStatus(Running...)
onRuntimeInitialized
C++ main(argc=4, argv=['./this.program','HELLO','WASM','WORLD'])
postRun
setStatus()
次回 は MODULARIZE=1 によるインスタンス化の制御について記述している。