(基本だらだら進行で、過程を追記していきます)
Google Chrome が出ました
Google Chrome で JavaScript エンジンが刷新されたということで、その JavaScript エンジン V8 についていろいろ調べてみようと思います。
Issues - v8 - V8 JavaScript Engine - Monorail
ビルドしてみる
まず、 svn からソースを持ってくる
$ svn co http://v8.googlecode.com/svn/trunk/ v8
おおお。以外と少ない
で、 trunk の中に入って
$ cd v8
scons でビルド(scons が入ってない人は、 port や apt-get で入れる)
$ scons scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... g++ -o obj/release/third_party/jscre/pcre_compile.o -c -ansi -w -fno-strict-aliasing -O2 -fno-rtti -fno-exceptions -ansi -w -fno-strict-aliasing -O2 -DENABLE_LOGGING_AND_PROFILING -DSUPPORT_UTF8 -DNO_RECURSE -DSUPPORT_UCP src/third_party/jscre/pcre_compile.cpp : : ranlib libv8.a
libv8.a が出来た。ここまでは順調
Shell をビルドしてみる
scons のオプションを見る
$ scons --help scons: Reading SConscript files ... scons: done reading SConscript files. mode: compilation mode (debug, release) default: release actual: release sample: build sample (shell, process) default: actual: env: override environment settings (NAME1:value1,NAME2:value2) default: actual: toolchain: toolchain (gcc, msvc) default: gcc actual: gcc simulator: simulator (arm, none) default: none actual: none arch: arch (arm, ia32) default: ia32 actual: ia32 library: library (static, shared) default: static actual: static wordsize: wordsize (64, 32) default: 32 actual: 32 snapshot: snapshot (on, off) default: off actual: off os: os (linux, macos, win32) default: macos actual: macos
いろいろとあるが sample フラグで shell を作れるっぽいことが分かる
shell をビルドする
$ scons sample=shell scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... g++ -o shell obj/sample/shell/release/shell.o -L. -lv8 -lpthread scons: done building targets.
shell.o と libv8 と libpthread をリンクして完了。 shell というバイナリが出来た。
実行してみる。
$ ./shell V8 version 0.2.5 > for (var n in function () { return this } ()) print(n) n load quit print version > quit()
おおおおお。 JavaScript が動いた
shell のソースを見てみる
shell.cc をエディタで開く
$ vim samples/shell.cc
209 行くらいのシンプルなファイルだ。
とりあえず雰囲気だけ分かった。
Hello, world を雰囲気で書いてみる
雰囲気だけ分かったので、雰囲気で Hello, world してみる
// v8.h を読み込む #include <v8.h> v8::Handle<v8::Value> Print(const v8::Arguments& args); int main(int argc, char* argv[]) { // 準備 v8::HandleScope handle_scope; // グローバルオブジェクトの生成 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); // 関数名の生成 v8::Handle<v8::String> str_print = v8::String::New("print"); // 関数オブジェクトの生成 v8::Handle<v8::FunctionTemplate> fn_print = v8::FunctionTemplate::New(Print); // グローバルオブジェクトのプロパティに関数を設定 global->Set(str_print, fn_print); // グローバルオブジェクトから環境を生成 v8::Handle<v8::Context> context = v8::Context::New(NULL, global); // 環境からスコープを生成 v8::Context::Scope context_scope(context); // 実行する文字列を生成 v8::Handle<v8::String> str = v8::String::New("print('Hello, world!')"); // Undefined を生成(ファイル名がないから) v8::Handle<v8::Primitive> undefined = v8::Undefined(); // コンパイル v8::Handle<v8::Script> script = v8::Script::Compile(str, undefined); // 実行 v8::Handle<v8::Value> result = script->Run(); // 終了 return 0; } // 関数オブジェクト print の実体 v8::Handle<v8::Value> Print(const v8::Arguments& args) { v8::String::AsciiValue str(args[0]); printf("%s\n", *str); return v8::Undefined(); }
ビルドする(-L と -I は適宜)
$ g++ helloworld.cc -L. -lv8 -Isrc
おお。成功
$ ./a.out Hello, world!
おおおお。動いた
gdb で追いかけてみる
デバッグビルドする
$ scons mode=debug
こんどは、 libv8_g.a というファイルが出来た。
さっきの helloworld.cc のデバッグ版を作る
$ g++ -O0 -g helloworld.cc -L. -lv8_g -Isrc
で、 gdb コマンドで実行
$ gdb ./a.out GNU gdb 6.3.50-20050815 (Apple version gdb-768) (Tue Oct 2 04:07:49 UTC 2007) Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-apple-darwin"...Reading symbols for shared libraries .... done (gdb) b main Breakpoint 1 at 0x25c1: file helloworld.cc, line 33. (gdb) r Starting program: /Users/amachang/v8/a.out Reading symbols for shared libraries +++. done Breakpoint 1, main (argc=1, argv=0xbffff9b4) at helloworld.cc:33 33 v8::HandleScope handle_scope; (gdb) s v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:397 397 } (gdb) v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:395 395 HandleScope() : previous_(current_), is_closed_(false) { (gdb) 396 current_.extensions = 0; (gdb) 397 } (gdb) 0x00022ac1 in v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:397 397 } (gdb) main (argc=1, argv=0xbffff9b4) at helloworld.cc:35 35 v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New(); (gdb) v8::ObjectTemplate::New () at src/api.cc:824 824 return New(Local<FunctionTemplate>());
おおお