view 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 source

//
// 仮想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;
}