M is for MIDI (c88)

今年の夏コミ(C88)に、TechBooster(「てくぶ」)という技術系サークルで出す、新刊4冊のうちの1冊、Android Mの最新情報をまとめた本に、Android Mで新しく追加されたMIDI APIについての記事を寄稿しました。

techbooster.github.io

執筆者が全員入った表紙があるとのことで、さり気なくわたしもいるみたいですよ。分かるかな…?

同人誌向けの原稿、これまで書いたことがなかったわけではないのですが、だいたい原稿をテキトーに書いて渡したらそれでおしまい、くらいの軽いノリでいたわけです。そしたら、このグループの人たち、原稿の書式はRe:VIEWを使います、文章の望ましい書き方はこれこれこうこう、書き終わった後にクロスレビューをやります…と、えらいガチなんですね。なるほど、作業フローこそサークル前提だけど、こうやってクオリティを上げているのね…と感嘆したものでした。

そんなわけで、7月はのんびり日本をエンジョイ()しようと思っていたわけですが、この辺の作業で思っていたより忙しく過ごすことになっちゃいました。

わたし書いた内容ですが、本当はMIDI APIを使ったawesomeなライブラリも合わせて実装して出したかったのですが、そこまで気軽に出来るスケジュールでもなかったので、モバイルのMIDIを取り巻く状況の話と、新しいAPIの使い方の話が中心です。Android SDKのサンプルにすら含まれていないので、地味にコードを書いて調べたりissuesにレポートを登録したりしながら書きました。*1

3日目(8/16)は、わたしはCOSCUPに参加していて日本にいないことになっているので、現場にはいない予定ですが、興味のある人がいたらぜひ見ていって下さいませ。

coreclr関係もろもろ

Open .NET technology explained at COSCUP 2015

これは告知してもしょうがないのですが、8/16に台北で行われるCOSCUP(オープンソース技術系カンファレンス)で、オープンソース化した.NET関係の技術について、40分ばかり雑談してきます。

Schedule 議程 | 2015 COSCUP

今 年でセッションは3年目なのですが、monodevelop -> mono -> .NET と、だんだん話が大きくなって希薄化している感はありますね…個人的には細かい部分を掘り下げるほうが楽しいのですが、まあ正直台湾のOSS方面では現 状.NETネタを受け入れてもらうのも一苦労だと思うので、エントリーレベルの話から始めたほうがいいのかもしれません。(あれ、エントリーレベルの話な んてする気あったっけ…?)

参加申し込みももう締め切られているので(というか公開後ほどなく満員御礼になっちゃうんですよね)、万が一興味があるという方は、後日の資料公開などを期待していて下さい。

coreclr Book of the Runtime日本語訳プロジェクト

そんなわけで、coreclrやらcorefxやらroslynやらの調べ物をしようと思って日々過ごしているわけですが、最近気付いたもので、coreclrのリポジトリの中に、"Book of the Runtime" (BotR) と呼ばれるドキュメント集があって、.NETランタイムの内部設計についていろいろ解説してあるのです。これはなかなか興味深い。ランタイムの各コンポーネントの担当者がまとめた文章を集めたものであるらしく、コードの詳細までは踏み込まないけど、内部実装の理解がそれなりに得られるものだと思います。

 

というわけで、少しずつ読み解きながら翻訳してみたいと思っています。翻訳したドキュメントは、このリポジトリに置いておきたいと思います。翻訳を手伝っていただける方は随時募集しています(既にわたしだけのプロジェクトではないです)。

github.com

 

このBotR、FAQを見てもらえれば分かるかと思いますが、基本的には文書作成時からほとんど加筆修正されていないものであるようです。なので、古い内容のものもけっこうあります。とはいえ、ランタイムの基本的な構成要素、たとえば型システムなどはそうそうリニューアルされないので、それで困ることは多分あまり無いでしょう。一方でRyuJITみたいな、新し目のコンポーネントについての文書もあります。翻訳しながらじっくり読むと、勉強になるかもしれません。

coreclrをUbuntu 14.04だけでビルドする

で、調べ物をするにあたって、やっぱりcoreclrもcorefxもビルドして動かしたいと思ったわけですが、わたしの作業環境はLinuxで、どうやらcoreclrのビルドにはWindowsが必要なんだそうです。

 

blog.shibayan.jp

www.atmarkit.co.jp

えー。Windows機、ありますけど、いちいち起動してビルド環境をセットアップしてビルドするのは、ちょっとめんどくさいですね。 しかも、もしmscorlibの実装をちょっとだけ修正してビルドしたいと思っても、毎回これをやることになるわけですね。めんどくさい。

mscorlib.dllはマネージドコードだからビルドする環境が無い、というのは確かに分か…あれ? でもcorefxはLinuxでもビルドしますよね。何でcoreclrのmscorlibで同じことをしないんでしょうか? もしかして単に手が回ってないだけなんでは?

…というわけで、corefxのビルドスクリプト(主にMSBuildの大盛りtargetsスパゲッティ…)を見ながら、半ばコピペでmscorlibもビルドできるようにしてみました。

https://github.com/dotnet/coreclr/pull/1275

実際に完成させるところまでやって気付いたわけですが、けっこう大変ですね。他のcorefxのライブラリのビルドと違って、mscorlibはrc.exeの呼び出しとか、色々なバイナリ書き換えとか、チマチマとWindows依存のビルドステップが入ってきます。主にそれらを取り除く作業となりました。roslynを使ったビルドでも、デバッグシンボルを生成しようとするとpdb生成はCOM依存なので落ちるとか、割と厳しい感じです。

実のところ、何とかビルドできたmscorlib.dllでhello world的なコードを動かせて、パッチをコミットしてpull requestを送った後も、実はビルドの一部(crossgen)がクラッシュしていたとか、バイナリ書き換え(BclRewrite)がかからないと何処でエラーが出て落ちるか分からんみたいな事情があるようで、取り込んでもらえるかどうかは、雲行きが怪しいところです。BclRewriteは何でクローズドソースなんじゃあ、とか、コミュニティからも改善要望が出ていて、Microsoftも方針を決めかねている状態であるようです(ということは、よっぽどWindows依存なんだろうなあ)。とりあえずクロスプラットフォームまわりの深淵を覗きこんだような感じでした。

…とまあ、その辺の話を(盛り込む余裕があれば)COSCUPでしてこようかなあと思っています(そのための調べ物だった)。

llilcについて

Microsoftがcoreclrまわりの新しいネタを投入してきましたね。LLVMを.NET Coreで使うものだそうです。

github.com

"an LLVM based compiler for .NET Core." 何だかよくわからないですね。

llilcは、.NETで言えばランタイムの一部分の一種であり、99%の.NET開発者には意識する必要のないプロジェクトです。

.NETランタイムには、MSILを解釈して、実行マシン上のCPUネイティブコードに変換して実行する機能が求められます。いわゆるJITコンパイラーというやつです。LLVM based "compiler"というのは、このJITコンパイラーのことです(RoslynみたいなC#コンパイラーとは、取り扱っている問題が違います)。

オープンソースで公開されているcoreclrには、現在、RyuJITというJITコンパイラーがあります。このJITコンパイラーは差し替え可能なcoreclrの部品なので す。llilcは、その代替候補のひとつとなります。Javascriptの世界では、よく新しいJITが導入されて(v8, spidermonkey, chakra, ftljit…)、そのパフォーマンスが議論されますが、MSIL JITの世界でも同じことが起こっているということですね。

これらのJITの実装にはさまざまな特徴があり、Javascriptの世界だと、大概は「新しいほうがパフォーマンスが良い」みたいな文脈で語られますが、実際には一長一短の世界でもあります。RyuJITはWindowsで動作する.NETのMSILに特化したJITとして開発されてきたものであり、MSILを最適に実行できるJITとして在るのだと思いますが、LLVMほど多様な環境を前提としてはおらず、移植性(あるいは「可能性」)は、LLVMほど高くはないでしょう。

JITで活用されるLLVMフロントエンド、とは何なのか?

llilcはLLVMフロントエンドのひとつとして実装されています。この意味が分かる人は、ここからしばらく読み飛ばしてもらっても大丈夫ですが、LLVMについてよく分かっている人は多くないと思うので、この辺で少し解説しておこうと思います。

LLVMは "compiler infrastructure" なのですが、LLVMが主にターゲットにしている「コンパイラー言語」は、ネイティブコードを直接生成するC++のような言語です。われわれは、コンパイラーを作成する時、まずソースコード構文解析してシンタックス ツリー(AST)を構築し(文法エラーなどをレポートし)、そのASTを解釈してコードのセマンティック モデルを構築し(おかしなコードの定義や参照をレポートし)、そこから仮想的な実行命令(IR*1)の集合を生成します。この実行命令の集合は、プラットフォームやアーキテクチャに特化していないもの(そのようにあることを意図したもの)であり、実行するためにはこれを各プラットフォーム/アーキテクチャのネイティブコードに置き換えるものが必要です。

LLVMでは、この仮想的な実行命令の集合を構築するまでの部分をLLVMフロントエンド、仮想的な実行命令の集合からCPU固有のネイティブコードを生成する部分をLLVMバックエンドと呼びます。これらが切り離されていることで、LLVMは、多様なコンパイラー言語(のLLVMフロントエンド)から、さまざまなプラットフォーム用の実行コードを(LLVMバックエンドで)生成できるような "compiler infrastructure" であるわけです。例を挙げるなら、AppleObjective-Cコンパイラはフロントエンド、emscriptenのようなプロジェクトは(特殊な)バックエンドですね*2

LLVMフロントエンドが.NET Coreをサポートするというのは、まだよくわかりませんね。.NETはMSILを実行するためのものです。LLVMコンパイラーです。llilcはC#ソースコードを解析するLLVMフロントエンドなんでしょうか?

そういうことではありません。llilcにとっての「ソース」は、C#ではなく、MSILなのです。そして、llilcはコンパイラツールとして使われるわけではないのです*3C#からMSILを生成するのは、これまで通りC#コンパイラー(csc, mcs, roslyn)の仕事です。llilcは、CoreCLRにおけるJITコンパイラーとして使われます。言い換えれば、LLVMはllilcのJITコンパイラインフラストラクチャー」となるわけですね。

ちなみに(ここに来てようやく)monoの話をしますと、monoにも、開発初期からずっと存在しているMSILのみをターゲットとするコード生成エンジンと、LLVM IRを生成するmono-llvmエンジンのふたつが存在します。これらは、JITの側面では、概ねRyuJITとこのllilcの関係に近いと言えるでしょう。mono-llvmはmonoのエンジンに比べてサイズが大きく、Xamarin.Androidのような環境では、まだデフォルトとしては使えません。

(ちなみにmonoの実装の中では、"LLVM Backend"という表現が使われていますが、monoの実行エンジンのbackendという意味であって、mono-llvmLLVMの世界におけるLLVM backendとして実装されているわけではありません。あーややこし。)

AOT実装について

JITのコード生成部分が差し替え可能な環境でしばしば挙げられる目標として、ネイティブコードに直接変換した上で実行できるような事前コンパイル(AOT; ahead of time compilation)が挙げられます。llilcは意欲的で、このAOTサポートも目的の一つとしています(まだ出来ていません)。動的コード生成がAppleによって独占されているiOSのような環境で使おうと思うと、AOT対応が必須になってきます。

llilcが特に興味深いのは、コード生成部分だけが異なるmono-llvmとは異なり、llilcのAOTはcoreclrを実行時に組み込む前提としていないところです。llilcのアーキテクチャ ドキュメントには、JITとAOTのモデルが図示されているのですが、

llilc/llilc-arch.md at master · dotnet/llilc · GitHub

AOTの方にはCoreCLRのブロックが見当たりません。アーキテクチャのドキュメントでは、詳しいことはこれから書く、みたいに書かれているのですが、どうも実行エンジンそのものがcoreclrから独立している感じですね。そのせいか、llilcで実行する場合にはメモリ管理をどうするか(LLVMに含まれるGC実装を使う)、とか、例外のpropagationをどうするか、とかいった話が、割と詳しく書かれているようです。

(これらはAOT固有の話というわけではなく、coreclrに実行エンジンを組み合わせる場合にはここから実装しなければならないということかもしれません。monoのLLVMサポートでは、独自にメモリ管理まわりを繋ぎ込んでいることは ない よう です。)

この辺は今後出てくるドキュメントとコード次第ですね。

ちなみに、RyuJITに対応するAOTは今のところ存在しないと思いますが、.NETの世界では、.NET Nativeというものがあって(と言っても正式版はまだでしたか)、.NETのコードをネイティブアプリケーションにして配布できるようになっているのですが、あれもAOT技術のひとつなので、coreclrのメインストリームにおけるAOTの実態は既にあるか、準備出来つつあるということなのではないかと思います。

というわけで、llilcがどんな位置付けにあるのかをざっと解説してみました。LLVMを使うことで、RyuJITでは手が回らないようなプラットフォーム / アーキテクチャでも.NET Coreのコードが動くとなると、なかなか魅力的である気がします。

まあ、マネージドコードを書くだけの開発者にとっては、これで大きく可能性が広がったというわけでは特に無くて、主に、ランタイムを.NETが動かないプラットフォームに組み込んで使いたい人なんかが、こういったプロジェクトで恩恵をこうむるんじゃないかとは思います。

*1:intermediate representation https://idea.popcount.org/2013-07-24-ir-is-better-than-assembly/ が参考になるでしょう

*2:「プラットフォームの実行コードとして」Javascriptを生成するわけですね

*3:最終的には、AOTコンパイラーとしての部分とroslynを繋ぎ合わせて、ソースから実行ファイルを生成するようなツールが作られるかもしれませんが、ここで書いていることはそういう話ではありません

JXUG #4で Java Bindingの話をしてきました

書くの忘れてた!

もう終わってしまったネタですが、先週末にJXUGでちまちまとしゃべってきました。

jxug.connpass.com

スライドも公開してあります。

speakerdeck.com

後半は割とworldwideでも喋られていないレベルで掘り下げてあります(かつて主に実装していたのが自分なので…)。Javaバインディングまわりは意のままにならず気に入らない部分も多いのですが、まあ現状の紹介としてはこんなものでしょう。

実際にバインディングのDLLを作るという目的を達成するところまで辿り着けるかは、かなり運次第なところもあるのですが、なんかしらの参考になればと思います。

オープンソース化されたMSBuildについて

昨日のdotnetconf2015でMSBuildオープンソースになりましたね。

github.com

Miguelがゲストでセッションに参加していて、もしかして何か来るかなと思っていましたが、アタリでした。

このMSBuildのソース、基本的に新しいビルドエンジンのみが対象で、逆に旧エンジンしか無いmonoでは*1、新しいものにdllだけ差し替えるというより、別のツールにするといいかなあと個人的には思っています(xbuildじゃなくてmsbuildにする)が、既に移植を担当する新人ハカー*2がいるので、その辺はそちらの采配次第です。旧エンジンも新エンジンも同じファイル名のtargetsを使っているので、分けて使うのも簡単ではないかもしれませんし。

このMSのコード、昨日仲間内で眺めていたのですが、やはりだいぶWindows依存のコードが多く("DllImport" とか、それで引っかかる "NativeMethods" をさらに検索してみると大まかにわかります)、やはり簡単に取り込めるというわけにはいかなそうです。

ただ、referencesourceと異なり、こちらはMSもクロスプラットフォームなビルドツールにしていく方向性であるようです。

http://blogs.msdn.com/b/dotnet/archive/2015/03/18/msbuild-engine-is-now-open-source-on-github.aspx

どちらかというと coreclr, corefx, roslyn などと同じ、継続して開発・公開していくスタイルということになりそうですね。githubリポジトリも、masterの他にxplatというブランチが切られていて、早速さまざまなpull requestが取り込まれているようです。

新しいMSBuildエンジンが使えるようになると、新機能(というほど新しくもないのですが)を無理やり旧エンジンに埋め込むことなく使えるようになりますし、ビルドのパフォーマンスもある程度向上するのではないかと期待しています。

…というわけで、msbuildの取り込みは、短期的には実現しないでしょうが、それほど遠くないうちにmonoでも使えるようになるだろうとは思います。

*1:新しいMicrosoft.Build.dllのエンジンは、わたしがちょっとだけ実装していたこともあるのですが、時間が取れないままで結局使えませんでした

*2:って言ってもだいぶ前にmonoをいじっていた昔の仲間ですが

Mono x referencesource updates

最近ほとんど告知とまとまったネタしか書いていなかったので、ひさびさにmonoの細々としたアップデートを、主にreferencesource絡みでいろいろ書いてみようと思います。

最近monoの中で主に行われているのは、Microsoftから公開されたreferencesourceの取り込み作業で、大部分はわたしを含む3人くらいでやっています。他の2人がmscorlib.dllとSystem.dllの内容を適宜置き換えている間に、わたしも適当に参戦しつつ(EncodingとかSystem.Diagnostics.Traceとかを置き換えました)、この前ようやくSystem.Xml.dllの大部分(XmlSerializer以外)とSystem.Xml.Linq.dllの全てを置き換えました。つまりわたしのコードはもうSystem.Xmlにはほとんどありません(!)

XmlSerializerが古いままなのは、先日GoAzureでもしゃべりましたが、referencesourceのXmlSerializerが動的コード生成に依存していてiOSで使えなくなる、という問題のせいです。これは誰かがreferencesourceの実装に沿ったインタープリターを書けば取り込めるかもしれません(!) なんか、個人的に「オマエでもいいんだけどカネ払ってもいいからやってくれる人いないか?」とか頼まれたりしているので、誰かやりたい人がいたら繋ぎます。(わたしは一応フルタイムで仕事しているしそんなのやる気は…w)

mscorlib.dllやSystem.dllについては、ソースコードのどの部分がreferencesourceに置き換えられているか、ビルドのレスポンスファイルのソースを見てみると、大まかな状況が掴めてくるのではないかと思います。collectionsとかcomponentmodelとかは置き換えられていますね。

わたしはそれに続いてWCFの取り込みにも目を向けているのですが、当初われわれ(主にMiguelとわたし)が「マネージドコードだし簡単なんじゃね?」と言っていたSystem.Runtime.Serializationがガチガチの動的コード生成仕様だったので、これはどうにかせんとなあという感じです。コレが取り込めないとSystem.ServiceModel.dllも取り込めないので、困っちゃいますね。あといろいろ足りない部分があって、ビルド出来るところまで持っていくのがひと苦労です。まあこれは11日にreferencesourceにSMDiagnosticsが追加されて、少し緩和されたかもしれませんが。

ただ、個人的には先にSystem.Data.dllを片付けたいという気もしなくはないところです。アレはメンテナーがほぼ壊滅状態なので…まあそれを言ったらWCFも(ry

あと最近referencesourceにWorkflow Foundationも追加されたので、これも取り込みたいところですが、こいつはWCFに依存している部分がある程度あるので、それもどうにかすべきところですね。WFにはSystem.Xaml.HostingとかXamlBuildTasksとかあるくせに、System.Xamlのソースはまだ公開されていないという…(アレが置き換えられるとわたしの成果がまたひとつ消せるのですがw)

ちなみにもう1人は新しいTLS実装に取り組んでいるみたい。この辺はreferencesourceがWindows に依存していて役に立たない部分であるわけです。

SocketとかHTTPSの実装まわりは、いろいろバグが出てくることが多いので、この辺はうまく置き換えられるようになると良いなあとは思います(Socketは難しいかな)。

とりあえず現在進行形の作業はこんなところでしょうか。ちなみにreferencesource統合作業については、パブリックなtrelloボードがあって、ここに計画や(部分的に)進捗なども記録されているので、興味がある人は見てみるといいと思います。referencesourceだけでなく、coreclrからGCのコードを引っ張ってくる、みたいな野望もリストアップされていたりして、割と面白いかもしれません。

https://trello.com/b/vRPTMfdz/net-framework-integration-into-mono

あと、先日Google Summer of Code 2015が発表されたのですが、referencesourceを取り込む作業もこの一部として含まれています。これももし興味のある人がいたらぜひどうぞ…まあGSoCって日本の大学の夏休みと合わないんですけどね…

http://monosoc.blogspot.tw/2015/03/mono-summer-of-code-2015.html

とまあ、ざっとこんなところでしょうか。本当はこういう話はこの辺のイベントに顔を出していろいろしゃべると良いのでしょうけど、たまたま裏番組でしゃべることになってしまったので、泣く泣くこうして落書きにして出した次第です。

この辺の作業については、またしばらくしてまとまった進捗が得られたら && 気が向いたら書こうと思います。

GoAzure2015 - オープンソース.NETと Mono / Xamarin の今後について

今日(いやtechnicallyもう昨日ですが)GoAzureのセッションに参加していただいた皆様 & お招きいただいたJAZUGの皆様、ありがとうございました。

今回のスライドはこちらに上げておきます:

[GoAzure2015] オープンソース.NETと Mono / Xamarin の今後について - Google スライド

今回はデモなしでしゃべりっぱなしでしたが、時間オーバーしちゃったのと最後少し巻いてしまった以外は、まあ過不足ない内容になったのではないかと思います。

会場でも、ここ1年くらいの.NET/Xamarin系の繋がりにある東京近辺の人々と、だいぶ総ざらいに近い感じで話せたので、満足しています。

そんなわけで、今後の機会にもよろしくお願いします。