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;
+}