V8 JavaScript Engine

ふと思いついて、V8 JavaScript Engineを試したのでメモ。

参考にしたのは、I am Bad at Mathnode.jsとは何か(4)

macでmacportsの環境で試す。

バイナリパッケージは無いので、ソースコードからビルドする。

ビルドするのに、sconsを使用するので、インストール。

$ sudo port install scons

ソースコードを持ってきて、ビルド

$ svn checkout http://v8.googlecode.com/svn/trunk/ v8
$ cd v8
$ scons arch=x64

これで、ヘッダがv8/includeの下に、それとライブラリがv8/libv8.aに出来上がる。

まず、Hello Worldの出力プログラム

#include <v8.h>

using namespace v8;

int main(int argc, char* argv[]) {

// Create a stack-allocated handle scope.
HandleScope handle_scope;

// Create a new context.
Persistent<Context> context = Context::New();

// Enter the created context for compiling and
// running the hello world script.
Context::Scope context_scope(context);

// Create a string containing the JavaScript source code.
Handle<String> source = String::New("'Hello' + ', World!'");

// Compile the source code.
Handle>Script< script = Script::Compile(source);

// Run the script to get the result.
Handle<Value> result = script->Run();

// Dispose the persistent context.
context.Dispose();// Convert the result to an ASCII string and print it. String::AsciiValue ascii(result); printf("%sn", *ascii); return 0; }

どっかにhello_world.cppとして保存して、

$ g++ hello_world.cpp -I ../v8/include -o hello_world ../v8/libv8.a -lpthread

てな感じで、ビルド。include とlibv8.aのパスは適宜変更してください。

$ ./hello_world
hello,World!

できた。

次にjsファイルを読んで実行するサンプル

#include <v8.h>

using namespace v8;

Handle<String> ReadFile(const char* name) {
  FILE* file = fopen(name, "rb");
  if (file == NULL) return Handle<String>();

  fseek(file, 0, SEEK_END);
  int size = ftell(file);
  rewind(file);

  char* chars = new char[size + 1];
  chars[size] = '';
  for (int i = 0; i < size;) {/P
    int read = fread(&chars[i], 1, size - i, file);
    i += read;
  }
  fclose(file);
  Handle<String> result = String::New(chars, size);
  delete[] chars;
  return result;
}

int main(int argc, char* argv[]) {

  Persistent<Context> context = Context::New();
  Context::Scope context_scope(context);

  // 引数が渡されなかったらエラーで終了
  if(argc < 2)  {
    fprintf(stderr, "script was not specified.n");
    return 1;
  }
  HandleScope hs;
  // 引数に指定されたファイルを読み込む
  Handle<String> source = ReadFile(argv[1]);

  Handle<Script> script = Script::Compile(source);
  Handle<Value> result = script->Run();

  String::AsciiValue ascii(result);
  printf("%sn", *ascii);

  context.Dispose();
  return 0;
}

こいつをreadjs.cppと保存して、適当にjsファイルを作って、

$ g++ readjs.cpp -I ../v8/include -o readjs ../v8/libv8.a -lpthread
$ ./readjs sample.js
3

ということで、JSを叩くのはとっても簡単。

次回はlibevを使ったイベントループ実装編の予定。

まだ、投稿されていないみたい。楽しみ。。。

次に、IT戦記Google ChromeのJavaScriptエンジン V8を試す

sconsのオプションを見る

$ scons –help

これで、ずらずらーっとどんなビルドオプションがあるのかがわかる模様。

sample: build sample (shell, process, lineprocessor)
   default:
   actual:

なるほど。

$ scons arch=x64 sample=shell
$ scons arch=x64 sample=process
$ scons arch=x64 sample=lineprocessor

でビルド。archを忘れて、ほぼ全部ビルドしなおしになって、びっくりした。

この中でshellが一番おもしろいかと。

いや、なんで、こんなことを始めたかというと、Node.jsを読み始めたから。

コメントを残す

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください