Mercurial > hg > Members > nobuyasu > SampleSource
diff WindowsOnly/WinScript2/vm.cpp @ 0:db40c85cad7a default tip
upload sample source
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 09 May 2011 03:11:59 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WindowsOnly/WinScript2/vm.cpp Mon May 09 03:11:59 2011 +0900 @@ -0,0 +1,55 @@ +// +// 仮想CPU +// +// switch-caseでの実装例 +// +// (c)2008 Chihiro.SAKAMOTO HyperWorks +// +#include <exception> +#include "vm.h" + +// 実行 +int vm::vcpu::internal_call(data &program, int entry, int *arg, int narg) +{ + if (program.entry_point_[entry] < 0) // エントリーポイントが無い + return 0; + + command_ = program.command_; // プログラム格納位置 + text_buffer_ = program.text_buffer_; // テキストデータ格納位置 + command_size_ = program.command_size_; // プログラムの大きさ + text_size_ = program.text_size_; // データの大きさ + + global_value.resize(program.value_size_); // 外部変数テーブル確保 + command_ptr_ = command_ + program.entry_point_[entry]; // プログラムカウンター初期化 + + // スクリプトをcall + for (int i=0; i<narg; i++) { + push(arg[i]); // 引数をpush + } + push(narg); // 引数カウントをpush + push(0); // stack_baseの初期値をpush + push(0); // プログラム終了位置をpush + stack_base = stack.size(); // スタック参照位置初期化 + + try { + int op; + while ((op = *command_ptr_++) != VM_HALT) { // Haltするまでループ + switch (op) { + #define VM_SWITCHTABLE + #include "vm_code.h" + #undef VM_SWITCHTABLE + } + } + } + catch (const std::exception &e) { + std::cerr << "例外発生(" << e.what() << ")" << std::endl; + return -1; + } + if (stack.empty()) { // void型関数 + return 0; + } + + int result = top().i_; // 関数戻り値 + pop(); + return result; +}