ChalkTalk CLR – 動的コード生成技術(式木・IL等)

ChalkTalkCLR12122636_1505045119820235_1955812025993410087_n「ChalkTalk CLR – 動的コード生成技術(式木・IL等) 」というお題で、小規模で濃い話が出来る場を設けてディスカッションしてきました。

今回の会場は、「Maker Lab NAGOYA」さんをお借りすることが出来ました。モノづくり主題のワークスペースで、色んな加工装置とかあって、IoTネタとか常時面白そうなことをやっています。案内頂いたMatsuokaさんは、.NET Micro Framework (GR-PEACH) のバグフィックスとかやっていて、わぉーと言う感じです。

WP_20151017_12_58_31_Pro__highres


開催の背景

「ChalkTalk」という名称は、チョークと黒板を使って、密なディスカッションをする、のような意(のはず)です。普段のCenter CLR勉強会でもディスカッションと言う事は意識しているのですが、もっと密にやりたかったという動機があります。

  • 今回のテーマが、ILや式木なので、いきなり展開するにはディープ過ぎる。
  • でも、個人的にはやってみたい。なので、小規模でやってみて、このネタをどうやって本会でやるのかを練ってみたい。
  • そもそも、Center CLRに近しいメンバーが、この辺りの技術にどれだけ長けているか・追従できるか、と言う事を知りたい。
  • そして、ChalkTalkは面白い(知ったのはde:code 2015)ので、自分でもやりたい。

と言う事が背景にあって、オーガナイザーなんだから、やってみればいいよね、ダメなら今回で終わりにすればいいし、と思って開きました。

WP_20151017_17_49_59_Pro__highres告知通り、事前に資料の準備なし(以前にやった勉強会の資料とかはありますが)としたのですが、あまりにフリーダムだと議論が発散する可能性もあったので、KPTを使って、参加者がどのような課題を持っているのかを視覚化してみようと思いつき、このような感じで5分で書き出してもらいました。

一部の参加者が「COMが~COMが~」と言っていたのですが、COMの基礎をやり始めるとそれだけで潰れてしまうので、やむなく我慢してもらうことに (;´Д`) 何故COM?と聞いてみたところ、「WinRTのバックグラウンドにCOMがあるらしいけど、もうググっても情報が得られなくて云々…」との事。この、某学生MVPには、やたら熱くアピールされたので、COMについてはまたChalkTalkでリベンジすることにしました。

結局、KPTでは各参加者のレベル確認的な所となり、順当にILとかCLSの説明からスタートする事に。KPTの導入は、私のアジャイル方面への試みの一つでもあるんですが、全然生かせていないのは今後の課題だなと感じました。
題目が「IL・式木」と言うように、初めから技術にフォーカスしていて、これらの技術を使う動機というか、バックグラウンドと言うか、そういうところに焦点が当たりにくかったのも敗因かなと思っています(技術フォーカスだとわかりやすいし、もともとは自分がやりたかった話なので、仕方ないんですが)。


ILとCLSの話

makerlab1x86とかx64のような物理CPUアーキテクチャの話と、それをつなぐCLSやILのコードの関係・実行時に何が起こっているのかという概要の話をしました。参加者には経験が浅くてILとかそもそも中間言語や仮想CPUとかわからない方も居たので、概要レベルでの導入を試みました(どんなエキスパートでも、最初に通る道なので、知らなくても恥じる必要はないです)

特に、仮想的なCPUが「スタックマシン」であり、スタックの出し入れで処理がおこなわれる、という所が焦点だと思ったので、ILSpyで逆コンパイルした結果を見せ、仮想CPUのスタックにどのように値が出し入れされるのかを、詳しく説明しました。この部分は、以前にMGK2015(三重合同懇親会)で、LTでILを説明するという無謀を試みたことがあり :)、その話も交えながら。写真のように、白板にスタックの図を描いて、ILコードからどのようにスタックが操作されるのかを詳しく説明しました。

ILの仮想CPUがスタックマシンであることと、もう一つ重要な概念として「box化(boxing)」とその解除の話をしました。.NETにはValueType型があり、この型を継承した型が構造体(struct)となって、ILのレベルでは扱いが異なると言う事を話しました。マサカリ来ましたねー (;´Д`) ValueType型自身は構造体ではなく、クラスでしたね(今、ちゃんとリファレンスで再確認しました)。

構造体のインスタンスは、ローカル変数領域(.locals)や、フィールド変数などで、直接そこに値が格納されます(物理CPUでどう実装されるのかは、ひょっとしたら違いがあるかもしれません)。それに対して、「参照型(クラス)」は、不透明なポインタ値がそこに格納され、実際の値(インスタンス)は、ヒープ領域に格納されます。object型のフィールドや変数にインスタンスを格納する場合、構造体のインスタンスであれば「box命令」「unbox.any命令」で、ヒープ領域への格納と取り出しが行われる、というのを図示しました。この操作にコストがかかることについても理解してもらえたと思います。

トリビアとして、box化を忘れたり、やらなくてもよい所でbox化や解除したりすると、おかしな現象が起きたり起きなかったり、InvalidProgramExceptionで落ちるよ、みたいな話もしました。CLRがロード時にILに対してどこまでの検査をしている・していないのか、というのは興味深いところです。bleisさんからは、PeVerifyツールを紹介して頂きました。自分でEmitで生成したコードに問題がないかどうかを、静的に解析できます。ILSpyは、ILの使用方法が間違っていても、一見それっぽく逆コンパイルコードを表示してくる(クラッシュする場合もある)ので、初めのうちは特に注意した方が良いでしょう。

ILについては、あとは命令のバリエーションを理解すれば、少なくともILSpyで逆コンパイルしながらコードを調整していくことで、そこそこILが書けるようになると思います。と、ここで、「IL Support」という拡張機能の事についても教えて貰えました。これを導入しておくと、il用のソースを別に用意しておき、C#側からそれを参照する定義をexternで書いておくだけで、動的にEmitしまくる事無く静的に自分のコードにILを導入できます。更にILソースファイルは、pdbにデバッグ情報も出力されるので、デバッガでILにステップイン出来るという、正に神ツールです。すばらすぃ….

ILを書いたソースコードファイルをhoge.ilのようなファイルで保存し:

.namespace CenterCLR
{
	.class public ILSupportSampleClass
	{
		.method public static int32
			Compute(int32 a, int32 b) cil managed 
		{
			ldarg.0
			ldarg.1
			add
			ret        
		}
	}
}

C#側からはMethodImpl属性で参照可能にします。

namespace CenterCLR
{
	public class ILSupportSampleClass
	{
		[MethodImpl(MethodImplOptions.ForwardRef)]
		public static extern int Compute(int a, int b);
	}
}

式木の話

ILの話は低レベルでなじみが薄いため、一般的にはILの方が難しいような印象がありますが、上記の話を押さえておけば、結構誰でも掛けたります。間違ってると簡単にクラッシュもしますが。しかし、式木については概念からわかってないと扱いづらい(≒解説が長期化してしまう)と言う事もあって、どうやってディスカッションするか、考えあぐねていました。

第一回~第三回のCenterCLR勉強会でも度々取り上げてきたので、参加者には「ぼんやりと」式木の概念は伝わっていたようですが… ここでもbleisさんに、式木についての説明をしてもらいました。王道的に計算式的な定義から、ノードに分解される様、そしてノードの木構造があれば、プログラマブルに探索が可能・変形も可能、という感じでの解説でした。簡潔で分かりやすい。ちゃんと伝わったかな?

式木は:

  • (C#において)ラムダ式からExpressionクラスのインスタンスを取得して、式を動的に解釈する(Entity FrameworkのようなO/Rマッパーが行っている手法)
  • Expressionクラスのインスタンスを動的に組み立て、Compileメソッドを呼び出して、実際に実行可能なデリゲートを入手する
  • 式木ノードを探索して、メタデータ参照に役立てる

というような代表的な用途があることを説明しました。

最初の例では、Entity Frameowrkの話だけでは終わってしまうので :)、Final LINQ Extensions IIIで解説した、即席O/Rマッパーについて軽く復習して、式木の内容をどうやってサーバーサイドで実行するか、のような話をしました。

次に、がりっち=サンに話を振って、「某ronia」というツイッタークライアントのフィルタ条件を動的に構築するために、入力されたフィルタ式をパースして(ここは手動)、Expressionを生成して式木を組み立てて、フィルタ処理を実現した、という話をして貰いました。

最後に、EXCEL仕様書の駆逐ネタでやった、メタデータの参照利用としての式木の話をしました。

そのほか、貴重なお話として、bleisさんの業務での式木の利用経験として、F#の式木をどうやって解釈するのかを考えたという話をしてもらいました。F#の式木は、概念的にはC#(というより.NET FrameworkのExpression)と同じようなものですが実際は異なり、高速化のためにExpressionにマップしてCompileするか、またはF#式木を直接解析してILを生成するか、のような事で、いくつか障害があって頭を悩ましたという話を聞くことが出来ました。この話、以前に何かで見た記憶があるなーと思っていたのですが、今になって繋がった!みたいな、妙な感動がありました。

# 関数型言語にまつわるドタバタで徘徊していた時に見た気がする。
# (えーと、私は面白い技術であればおk的な立場です)

ちなみに、このF#の解析器、手伝ってくれる人募集中とのこと。私が手伝うには、F#をモノにする必要があるな….


総括

WP_20151017_17_54_15_Pro__highres結局、結構時間もおしてしまって、いつも通り(?)最後にバタバタしてしまったのは申し訳ないです。クロージングでKPTを再度書いてもらったのですが、振り返りの時間がまともに取れなかったのでダメですねー。でも、ディスカッションとしては楽しい時間を過ごせました。参加者の皆さんありがとうございます。

課題的にはやはりというか、参加者に想定する知識レベルの差をどうやって埋めるか、と言う事が課題だなと思います。長い目で見た場合、Center CLRへの参加者のレベルが全体的に底上げされて来れば、だんだん解消されるかなと思っています。気の長い話ですが、コミュニティベースなので、このぐらいが良いかなと。ChalkTalkについても、レベル差で細分化した方が良いのかもしれません。私のマンパワーにも限界があるので、中々難しい所ですが、あまり小難しく考えず、トライして方針を修正していく、という感じでやりたいと思っています。

それにしても、白板に書きまくったのに、写真全然撮ってなかったのも残念。だれかカメラ担当お願いすれば良かったです orz

抽象太郎ものがたり そして伝説へ – NGK2014B 名古屋合同懇親会

今年も残りわずか、NGK2014B 名古屋合同懇親会にて、「抽象太郎ものがたり そして伝説へ」というタイトルでLT登壇してきました。

WP_20141206_14_24_43_Pro

会場の様子: 今年は名工大が会場でした。会場はほぼ満席、いつもながら(去年しか知らないけど)凄いです。

NGK2014Bは大LT大会で、LT持ち時間は5分、5分を過ぎると強制終了、5分未満だと放置プレイですww


WP_20141206_16_12_42_Pro

今年の一番の驚きは、ふ”れいすさんの「FCell」でした。うーむ、EXCEL侮りがたし… F#/C#/VB.netのコードを直接EXCEL上で書けて、しかもセルの計算式に指定出来て、しかも再計算も勿論自動で、しかも非同期処理出来て結果も非同期で反映できるという… ええ、私もVBA「大嫌い」ですよ。妄想でこういうの考えた事はあった。これマジ欲しい!!!

「札束でEXCELを殴る」で、Ust見れます。今、ようやくタイトルの意味が分かったw ちなみに、その次の「Play emacs」もデモンストレーションとして凄い良かった・面白かったです。


で、私の登壇した内容ですが… (;´Д`) ええと、忘年会なので、完全にネタです。ただ、ILやりたい人には、サンプルコードは参考になるかと思います。例によってGitHubにアップするので、遊んで下さい。

オリジナルプレゼンはこちら:抽象太郎ものがたり_e
GitHub: CenterCLR.StaticMethodInInterface
Ust: [6/6] NGK2014B 名古屋合同懇親会 昼の部 19:52から

ちなみに、突っ込まれました、その通りです、ハイ。

Youtubeで動画が公開されています。20分ぐらいからです。

去年もネタで笑いが取れるかどうかが勝負だったんですが、今年も何とか笑いが取れたので満足です。
来年も頑張ります。


WP_20141206_18_00_44_Pro

昼の部のLT大会の後は、夜の部で、しゃぶしゃぶ&しーすー食べ放題&飲み放題!!! とっても楽しかったです。

それでは、また。

山椒の味は大人の味 – NGK2013B

名古屋合同懇親会 2013忘年会に参加して、急遽LT登壇しました。
(実はまだ進行中です。Twitter #NGK2013B

後半、ちょっとまくって苦しかった。ウケは取れたので満足です?
ご清聴ありがとうございました。早速、プレゼンおいておきます。

山椒の味は大人の味