組み込みC言語プログラマのためのmruby入門(後編) ―― mrubyの組み込み方とJavaとの違い

邑中 雅樹

tag: 組み込み

技術解説 2012年12月14日

4.mrubyバイトコードとJavaバイトコード

 バイトコードを用いた言語VM(仮想マシン)にはさまざまなものがありますが,それらのうち,組み込みをはじめ幅広い分野で応用されているものの代表格としてJavaバイトコードがあります.ここで,mrubyバイトコードの特徴をあぶり出すために,Javaバイトコードとの比較を試みてみます.Javaの詳細をご存じない方のために,Javaについても軽く解説を加えてみました.

 

●mrubyバイトコードは「Write Once, Run Everywhere」ではない

 Java言語は,携帯電話や小型情報端末などといった組み込みエンジニアにとってなじみの深い製品から,銀行の基幹システムのような大規模なものまで,広く用いられています.使用できるライブラリは,それぞれの応用分野で若干異なっています.また,同じ応用分野でも,デスクトップGUIのツールキットとしてAWT/SwingとSWTの二つが存在する,などといった分岐もあります.

 とはいえ,Java言語を支えているJavaバイトコードは,命令セットが厳しく規定されています.命令セットを包み込むクラス・ファイルのフォーマットに依存して,下位互換性が損なわれたことはありますが,バージョンさえそろえれば,Java仮想マシンは動作環境の規模によらずバイトコードを実行することが可能です.このような性質を,Javaを支持する人たちは「Write Once, Run Everywhere」(一度書けば,どこでも動く)と主張することがあります.

 一方,mrubyバイトコードは「Write Once, Run Everywhere」ではありません.mrubyよりも規模の大きな環境のために存在しているRuby 1.9は,mrubyと同様にバイトコードにコンパイルされ実行されますが,それぞれの実行環境(VM)には互換性がありません.

 Ruby 1.9のバイトコードは,YARV(Yet Another Ruby VM)と呼ばれる仮想マシンで実行することが想定されています.mrubyでは,RiteVMと呼ばれる仮想マシンで実行されることが想定されています.Ruby 1.9とmrubyは,Ruby言語というレベルでは高い互換性があります.しかし,VARVとRiteVMの間には,互換性は一切ありません.

 互換性を切ることで,失うものも得るものもあるでしょう.例えば,開発ホスト環境と動作ターゲット環境で同じバイトコードが動作すれば,開発効率は上がるかもしれません.しかし,使用環境が異なれば重視するべき点は変わります.環境に応じた仮想マシンをそれぞれに用意すべきという考え方もあるかもしれません.

 

●mrubyバイトコードは(今のところ)実行時安全性を考慮していない

 実行環境としてのJavaは,攻撃者による有害なコードを実行できないように(少なくとも設計上は)考慮されています.バイトコードを包み込むクラス・ファイルは,JavaVM(厳密にはクラス・ローダ)にあるベリファイアによってチェックされます.実行時に予期しない挙動を示すバイトコードが含まれている場合,クラス・ローダは,実行前に例外を発生させます.

 また,バイトコードを束ねるjarファイルには,配布者が電子署名を付けることができます.クラスローダは,攻撃者による改変やネットワークの問題による破損を,電子署名と照合することで検出できます.

 一方,mrubyのバイトコードは,今のところ,実プロセッサにおけるオブジェクト・ファイルのような,生のバイトコードとシンボルの固まりです.コンパイル後バイトコードが実行されるまでの間に攻撃者が存在した場合には,防御の方法がありません.また,万一コンパイラにバグがあった場合も,mrubyの実行環境であるRiteVMは,与えられたバイトコードを疑いもなく実行します.

 実行時安全性と省リソースとは,背反になりがちなものです.現時点でのmrubyは,Javaと比べると,省リソースのほうに重きを置いていると言えます.ですので,バイトコードの破損が起きやすかったり,攻撃者の介入を受けるリスクが高い環境では,より慎重になる必要があります.

 

●RiteVMには(今のところ)標準仕様がない

 Javaの実行環境であるJavaVMは,バイトコードの命令セットやクラス・ファイルのフォーマットなど,標準仕様が文書として存在しています.mrubyの実行環境であるRiteVMは,まだ標準仕様がありません.実装が仕様であり,実装が変わる可能性はいまだに残っています.README文書の先頭には「This is a preliminary release for internal team review.(これは内部チーム・レビュー用の初期リリースです)」との宣言があります.仕様や実装が不確定なのは,当然のことではあります.

 mrubyを今から製品に組み込もうという方々は,標準仕様が存在しないことを強く認識しておく必要があります.バイトコードのバイナリを,ファイルやフラッシュROMなどから動的に読み込もう,という方は特に注意が必要です.mrubyのバージョンアップに伴い,それらのバイナリは互換性を失うリスクが(本稿執筆時点では)ゼロではありません.

 また,C言語APIも流動的です.実は本稿執筆中にも,本稿で触れていたAPIの仕様が変更され(詳しくはhttps://github.com/mruby/mruby/commit/b8e5a570479a2e4を参照),あわてて内容を修正するはめになりました.当面は特定バージョンに固定するか,最新バージョンの変更点を常に監視してアップデートするか,どちらか明確に決めた上でアプリケーションを作る必要がありそうです.

* * *

 駆け足になりましたが,mrubyの神髄である,mrubyの実行環境RiteVMとバイトコードについて解説しました.アプリケーションに組み込む際には,本稿で解説した実行環境の呼び出し方のほかに,RubyオブジェクトのC言語からの読み書き方法や,RubyメソッドのC言語での記述方法を修得する必要があるでしょう.しかし,本稿執筆時点では,mrubyのAPI仕様が固まっているとは言えない段階のため,あえて割愛しました.興味のある方は,src/以下のソース・コードを追跡することである程度の推測はできるものと思います.そのためには,mrb_stateが環境を握っている,ということを理解する必要があります.

 また,mrubyと同じくバイトコード仮想マシンを採用しているJavaを例にとって,mrubyの実行環境であるRiteVMを取り扱う際の注意点を整理しました.mrubyは,おおむね安定してきています.しかし,命令セットの細部など,まだ仕様変更の可能性がゼロではない段階にも見えます.意識的に最新情報を参照するように心がけるべきだと思います.

 率直に言って,mrubyには,まだ荒削りなところが残っています.しかし,急速に磨き上げられつつもあります.本連載執筆開始以降だけを見ても,モジュールの管理機構(rubygems)の追加がありました.また,サード・パーティの動きも活発です.LLVM(Low Level Virtual Machine)を経由してJavaScriptへの変換を行うコンパイラや,本家の8倍の実行速度をうたうネイティブ・コンパイラなどが登場しています.

 明日から製品に組み込むのは若干リスクが伴いますが,次期製品への組み込みのために,そろそろ調査を始めてもよいころかもしれません.本稿がそのとっかかりとして,少しでもお役に立てたなら幸いです.

 

むらなか・まさき

 

組み込みキャッチアップ

お知らせ 一覧を見る

電子書籍の最新刊! FPGAマガジン No.12『ARMコアFPGA×Linux初体験』好評発売中

FPGAマガジン No.11『性能UP! アルゴリズム×手仕上げHDL』好評発売中! PDF版もあります

PICK UP用語

EV(電気自動車)

関連記事

EnOcean

関連記事

Android

関連記事

ニュース 一覧を見る
Tech Villageブログ

渡辺のぼるのロボコン・プロモータ日記

2年ぶりのブログ更新w

2016年10月 9日

Hamana Project

Hamana-8最終打ち上げ報告(その2)

2012年6月26日