無料Wikiサービス | デモページ
Linuxなどのメモ書き

V8 JavaScriptエンジン - 変数の追加


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できていることが確認できる。


次にグローバル空間にオブジェクトを追加してみる。

つづく。


最終更新 2012/08/30 10:10:54 - kztomita
(2012/08/28 21:11:00 作成)