2022/04/04
実装したもの
https://github.com/kgtkr/wjit
$ cat ./sample.wjit
func main() {
var x = fib(10) in
println(x);
func_a(10);
println(is_prime(3));
println(is_prime(4));
println(is_prime(5));
println(is_prime(6));
}
func fib(n) {
if (n < 2) {
n;
} else {
fib(n - 1) + fib(n - 2);
};
}
func func_a(x) {
println(x);
if (x <= 0) {
x;
} else {
func_b(x - 1);
};
}
func func_b(x) {
println(x);
2019/12/21
はじめに
RustでWebAssemblyインタプリタを作ったのでその実装の話や、wasmの仕様についての記事です。
HListを使ったジェネリックプログラミングの話や、最後の方には「自作言語 on 自作wasmインタプリタ on 自作wasmインタプリタ」みたいな話も出てきます。
分かりにくい所や間違っている所は指摘してくださると助かります。
リポジトリ
https://github.com/kgtkr/wasm-rs
作った成果物のリポジトリです。まだpublishはしていませんがクレートになっています。
cargoのexample実行に対応しているのでそれを見ればだいたい分かると思います。
今回はadc-2019-12-22というタグがついたコミットのソースを元に解説していきます。
https://github.com/kgtkr/wasm-rs/tree/adc-2019-12-22
仕様書
この記事では仕様書を読みながら順番に実装を解説していきます。
https://webassembly.github.io/spec/
2019/12/08
資料
31回だったのに32回と勘違いしててURLが32になっていますが気にしないでください。ライブデモ多いので多分LT資料だけじゃよく分かりません。
https://gitpitch.com/kgtkr/slide-student-lt-32
LT動画
内容
自己紹介wasmに関する説明
watについて(watコード読みながら解説した)wasm(バイナリ)について(wasmバイナリ読みながら解説した)
rustでwasmインタプリタ作った話
デコーダーエンコーダースタックマシン
自作言語 on 自作インタプリタ(ライブデモ)自作言語 on 自作インタプリタ on 自作インタプリタ(ライブデモ)
補足資料とか
成果物: https://github.com/kgtkr/wasm-rswasm仕様書: https://webassembly.github.io/spec/core/index.html自作言語などについて(去年のアドカレ)
WebAssemblyでメモリアロケータを実装WebAssemblyでGCを実装するWebAssemblyに
2019/11/02
はじめに
WebAssemblyにはbrという命令があります。
この命令はbr <label>という形になっており、<label>が示す制御構造に対して何らかの動作をします。
例えばブロックに対して使えばブロックを抜け、ループの中で使えばcontinueのような振る舞いをします。
wasmのループについてはκeenさんのWebAssemblyのloopはまりどころという記事を見てみて下さい。
なぜこのように制御構造によってブロックを抜ける働きをしたり、continueの働きをしたりするか仕様書を読んでいたところ理由が分かり面白いと思ったので記事にしました。
br命令
基本的にはbr 数値という形の命令です。この数値は相対的な値となっておりbr命令を囲っているすぐ外側の制御構造に対してなにかするときはbr 0と、その外側であればbr 1と...いうふうに指定します。
また、watでは制御構造に$labelをつけることでbr $labelと書けばbr命令がどの深さに関係なくその制御構造に対して命令を実行することができます。
例
関数に対して
2018/12/02
はじめに
Haskellでwasmにコンパイルする言語を実装してみたので記事にしました。
LLVMなどには依存せず直接wasmを出力します。
また、現段階ではエラー処理などは未完成なので間違ったコードを入力するとコンパイラがクラッシュするか不正なwasmを出力するかその他色々おかしな事が起きたりします。
メモリアロケータはこの記事で実装したものを使っています。
GCは実装は一応終わっているのですが(記事)まだコンパイラ側の対応が終わっていません。
このようにまだかなりひどい状態ですが少しずつ改善していけたらなと思っています。
リポジトリ
https://github.com/kgtkr/cl8w
サンプルソース
先にサンプルを見たほうがイメージしやすいと思うので置いておきます。
まず実行の為のJSのソースです。
main.wasmはコンパイル結果、./memory/memory.wasmはメモリアロケータです。
数値のprintも欲しいのでprint関数をimportしています。
エントリポイントはmain.wasmのmain関数とな
2018/12/01
初めに
この記事でメモリアロケータを実装したので今回はGCを実装してみます。
様々な事情でアロケータのコードが少し変わっているのでソースはここを見て下さい。
大きな変更点はfreeの返り値でfreeしたブロックのポインタを取得出来るようになった事くらいです(ブロックが消失した時は0が返ります)。
今回もwatでとりあえず動く物を作る事を目標に実装していきます。
方針
参照カウントとmark and sweepを組み合わせたような実装をします。
ローカル変数などからの参照のみを参照カウントで管理し(これはコンパイラがinc_countとdec_countを呼び出すコードを挿入する必要がある)、参照カウントが0でないブロックをルートセットとして扱いmark and sweepします。
ブロックには2種類あり「データブロック」と「参照ブロック」です。
これはmark and sweepで使用し、データブロックの場合はbodyをただのバイト列として扱うのでmark and sweepの再帰的なマークには影響しません。参照ブロックの場合はbodyを全
2018/12/01
初めに
WebAssemblyには線形メモリがあるだけで動的なメモリ管理機能はありません。
ライブラリを使うことも出来ますが、今回はmallocとfreeを実際に実装してみます。
方針
パフォーマンスは気にしない。とにかく動くものを作るwasmのテキストフォーマットであるwatで実装する
仕様
mallocを呼び出すとメモリブロックが作られます。
メモリブロックにはヘッダ部とボディ部があり、mallocはボディ部の先頭アドレスを返します。
このボディ部の先頭アドレスをブロックのポインタとします。
メモリアドレスは0から始まり、ボディの前にヘッダが入ることからブロックのポインタが0になることはないことがわかるかと思います。
ブロックの間には隙間がなく、またmallocは要求サイズ以上確保するのではなくぴったり要求サイズ確保するものとします。
ヘッダのメモリ配置
サイズ 名前 説明1 flag 終端ブロック:0、未使用:1、使用中:2
4 size ボディのサイズ
4 prev 前ブロックのポインタ。先頭ブロックなら0
終端ブロックはこ