Google Chrome の JavaScript エンジン V8 を試す


Google Chrome が出ました

Google ChromeJavaScript エンジンが刷新されたということで、その JavaScript エンジン V8 についていろいろ調べてみようと思います。
Issues - v8 - V8 JavaScript Engine - Monorail


まず、 svn からソースを持ってくる

$ svn co 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)

env: override environment settings (NAME1:value1,NAME2:value2)

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)
> quit()

おおおおお。 JavaScript が動いた

shell のソースを見てみる をエディタで開く

$ vim samples/

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++ -L. -lv8 -Isrc


$ ./a.out
Hello, world!


gdb で追いかけてみる


$ scons mode=debug

こんどは、 libv8_g.a というファイルが出来た。
さっきの のデバッグ版を作る

$ g++ -O0 -g -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, 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
33	  v8::HandleScope handle_scope;
(gdb) s
v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:397
397	  }
v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:395
395	  HandleScope() : previous_(current_), is_closed_(false) {
396	    current_.extensions = 0;
397	  }
0x00022ac1 in v8::HandleScope::HandleScope (this=0xbffff940) at v8.h:397
397	  }
main (argc=1, argv=0xbffff9b4) at
35	  v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
v8::ObjectTemplate::New () at src/
824	  return New(Local<FunctionTemplate>());