ふと思いついて、V8 JavaScript Engineを試したのでメモ。
参考にしたのは、I am Bad at Math の node.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を読み始めたから。