SlideShare ist ein Scribd-Unternehmen logo
1 von 37
Build Node.js – WASM/WASI tiny compiler
with Node.js
JSConf JP 2019 LT (2019.11.30)
@massie_g "Ma She[məʃ iː]"
Node.jsでつくる Node.js – WASM/WASI ミニミニコンパイラー
JSConf JP 2019 LT (2019.11.30)
@massie_g / がねこまさし
Are you interested in WASM ?
WASMに興味ありますよね?
• WASM = WebAssembly
• Then, how do you learn WASM?
• どうやって学びますか?
Learning WASM / WASMを学ぶ
• Read Spec. … I HATE BNF!
• 仕様を読む … BNFを読むと頭が痛くなる
Learning WASM / WASMを学ぶ
• Read Spec … I HATE BNF!
• Read code
• Use emscripten: hello_wold.c  wasm/wat … So huge code to read
• コードを読む
• Emscripten で変換: hello_wold.c  wasm/wat … 超巨大で読むの辛い
Learning WASM / WASMを学ぶ
• Read Spec … I HATE BNF!
• Read code
• Someone says, “You can write WASM by hand”
• … What are you talking about?
• 「手でWASM書けるよ」ていう人も
• … は?? 何言ってんの??
Learning WASM / WASMを学ぶ
• Read Spec … I HATE BNF!
• Read code
• “You can write WASM by hand” … What !? Crazy !?
• My suggestion: Build compiler to learn WASM !
• そうだ、コンパイラーを作って覚えよう!
The story so far / これまでの経緯
• I read the great book “Build Ruby with Ruby”
• I built Node.js tiny interpreter with Node.js
• I built Node.js tiny compiler with Node.js, using LLVM
• I made a talk in Nodefest Tokyo 2018
• Today: Node.js – WASM tiny compiler
• RubyでつくるRubyを読んだ
• Node.jsでつくるNode.jsミニインタープリター を作った
• Node.jsでつくるNode.jsミニコンパイラーをLLVMを使って作った
• 東京Node学園祭2018のセッションで話した
• https://www.slideshare.net/mganeko/nodejsnodejs-123707037
• 本日:Node.js でつくる ミニミニ Node.js-WASMコンパイラー
Structure of Node.js tiny compiler (2018)
Parser Simple AST
(abstract
syntax tree)
Code generator
Executable
binary
LLVM-IR
LLVM-IR
spec
esprima
Source
.js
Language spec:
Subset of JavaScript
llc
ld
Single Type:
32bit signed integer only
Structure of Node.js–WASM tiny compiler (2019)
Parser Simple AST
(abstract
syntax tree)
Code generator
WASM
spec
esprima
source
.js
Language spec:
Subset of JavaScript
wat2wasm
Re-use
.wat
(WebAssembly
Text format)
.wasm
(WebAssembly
binary format)
Web Browser
Node.js
read & execute
Just modify here
wat2wasm
• wat2wasm
• Convert WAT(text format) WASM(binary format)
• a tool of WebAssembly/wabt
• https://github.com/WebAssembly/wabt
• Install
• $ git clone --recursive https://github.com/WebAssembly/wabt
• $ cd wabt
• $ mkdir build
• $ cd build
• $ cmake ..
• $ cmake --build .
• Run
• $ wat2wasm src.wat -o dest.wasm
FYI/参考
Adapting to WASM is easy, (I thought)
WASM対応なんて楽勝!と思ってた
• … but, there are 2 big difference
• (1) machine architecture
• (2) Standard I/O Library
• … だがしかし、2つの大きな違い
• (1) レジスタマシン vs. スタックマシン
• (2) 標準ライブラリ
Difference (1): machine architecture
違い(1): レジスタマシンとスタックマシン
• LLVM … Register Machine /レジスタマシン
• Use register for data operation / データをレジスタに読み込んで処理
• LLVM, Lua VM, Erlang VM(BEAM), etc.
• WASM … Stack Machine / スタックマシン
• Use stack for data operation / データをスタックに積んで処理を行う
• WASM, Java VM(JVM), Ruby VM(YARV), etc.
Order of operation is different between LLVM  WASM
LLVM IR … Register Machine
CPU
register %r1
register %x
memory
load
point address
variable x
y = x + 1;
JavaScript
%r1 = load i32, i32* %x, align 4
%r2 = add i32 %r1, 1
store i32 %r2, i32* %y, align 4
LLVM-IR
FYI/参考
LLVM IR … Register Machine
CPU
ALU
register %r2
register %r1
memory
add
y = x + 1;
JavaScript
%r1 = load i32, i32* %x, align 4
%r2 = add i32 %r1, 1
store i32 %r2, i32* %y, align 4
LLVM-IR
1
FYI/参考
LLVM IR … Register Machine
CPU
register %r2 memory
point address
register %y
variable y
store
y = x + 1;
JavaScript
%r1 = load i32, i32* %x, align 4
%r2 = add i32 %r1, 1
store i32 %r2, i32* %y, align 4
LLVM-IR
FYI/参考
LLVM IR … Register Machine
CPU
ALU
register %r2
register %r1
register %x
memory
load
point address
register %y
variable x
variable y
store
add
y = x + 1;
JavaScript
%r1 = load i32, i32* %x, align 4
%r2 = add i32 %r1, 1
store i32 %r2, i32* %y, align 4
LLVM-IR
FYI/参考
WASM … Stack Machine
memory
variable x
y = x + 1;
JavaScript
get_local $x
i32.const 1
i32.add
set_local $y
WAT
value of x
1
1
ALU
FYI/参考
WASM … Stack Machine
ALU
memory
y = x + 1;
JavaScript
get_local $x
i32.const 1
i32.add
set_local $y
WAT
1
value of x
result (x+1)
result (x+1)
value of x
1
FYI/参考
WASM … Stack Machine
memory
variable y
y = x + 1;
JavaScript
get_local $x
i32.const 1
i32.add
set_local $y
WAT
result (x+1)
ALU
FYI/参考
WASM … Stack Machine
1
memory
variable x
variable y
y = x + 1;
JavaScript
get_local $x
i32.const 1
i32.add
set_local $y
WAT
value of x
result (x+1)
1
ALU
1
value of x
result (x+1)
FYI/参考
Difference (2) : Standard I/O Library
違い(2): 標準ライブラリ
• LLVM
• Link standard C library by linker (ld)
• easy to call puts(), printf()
• リンカーで C言語用のライブラリを一緒にリンク
• puts(), printf() が使えた
• WASM
• WASM has no standard I/O API/library
• Have to provide functions at outside, and import from WASM
• WASMとしての標準ライブラリ/APIは無し
• 呼び出し元で、インポート用の関数を提供
Ex) preparing functions at caller side
呼び出し元でインポート用関数の準備(例)
const imports = {
// --- print signed 32bit integer / 符号付32ビット整数を出力する関数 ---
imported_putn: function(arg) {
console.log(arg);
},
// --- print static string / 文字列を出力する関数 ---
imported_puts: function(offset) {
let str = '';
let arr = new Uint8Array(exported_string.buffer);
for (let i = offset; arr[i]; i++) {
str += String.fromCharCode(arr[i]);
}
console.log(str);
}
};
Exec WASM in Node.js
Node.jsからWASMの実行
const source = fs.readFileSync(filename); // read WASM / WASMファイルを読み込む
const typedArray = new Uint8Array(source);
let ret = null;
let exported_string = null;
WebAssembly.instantiate(typedArray,
{ imports: imports } // pass prepared functions / 先ほど用意したインポート用関数を渡す
).then(result => {
exported_string = result.instance.exports.exported_string;
ret = result.instance.exports.exported_main(); // call main of WASM / WASMのメイン関数を呼び出す
process.exit(ret);
}).catch(e => {
console.log(e);
});
Inside of WASM / WASMの中身
(module
;; ---- import print functions / 出力用関数をインポート ---
(func $putn (import "imports" "imported_putn") (param i32))
(func $puts (import "imports" "imported_puts") (param i32))
;; ---- static string area for puts()/ 出力用文字列の領域 ---
(memory $string_area 1) ;; string_area 64KiB
(export "exported_string" (memory $string_area))
;; --- export main/メインをエクスポート ---
(export "exported_main" (func $main))
(func $main (result i32)
(local $x i32)
(local $y i32)
i32.const 1 ;; let x = 1;
set_local $x
get_local $x ;; let y = x +1;
i32.const 1
i32.add
set_local $y
get_local $y ;; putn(y);
call $putn
i32.const 99 ;; return 99; (dummy)
return
)
)
Done! / できた
• I built Node.js-WASM tiny compiler
• able to run FizzBuzz, Fibonacci sequence
• https://github.com/mganeko/mini_node_wasm
• Node.js-WASM ミニミニコンパイラーができた
• FizzBuzzやフィボナッチ数列が動く
• https://github.com/mganeko/mini_node_wasm
WASI: Beyond Web
WASI でWebの外へ
• My Node.js-WASM tiny compiler is fun, but useless
• Convert .js to WASM, which was running on Node.js
• and run in Node.js again
• NEXT: Use WASM outside of Browser/Node.js
•  try WASI (WebAssembly system interface)
• 今回やったことは、楽しいけど意味はない
• もともとNode.jsで実行していた .js ファイルを、WASMに変換して
• またNode.js から実行
• ブラウザやNode.js以外の環境でWASMを動かしたい
• それなら、WASI (WebAssembly system interface) でしょ
WASI: WebAssembly System Interface
• WASI … a system interface to run WASM across all different OSs.
• https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
• POSIX like API … file, network, clock, random
• Example
• wasmtime ... WASI reference build with Rust
• https://wasmtime.dev/
• lucet ... Made by Fastly, aim to run on CDN edge server
• https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime
• WebAssembly Micro Runtime ... Lightweight runtime for embedded device
• No JIT, interpreter only
• https://github.com/bytecodealliance/wasm-micro-runtime
• WASI … WASMをいろんなOS上で動かすためのシステムインターフェイス
• ファイル、ネットワーク、クロック、乱数など
• 例
• Wasmtime … Rustで作られたリファレンス実装
• Lucet … Fastlyが作っている、CDNエッジサーバー上でWASMを動かすための環境
• WebAssembly Micro Runtime ... 組み込みデバイスで動かすための軽量ランタイム
WASI runtime functions / ランタイム関数
• WASI Core API System calls
• https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md
• provide primitive functions
• __wasi_fd_write()
• No printf()/puts()
• プリミティブな関数が提供される様子
• __wasi_fd_write() を使う必要がある
• 文字列出力puts()や、フォーマット付き出力のprintf()に相当するもはない
__wasi_fd_write(fd, *iovs, iovs_len, *nwritten)
arguments
• fd … file descriptor / ファイルデスクリプタ
• 0 … stdin / 標準入力
• 1 … stdout / 標準出力
• 2 … stderr / 標準エラー出力
• *iovs … start address of iov group
• iov->*buf … start address of byte array
• Iov->buf_len … length of byte array
• Iovs_len … size of iov group
• *nwritten … bytes written to file
• pointer of 32bit integer to output the value
*buf:
start address of
byte array
H i !
buf_len:
length of bye array
3
*buf
buf_len
Write multiple byte arrays
複数のバイト列を出力可能
”Hi!”
Implement built-in function
組み込み関数の実装
• putn() … prepare built-in function for print 32bit signed integer
• need to convert integer to byte string with WASM code
• Steps in putn()
• Check sign, Calculate length in string
• Take 1 digit  covert to ASCII code (1  81)
• store ASCII string in in memory
• call __wasi_fd_write()
• Writing WASM code for putn() by hand … quite tough work (for me)
• putn() … 32ビット符号付整数を出力するための組み込み関数を準備
• WASMで 32ビット符号つき整数 → 文字列(バイト列)に変換
• putn() のステップ
• 符号の有無を判定、長さの算出
• 1桁ずつASCIIコードのバイトに変換
• 文字列をメモリに書き込む
• __wasi_fd_write() を呼び出す
• この処理を行うWASMコードを手書きするのはシンドイ
Implement built-in function
組み込み関数の実装
• putn() … prepare built-in function for print 32bit signed integer
• need to convert integer to byte string with WASM code
• Steps in putn()
• Check sign, Calculate length in string
• Take 1 digit  covert to ASCII code (1  81)
• store ASCII string in in memory
• call __wasi_fd_write()
• Writing WASM code for putn() by hand … quite tough work (for me)
• putn() … 32ビット符号付整数を出力するための組み込み関数を準備
• WASMで 32ビット符号つき整数 → 文字列(バイト列)に変換
• putn() のステップ
• 符号の有無を判定、長さの算出
• 1桁ずつASCIIコードのバイトに変換
• 文字列をメモリに書き込む
• __wasi_fd_write() を呼び出す
• この処理を行うWASMコードを手書きするのはシンドイ
Use compiler to
generate WAT code!
今回作った
コンパイラーで生成
Example of compiled code:
_calcLength(n)
function _calcLength(n) { // n >= 0
let restValue = n;
let len = 1;
while (restValue >= 10) {
restValue = restValue / 10;
len = len + 1;
}
return len;
}
(func $_calcLength (param $n i32) (result i32)
(local $restValue i32)
(local $len i32)
get_local $n
set_local $restValue
i32.const 1
set_local $len
loop ;; --begin of while loop--
get_local $restValue
i32.const 10
i32.ge_s
if
get_local $restValue
i32.const 10
i32.div_s
set_local $restValue
get_local $len
i32.const 1
i32.add
set_local $len
br 1 ;; --jump to head of while loop--
end ;; end of if-then
end ;; --end of while loop--
get_local $len
return
)
Source .js
Compiled .wat
Node.js-
WASM
compiler
Structure of Node.js–WASM/WASI tiny compiler
Parser Simple AST
(abstract
syntax tree)
Code generator
WASM
spec
esprima
Source
.js
Language spec:
Subset of JavaScript
wat2wasm
Re-use
WASI ready .wat
(WebAssembly
Text format)
WASI ready .wasm
(WebAssembly
binary format)
read & execute
modify for WASI
wasmtime
prepared .wat
for built-in function
wasmtime : WASI runtime
• wasmtime
• WASI runtime built with Rust
• https://github.com/CraneStation/wasmtime
• Install
• Need Rust、Cargo
• $ git clone --recurse-submodules https://github.com/CraneStation/wasmtime.git
• $ cd wasmtime
• $ cargo build --release
• Run
• $ wasmtime wasi_ready.wasm
or
• $ wasmtime wasi_ready.wat
FYI/参考
Conclusion / まとめ
• I learned (a piece of) WASM by building tiny compiler
• I found some difference between WASM   LLVM
• I try WASI
• My tiny compiler helped me
• Exciting! Let’s try WASM/WASI
• コンパイラーを作ってWASM(の一部)を理解した
• 予想に反して、LLVMとは思想が違った
• WASIが気になってたけど、雰囲気分かった
• WASI用の組み込み関数を書くのに、初めてコンパイラーが役立った
• みなさんも、WASM/WASIに触れてみよう!
About me
• Masashi Ganeko / @massie_g
• Please pronounce "Ma She[məʃ iː]"
• Staff of WebRTC Meetup Tokyo
• がねこまさし / @massie_g (まっしー)
• WebRTC Meetup Tokyo のスタッフ
• インフォコム(株)の技術調査チームのマネージャー
Thank You!
Node.jsでつくるNode.jsミニコンパイラ - もくじ
https://qiita.com/massie_g/items/3ba1ba5d55499ee84b0b
Node.jsでつくるNode.js - もくじ(インタープリター)
https://qiita.com/massie_g/items/3ee11c105b4458686bc1
Node.jsでつくるNode.js-WASMコンパイラ - もくじ
https://qiita.com/massie_g/items/c663095759a80c53c126

Weitere ähnliche Inhalte

Was ist angesagt?

WebAssemblyのWeb以外のことぜんぶ話す
WebAssemblyのWeb以外のことぜんぶ話すWebAssemblyのWeb以外のことぜんぶ話す
WebAssemblyのWeb以外のことぜんぶ話すTakaya Saeki
 
ワタシはSingletonがキライだ
ワタシはSingletonがキライだワタシはSingletonがキライだ
ワタシはSingletonがキライだTetsuya Kaneuchi
 
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜aha_oretama
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門Kohei Tokunaga
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門増田 亨
 
第9回ACRiウェビナー_セック/岩渕様ご講演資料
第9回ACRiウェビナー_セック/岩渕様ご講演資料第9回ACRiウェビナー_セック/岩渕様ご講演資料
第9回ACRiウェビナー_セック/岩渕様ご講演資料直久 住川
 
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようrsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようKen Sawada
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48Preferred Networks
 
AnsibleによるInfrastructure as code入門
AnsibleによるInfrastructure as code入門AnsibleによるInfrastructure as code入門
AnsibleによるInfrastructure as code入門kk_Ataka
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Kohei Tokunaga
 
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす Akihiro Suda
 
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較beyond Co., Ltd.
 
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)NTT DATA Technology & Innovation
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugMasatoshi Tada
 
実務で役立つデータベースの活用法
実務で役立つデータベースの活用法実務で役立つデータベースの活用法
実務で役立つデータベースの活用法Soudai Sone
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計Yoshinori Matsunobu
 
そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?takezoe
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装infinite_loop
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」Masahito Zembutsu
 

Was ist angesagt? (20)

WebAssemblyのWeb以外のことぜんぶ話す
WebAssemblyのWeb以外のことぜんぶ話すWebAssemblyのWeb以外のことぜんぶ話す
WebAssemblyのWeb以外のことぜんぶ話す
 
ワタシはSingletonがキライだ
ワタシはSingletonがキライだワタシはSingletonがキライだ
ワタシはSingletonがキライだ
 
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
劇的改善 Ci4時間から5分へ〜私がやった10のこと〜
 
コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門コンテナ未経験新人が学ぶコンテナ技術入門
コンテナ未経験新人が学ぶコンテナ技術入門
 
ドメイン駆動設計入門
ドメイン駆動設計入門ドメイン駆動設計入門
ドメイン駆動設計入門
 
第9回ACRiウェビナー_セック/岩渕様ご講演資料
第9回ACRiウェビナー_セック/岩渕様ご講演資料第9回ACRiウェビナー_セック/岩渕様ご講演資料
第9回ACRiウェビナー_セック/岩渕様ご講演資料
 
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみようrsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
rsyncやシェルでバックアップするよりも簡単にOSSのBaculaでバックアップしてみよう
 
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
わかる!metadata.managedFields / Kubernetes Meetup Tokyo 48
 
AnsibleによるInfrastructure as code入門
AnsibleによるInfrastructure as code入門AnsibleによるInfrastructure as code入門
AnsibleによるInfrastructure as code入門
 
Dockerからcontainerdへの移行
Dockerからcontainerdへの移行Dockerからcontainerdへの移行
Dockerからcontainerdへの移行
 
root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす root権限無しでKubernetesを動かす
root権限無しでKubernetesを動かす
 
AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較AlmaLinux と Rocky Linux の誕生経緯&比較
AlmaLinux と Rocky Linux の誕生経緯&比較
 
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
Javaコードが速く実⾏される秘密 - JITコンパイラ⼊⾨(JJUG CCC 2020 Fall講演資料)
 
Java ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsugJava ORマッパー選定のポイント #jsug
Java ORマッパー選定のポイント #jsug
 
実務で役立つデータベースの活用法
実務で役立つデータベースの活用法実務で役立つデータベースの活用法
実務で役立つデータベースの活用法
 
FreeBSD Capsicum
FreeBSD CapsicumFreeBSD Capsicum
FreeBSD Capsicum
 
ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計ソーシャルゲームのためのデータベース設計
ソーシャルゲームのためのデータベース設計
 
そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?そんなトランザクションマネージャで大丈夫か?
そんなトランザクションマネージャで大丈夫か?
 
ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装ソーシャルゲーム案件におけるDB分割のPHP実装
ソーシャルゲーム案件におけるDB分割のPHP実装
 
コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」コンテナの作り方「Dockerは裏方で何をしているのか?」
コンテナの作り方「Dockerは裏方で何をしているのか?」
 

Ähnlich wie Build Node.js-WASM/WASI Tiny compiler with Node.js

Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようAkira Shimosako
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門sandai
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツールtotty jp
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesNoritada Shimizu
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0Kiwamu Okabe
 
Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Kiwamu Okabe
 
OSC 2011 Hokkaido 自宅SAN友の会(後半)
OSC 2011 Hokkaido 自宅SAN友の会(後半)OSC 2011 Hokkaido 自宅SAN友の会(後半)
OSC 2011 Hokkaido 自宅SAN友の会(後半)Satoshi Shimazaki
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...Naoya Ito
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Mori Shingo
 
IDAの脆弱性とBug Bounty by 千田 雅明
IDAの脆弱性とBug Bounty by 千田 雅明IDAの脆弱性とBug Bounty by 千田 雅明
IDAの脆弱性とBug Bounty by 千田 雅明CODE BLUE
 
シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016Yu Ito
 
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成Izumi Tsutsui
 
OpenStackで始めるクラウド環境構築入門
OpenStackで始めるクラウド環境構築入門OpenStackで始めるクラウド環境構築入門
OpenStackで始めるクラウド環境構築入門VirtualTech Japan Inc.
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~Akira Inoue
 

Ähnlich wie Build Node.js-WASM/WASI Tiny compiler with Node.js (20)

Vyatta 改造入門
Vyatta 改造入門Vyatta 改造入門
Vyatta 改造入門
 
Groovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみようGroovyで楽にSQLを実行してみよう
Groovyで楽にSQLを実行してみよう
 
SocketStream入門
SocketStream入門SocketStream入門
SocketStream入門
 
【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門【学習メモ#1st】12ステップで作る組込みOS自作入門
【学習メモ#1st】12ステップで作る組込みOS自作入門
 
Open VZ
Open VZOpen VZ
Open VZ
 
恋に落ちるデプロイツール
恋に落ちるデプロイツール恋に落ちるデプロイツール
恋に落ちるデプロイツール
 
Hadoop on LXC
Hadoop on LXCHadoop on LXC
Hadoop on LXC
 
Hbstudy41 auto scaling
Hbstudy41 auto scalingHbstudy41 auto scaling
Hbstudy41 auto scaling
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
 
スタート低レイヤー #0
スタート低レイヤー #0スタート低レイヤー #0
スタート低レイヤー #0
 
Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介Debianを用いたCortex-M3マイコン開発事例のご紹介
Debianを用いたCortex-M3マイコン開発事例のご紹介
 
OSC 2011 Hokkaido 自宅SAN友の会(後半)
OSC 2011 Hokkaido 自宅SAN友の会(後半)OSC 2011 Hokkaido 自宅SAN友の会(後半)
OSC 2011 Hokkaido 自宅SAN友の会(後半)
 
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
SmartPhone development guide with CoffeeScript + Node + HTML5 Technology, for...
 
Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋Node予備校 vol.1 名古屋
Node予備校 vol.1 名古屋
 
Yesod on Heroku
Yesod on HerokuYesod on Heroku
Yesod on Heroku
 
IDAの脆弱性とBug Bounty by 千田 雅明
IDAの脆弱性とBug Bounty by 千田 雅明IDAの脆弱性とBug Bounty by 千田 雅明
IDAの脆弱性とBug Bounty by 千田 雅明
 
シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016シラサギハンズオン 1015 1016
シラサギハンズオン 1015 1016
 
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成
NetBSDのクロスビルドのしくみとインストール済みLive Imageの作成
 
OpenStackで始めるクラウド環境構築入門
OpenStackで始めるクラウド環境構築入門OpenStackで始めるクラウド環境構築入門
OpenStackで始めるクラウド環境構築入門
 
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
TypeScript ファーストステップ (Rev.2) ~ Any browser. Any host. Any OS. Open Source. ~
 

Mehr von mganeko

Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)mganeko
 
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたAmazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたmganeko
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...mganeko
 
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねSkywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねmganeko
 
WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3mganeko
 
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updateWebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updatemganeko
 
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたmganeko
 
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sampleWebRTC SFU mediasoup sample
WebRTC SFU mediasoup samplemganeko
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2mganeko
 
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannelNode.js with WebRTC DataChannel
Node.js with WebRTC DataChannelmganeko
 
WebRTC Build MCU on browser
WebRTC Build MCU on browserWebRTC Build MCU on browser
WebRTC Build MCU on browsermganeko
 
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorderPeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecordermganeko
 
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴mganeko
 
Webrtc bootcamp handson
Webrtc bootcamp handsonWebrtc bootcamp handson
Webrtc bootcamp handsonmganeko
 
WebRTC multitrack / multistream
WebRTC multitrack / multistreamWebRTC multitrack / multistream
WebRTC multitrack / multistreammganeko
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようmganeko
 
WebRTC multistream
WebRTC multistreamWebRTC multistream
WebRTC multistreammganeko
 
Inside WebM
Inside WebMInside WebM
Inside WebMmganeko
 
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live StreamingMediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streamingmganeko
 

Mehr von mganeko (20)

Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
Google Meet でもバーチャル背景を使いたい (WebRTC Meetup Online)
 
Amazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみたAmazon Kinesis Video Streams WebRTC 使ってみた
Amazon Kinesis Video Streams WebRTC 使ってみた
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
Node.js x Headless Chrome for WeRTC MCU / Node.js x Chrome headless で、お手軽WebR...
 
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでねSkywayのビデオチャットを録画しよう。そう、ブラウザでね
Skywayのビデオチャットを録画しよう。そう、ブラウザでね
 
WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3WebRTC mediasoup on raspberrypi3
WebRTC mediasoup on raspberrypi3
 
WebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample updateWebRTC SFU Mediasoup Sample update
WebRTC SFU Mediasoup Sample update
 
ブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみたブラウザでWebRTC - iOSゲートウェイ作ってみた
ブラウザでWebRTC - iOSゲートウェイ作ってみた
 
WebRTC SFU mediasoup sample
WebRTC SFU mediasoup sampleWebRTC SFU mediasoup sample
WebRTC SFU mediasoup sample
 
Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2Inside of 聖徳玉子 by O2
Inside of 聖徳玉子 by O2
 
Node.js with WebRTC DataChannel
Node.js with WebRTC DataChannelNode.js with WebRTC DataChannel
Node.js with WebRTC DataChannel
 
WebRTC Build MCU on browser
WebRTC Build MCU on browserWebRTC Build MCU on browser
WebRTC Build MCU on browser
 
PeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorderPeerConnectionリレーとMediaRecorder
PeerConnectionリレーとMediaRecorder
 
ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴ここがつらいよWebRTC - WebRTC開発の落とし穴
ここがつらいよWebRTC - WebRTC開発の落とし穴
 
Webrtc bootcamp handson
Webrtc bootcamp handsonWebrtc bootcamp handson
Webrtc bootcamp handson
 
WebRTC multitrack / multistream
WebRTC multitrack / multistreamWebRTC multitrack / multistream
WebRTC multitrack / multistream
 
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみようWebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
WebRTC UserMedia Catalog: いろんなユーザメディア(MediaStream)を使ってみよう
 
WebRTC multistream
WebRTC multistreamWebRTC multistream
WebRTC multistream
 
Inside WebM
Inside WebMInside WebM
Inside WebM
 
MediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live StreamingMediaRecorder と WebM で、オレオレ Live Streaming
MediaRecorder と WebM で、オレオレ Live Streaming
 

Build Node.js-WASM/WASI Tiny compiler with Node.js

  • 1. Build Node.js – WASM/WASI tiny compiler with Node.js JSConf JP 2019 LT (2019.11.30) @massie_g "Ma She[məʃ iː]" Node.jsでつくる Node.js – WASM/WASI ミニミニコンパイラー JSConf JP 2019 LT (2019.11.30) @massie_g / がねこまさし
  • 2. Are you interested in WASM ? WASMに興味ありますよね? • WASM = WebAssembly • Then, how do you learn WASM? • どうやって学びますか?
  • 3. Learning WASM / WASMを学ぶ • Read Spec. … I HATE BNF! • 仕様を読む … BNFを読むと頭が痛くなる
  • 4. Learning WASM / WASMを学ぶ • Read Spec … I HATE BNF! • Read code • Use emscripten: hello_wold.c  wasm/wat … So huge code to read • コードを読む • Emscripten で変換: hello_wold.c  wasm/wat … 超巨大で読むの辛い
  • 5. Learning WASM / WASMを学ぶ • Read Spec … I HATE BNF! • Read code • Someone says, “You can write WASM by hand” • … What are you talking about? • 「手でWASM書けるよ」ていう人も • … は?? 何言ってんの??
  • 6. Learning WASM / WASMを学ぶ • Read Spec … I HATE BNF! • Read code • “You can write WASM by hand” … What !? Crazy !? • My suggestion: Build compiler to learn WASM ! • そうだ、コンパイラーを作って覚えよう!
  • 7. The story so far / これまでの経緯 • I read the great book “Build Ruby with Ruby” • I built Node.js tiny interpreter with Node.js • I built Node.js tiny compiler with Node.js, using LLVM • I made a talk in Nodefest Tokyo 2018 • Today: Node.js – WASM tiny compiler • RubyでつくるRubyを読んだ • Node.jsでつくるNode.jsミニインタープリター を作った • Node.jsでつくるNode.jsミニコンパイラーをLLVMを使って作った • 東京Node学園祭2018のセッションで話した • https://www.slideshare.net/mganeko/nodejsnodejs-123707037 • 本日:Node.js でつくる ミニミニ Node.js-WASMコンパイラー
  • 8. Structure of Node.js tiny compiler (2018) Parser Simple AST (abstract syntax tree) Code generator Executable binary LLVM-IR LLVM-IR spec esprima Source .js Language spec: Subset of JavaScript llc ld Single Type: 32bit signed integer only
  • 9. Structure of Node.js–WASM tiny compiler (2019) Parser Simple AST (abstract syntax tree) Code generator WASM spec esprima source .js Language spec: Subset of JavaScript wat2wasm Re-use .wat (WebAssembly Text format) .wasm (WebAssembly binary format) Web Browser Node.js read & execute Just modify here
  • 10. wat2wasm • wat2wasm • Convert WAT(text format) WASM(binary format) • a tool of WebAssembly/wabt • https://github.com/WebAssembly/wabt • Install • $ git clone --recursive https://github.com/WebAssembly/wabt • $ cd wabt • $ mkdir build • $ cd build • $ cmake .. • $ cmake --build . • Run • $ wat2wasm src.wat -o dest.wasm FYI/参考
  • 11. Adapting to WASM is easy, (I thought) WASM対応なんて楽勝!と思ってた • … but, there are 2 big difference • (1) machine architecture • (2) Standard I/O Library • … だがしかし、2つの大きな違い • (1) レジスタマシン vs. スタックマシン • (2) 標準ライブラリ
  • 12. Difference (1): machine architecture 違い(1): レジスタマシンとスタックマシン • LLVM … Register Machine /レジスタマシン • Use register for data operation / データをレジスタに読み込んで処理 • LLVM, Lua VM, Erlang VM(BEAM), etc. • WASM … Stack Machine / スタックマシン • Use stack for data operation / データをスタックに積んで処理を行う • WASM, Java VM(JVM), Ruby VM(YARV), etc. Order of operation is different between LLVM  WASM
  • 13. LLVM IR … Register Machine CPU register %r1 register %x memory load point address variable x y = x + 1; JavaScript %r1 = load i32, i32* %x, align 4 %r2 = add i32 %r1, 1 store i32 %r2, i32* %y, align 4 LLVM-IR FYI/参考
  • 14. LLVM IR … Register Machine CPU ALU register %r2 register %r1 memory add y = x + 1; JavaScript %r1 = load i32, i32* %x, align 4 %r2 = add i32 %r1, 1 store i32 %r2, i32* %y, align 4 LLVM-IR 1 FYI/参考
  • 15. LLVM IR … Register Machine CPU register %r2 memory point address register %y variable y store y = x + 1; JavaScript %r1 = load i32, i32* %x, align 4 %r2 = add i32 %r1, 1 store i32 %r2, i32* %y, align 4 LLVM-IR FYI/参考
  • 16. LLVM IR … Register Machine CPU ALU register %r2 register %r1 register %x memory load point address register %y variable x variable y store add y = x + 1; JavaScript %r1 = load i32, i32* %x, align 4 %r2 = add i32 %r1, 1 store i32 %r2, i32* %y, align 4 LLVM-IR FYI/参考
  • 17. WASM … Stack Machine memory variable x y = x + 1; JavaScript get_local $x i32.const 1 i32.add set_local $y WAT value of x 1 1 ALU FYI/参考
  • 18. WASM … Stack Machine ALU memory y = x + 1; JavaScript get_local $x i32.const 1 i32.add set_local $y WAT 1 value of x result (x+1) result (x+1) value of x 1 FYI/参考
  • 19. WASM … Stack Machine memory variable y y = x + 1; JavaScript get_local $x i32.const 1 i32.add set_local $y WAT result (x+1) ALU FYI/参考
  • 20. WASM … Stack Machine 1 memory variable x variable y y = x + 1; JavaScript get_local $x i32.const 1 i32.add set_local $y WAT value of x result (x+1) 1 ALU 1 value of x result (x+1) FYI/参考
  • 21. Difference (2) : Standard I/O Library 違い(2): 標準ライブラリ • LLVM • Link standard C library by linker (ld) • easy to call puts(), printf() • リンカーで C言語用のライブラリを一緒にリンク • puts(), printf() が使えた • WASM • WASM has no standard I/O API/library • Have to provide functions at outside, and import from WASM • WASMとしての標準ライブラリ/APIは無し • 呼び出し元で、インポート用の関数を提供
  • 22. Ex) preparing functions at caller side 呼び出し元でインポート用関数の準備(例) const imports = { // --- print signed 32bit integer / 符号付32ビット整数を出力する関数 --- imported_putn: function(arg) { console.log(arg); }, // --- print static string / 文字列を出力する関数 --- imported_puts: function(offset) { let str = ''; let arr = new Uint8Array(exported_string.buffer); for (let i = offset; arr[i]; i++) { str += String.fromCharCode(arr[i]); } console.log(str); } };
  • 23. Exec WASM in Node.js Node.jsからWASMの実行 const source = fs.readFileSync(filename); // read WASM / WASMファイルを読み込む const typedArray = new Uint8Array(source); let ret = null; let exported_string = null; WebAssembly.instantiate(typedArray, { imports: imports } // pass prepared functions / 先ほど用意したインポート用関数を渡す ).then(result => { exported_string = result.instance.exports.exported_string; ret = result.instance.exports.exported_main(); // call main of WASM / WASMのメイン関数を呼び出す process.exit(ret); }).catch(e => { console.log(e); });
  • 24. Inside of WASM / WASMの中身 (module ;; ---- import print functions / 出力用関数をインポート --- (func $putn (import "imports" "imported_putn") (param i32)) (func $puts (import "imports" "imported_puts") (param i32)) ;; ---- static string area for puts()/ 出力用文字列の領域 --- (memory $string_area 1) ;; string_area 64KiB (export "exported_string" (memory $string_area)) ;; --- export main/メインをエクスポート --- (export "exported_main" (func $main)) (func $main (result i32) (local $x i32) (local $y i32) i32.const 1 ;; let x = 1; set_local $x get_local $x ;; let y = x +1; i32.const 1 i32.add set_local $y get_local $y ;; putn(y); call $putn i32.const 99 ;; return 99; (dummy) return ) )
  • 25. Done! / できた • I built Node.js-WASM tiny compiler • able to run FizzBuzz, Fibonacci sequence • https://github.com/mganeko/mini_node_wasm • Node.js-WASM ミニミニコンパイラーができた • FizzBuzzやフィボナッチ数列が動く • https://github.com/mganeko/mini_node_wasm
  • 26. WASI: Beyond Web WASI でWebの外へ • My Node.js-WASM tiny compiler is fun, but useless • Convert .js to WASM, which was running on Node.js • and run in Node.js again • NEXT: Use WASM outside of Browser/Node.js •  try WASI (WebAssembly system interface) • 今回やったことは、楽しいけど意味はない • もともとNode.jsで実行していた .js ファイルを、WASMに変換して • またNode.js から実行 • ブラウザやNode.js以外の環境でWASMを動かしたい • それなら、WASI (WebAssembly system interface) でしょ
  • 27. WASI: WebAssembly System Interface • WASI … a system interface to run WASM across all different OSs. • https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/ • POSIX like API … file, network, clock, random • Example • wasmtime ... WASI reference build with Rust • https://wasmtime.dev/ • lucet ... Made by Fastly, aim to run on CDN edge server • https://www.fastly.com/blog/announcing-lucet-fastly-native-webassembly-compiler-runtime • WebAssembly Micro Runtime ... Lightweight runtime for embedded device • No JIT, interpreter only • https://github.com/bytecodealliance/wasm-micro-runtime • WASI … WASMをいろんなOS上で動かすためのシステムインターフェイス • ファイル、ネットワーク、クロック、乱数など • 例 • Wasmtime … Rustで作られたリファレンス実装 • Lucet … Fastlyが作っている、CDNエッジサーバー上でWASMを動かすための環境 • WebAssembly Micro Runtime ... 組み込みデバイスで動かすための軽量ランタイム
  • 28. WASI runtime functions / ランタイム関数 • WASI Core API System calls • https://github.com/CraneStation/wasmtime/blob/master/docs/WASI-api.md • provide primitive functions • __wasi_fd_write() • No printf()/puts() • プリミティブな関数が提供される様子 • __wasi_fd_write() を使う必要がある • 文字列出力puts()や、フォーマット付き出力のprintf()に相当するもはない
  • 29. __wasi_fd_write(fd, *iovs, iovs_len, *nwritten) arguments • fd … file descriptor / ファイルデスクリプタ • 0 … stdin / 標準入力 • 1 … stdout / 標準出力 • 2 … stderr / 標準エラー出力 • *iovs … start address of iov group • iov->*buf … start address of byte array • Iov->buf_len … length of byte array • Iovs_len … size of iov group • *nwritten … bytes written to file • pointer of 32bit integer to output the value *buf: start address of byte array H i ! buf_len: length of bye array 3 *buf buf_len Write multiple byte arrays 複数のバイト列を出力可能 ”Hi!”
  • 30. Implement built-in function 組み込み関数の実装 • putn() … prepare built-in function for print 32bit signed integer • need to convert integer to byte string with WASM code • Steps in putn() • Check sign, Calculate length in string • Take 1 digit  covert to ASCII code (1  81) • store ASCII string in in memory • call __wasi_fd_write() • Writing WASM code for putn() by hand … quite tough work (for me) • putn() … 32ビット符号付整数を出力するための組み込み関数を準備 • WASMで 32ビット符号つき整数 → 文字列(バイト列)に変換 • putn() のステップ • 符号の有無を判定、長さの算出 • 1桁ずつASCIIコードのバイトに変換 • 文字列をメモリに書き込む • __wasi_fd_write() を呼び出す • この処理を行うWASMコードを手書きするのはシンドイ
  • 31. Implement built-in function 組み込み関数の実装 • putn() … prepare built-in function for print 32bit signed integer • need to convert integer to byte string with WASM code • Steps in putn() • Check sign, Calculate length in string • Take 1 digit  covert to ASCII code (1  81) • store ASCII string in in memory • call __wasi_fd_write() • Writing WASM code for putn() by hand … quite tough work (for me) • putn() … 32ビット符号付整数を出力するための組み込み関数を準備 • WASMで 32ビット符号つき整数 → 文字列(バイト列)に変換 • putn() のステップ • 符号の有無を判定、長さの算出 • 1桁ずつASCIIコードのバイトに変換 • 文字列をメモリに書き込む • __wasi_fd_write() を呼び出す • この処理を行うWASMコードを手書きするのはシンドイ Use compiler to generate WAT code! 今回作った コンパイラーで生成
  • 32. Example of compiled code: _calcLength(n) function _calcLength(n) { // n >= 0 let restValue = n; let len = 1; while (restValue >= 10) { restValue = restValue / 10; len = len + 1; } return len; } (func $_calcLength (param $n i32) (result i32) (local $restValue i32) (local $len i32) get_local $n set_local $restValue i32.const 1 set_local $len loop ;; --begin of while loop-- get_local $restValue i32.const 10 i32.ge_s if get_local $restValue i32.const 10 i32.div_s set_local $restValue get_local $len i32.const 1 i32.add set_local $len br 1 ;; --jump to head of while loop-- end ;; end of if-then end ;; --end of while loop-- get_local $len return ) Source .js Compiled .wat Node.js- WASM compiler
  • 33. Structure of Node.js–WASM/WASI tiny compiler Parser Simple AST (abstract syntax tree) Code generator WASM spec esprima Source .js Language spec: Subset of JavaScript wat2wasm Re-use WASI ready .wat (WebAssembly Text format) WASI ready .wasm (WebAssembly binary format) read & execute modify for WASI wasmtime prepared .wat for built-in function
  • 34. wasmtime : WASI runtime • wasmtime • WASI runtime built with Rust • https://github.com/CraneStation/wasmtime • Install • Need Rust、Cargo • $ git clone --recurse-submodules https://github.com/CraneStation/wasmtime.git • $ cd wasmtime • $ cargo build --release • Run • $ wasmtime wasi_ready.wasm or • $ wasmtime wasi_ready.wat FYI/参考
  • 35. Conclusion / まとめ • I learned (a piece of) WASM by building tiny compiler • I found some difference between WASM   LLVM • I try WASI • My tiny compiler helped me • Exciting! Let’s try WASM/WASI • コンパイラーを作ってWASM(の一部)を理解した • 予想に反して、LLVMとは思想が違った • WASIが気になってたけど、雰囲気分かった • WASI用の組み込み関数を書くのに、初めてコンパイラーが役立った • みなさんも、WASM/WASIに触れてみよう!
  • 36. About me • Masashi Ganeko / @massie_g • Please pronounce "Ma She[məʃ iː]" • Staff of WebRTC Meetup Tokyo • がねこまさし / @massie_g (まっしー) • WebRTC Meetup Tokyo のスタッフ • インフォコム(株)の技術調査チームのマネージャー
  • 37. Thank You! Node.jsでつくるNode.jsミニコンパイラ - もくじ https://qiita.com/massie_g/items/3ba1ba5d55499ee84b0b Node.jsでつくるNode.js - もくじ(インタープリター) https://qiita.com/massie_g/items/3ee11c105b4458686bc1 Node.jsでつくるNode.js-WASMコンパイラ - もくじ https://qiita.com/massie_g/items/c663095759a80c53c126

Hinweis der Redaktion

  1. Hi everyone. I’d like to talk about “Build Node.js – WASM/WASI tiny compiler, with Node.js” (I am massie.)
  2. At first, are you interested in WebAssembly? Please raise your hand who are intrested? Thank you. Great, almost half of you! Then how do you learn WASM?
  3. First choice is reading spec, but I don’t like BNF
  4. Second choice is, reading wasm code. For example I can use emscripten to convert C code to WASM and read it. But generated code is so huge to read.
  5. Someone says, “you can write WASM by hand”. But it sounds crazy for me.
  6. So, my suggestion is “Build compiler to learn WASM!”. Don’t you think so?
  7. Why I am talking about compiler? Because, I read a great book “build Ruby with ruby”, and built a tiny compiler using LLVM last year. So, I am talking about WASM compiler today.
  8. This is a structure of my tiny compiler. It support very small subset of JavaScript. It has only single type. 32 bit signed integer. I use esprima module for parse. I write a code generator for LLVM-IR, intermediate representation. Then I use LLVM tools to generate executable binary.
  9. To build WASM compiler, I re-use parse and modify generator to generate WebAssmebly Text format. After that, I use wat2wasm to convert to WebAssembly binary format, then execute in Web Browser or Node.js
  10. Wet2wasm is a tool of WebAssembly/wabt
  11. Adapting my compiler from LLVM to WASM is easy, I thought. But it wasn’t. There are 2 big differences. Machine architecture , and Standard I/O library ※ LLVM との違いをなぜ出しているのか?
  12. LLVM is register machine. It use register for date operation. On the other hand, WASM is stack machine. Push data to a stack before data operation. So order of operation is quite different.
  13. Sorry, I don’t have a enough time, so skipping a couple of pages
  14. Second difference is Standard I/O library. In LLVM, I link standard C library by linker, so it is easy to call puts() or printf(). On the other hand, WASM has no standard I/O API or Library.
  15. I have to prepare functions at caller side, outside of WASM. In this example, I provide 2 functions. Printing 32bit integer, and printing static string
  16. I pass my function when executing wasm code like this.
  17. Inside of WASM, I import function like left side. And call it like right side.
  18. Now my tiny compiler is done! I can compile and run FizzBuzzz and Fibonacci sequence.
  19. My tiny WASM compiler is fun, but useless. Because it convert JS file to WASM, which was running on Node.js. And run in Node.js again. There is no additional value. So I want to run my wasm at outside of Browser or Node.js. I heard about WASI (WebAssembly system interface), so I want to try it next.
  20. What is wasi? WASM is a fast, scalable, secure way to run the same code across all machines. WASI is a system interface to run WASM across all different OSs. There are runtimes for CDN edge server or embedded devices. Luchet is a runtime to run WASM on CDN edge WebAssembly Micro Runtime is a lightweight runtime for embedded devices.
  21. WASI runtime functions are listed in this page. It provides primitive functions There is no printf(). I have to use fd_write() instead.
  22. It is possible to write multiple byte arrays at once with fd_write(). To use it, I have to pass a set of buffers. It is a pointer of of pointer. Using fd_write() is quite complicated.
  23. I want to provide simple built-in function putn(), for printing 32bit integer, instead of calling fd_write() directly. In this function, I need to convert integer value to byte string with WASM code. There are some steps in putn() Writing these steps in WASM code by hand is quite a tough work for me.
  24. So I decide to use my compiler to generate WAT code for some part of built-in function.
  25. This is an example of one step. Take integer value and calculate length in string. Left side is source JS code. And right side is generated WAT code by my compiler.
  26. I prepare .wat file for built-in function, and use it for generating WASI ready WAT code. Then, I use “wasmtime” for run WASI ready wasm. Done!
  27. Wasmtime is a WASI runtime built with Rust.
  28. Conclusion. I learn (a piece of) WASM by building tiny compiler Also, I try WASI. It was exiting! So, I want to say “Let’s try WASM and WASI” everyone.
  29. That’s all.
  30. Thank you!