Scala×Silverlight
Scala×
         terurou (YAGI.Teruo)
                  YAGI.Teruo)
                 大名古屋, DSTokai
FLOSS桜山, DeLLa.JS, Python東海, ...
Agenda
Agenda

• 本題に入る前の予習
• Scala×Silverlight
• まとめなど
本題に入る前の予習
本題に入る前の予習

Question1
• Scalaって何だっけ?
本題に入る前の予習

Question1
• Scalaって何だっけ?

Answer
• JavaVM上で動作するこれからの時代の言語。
  JavaVMって言いたっかったんだ。。。
本題に入る前の予習

Question2
• Silverlightって何だっけ?
本題に入る前の予習

Question2
• Silverlightって何だっけ?

Answer
• 超簡単に言うと、Microsoft版Flash。
• マルチプラットフォームなブラウザPlugin。
• .NET Frameworkのサブセット(mini-CLR)を
  実行エンジンとして搭載
本題に入る前の予習

Question3
• LTタイトルの「Scala×Silverlight」って
  ScalaをSilverlight上で動かすって意味?
本題に入る前の予習

Question3
• LTタイトルの「Scala×Silverlight」って
  ScalaをSilverlight上で動かすって意味?

Answer
• Yes、それ以外にないだろ。
本題に入る前の予習

Question4
• SilverlightでScalaは動かねーだろw
• そもそも.NETとJavaってVMがちがうwww
本題に入る前の予習

Question4
• SilverlightでScalaは動かねーだろw
• そもそも.NETとJavaってVMがちがうwww
Answer
• scala-msilを使うと.NETでも動くよ(キリッ
本題に入る前の予習

Question5
• えっ、scala-msilって何?
本題に入る前の予習

Question5
• えっ、scala-msilって何?

Answer
• Scalaプログラムを.NETプログラム(MSIL)に
  変換してくれる。
• というか、はじめからscalacのオプションに
  target:msilってオプションあるんだけど、
  それをもうちょっと使いやすくしてくれる。
本題に入る前の予習

Question6
• MSILとか言われても。。。何それ?
本題に入る前の予習

Question6
• MSILとか言われても。。。何それ?

Answer
• MicroSoft Intermediate Language、
  実行可能コードを記述するための中間言語。
• 要はCLR(.NETのVM)用のアセンブリ言語。
• 次のページでもう少し詳しく説明するます。
本題に入る前の予習

MSILとCLR(.NET Framework)
MSILと CLR(    Framework)
だいたいこんな感じ。
本題に入る前の予習

Question7
• つまり、、、どういうことだってばよ!?
本題に入る前の予習

Question7
• つまり、、、どういうことだってばよ!?

Answer
• scala-msil→ilasmで.NETバイナリができる。
• Silverlightの実行エンジンはmini-CLR。
• .NETとSilverlightの実行バイナリ(PE)は
  同一フォーマット。
• つまり動作する見込みあり!
Scala×Silverlight
Scala×Silverlight

scala-msilのインストールと使い方
scala-msilのインストールと使い方
• インストール
  $ sbaz install scala-net
• .scalaをMSILに変換
  .scalaをMSILに変換
  $ scalac-net hoge.scala
• MSILを実行バイナリ(DLL)にアセンブル
  MSILを実行バイナリ( DLL)にアセンブル
      を実行バイナリ(DLL
  $ ilasm /dll hoge.msil
• scala-msilで作ったバイナリの依存性
  scala-msilで作ったバイナリの依存性
  scalaruntime.dllとpredef.dllに依存。
  scala/libからコピーすること。
Scala×Silverlight

scala-msil 使用上の注意
• どうやらscala2.8.0のscalacはバグ持ち。
  target:msilオプションをつけると落ちる。
• trunkやnightly buildやらを色々試したが、
  マトモに動きそうなのはscala 2.7.7。
  scala-msilを試したい人はscala 2.7.7を
  使うと良い。
• DLLだけでなくEXEも作れるはずだが、そこも
  微妙にバグってたりとか。対策は簡単だが、
  今回のテーマから外れるので割愛。
Scala×Silverlight

とりあえず安直に試してみる
• .NETとSilverlightの実行バイナリ(PE)は
  同じファイルフォーマットなんだから、
  意外とそのまま動いたりするかも?
• 適当なソースをビルドしてDLLを作成して、
  VisualStudio/Silverlightプロジェクトから
  参照させてみる。
Scala×Silverlight

生贄となるコード(Hoge.scala)
生贄となるコード(Hoge.scala
                  Hoge.scala)
このコードをDLLにビルドして参照させる。
class Hoge() {
  def add(x:Int, y:Int) = {
     x + y
  }
}
Scala×Silverlight

試してみたが、考えが安直すぎた。。。
• ビルド自体は問題なくできた。
• ビルドしたDLL以前に、scalaruntime.dllが
  参照できねーじゃん!
Scala×Silverlight

Silverlight用の依存DLLが必要。。。
Silverlight用の依存 DLLが必要。。。
           用の依存DLL
• やっぱりSilverlightで.NET用のバイナリは
  使えませんよねー。
• scala-msilにはSilverlight用のバイナリは
  付属してない。
• どうすんの。。。
Scala×Silverlight

ふと、私の中の天使が囁いた。
Scala×Silverlight

ふと、私の中の天使が囁いた。




   バイナリ弄ったらいいじゃない。
      天使ちゃんマジ天使
Scala×Silverlight

まずはバイナリの調査から
• ildasmでも良いが、.NETの逆アセンブラと
  いえば.NET Reflector。
  http://www.red-gate.com/products/reflector/
• バイナリからMSIL、C#、VB.NET、F#、Delphiなどに
  逆アセンブリ可能!
• 今回は簡単なバイナリの解析に利用。
Scala×Silverlight

.NET Reflectorでscalaruntime.dllを調査
     Reflectorでscalaruntime.dllを調査
• scalaruntime.dllから参照されているのは、
  .NET 2.0のmscorlib.dllのみ。
• IntRefなどの基本的な型クラスのみが存在。
Scala×Silverlight

同様にpredef.dellも調査
同様にpredef.dell
      predef.dellも調査
• こちらもmscorlib.dll(あれ、.NET 1.1用?)と
  scalaruntime.dllの2つしか参照していない。
• TuppleやCollectionなどの基本的なクラスが存在。
Scala×Silverlight

mscorlibって何?
mscorlibって何?
• .NET Frameworkの根幹をなすライブラリ。
   – IntegerやCharなどの基本的な型クラス
   – ArrayListやHashtableなどのCollection
   – ファイルI/O
   – Thread
   – Console、Debug
   – Reflection
• 当然、Silverlightにもサブセットが存在。
Scala×Silverlight

見えてきた勝算
• 両DLLともmscorlibしか参照していない。
• バイナリを流し見たところ、特殊なクラスや
  メソッドは使用していないようだ。
• Silverlightのmscorlibを参照するように
  バイナリを改変したら動作しそうな感じ。
Scala×Silverlight

依存バイナリを改変してみる(1)
依存バイナリを改変してみる(1
• DLLをMSILに逆アセンブリ
  $ ildasm /out=scalaruntime.msil 
  > /utf8 scalaruntime.dll

  $ ildasm /out=predef.msil /utf8 
  > predef.dll
Scala×Silverlight

依存バイナリを改変してみる(2)
依存バイナリを改変してみる(2
• Silverlightのmscorlibを参照するように
  MSILの「.assembly extern mscorlib」を
  書き換える。
  .assembly extern mscorlib
  {
    .publickeytoken =
              (7C EC 85 D7 BE A7 79 8E )
    .ver 2:0:5:0
  }
Scala×Silverlight

依存バイナリを改変してみる(3)
依存バイナリを改変してみる(3
• 修正したMSILからDLLを再作成する。
  $ ilasm /resource=scalaruntime.res 
  > /dll scalaruntime.msil

  $ ilasm /dll predef.msil
Scala×Silverlight

実行プログラムのMSILも修正する
実行プログラムのMSIL   MSILも修正する
• scala-msilの出力するMSILも、当然.NET用の
  mscorlib.dllを参照しているので修正する。
• 修正方法は全く同じなので手順省略。
• 修正したらilasm。
Scala×Silverlight

さあ、リベンジだ!
• ちゃんと参照できて動いたよ!
まとめなど
まとめなど

ScalaプログラムをSilverlightで動かす手順
Scalaプログラムを Silverlightで動かす手順
     プログラムをSilverlight
• scalaruntime.dll、predef.dllのバイナリの
  .assembly extern mscorlibの部分を改変し、
  Silverlightに対応させる。
• scalac-netで生成したMSILもSilverlightで
  動作するよう.assembly extern mscorlibの
  箇所を修正してからアセンブリする。
Scala×Silverlight

scala-msilを触って気がついた問題点
scala-msilを触って気がついた問題点
• Actorがない。。。たぶん他にも色々無い。
• コンパイラがたまに不可解なエラーを吐く。
• そもそもコンパイラが中途半端。
  (mscorlib|scalaruntime|predef).dllに
  存在しないパッケージやクラスを参照しよう
  とすると、「そんなもんねーよ」って怒る。
まとめなど

今後の展開




   え、今後も続けるの・・・?
まとめなど

今後の展開
• とりあえずDLLをビルドしてみただけなので、
  簡単なアプリまでは作ってみたい気はする。
• SilverlightアプリのEntryPoint(起動時に
  キックされる部分)だけを橋渡しするように
  ごにょってしまえば、だいたいPure-Scalaで
  Silverlightを書けるようになるはず。
• Scala製Silverlightプレゼンツールぐらいは
  作れるんじゃね?技術的な目処はついてる。
Scala×Silverlight

本セッションの総括
Scala×Silverlight

本セッションの総括




        MSILたのしいです。
ご清聴ありがとうございました。

Scala×silverlight