V8 JavaScriptエンジン - 変数の追加
Rev.1を表示中。最新版はこちら。
V8 JavaScriptエンジンの組み込み - 変数の追加
V8 JavaScriptエンジンの組み込みの続き。今度はグローバル領域への変数の追加をしてみる。追加する変数は以下のとおり。
変数名:LogCalledCount
内容:log()を呼び出した回数がカウントされる。
Read/Writeともに可。
変数を追加する場合は、変数名とそれに対応するアクセサ(setter,getter)をオブジェクトテンプレートに登録する。
#include <v8.h> #include <iostream> #include <string> using namespace v8; static void read_file(std::istream& ifs, std::string &content) { content = ""; std::string t; while (!ifs.eof()) { getline(std::cin, t); content += t + "\n"; } } // log()呼び出し回数カウント用の変数 static int log_called_count = 0; // log()が呼ばれた時のコールバックルーチン static Handle<Value> log_callback(const Arguments& args) { if (args.Length() < 1) return v8::Undefined(); HandleScope scope; Handle<Value> arg = args[0]; String::Utf8Value value(arg); std::cout << "log: " << *value << std::endl; log_called_count++; return v8::Undefined(); } // LogCalledCount変数のアクセサ Handle<Value> get_log_called_count(Local<String> property, const AccessorInfo& info) { return Integer::New(log_called_count); } void set_log_called_count(Local<String> property, Local<Value> value, const AccessorInfo& info) { log_called_count = value->Int32Value(); } int main(int argc, char* argv[]) { std::string js_str; read_file(std::cin, js_str); // Create a stack-allocated handle scope. HandleScope handle_scope; Handle<ObjectTemplate> global = ObjectTemplate::New(); // log()関数のコールバックを指定 global->Set(String::New("log"), FunctionTemplate::New(log_callback)); // LogCalledCount変数のアクセサを指定 global->SetAccessor(String::New("LogCalledCount"), get_log_called_count, set_log_called_count); // Create a new context. //Persistent<Context> context = Context::New(); Persistent<Context> context = Context::New(NULL, global); // 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(js_str.c_str()); // 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("%s\n", *ascii); return 0; }
上記のソースでは、変数名"LogCalledCount"に対し、アクセサget/set_log_called_count()を登録している。JavaScriptからLogCalledCount変数にアクセスすると、アクセサ関数が呼び出される。アクセサ関数では、log()の呼び出し回数をカウントしているlog_called_count変数をRead/Writeしている。
以下のtest3.jsを読み込んで実行してみる。
test3.js
log("LogCalledCount:" + LogCalledCount); log("LogCalledCount:" + LogCalledCount); LogCalledCount = 0; // reset log("LogCalledCount:" + LogCalledCount);
実行結果
# ./a.out < test3.js log: LogCalledCount:0 log: LogCalledCount:1 <-- log()が呼ばれたのでインクリメントされている。 log: LogCalledCount:0 <-- 0を書き込んだので、カウンタが戻っている。 undefined
log()の呼び出し回数がカウントされ、Read/Writeできていることが確認できる。
次にグローバル空間にオブジェクトを追加してみる。
つづく。