スクリプトエンジン の検索結果
本日、サイボウズラボにて、Shibuya.abc#1が開催され、無事終了致しました。色々と協力してくださったTAKESAKOさん、nishioさん、そして発表してくださった変態の方々、見に来てくださった変態の方々、本当にありがとうございました。予想以上に楽しかったと僕は感じてるんですがどうでしょう?なんだかんだ言って皆かなりABC的な話で盛り上がってましたね。以下簡単レポ。
Shibuya.abc#1 基調講演 - beinteractive
まず最初に僕の基調講演から。いきなりバイナリの話をして死者が出るといけないので、Tamarinで遊ぼう的な内容です。が、それが高じて遂にサーバーサイドActionScriptを実現してしまいました。詳しくは以下のスライド(PDF, 1.7MB)で。
スライド中に出てくる全ASソースは以下にあります。見所は、簡易Webフレームワークである、org.libspark.web.asファイルと、AMF通信のためにBlazeDSをガッツリ移植したamfディレクトリの中です。
Tamarin拡張に当たって書き換えたソースは以下にアップしてあります。
あ、ちなみにスライドの途中で出てくるabc.libspark.orgのアドレスですが、何かあると怖いので一旦全部削除してしまいました。すみません。でもちゃんと動いてました。
携帯電話で遊べる俺様言語を作ってあそぶ - クジラ飛行机さん
flasm, swfmill, kmyacc等を駆使してFlashを生成することにより、携帯で動くプログラミング言語環境を構築してしまおうという、クジラさんらしいなんともアグレッシブな内容。懇親会でちらっと話題に出てたけど、携帯プログラミングは教育に良いかもしれない。
葵Flashにも密かに期待。
FlashLite最適化バッドノウハウ - 鴨志田さん
FlashLiteの最適化について、サイズダウン & 高速化のふたつの観点から解説した、なんともShibuya.abcらしい素敵な発表。1バイトをも削るその心意気にニヤニヤ。
Flashアンチリバースエンジニアリング - TAKESAKOさん
Flashのリバースエンジニアリングを行う人が多い中、それを阻止するためのノウハウを解説した、実用的な発表。as2lookがお目見え。誰かas2unlockを以下略。
gnashであそぶ - gyuqueさん
GNUのオープンソースFlashPlayer、Gnashの紹介と、そのソースコードを利用してAS2バイナリをAS3上で動かすVMのデモ。すばらしす。codereposにソースがあるらしいので、作り込んできちんとしたスクリプトエンジンにしたら面白そう。
avmplus であそぶ - nitoyonさん
僕の発表に続き、avmplus拡張ネタで、jQueryのwindows版winQueryというとんでもない代物を作りましたというデモ。いろいろとすごかった。というか笑った。
以上簡単ではありますが、相当濃かったというのは伝わったかと思います。なんでみんなこんなにASバイナリ好きなんだ。素敵すぎる。
ちなみに動画も撮っていたみたいなので、wikiの方に近々nishioさんからリンクが貼られると思います。ニコ動にもアップされるらしいです。(追記)→されました
いやいやホント素敵な勉強会でした。果たして次はあるのだろうか!
「それActionScriptでやる必要あるの?」的なものをあえて実装したい身としては、やっぱりActionScript3でもスクリプトエンジン作りたいよね。で、やるからにはAS3だからこそ出来るモノを作りたい。
そうなると、実はもうやるべきことはほとんど決まってくる。それは、「言語仕様はECMAScript4で、ActionScriptByteCode(ABC)にコンパイルして、ネイティブ実行」。
ECMAScript4は、ご存知ActionScript3.0のベースとなってる言語仕様。
ActionScriptByteCode(ABC)ってのは、その名の通り、ActionScriptで使われてるバイトコード。AS3から採用。FlashやFlexでActionScriptをコンパイルすると、全てこのABCってヤツに変換されるわけです。フォーマットについては、Tamarin参照。つまり、ABCコンパイラを作っておけば、ASとの高い互換性を確保できると。
で、このABCをネイティブ実行。ASでそんなこと出来るの?って思うかもしれないけど、理論的には可能なはず。ABCをSWFで包んで、Loaderに読み込ませて、ApplicationDomainからClassをgetDefinitionすれば、めでたく本物のクラスが取り出せる(はず)。これを利用して、ABCを本物のAVM上で実行する。ただ、念のために自前のAVMも作っておいた方がいいかなぁ。
これが実現できると、まさに「ActionScript3.0上でActionScript3.0が動く」環境が整う。動的コンパイルとか、アスペクトなんかに応用できるんじゃないかなー。
と、妄想を垂れ流しつつ、いつやるかは分からないで終了。やるならSparkのプロジェクトとしてやります。
何かアクセスが増えてると思ったら、fladdict.netさんからトラックバックが来てた。スクリプトエンジンで(一部の)ビルトインクラスのnewが上手くいかないので汎用ファクトリを作ろうという話です。
何気なしに考えてたら、(あまり美しくは無いですが)バイトコード直書き(Cのインラインアセンブラみたいなの)で実現できることに気付いたので書いておきます。
まず、次のコードを1フレーム目とかに書いておきます。長いですが、区切ったり改行入れたりしないで下さい。
__bytecode__("8E2E00637265617465496E7374616E636546726F6D537472696E67000200062A0001706174680002706172616D73005B0096020004011C8701000317960A000402006C656E677468004e8701000417960500070000000087010005179604000405040448129d02001800960400040204054e9602000405508701000517990200daff9605000404040303533e");
これを書くと、createInstanceFromString()というメソッドが定義されます。ので、次のようにして使います。
import flash.display.BitmapData;
var b:BitmapData = createInstanceFromString("flash.display.BitmapData", [10, 10]);
第1引数にクラスのコンストラクタへのパスを文字列で、第2引数にコンストラクタに渡す引数を配列にして呼び出します(要素は何個でも大丈夫です)。すると、オブジェクトが生成されて返ってきます。以上。
実際どんなことをやっているか、flasmで見やすくしたバイトコードを載せておきます。
function2 createInstanceFromString (r:1='path', r:2='params') ()
push r:path
getVariable
setRegister r:3
pop
push r:params, 'length'
getMember
setRegister r:4
pop
push 0
setRegister r:5
pop
label1:
push r:5, r:4
lessThan
not
branchIfTrue label2
push r:params, r:5
getMember
push r:5
increment
setRegister r:5
pop
branch label1
label2:
push r:4, r:3, UNDEF
newMethod
return
end // of function createInstanceFromString
要は配列の要素を push してスタックに積んで、 newMethod を呼んでるだけです。
追記
上のコードバグってました。ストリングからクラスのインスタンスを作る 訂正をご覧下さい。
昨日のエントリがfladdict.netさんで紹介されて浮かれております。という訳で、続きです。
そもそも、どういう時にスクリプトエンジンが必要になるのか?という所ですが、元々このエンジンはゲームを製作しやすくしようプロジェクト(今勝手に命名)の一環として作ったもので、やはりゲーム系なんかで役に立ちそうです。
とりあえず、このスクリプトエンジンの特徴と仕様を書いてから、いくつか使用例を挙げてみるので、そこからスクリプトエンジンの使い道を探ってみてください(笑
- スクリプトエンジンの動作サンプル
- スクリプトエンジンのコード一式(リファクタリングしきれてません。すいません)
JavaScriptやActionScriptなど、ECMAScript系のスクリプトには、evalという、引数の文字列をスクリプトとして実行するメソッドがあります。・・・あるはずなんですが、ActionScriptではevalはマトモに動きません。
というわけで、この辺でも書いた、ActionScript上で動作するスクリプトエンジンを作りました。やっと完成した・・・。時間かかった・・・。
動作サンプルはこれです。基本的に文法はECMA-262 3rd Editionにのっとってます。ActionScript1的な感じ。
独自拡張として、スクリプト中に
suspend;
と書くと、一旦Flash側に制御が戻るようになっています。そして、Flash側が再びスクリプトを実行したときに、中断したポイントから再開されます。(マイクロスレッド)
上のサンプルでは、Flash側に
this.onEnterFrame = funciton () {
virtualMachine.execute();
}
と書いているので(少し略してますが)、スクリプトを
loop {
trace('Hello');
suspend;
}
と書けば(loopは無限ループ構文)、毎フレームHelloが出力されることになります。
とりあえず、体が休息を求めているので詳しいことはまた今度書きます。それまで上のサンプルを弄って待っててください(笑
出来たばっかりでごちゃごちゃしてますけどコードも置いておきますので興味ある人はどうぞ。
// コード
var code:String = [
"loop {",
" trace('Hello');",
" suspend;",
"}"
].join("\n");
// コンパイル
var parser:IParser = new Parser(new Scanner(code));
var vm:VirtualMachine = new VirtualMachine();
vm.setByteCode(parser.parse());
// trace関数のエクスポート
vm.getGlobal().trace = trace;
// 実行
this.onEnterFrame = function () {
vm.execute();
}
みたいな感じで実行できます。
この辺からのOO再考の流れで、ここ2週間ぐらい色々な技術やらプロジェクトやら本やらを調べまわってます。
とりあえず、今後メインで開発していきたいなー、と考えているのは、
- ActionScript2.0/3.0用ゲーム開発フレームワーク「Spark」
- PHP用Webアプリケーションフレームワーク「Skelwork(仮)」
- PHP用テンプレートエンジン「VisualFusion2」
です。なんとも枠だらけ。
とりあえず、今日はSpark用のアイデアを書き残しておきます。
- レイヤー
- タスク
- シーン管理
- 3D / Video / Bitmap
- データ暗号化
- スクリプトエンジン
- デバッグ機能
- ネットワーク関係
- DI / AOP
レイヤーってのは、MCだとかSpriteだとかよりはもう少し抽象度が高いというか、ゲーム向きな描画単位のコト。描画周りにおけるFlash特有のことは出来るだけ考えずにゲームを組めるようにしたい。
タスク・シーン管理は前々から散々言ってるヤツ。今のよりはもうちょっとスマートにしたいなぁ。ビューとロジックの分離も取り入れるかもしれない。
3DとかBitmapとか、今までのFlashであまり弄られてこなかった分野も切り開けると良いなという願望。(Bitmap直弄りの派手なエフェクトとかね)
データ暗号化は、ちょっと商用チックな話。画像なんかのデータを、外部化&暗号化して、AS3のByteArrayに読み込んで復号後、Loader#loadBytesで読ませるという構想。暗号化とは違うけど、対応していない画像ファイル形式をコンバートするとかも。
実は一番力を入れたいかもしれない、スクリプトエンジン。Flashでスクリプトエンジン?と思うかもしれないけれど、例えば敵の動きなんかを外部化しておければ、再パブリッシュ無しに変更をチェックできる。何より、Flashを持っていない人でもゲーム開発が可能に。
デバッガはFlashにも標準で備わってるけど、それよりもこのフレームワーク向きなLocalConnectionデバッガとデバッグ機能。例えば、実行しているタスクのリストを表示したり、エディットしたり、途中のシーンから開始したり、1フレームごとに実行できたり。
ネットワーク関係は、FlashRemotingのラッパーと、AS3のSocketを使った汎用データ通信フォーマットとか。
んで、最終的に各コンポーネントは、流行のDIコンテナで管理する。DIの考え方はゲーム開発でも結構有効なんじゃないかと思ってます。画面表示を行うタスクに、使用するグラフィックをInjectする、なんてのも面白いかもしれない。
