SlidePub
Home
Categories
Login
Register
Home
Technology
emruby: ブラウザで動くRuby
emruby: ブラウザで動くRuby
mametter
10,743 views
35 slides
Apr 23, 2021
Slide
1
of 35
Previous
Next
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
About This Presentation
銀座Rails #32
https://ginza-rails.connpass.com/event/207692/
Size:
795.3 KB
Language:
none
Added:
Apr 23, 2021
Slides:
35 pages
Slide Content
Slide 1
emruby:
ブラウザで動く Ruby
銀座Rails #32
Yusuke Endoh
1
Slide 2
自己紹介:遠藤侑介 (@mametter)
•クックパッドで働くフルタイム Rubyコミッタ
•Ruby 3添付の静的解析ツール TypeProf作ってます
•https://github.com/ruby/typeprof
•でも今日はぜんぜん違う話をします
2
Slide 3
emruby: ブラウザの上で動く Ruby
https://mame.github.io/emruby/
3
Slide 4
emrubyの狙い
•ブラウザで Rubyが動くのは楽しい
•頑張れば TryRuby(お試し環境)くらいにはなるか?
•将来的にJavaScriptの代替になるかは WASM次第?
•Rust / Go / KotlinなどもWASM出力に対応してる ので
•おことわり
•この発表には RailsもRuby言語もほとんど出てきません
•Rubyのビルドの知識が少し身につきます
4
Slide 5
Rubyをブラウザで動かす関連研究
•Opal: JavaScriptで書かれた Rubyインタプリタ
•https://github.com/opal/opal
•Artichoke:Rustで書かれた Rubyインタプリタ( WASM出力対応)
•https://github.com/artichoke/artichoke
•repl.it: Ruby 1.8をEmscriptenしたもの(らしい)
•https://github.com/replit-archive/emscripted-ruby
•Ruby on WebAssembly: mrubyをEmscriptenしたもの
•https://github.com/blacktm/ruby-wasm
•RubyのNaClサポート( 2012~2017)
•よくまとまってる記事
•https://blog.unasuke.com/2021/products-about-webassembly-and-ruby/
5
Slide 6
アジェンダ
•➔WASM / Emscriptenとは
•emrubyが動くまで
•まとめ
6
Slide 7
WebAssembly(WASM)
•ブラウザの上で動く実行ファイル形式
•2017年頃からメジャーブラウザが対応している
•JavaScriptより速くて (?)小さいらしい
7
Slide 8
Emscripten
•C/C++のプログラムを WASMに変換するコンパイラ
•LLVMベース
•デモ一覧(古そう): https://github.com/emscripten-
core/emscripten/wiki/Porting-Examples-and-Demos
•http://kripken.github.io/boon/boon.html
•https://files.unity3d.com/jonas/AngryBots/
•http://coolwanglu.github.io/vim.js/emterpreter/vim.html
8
Slide 9
Emscriptenの基本的な使いかた
9
#include <stdio.h>
int main() {
printf("hello, world!¥n");
return 0;
}
emcchello.c–o hello.js && node hello.js
emcchello.c–o hello.html
Slide 10
アジェンダ
•WASM / Emscriptenとは
•➔emrubyが動くまで
•まとめ
10
Slide 11
前提知識: Rubyのふつうのビルド
•Rubyソースのディレクトリで次のコマンドを打つ
•./configure:環境ごとにビルド方法を調整する
•どのシステム関数が使えるか、コンパイラオプションが使えるか
•OS、コンパイラ、バージョンなどの違いを調べる
•make:ソースコードをコンパイルする
•まずminirubyという制限版 ruby実行ファイルを作る
•minirubyを使ってスクリプト( Rubyで書かれている)を動かし、
拡張ライブラリや最終的な ruby実行ファイルを作る
11
./configure&&make
Slide 12
話の流れ
•minirubyをWASMにする
•本当のrubyをWASMにする
•最終目標: irbを動かす?
12
Slide 13
./configure&&makeのEmscripten化
•Emscriptenはconfigure+makeに対応している
•emconfigure/ emmakeはビルドをうまくだまして
Emscriptenコンパイラを使わせる
•これだけ……ではない
•実用プログラムがゼロ変更でビルドできることは無いと思う
13
emconfigure./configure&&emmakemake
Slide 14
Emscriptenが未実装の C関数に対処する
•問題:Emscriptenで利用できない C関数がいっぱいある
•popenがない
•pthread_createはあるがpthread_killはない
•pthread_createはあるが pthread_attr_getguardsizeがない
•pthread_sigmaskはあるけど実際には動かない (!) 、など
•configureの盲点をつくような未実装がいろいろあった
•対処:Rubyのconfigureを改善して対応した
•コミッタなので、 Ruby側を直接変更しまくった
14
Slide 15
Rubyは関数の引数の数にルーズだった
•C言語では、関数に引数を余分に渡しても良い (!?)
•C言語仕様違反だが、
多くのCコンパイラで動く
•Rubyはこれに依存していた
•Emscriptenのオプションで
対応した
•-s EMULATE_FUNCTION_POINTER_CASTS=1
15
int foo(int a) {
printf("%d¥n", a);
}
int main() {
int(*foo2)(int,int) =
(int(*)(int,int))foo;
foo2(42, 43); // 42
}
1引数の関数 fooを2引数で呼び出す例
Slide 16
miniruby.wasmできた!
•2018年はこの段階で公開した
•残念なお知らせ
•EMULATE…オプションが Emscirptenから削除された
•コンパイル できなくなった
•どうしたか
•放置した → 3年経ったら、 Ruby側が直っていた!
•微修正で 2021年1月に再ビルドに成功した
16
Slide 17
話の流れ
•minirubyをWASMにする
•ここまでできた
•本当のrubyをWASMにする
•最終目標: irbを動かす?
17
Slide 18
ruby.wasmを作るには
•ふつうのrubyのビルドには、 minirubyが必要
•しかしminiruby.wasmはLinuxで実行できない
•クロスコンパイルする
•ビルド環境とはちがう環境の実行ファイルを作ること
•Linuxでruby.exe(Windowsの実行ファイル)を作る、とか
•今回はLinuxでruby.wasmを作る
•emconfigureはかえってややこしくなるのでやめた
18
Slide 19
Rubyのクロスコンパイル
•Rubyのconfigureはクロスコンパイルに対応している
•minirubyの代わりにビルド環境の rubyを使ってくれる
•これで一応 ruby.wasmはできた
•が、全然動かないのでデバッグ&ドキュメント&ソース読み
19
$ ./configure¥
--build x86_64-pc-linux-gnu ¥
--host wasm32-unknown-emscripten ¥
CC=emccLD=emccAR=emarRANLIB=emranlib
$ make
ビルド環境
対象環境
Emscripten
Slide 20
問題:Rubyの保守的GC
•保守的GCとは
•マシンスタックの値がオブジェクトの参照であると仮定して
マーク対象とするガベージコレクタの方式
•https://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%BC%E3%82%AF%E3%83%BB%E3%82%A2%E3%83%B3%E3%83%89%E3%83%BB%E3%82%B9%E3%82%A4%E3%8 3%BC%E3%
83%97#%E4%BF%9D%E5%AE%88%E7%9A%84%E3%81%AA%E3%82%AC%E3%83%99%E3%83%BC%E3%82%B8%E3%82%B3%E3%83%AC%E3%82%AF%E3%82%BF
•つまり意図的に C言語仕様違反なメモリアクセスをする
•Emscriptenのメモリモデルでは全然動かない
•対処:Emscriptenが保守的GC用のAPIを用意していた
•emscripten_scan_stack/ emscripten_scan_registers
•スタックの先頭と終端がわかる、これらを使うようにした
20
Slide 21
余談:Fiberに対応する(未完)
•Rubyは2018年末にFiberの一部をアセンブリで実装した
•Emscriptenでx86アセンブリはコンパイルできないので
コンパイルエラーになっていた
•対処:EmscriptenのAPIを使って実装した
•emscripten_fiber_init / emscripten_fiber_swap
•コンパイルオプション -s ASYNCIFY と合わせて使う
•miniruby.wasmでは動いたが、 ruby.wasmでは動かない
•原因未解明、今後の課題
•とりあえず Fiber使わなければ問題ない
21
Slide 22
問題:動的リンクができない
•つまり、拡張ライブラリの require ができない
•require "ripper"したらripper.soを動的リンクする
•しかしEmscriptenは動的リンクに未対応(たぶん)
•解決:ripperを静的リンクした
•他にも必要な拡張ライブラリを色々足した
22
$ ./configure¥
--with-static-linked-ext--with-ext=ripper …
$ make
Slide 23
その他Emscripten特有っぽい話
•リンクが失敗する( htonsが見つからない、とか)
•-lcでlibcを明示的にリンクすれば動いた
•-fstack-protectorも対応してないようなので消した
•すぐメモリ不足エラーになる
•Emscriptenはデフォルトでメモリサイズを固定確保する
•サイズ可変にするオプションをつけた
(-sALLOW_MEMORY_GROWTH=1)
•stack overflowの検出が動かないので止めた、など
23
Slide 24
ruby.wasmできた!
•require "ripper.so"も動く
•ある程度複雑な Rubyスクリプトも動く
24
Slide 25
話の流れ
•minirubyをWASMにする
•本当のrubyをWASMにする
•ここまでできた
•最終目標: irbを動かす?
25
Slide 26
irbを動かすのに必要なもの
•Rubyインタプリタ(できた)
•ripper.soなどの拡張ライブラリ(できた)
•irbのソースコード(あるけどまだ組み込んでない)
•端末エミュレータ(無い)
26
Slide 27
仮想ファイルシステム
•Emscriptenのfile_packagerツールで作れる
•irbやrubygemsなど必要な Rubyソースコードをまとめた
•fs.jsとfs.dataができた
•がんばってロードできるようにした
•コンパイルオプションに -s FORCE_FILESYSTEM=1 追加
•fs.jsを<script>で呼ぶだけ ……なのだが意外と苦労した
27
Slide 28
xterm.jsを組み込む
•xterm.js: ブラウザで動く端末 エミュレータ
•https://xtermjs.org/
•VS Codeでも使われている
•残念なお知らせ
•Emscriptenは標準入出力の実装がいまいち
•とりあえずの対応
•ライン編集は xterm.js側でやり、 irbには行単位で送る
•reline(irbの新しい編集機能)の活用は今後の課題
28
Slide 29
ということで
https://mame.github.io/emruby/irb/
29
Slide 30
CPU 100%を防ぐ
•Emscriptenの生成物はほぼ同期で動く( asyncでない)
•入力待ちをポーリングでやるみたい(ゲーム想定?)
•対処:別スレッド( Web Worker)で動かすようにした
•通信方法は vim.wasmに習った( SharedArrayBuffer使用)
https://rhysd.hatenablog.com/entry/2019/06/13/090519
•残念なお知らせ: 5月に動かなくなる見込み
30
Slide 31
ということで
•(かなり妥協したけど) irbがブラウザで動いた!
•rubygems、did_you_meanなども一応動いているっぽい
31
Slide 32
落ち穂拾い
•ruby.wasmのサイズ: 29 MB
•コンパイルオプションで調整して 8 MB
•-Os: 省サイズ重視で最適化する
•-g0: デバッグ情報を省く
32
Slide 33
Emscripten所感
•夢の技術ではない
•現実のC言語コードをゼロ変更でビルドできることは無い
•いっぱい問題に遭遇する
•が、とてもよくできている
•一生懸命調べればたいてい対処方法や APIがある
•検索に頼らずドキュメントを通して読むのが早道
•動いたらとても嬉しい
33
Slide 34
まとめ
•ブラウザで動く Ruby、emrubyを紹介しました
•大体Ruby側で対応したのでたったこれだけでビルドできる
34
$ ./configure¥
--build x86_64-pc-linux-gnu ¥
--host wasm32-unknown-emscripten ¥
--with-static-linked-ext¥
--with-ext=ripper,date,strscan,io/console,…,psych ¥
optflags=-Osdebugflags=-g0 ¥
CC=emccLD=emccAR=emarRANLIB=emranlib
$ make
Slide 35
今後の予定
•ほそぼそとメンテナンスするつもり
•WASMが大ヒットする日に備える
•そのとき「 RubyもWASM対応してます」と言いたい
•RubyからJSやDOMを操作できたらいいなあ
•当面はOpalを使うのがいいと思います
•WASM版TryRubyができたらいいなあ
•Opalであまり問題はないですが
35
Tags
ruby
emruby
emscripten
wasm
Categories
Technology
Download
Download Slideshow
Get the original presentation file
Quick Actions
Embed
Share
Save
Print
Full
Report
Statistics
Views
10,743
Slides
35
Age
1683 days
Related Slideshows
11
8-top-ai-courses-for-customer-support-representatives-in-2025.pptx
JeroenErne2
44 views
10
7-essential-ai-courses-for-call-center-supervisors-in-2025.pptx
JeroenErne2
45 views
13
25-essential-ai-courses-for-user-support-specialists-in-2025.pptx
JeroenErne2
36 views
11
8-essential-ai-courses-for-insurance-customer-service-representatives-in-2025.pptx
JeroenErne2
33 views
21
Know for Certain
DaveSinNM
19 views
17
PPT OPD LES 3ertt4t4tqqqe23e3e3rq2qq232.pptx
novasedanayoga46
23 views
View More in This Category
Embed Slideshow
Dimensions
Width (px)
Height (px)
Start Page
Which slide to start from (1-35)
Options
Auto-play slides
Show controls
Embed Code
Copy Code
Share Slideshow
Share on Social Media
Share on Facebook
Share on Twitter
Share on LinkedIn
Share via Email
Or copy link
Copy
Report Content
Reason for reporting
*
Select a reason...
Inappropriate content
Copyright violation
Spam or misleading
Offensive or hateful
Privacy violation
Other
Slide number
Leave blank if it applies to the entire slideshow
Additional details
*
Help us understand the problem better