ふと思いついて、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を読み始めたから。