Beispiel #1
0
void timer_print(const char *what, uint64_t usec)
{
#if DEBUG > 1
	uint64_t a = usec / 1e6;
	uint64_t b = usec - a * 1e6;

	__debug_print("TIMER", "%s: %11u.%06u\n", what, (unsigned int)a, (unsigned int)b);
#endif
}
Beispiel #2
0
/*
 *  VM_Execute
 *
 *  Description: the VM f****r
 */
void VM_Execute(vm_object_file_t * vm_obj, char * data, int entry)
{
#ifdef DEBUG_VM
	freopen("c:/stdout.txt", "w+", stdout);
#endif
	long int i;//instruction pointer;
	long int bp;//base (stack level) pointer
	long int num;//data offset
	char * code;//bytecode pointer

#define __i i
#define __num num
#define __code code

	long int opcode;//current opcode(instruction)
	long int curr_proc;//current procedure
	long int old_num;//temporary copy of 'num'

	static int callers_stack[512];
	static int callers_stack_level = 0;
#define CALLER_PUSH(n) callers_stack[callers_stack_level++] = n
#define CALLER_POP(n) n = callers_stack[--callers_stack_level]

	code = vm_obj->code;
	curr_proc = entry;
	if ( curr_proc < 0 )
		return;
	i = vm_obj->proc_index[curr_proc];
	bp = vm_obj->stack_start;

	bframe.bp = bp + vm_obj->proc_sizes[curr_proc];
	bframe.data = data;

	while ( 1 )
	{
		opcode = code[i++];

		if ( (opcode & (LOCAL-1)) < PUSHI )
		{
			//get the general argument 
			//(could be anything: constant, address, field offset in record )
			num = *(int *)(code + i);
			//save it for later (in case it's a "by ref" record)
			old_num = num;
			//check to see if it's a local variable
			//if it is, add the local stack level
			//note: "by ref" vars will also take the if
			if ( (opcode & LOCAL) == LOCAL )
				num += bp;
			//check to seek if it's a "by ref" value
			if ( (opcode & FORMAL ) == FORMAL )
			{
				//a "by ref" value stores only an offset, so make "num"
				//the value of the real variable witch it initially pointed to !
				num = *(int*)(data + num - old_num);
				//we needed to substract old_num from the address just in case
				//num originally was a field offset
				//now add old_num again (this time we need the field offset)
				num += old_num;
				//note: for ordinary vars. old_num will be 0 so will 
				//get some redundancy
			}

			switch ( opcode & (LOCAL-1) )
			{
			case PUSHIV:
			//case PUSHFV:
				__debug_print("pushv", code[i+4])
				__asm mov edx, dword ptr [data]
				__asm add edx, dword ptr __num
				__asm push dword ptr [edx]
				break;
			case aPUSHIV:
			//case aPUSHFV:
				__debug_print("_pushv", code[i+4])
				__asm pop eax
				__asm add dword ptr __num, eax
				__asm mov edx, dword ptr [data]
				__asm add edx, dword ptr __num
				__asm push dword ptr [edx]
				break;
			case PUSHSV:
				__debug_print("pushsv", code[i+4])
				__asm mov ecx, dword ptr __code
				__asm add ecx, dword ptr __i
				__asm push dword ptr __num //offset
				__asm push dword ptr [ecx+5] //strlen
				__asm add dword ptr __i, 4
				break;
			case aPUSHSV:
				__debug_print("_pushsv", code[i+4])
				__asm mov ecx, dword ptr __code
				__asm add ecx, dword ptr __i
				__asm pop eax
				__asm add dword ptr __num, eax
				__asm push dword ptr __num //offset
				__asm push dword ptr [ecx+5] //strlen
				__asm add dword ptr __i, 4
				break;

			case PUSHA:
				__debug_print("pusha", num)
				__asm push dword ptr __num
				break;
			case aPUSHA:
				__debug_print("_pusha", num)
				__asm pop eax
				__asm add dword ptr __num, eax
				__asm push dword ptr __num
				break;

			case POPI:
			//case POPF:
			//case POPA:
				__debug_print("pop", code[i+4])
				__asm mov edx, dword ptr [data]
				__asm add edx, dword ptr __num
				__asm pop eax
				__asm mov dword ptr [edx], eax
				break;
			case aPOPI:
			//case aPOPF:
			//case aPOPA:
				__debug_print("_pop", code[i+4])
				__asm mov edx, dword ptr [data]
				__asm add edx, dword ptr __num
				__asm pop eax
				__asm pop ebx
				__asm mov dword ptr [edx+ebx], eax
				break;
			case POPS:
				__debug_print("pops", code[i+4])
				__asm mov ecx, dword ptr [esp] //pop ecx

				__asm mov eax, dword ptr [esp+4] //pop eax
				__asm mov edx, dword ptr [data]
				__asm lea esi, dword ptr [edx+eax]
				__asm mov eax, dword ptr __num
				__asm lea edi, dword ptr [edx+eax]

				__asm cld
				__asm rep movsb

				__asm add esp, 8 //clean the stack
				__asm add dword ptr __i, 4
				break;
			case aPOPS:
				__debug_print("_pops", code[i+4])
				__asm mov eax, dword ptr [esp+8]
				__asm add dword ptr __num, eax

				__asm mov ecx, dword ptr [esp] //pop ecx

				__asm mov eax, dword ptr [esp+4] //pop eax
				__asm mov edx, dword ptr [data]
				__asm lea esi, dword ptr [edx+eax]
				__asm mov eax, dword ptr __num
				__asm lea edi, dword ptr [edx+eax]

				__asm cld
				__asm rep movsb

				__asm add esp, 12 //clean the stack
				__asm add dword ptr __i, 4
				break;

			default:
				return;
			}
			i += 5;
		}
		else
		switch ( opcode & (LOCAL-1) )