Ejemplo n.º 1
0
Archivo: utility.c Proyecto: lenywv/xsm
struct address translate(int virtual_addr) {
	if (mode == USER_MODE) {
		struct address resultant_addr;
		int page_entry;
		resultant_addr.page_no = -1;
		resultant_addr.word_no = -1;
		if (getType(reg[PTBR_REG]) == TYPE_STR) {
			raiseException(newException(EX_ILLMEM, "Illegal Register Value.\n", 0));
			return resultant_addr;
		}
		page_entry = getInteger(reg[PTBR_REG]) + (virtual_addr / PAGE_SIZE) * 2;
		if (page[(page_entry+ 1 ) / PAGE_SIZE].word[(page_entry + 1) % PAGE_SIZE][1] == VALID ) { 
			resultant_addr.page_no = getInteger(page[page_entry / PAGE_SIZE].word[page_entry % PAGE_SIZE] );
			resultant_addr.word_no = virtual_addr % PAGE_SIZE;
			page[(page_entry + 1) / PAGE_SIZE].word[(page_entry + 1) % PAGE_SIZE][0] = REFERENCED;
		}
		else raiseException(newException(EX_PAGEFAULT, "Page Fault.\n", virtual_addr / PAGE_SIZE));
		return resultant_addr;
	} else {
		struct address resultant_addr;
		resultant_addr.page_no = virtual_addr / PAGE_SIZE;
		resultant_addr.word_no = virtual_addr % PAGE_SIZE;
		return resultant_addr;
	}
}
Ejemplo n.º 2
0
Archivo: utility.c Proyecto: lenywv/xsm
int performIRET() {
	if (mode == USER_MODE) {
		raiseException(newException(EX_ILLINSTR, "Call to Privileged Instruction IRET in USER mode", 0));
		return 0;
	}
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	mode = USER_MODE;
	Address T = translateAddress(getInteger(reg[SP_REG]));
	if (T.page == -1 && T.word == -1) {
		mode = KERNEL_MODE;
		return 0;
	}
	char * value = getWordFromAddress(T);
	if (getType(value) == TYPE_STR) {
		mode = KERNEL_MODE;
		raiseException(newException(EX_ILLMEM, "Illegal return address", 0));
		return 0;
	}
	int result = getInteger(value);
	if (result < 0 || result >= getInteger(reg[PTLR_REG]) * PAGE_SIZE) {
		mode = KERNEL_MODE;
		raiseException(newException(EX_ILLMEM, "Illegal return address", 0));
		return 0;
	}
	storeInteger(reg[IP_REG], result);
	storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1);
	return 1;
}
Ejemplo n.º 3
0
Archivo: utility.c Proyecto: lenywv/xsm
int performPop(int X, int flagX) {
	char * value;
	Exception e;
	Address T = translateAddress(getInteger(reg[SP_REG]));
	if (T.page == -1 && T.word == -1) return 0;
	switch (flagX) {
		case REG:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}				
			value = getWordFromAddress(T);
			strcpy(reg[X], value);
			storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1);
			return 1;
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
			return 0;
			break;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
			return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal Operand", 0));
			return 0;
			break;
	}
}
Ejemplo n.º 4
0
Archivo: utility.c Proyecto: lenywv/xsm
int performIN(int X, int flagX) {
	int value;
	Exception e;
	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case PTBR:
		case PTLR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
			return 0;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
			return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand.", 0));
			return 0;
			break;
	}
	char input[WORD_SIZE];
	scanf("%s", input);
	FLUSH_STDIN(input);
	input[WORD_SIZE - 1] = '\0';
	strcpy(reg[X], input);
	return 1;
}
Ejemplo n.º 5
0
Archivo: utility.c Proyecto: lenywv/xsm
/*
 * Gets the instruction pointed by IP, to the argument
 * Return 0 on success
 * Returns -1 on error after setting IP to exception handler
 */
int getInstruction(char *instruction) {
	struct address translatedAddr;
	int len;
	bzero(instruction, WORD_SIZE * WORDS_PER_INSTR);
	if (getType(reg[IP_REG]) == TYPE_STR) {	
		raiseException(newException(EX_ILLMEM, "Illegal IP value. Not an address.\n", 0));
		return -1;
	}
	if (mode == USER_MODE && getType(reg[PTLR_REG]) == TYPE_STR) {	
		raiseException(newException(EX_ILLMEM, "Illegal PTLR value.\n", 0));
		return -1;
	}
	if (getInteger(reg[IP_REG]) < 0 || getInteger(reg[IP_REG]) + 1 >= SIZE_OF_MEM) {
		raiseException(newException(EX_ILLMEM, "IP Register value out of bounds.\n", 0));
		return -1;
	}
	if (mode == USER_MODE) {
		if (getInteger(reg[IP_REG]) < 0 || getInteger(reg[IP_REG]) + 1 >= getInteger(reg[PTLR_REG]) * PAGE_SIZE) {
			printf("%d", getInteger(reg[IP_REG]));
			raiseException(newException(EX_ILLOPERAND, "Illegal IP Access.\n", 0));
			return -1;
		}
	}
	translatedAddr = translate(getInteger(reg[IP_REG]));
	if (translatedAddr.page_no == -1 && translatedAddr.word_no == -1) return -1;
	strcpy(instruction, page[translatedAddr.page_no].word[translatedAddr.word_no]);
	translatedAddr = translate(getInteger(reg[IP_REG]) + 1);
	if (translatedAddr.page_no == -1 && translatedAddr.word_no == -1) return -1;
	len = strlen(instruction);
	instruction[len]=' ';
	instruction[len + 1]='\0';
	strcat(instruction, page[translatedAddr.page_no].word[translatedAddr.word_no]);
	return 0;
}
Ejemplo n.º 6
0
Archivo: utility.c Proyecto: lenywv/xsm
int performINT(int X, int flagX) {
	if (mode == KERNEL_MODE) {
		raiseException(newException(EX_ILLINSTR, "Cannot call INT in KERNEL Mode", 0));
		return 0;
	}
	if (flagX != NUM) {
		raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
		return;
	}
	invokeInterrupt(X);
	return 1;
}
Ejemplo n.º 7
0
Archivo: utility.c Proyecto: lenywv/xsm
Exception isSafeState2() {
	if (getType(reg[SP_REG]) == TYPE_STR || getType(reg[BP_REG]) == TYPE_STR || getType(reg[PTLR_REG]) == TYPE_STR
		|| getType(reg[PTBR_REG]) == TYPE_STR) {
		return newException(EX_ILLMEM, "Illegal Register value", 0);
	}
	if (getInteger(reg[PTBR_REG]) < 0 || getInteger(reg[PTBR_REG]) >= SIZE_OF_MEM) {
		return newException(EX_ILLMEM, "Illegal address access.\n PTBR value is out of bounds.", 0);
	}
	if (getInteger(reg[PTLR_REG]) < 0 || getInteger(reg[PTLR_REG]) >= SIZE_OF_MEM) {
		return newException(EX_ILLMEM, "Illegal address access.\n PTLR value is out of bounds.", 0);
	}
	if (getInteger(reg[SP_REG]) + 1 < 0) {
		return newException(EX_ILLMEM, "Stack underflow\n", 0);
	}
	if (getInteger(reg[SP_REG]) >= SIZE_OF_MEM || (mode == USER_MODE && getInteger(reg[SP_REG]) >= getInteger(reg[PTLR_REG]) * PAGE_SIZE)) {
		return newException(EX_ILLMEM, "Stack overflow\n", 0);
	}
	if (getInteger(reg[BP_REG]) < 0) {
		return newException(EX_ILLMEM, "Negative Value for BP Register\n", 0);
	}
	if (getInteger(reg[BP_REG]) >= SIZE_OF_MEM || (mode == USER_MODE && getInteger(reg[BP_REG]) >= getInteger(reg[PTLR_REG]) * PAGE_SIZE)) {
		return newException(EX_ILLMEM, "BP Register Value out of bounds\n", 0);
	}
	return newException(EX_NONE, "", 0);	
}
Ejemplo n.º 8
0
Archivo: utility.c Proyecto: lenywv/xsm
int performPush(int X, int flagX) {
	Address T = translateAddress(getInteger(reg[SP_REG]) + 1);
	if (T.page == -1 && T.word == -1) return 0;
	Exception e;

	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case IP:
		case PTBR:
		case PTLR:
		case EFR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			if (storeWordToAddress(T, reg[X])) {
				storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) + 1);
				return 1;
			} else return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal Operand", 0));
			return 0;
			break;
	}
}
    void NSFThread::handleException(const std::exception& exception)
    {
        // NSFExceptionContext maintains exception as a reference, so use two statements for proper scoping
        std::runtime_error newException(getName() + " thread exception: " + exception.what());
        NSFExceptionContext newContext(this, newException);

        ExceptionActions.execute(newContext);
        NSFExceptionHandler::getExceptionHandler().handleException(newContext);
    }
Ejemplo n.º 10
0
Archivo: utility.c Proyecto: lenywv/xsm
Exception isRegisterInaccessible(int r) {
	if (r < 0 || r > (NO_USER_REG + NO_SYS_REG + NO_TEMP_REG + NO_SPECIAL_REG)) {
		return newException(EX_ILLOPERAND, "Invalid Register Provided", 0);
	}
	//	User Register
	if (r >= R0 && r < R0 + NO_USER_REG) return newException(EX_NONE, "", 0);
	//	System Register
	if (r >= S0 && r < S0 + NO_SYS_REG + NO_TEMP_REG) {
		if (mode == KERNEL_MODE) return newException(EX_NONE, "", 0);;
		return newException(EX_ILLOPERAND, "Illegal Register Access in User Mode", 0);
	}
	//	Special Register
	if (mode == KERNEL_MODE) return newException(EX_NONE, "", 0); 
	if (r == SP_REG || r == BP_REG) return newException(EX_NONE, "", 0);
	if (r == PTBR_REG) return newException(EX_ILLOPERAND, "Illegal Register Access in User Mode -> {PTBR}", 0);
	if (r == PTLR_REG) return newException(EX_ILLOPERAND, "Illegal Register Access in User Mode -> {PTLR}", 0);
	if (r == IP_REG) return newException(EX_ILLOPERAND, "Illegal Register Access in User Mode -> {IP}", 0);
	if (r == EFR_REG) return newException(EX_ILLOPERAND, "Illegal Register Access in User Mode -> {EFR}", 0);
}
Ejemplo n.º 11
0
Archivo: utility.c Proyecto: lenywv/xsm
int performMOV(int X, int flagX1, int flagX2, int Y, int flagY1, int flagY2, char * value) {
	char * resolvedValue = resolveOperand(Y, flagY1, flagY2, value);
	if (resolvedValue == NULL) return 0;
	if ((flagY1 == MEM_DIR_REG || flagY1 == MEM_DIR_SP || flagY1 == MEM_DIR_BP || flagY1 == MEM_DIR_PTBR || flagY1 == MEM_DIR_PTLR
		|| flagY1 == MEM_DIR_IN) && (flagX1 == MEM_DIR_REG || flagX1 == MEM_DIR_SP || flagX1 == MEM_DIR_BP || flagX1 == MEM_DIR_PTBR
		|| flagX1 == MEM_DIR_PTLR || flagX1 == MEM_DIR_IN)) {
		raiseException(newException(EX_ILLOPERAND, "Illegal Operands", 0));
		return 0;
	}
	return (storeValue(X, flagX1, flagX2, resolvedValue));
}
Ejemplo n.º 12
0
Archivo: utility.c Proyecto: lenywv/xsm
int isSafeState() {
	if (getType(reg[SP_REG]) == TYPE_STR || getType(reg[BP_REG]) == TYPE_STR || getType(reg[PTLR_REG]) == TYPE_STR) {
		raiseException(newException(EX_ILLMEM, "Illegal Register Value.\n", 0));
		return 0;
	}
	if (getInteger(reg[PTLR_REG]) < 0 || getInteger(reg[PTLR_REG]) >= SIZE_OF_MEM) {
		raiseException(newException(EX_ILLMEM, "Illegal address access.\n PTLR value is out of bounds.\n", 0));
		return 0;
	}
	if (getInteger(reg[SP_REG]) + 1 < 0) {
		raiseException(newException(EX_ILLMEM, "Stack underflow.\n", 0));
		return 0;
	}
	if (getInteger(reg[SP_REG]) >= SIZE_OF_MEM || (mode==USER_MODE && getInteger(reg[SP_REG]) >= getInteger(reg[PTLR_REG]) * PAGE_SIZE)) {
		raiseException(newException(EX_ILLMEM, "Stack overflow.\n", 0));
		return 0;
	}
	if (getInteger(reg[BP_REG]) < 0) {
		raiseException(newException(EX_ILLMEM, "Negative value for BP.\n", 0));
		return 0;
	}
	if (getInteger(reg[BP_REG]) >= SIZE_OF_MEM || (mode==USER_MODE && getInteger(reg[BP_REG]) >= getInteger(reg[PTLR_REG]) * PAGE_SIZE)) {
		raiseException(newException(EX_ILLMEM, "BP Register Value out of bounds.\n", 0));
		return 0;
	}
	return 1;
}
    void NSFThread::threadEntry(const NSFContext&)
    {
        try
        {
            threadLoop();
        }
        catch(const std::exception& exception)
        {
            std::runtime_error newException(getName() + " thread loop exception: " + exception.what());
            handleException(newException);
        }
        catch(...)
        {
            std::runtime_error newException(getName() + " thread loop exception: unknown exception");
            handleException(newException);
        }

        LOCK(getThreadMutex())
        {
            NSFEnvironment::getEnvironment().removeThread(this);
            terminationStatus = ThreadTerminated;
        }
        ENDLOCK;
    }
Ejemplo n.º 14
0
void NLog::appendToLog(LogMessage::Type type, bool fromServer,
                       const QString & message)
{
  QString header = "[ %1 ][ %2 ] ";
  QString msg;

  header = header.arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"));
  header = header.arg(fromServer ? "Server" : "Client");

  msg = message;
  msg.replace('\n', QString("\n%1").arg(header));
  msg.prepend(header);

  emit newMessage(msg, type);

  if(type == LogMessage::EXCEPTION)
    emit newException(message);
}
Ejemplo n.º 15
0
Archivo: utility.c Proyecto: lenywv/xsm
Address translateAddress(int address) {
	Address resultant_address = { -1, -1 };
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return resultant_address;
	}
	if (mode == USER_MODE) {
		int page_entry;
		page_entry = getInteger(reg[PTBR_REG]) + (address / PAGE_SIZE) * 2;
		if (page[(page_entry + 1) / PAGE_SIZE].word[(page_entry + 1) % PAGE_SIZE][1] == VALID) { 
			resultant_address.page = getInteger(page[page_entry / PAGE_SIZE].word[page_entry % PAGE_SIZE]);
			resultant_address.word = address % PAGE_SIZE;
			page[(page_entry + 1) / PAGE_SIZE].word[(page_entry + 1) % PAGE_SIZE][0] = REFERENCED;
		} else raiseException(newException(EX_PAGEFAULT, "Page Fault.\n", address / PAGE_SIZE));
		return resultant_address;
	} else {
		resultant_address.page = address / PAGE_SIZE;
		resultant_address.word = address % PAGE_SIZE;
		return resultant_address;
	}
}
Ejemplo n.º 16
0
Archivo: utility.c Proyecto: lenywv/xsm
int performCall(int X, int flagX) {
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	if (flagX != NUM) {
		raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
		return 0;
	}		
	e = isRestrictedMemoryLocation(X);
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	Address	T = translateAddress(getInteger(reg[SP_REG]) + 1);
	if (T.page == -1 && T.word == -1) return;
	storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) + 1);
	storeInteger(page[T.page].word[T.word], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
	storeInteger(reg[IP_REG], X);
	return 1;
}
Ejemplo n.º 17
0
Archivo: utility.c Proyecto: lenywv/xsm
int performRet() {
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	Address T = translateAddress(getInteger(reg[SP_REG]));
	if (T.page == -1 && T.word == -1) return;
	char * value = getWordFromAddress(T);
	if (value == NULL || getType(value) == TYPE_STR) {
		raiseException(newException(EX_ILLMEM, "Illegal return address", 0));
		return 0;
	}
	int result = getInteger(value);
	e = isRestrictedMemoryLocation(result);
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	storeInteger(reg[IP_REG], result);
	storeInteger(reg[SP_REG], getInteger(reg[SP_REG]) - 1);
	return 1;
}
Ejemplo n.º 18
0
Archivo: utility.c Proyecto: lenywv/xsm
int performOUT(int X, int flagX) {
	Exception e;
	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case IP:
		case PTBR:
		case PTLR:
		case EFR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand.", 0));
			return 0;
	}
	printf("%s\n", reg[X]);
	fflush(stdout);
	return 1;
}
Ejemplo n.º 19
0
/*
 *	This code is used to execute each instruction.
 */
void executeOneInstruction(int instr) {
	int X, Y, flagX1, flagX2, flagY1, flagY2, operation;
	char string[WORD_SIZE];
	bzero(string, 16);
	switch (instr) {
		case START:
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);	//increment IP
			break;
		case MOV:						//1st phase:get the value		2nd phase:store the value
			X = yylex();
			flagX1 = yylval.flag;
			flagX2 = yylval.flag2;
			Y = yylex();
			flagY1 = yylval.flag;
			flagY2 = yylval.flag2;
			strcpy(string, yylval.data);
			if (!performMOV(X, flagX1, flagX2, Y, flagY1, flagY2, string)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
		break;
		case ARITH:
			operation = yylval.flag;
			X = yylex();
			flagX1 = yylval.flag;
			if (operation != INR && operation != DCR) {
				Y = yylex();
				flagY1 = yylval.flag;
			}
			if (!performArithmetic(X, flagX1, Y, flagY1, operation)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
		break;
		case LOGIC:
			operation = yylval.flag;
			X = yylex();
			flagX1 = yylval.flag;
			Y = yylex();
			flagY1 = yylval.flag;
			if (!performLogic(X, flagX1, Y, flagY1, operation)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
		break;
		case BRANCH:
			operation = yylval.flag;
			X = yylex();
			flagX1 = yylval.flag;
			if (operation != JMP) {
				Y = yylex();
				flagY1 = yylval.flag;				
			}
			if (!performBranching(X, flagX1, Y, flagY1, operation)) return;
			break;
								
		case PUSH:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performPush(X, flagX1)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;
			
		case POP:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performPop(X, flagX1)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;

		case CALL:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performCall(X, flagX1)) return;
			break;

		case RET:
			if (!performRet()) return;
			break;

		case INT:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performINT(X, flagX1)) return;
			break;

		case IRET:
			if (!performIRET()) return;
			break;

		case IN:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performIN(X, flagX1)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;
		
		case OUT:
			X = yylex();
			flagX1 = yylval.flag;
			if (!performOUT(X, flagX1)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;

		case LOAD:
		case STORE:
			X = yylex();
			flagX1 = yylval.flag;
			Y = yylex();
			flagY1 = yylval.flag;
			if (!performLoadStore(X, flagX1, Y, flagY1, instr)) return;
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;
				
		case HALT:
			if (mode == USER_MODE) {
				raiseException(newException(EX_ILLINSTR, "Call to Privileged Instruction HALT in USER mode", 0));
				return;
			}
			printf("Machine is halting\n");
			exit(0);
			break;
		case END:
			break;
		
		case BRKP:
			if (isDebugModeOn()) {
				step_flag = 1;
				printf("\nXSM Debug Environment\nType \"help\" for getting a list of commands\n");
			}
			storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;
		default:
			raiseException(newException(EX_ILLINSTR, "Illegal Instruction", 0));
			return;
	}
}
Ejemplo n.º 20
0
/*Procedure that interprets current frame bytecode
 * Uses loop with switch statement.*/
YValue* EXECUTE_PROC(YObject* scope, YThread* th) {
	ExecutionFrame* frame = (ExecutionFrame*) th->frame;
	frame->regs[0] = (YValue*) scope;
	YRuntime* runtime = th->runtime;
	ILBytecode* bc = frame->bytecode;
	size_t code_len = frame->proc->code_length;

	while (frame->pc + 13 <= code_len) {
		// If runtime is paused then execution should be paused too.
		if (runtime->state == RuntimePaused) {
			th->state = ThreadPaused;
			while (runtime->state == RuntimePaused)
				YIELD();
			th->state = ThreadWorking;
		}
		// Decode opcode and arguments
		uint8_t opcode = frame->proc->code[frame->pc];

		int32_t* args = (int32_t*) &(frame->proc->code[frame->pc + 1]);
		const int32_t iarg0 = args[0];
		const int32_t iarg1 = args[1];
		const int32_t iarg2 = args[2];

		// Call debugger before each instruction if nescesarry
		YBreakpoint breakpoint = { .procid = frame->proc->id, .pc = frame->pc };
		DEBUG(th->runtime->debugger, instruction, &breakpoint, th);

		// Interpret opcode
		// See virtual machine description
		switch (opcode) {
		case VM_Halt:
			break;
		case VM_LoadConstant: {
			/*All constants during execution should be stored in pool.
			 * If pool contains constant id, then constant is returned*/
			YObject* cpool = th->runtime->Constants.pool;
			if (cpool->contains(cpool, iarg1, th)) {
				SET_REGISTER(cpool->get(cpool, iarg1, th), iarg0, th);
				break;
			}
			/*Else it is created, added to pool and returned*/
			Constant* cnst = bc->getConstant(bc, iarg1);
			YValue* val = getNull(th);
			if (cnst != NULL) {
				switch (cnst->type) {
				case IntegerC:
					val = newInteger(cnst->value.i64, th);
					break;
				case FloatC:
					val = newFloat(cnst->value.fp64, th);
					break;
				case StringC:
					val = newString(
							bc->getSymbolById(bc,
									cnst->value.string_id), th);
					break;
				case BooleanC:
					val = newBoolean(cnst->value.boolean, th);
					break;
				default:
					break;
				}
			}
			cpool->put(cpool, iarg1, val, true, th);
			SET_REGISTER(val, iarg0, th);
		}
			break;
		case VM_LoadInteger: {
			/*Load integer from argument directly to register*/
			YValue* val = newInteger(iarg1, th);
			SET_REGISTER(val, iarg0, th);
		}
			break;
		case VM_Copy: {
			/*Copy register value to another*/
			SET_REGISTER(getRegister(iarg1, th), iarg0, th);
		}
			break;
		case VM_Push: {
			/*Push register value to stack*/
			push(getRegister(iarg0, th), th);
		}
			break;
		case VM_PushInteger: {
			push(newInteger(iarg0, th), th);
		}
		break;

			/*Next instructions load values from two registers,
			 * perform polymorph binary operation and
			 * save result to third register*/
		case VM_Add: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.add_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Subtract: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.subtract_operation(v1, v2, th), iarg0,
					th);
		}
			break;
		case VM_Multiply: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.multiply_operation(v1, v2, th), iarg0,
					th);
		}
			break;
		case VM_Divide: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.divide_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Modulo: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.modulo_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Power: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.power_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_ShiftRight: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.shr_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_ShiftLeft: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.shl_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_And: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.and_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Or: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.or_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Xor: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.xor_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Compare: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);

			SET_REGISTER(newInteger(v1->type->oper.compare(v1, v2, th), th),
					iarg0, th);
		}
			break;

		case VM_Test: {
			/*Take an integer from register and
			 * check if certain bit is 1 or 0*/
			YValue* arg = getRegister(iarg1, th);
			if (arg->type == &th->runtime->IntType) {
				int64_t i = ((YInteger*) arg)->value;
				YValue* res = newBoolean((i & iarg2) != 0, th);
				SET_REGISTER(res, iarg0, th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_FastCompare: {
			YValue* v1 = getRegister(iarg0, th);
			YValue* v2 = getRegister(iarg1, th);
			int i = v1->type->oper.compare(v1, v2, th);
			YValue* res = newBoolean((i & iarg2) != 0, th);
			SET_REGISTER(res, iarg0, th);
		}
		break;
			/*These instruction perform polymorph unary operations*/
		case VM_Negate: {
			YValue* v1 = getRegister(iarg1, th);
			SET_REGISTER(v1->type->oper.negate_operation(v1, th), iarg0, th);
		}
			break;
		case VM_Not: {
			YValue* v1 = getRegister(iarg1, th);
			SET_REGISTER(v1->type->oper.not_operation(v1, th), iarg0, th);
		}
			break;
		case VM_Increment: {
			YValue* v1 = getRegister(iarg1, th);
			if (v1->type == &th->runtime->IntType) {
				int64_t i = getInteger(v1, th);
				i++;
				SET_REGISTER(newInteger(i, th), iarg0, th);
			} else if (v1->type==&th->runtime->FloatType) {
				double i = getFloat(v1, th);
				i++;
				SET_REGISTER(newFloat(i, th), iarg0, th);
			} else {
				SET_REGISTER(v1, iarg0, th);
			}

		}
		break;
		case VM_Decrement: {
			YValue* v1 = getRegister(iarg1, th);
			if (v1->type == &th->runtime->IntType) {
				int64_t i = getInteger(v1, th);
				i--;
				SET_REGISTER(newInteger(i, th), iarg0, th);
			} else if (v1->type==&th->runtime->FloatType) {
				double i = getFloat(v1, th);
				i--;
				SET_REGISTER(newFloat(i, th), iarg0, th);
			} else {
				SET_REGISTER(v1, iarg0, th);
			}

		}
		break;

		case VM_Call: {
			/*Invoke lambda from register.
			 * Arguments stored in stack.
			 * Argument count passed as argument*/
			size_t argc = (size_t) popInt(th);
/*			YValue** args = malloc(sizeof(YValue*) * argc);
			for (size_t i = argc - 1; i < argc; i--)
				args[i] = pop(th);*/
			YValue** args = &((ExecutionFrame*) th->frame)->stack[((ExecutionFrame*) th->frame)->stack_offset] - argc;
			((ExecutionFrame*) th->frame)->stack_offset -= argc;
			YValue* val = getRegister(iarg1, th);
			YObject* scope = NULL;
			if (iarg2 != -1) {
				YValue* scl = getRegister(iarg2, th);
				if (scl->type == &th->runtime->ObjectType)
					scope = (YObject*) scl;
				else {
					scope = th->runtime->newObject(NULL, th);
					OBJECT_NEW(scope, L"value", scl, th);
				}
			}
			if (val->type == &th->runtime->LambdaType) {

				YLambda* l = (YLambda*) val;
				SET_REGISTER(invokeLambda(l, scope, args, argc, th), iarg0, th);
			} else {
				throwException(L"CallingNotALambda", NULL, 0, th);
				SET_REGISTER(getNull(th), iarg0, th);
			}
			//free(args);
		}
			break;
		case VM_Return: {
			/*Verify register value to be some type(if defined)
			 * and return it. Execution has been ended*/
			YValue* ret = getRegister(iarg0, th);
			if (((ExecutionFrame*) th->frame)->retType != NULL
					&& !((ExecutionFrame*) th->frame)->retType->verify(
							((ExecutionFrame*) th->frame)->retType, ret, th)) {
				wchar_t* wstr = toString(ret, th);
				throwException(L"Wrong return type", &wstr, 1, th);
				free(wstr);
				return getNull(th);
			}
			return ret;
		}
		case VM_NewObject: {
			/*Create object with parent(if defined)*/
			YValue* p = getRegister(iarg1, th);
			if (iarg1 != -1 && p->type == &th->runtime->ObjectType) {
				YObject* obj = th->runtime->newObject((YObject*) p, th);
				SET_REGISTER((YValue*) obj, iarg0, th);
			} else
				SET_REGISTER((YValue*) th->runtime->newObject(NULL, th), iarg0,
						th);
		}
			break;
		case VM_NewArray: {
			/*Create empty array*/
			SET_REGISTER((YValue*) newArray(th), iarg0, th);
		}
			break;
		case VM_NewLambda: {
			/*Create lambda. Lambda signature is stored in stack.
			 * It is popped and formed as signature*/
			// Check if lambda is vararg
			YValue* vmeth = pop(th);
			bool meth =
					(vmeth->type == &th->runtime->BooleanType) ?
							((YBoolean*) vmeth)->value : false;
			YValue* vvararg = pop(th);
			bool vararg =
					(vvararg->type == &th->runtime->BooleanType) ?
							((YBoolean*) vvararg)->value : false;
			// Get argument count and types
			size_t argc = (size_t) popInt(th);
			int32_t* argids = calloc(1, sizeof(int32_t) * argc);
			YoyoType** argTypes = calloc(1, sizeof(YoyoType*) * argc);
			for (size_t i = argc - 1; i < argc; i--) {
				argids[i] = (int32_t) popInt(th);
				YValue* val = pop(th);
				if (val->type == &th->runtime->DeclarationType)
					argTypes[i] = (YoyoType*) val;
				else
					argTypes[i] = val->type->TypeConstant;
			}
			// Get lambda return type
			YValue* retV = pop(th);
			YoyoType* retType = NULL;
			if (retV->type == &th->runtime->DeclarationType)
				retType = (YoyoType*) retV;
			else
				retType = retV->type->TypeConstant;
			// Get lambda scope from argument and create
			// lambda signature and lambda
			YValue* sp = getRegister(iarg2, th);
			if (sp->type == &th->runtime->ObjectType) {
				YObject* scope = (YObject*) sp;
				YLambda* lmbd = newProcedureLambda(iarg1, bc, scope, argids,
						newLambdaSignature(meth, argc, vararg, argTypes,
								retType, th), th);
				SET_REGISTER((YValue*) lmbd, iarg0, th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
			// Free allocated resources
			free(argids);
			free(argTypes);
		}
			break;
		case VM_NewOverload: {
			/*Pop lambdas from stack and
			 * create overloaded lambda*/
			// Pop lambda count and lambdas
			size_t count = (size_t) iarg1;
			YLambda** lambdas = malloc(sizeof(YLambda*) * count);
			for (size_t i = 0; i < count; i++) {
				YValue* val = pop(th);
				if (val->type == &th->runtime->LambdaType)
					lambdas[i] = (YLambda*) val;
				else
					lambdas[i] = NULL;
			}
			// If default lambda is defined then get it
			YLambda* defLmbd = NULL;
			if (iarg2 != -1) {
				YValue* val = getRegister(iarg2, th);
				if (val->type == &th->runtime->LambdaType)
					defLmbd = (YLambda*) val;
			}
			// Create overloaded lambda
			SET_REGISTER(
					(YValue*) newOverloadedLambda(lambdas, count, defLmbd, th),
					iarg0, th);

			// Free allocated resources
			free(lambdas);
		}
			break;
		case VM_NewComplexObject: {
			/*Pop mixin objects from stack and create complex object*/
			// Get mixin count and pop mixins
			size_t count = (size_t) iarg2;
			YObject** mixins = malloc(sizeof(YObject*) * count);
			for (size_t i = 0; i < count; i++) {
				YValue* val = pop(th);
				if (val->type == &th->runtime->ObjectType)
					mixins[i] = (YObject*) val;
				else
					mixins[i] = NULL;
			}
			// Get base object
			YValue* basev = getRegister(iarg1, th);
			YObject* base = NULL;
			if (basev->type == &th->runtime->ObjectType)
				base = (YObject*) basev;
			else
				base = th->runtime->newObject(NULL, th);
			// Create complex object and free allocated resources
			SET_REGISTER((YValue*) newComplexObject(base, mixins, count, th),
					iarg0, th);
			free(mixins);
		}
			break;

		case VM_GetField: {
			/*Read value property and store it in register*/
			YValue* val = getRegister(iarg1, th);
			if (val->type->oper.readProperty != NULL) {
				SET_REGISTER(val->type->oper.readProperty(iarg2, val, th), iarg0,
						th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_SetField: {
			/*Set objects field*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->put(obj, iarg1, getRegister(iarg2, th), false, th);
			}
		}
			break;
		case VM_NewField: {
			/*Create new field in object*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->put(obj, iarg1, getRegister(iarg2, th), true, th);
			}
		}
			break;
		case VM_DeleteField: {
			/*Delete field from object*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->remove(obj, iarg1, th);
			}
		}
			break;
		case VM_ArrayGet: {
			/*Get index from value. If can't then throw exception*/
			YValue* val = getRegister(iarg1, th);
			YValue* val2 = getRegister(iarg2, th);
			// If value is array, but index is integer then
			// reads array element at index
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				SET_REGISTER(arr->get(arr, index, th), iarg0, th);
			} else if (val->type->oper.readIndex != NULL) {
				// Else calls readIndex on type(if readIndex is defined)
				SET_REGISTER(val->type->oper.readIndex(val, val2, th), iarg0,
						th);
			} else {
				throwException(L"AccesingNotAnArray", NULL, 0, th);
				SET_REGISTER(getNull(th), iarg0, th);
			}
		}
			break;
		case VM_ArraySet: {
			/*Set value to other value on index. If can't throw exception*/
			YValue* val = getRegister(iarg0, th);
			YValue* val2 = getRegister(iarg1, th);
			// If value if array, but index is integer
			// then assigns value to an array
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				arr->set(arr, index, getRegister(iarg2, th), th);
			} else if (val->type->oper.readIndex != NULL) {
				// Else calls writeIndex on type(if writeIndex is defined)
				val->type->oper.writeIndex(val, val2, getRegister(iarg2, th),
						th);
			} else {
				throwException(L"ModifyingNotAnArray", NULL, 0, th);
			}
		}
			break;
		case VM_ArrayDelete: {
			/*If value is array but index is integer set array index
			 * else throw an exception*/
			YValue* val = getRegister(iarg0, th);
			YValue* val2 = getRegister(iarg1, th);
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				arr->remove(arr, index, th);
			} else if (val->type->oper.removeIndex !=NULL) {
				val->type->oper.removeIndex(val, val2, th);
			} else {
				throwException(L"ModifyingNotAnArray", NULL, 0, th);
			}

		}
			break;

		case VM_Goto: {
			/*Get label id from argument, get label address and jump*/
			uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
			frame->pc = addr;
			continue;
		}
			break;
		case VM_GotoIfTrue: {
			/*Get label id from argument, get label address and jump
			 * if condition is true*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && ((YBoolean*) bln)->value) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
			break;
		case VM_GotoIfFalse: {
			/*Get label id from argument, get label address and jump
			 * if condition is false*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && !((YBoolean*) bln)->value) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
			break;
		case VM_Jump: {
			/*Goto to an address*/
			frame->pc = iarg0;
			continue;
		}
			break;
		case VM_JumpIfTrue: {
			/*Goto to an address if condition is true*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && ((YBoolean*) bln)->value) {
				frame->pc = iarg0;
				continue;
			}
		}
			break;
		case VM_JumpIfFalse: {
			/*Goto to an address if condition is false*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && !((YBoolean*) bln)->value) {
				frame->pc = iarg0;
				continue;
			}
		}
			break;

		case VM_Throw: {
			/*Throw an exception*/
			th->exception = newException(getRegister(iarg0, th), th);
		}
			break;
		case VM_Catch: {
			/*Save current exception in register and
			 * set exception NULL*/
			SET_REGISTER(th->exception, iarg0, th);
			th->exception = NULL;
		}
			break;
		case VM_OpenCatch: {
			/*Add next catch address to frame catch stack.
			 * If exception is thrown then catch address being
			 * popped from stack and interpreter
			 * jump to it*/
			CatchBlock* cb = malloc(sizeof(CatchBlock));
			cb->prev = frame->catchBlock;
			cb->pc = iarg0;
			frame->catchBlock = cb;
		}
			break;
		case VM_CloseCatch: {
			/*Remove catch address from frame catch stack*/
			CatchBlock* cb = frame->catchBlock;
			frame->catchBlock = cb->prev;
			free(cb);
		}
			break;

		case VM_Nop: {
			/*Does nothing*/
		}
			break;

		case VM_Swap: {
			/*Swap two register values*/
			YValue* r1 = getRegister(iarg0, th);
			YValue* r2 = getRegister(iarg1, th);
			SET_REGISTER(r1, iarg1, th);
			SET_REGISTER(r2, iarg0, th);
		}
			break;
		case VM_Subsequence: {
			/*Get subsequence from value if subseq method
			 * is defined*/
			YValue* reg = getRegister(iarg0, th);
			YValue* tfrom = getRegister(iarg1, th);
			YValue* tto = getRegister(iarg2, th);
			if (tfrom->type == &th->runtime->IntType&&
				tto->type == &th->runtime->IntType&&
				reg->type->oper.subseq!=NULL) {
				size_t from = (size_t) ((YInteger*) tfrom)->value;
				size_t to = (size_t) ((YInteger*) tto)->value;
				SET_REGISTER(reg->type->oper.subseq(reg, from, to, th), iarg0,
						th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_Iterator: {
			/*Get iterator from value if it is iterable*/
			YValue* v = getRegister(iarg1, th);
			if (v->type->oper.iterator != NULL) {
				SET_REGISTER((YValue*) v->type->oper.iterator(v, th), iarg0, th);\
			}
			else {
				SET_REGISTER(getNull(th), iarg0, th);
			}

		}
			break;
		case VM_Iterate: {
			/*If iterator has next value than get it and save
			 * to register. If iterator doesn't has next value
			 * then jump to a label*/
			YValue* v = getRegister(iarg1, th);
			YValue* value = NULL;
			if (v->type->oper.iterator != NULL) {
				YoyoIterator* iter = v->type->oper.iterator(v, th);
				if (iter->hasNext(iter, th))
					value = iter->next(iter, th);
			}
			if (value == NULL) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg2)->value;
				frame->pc = addr;
			} else
				SET_REGISTER(value, iarg0, th);
		}
			break;
		case VM_NewInterface: {
			/*Build new interface*/
			YoyoAttribute* attrs = calloc(1, sizeof(YoyoAttribute) * iarg2);
			// Pop interface parents
			YoyoInterface** parents = calloc(1, sizeof(YoyoInterface*) * iarg1);
			for (int32_t i = 0; i < iarg1; i++) {
				YValue* val = pop(th);
				YoyoType* type = NULL;
				if (val->type == &th->runtime->DeclarationType)
					type = (YoyoType*) val;
				else
					type = val->type->TypeConstant;
				parents[i] =
						type->type == InterfaceDT ?
								(YoyoInterface*) type : NULL;
			}
			// Pop interface fields
			for (int32_t i = 0; i < iarg2; i++) {
				attrs[i].id = popInt(th);
				YValue* val = pop(th);
				YoyoType* type = NULL;
				if (val->type == &th->runtime->DeclarationType)
					type = (YoyoType*) val;
				else
					type = val->type->TypeConstant;
				attrs[i].type = type;
			}
			// Build interface and free allocated resources
			SET_REGISTER(
					(YValue*) newInterface(parents, (size_t) iarg1, attrs,
							(size_t) iarg2, th), iarg0, th);
			free(attrs);
			free(parents);
		}
			break;
		case VM_ChangeType: {
			/*Change field type*/
			YValue* val = getRegister(iarg2, th);
			YoyoType* type = NULL;
			if (val->type == &th->runtime->DeclarationType)
				type = (YoyoType*) val;
			else
				type = val->type->TypeConstant;
			YValue* o = getRegister(iarg0, th);
			if (o->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) o;
				obj->setType(obj, iarg1, type, th);
			}
		}
			break;
		case VM_GotoIfEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_NOT_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_NOT_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER_OR_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER_OR_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER_OR_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER_OR_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_CheckType: {
			YValue* value = getRegister(iarg0, th);
			YValue* tv = getRegister(iarg1, th);
			YoyoType* type = NULL;
			if (tv->type == &th->runtime->DeclarationType)
				type = (YoyoType*) tv;
			else
				type = tv->type->TypeConstant;
			if (!type->verify(type, value, th)) {
				wchar_t* wcs = getSymbolById(&th->runtime->symbols, iarg2);
				throwException(L"WrongFieldType", &wcs, 1, th);
			}
		}
		break;
		}
		/*If there is an exception then get last catch block
		 * and jump to an address. If catch stack is empty
		 * then return from procedure*/
		if (th->exception != NULL) {
			if (frame->catchBlock != NULL) {
				frame->pc = frame->proc->getLabel(frame->proc,
						frame->catchBlock->pc)->value;
				continue;
			} else
				return getNull(th);
		}
		frame->pc += 13;
	}
	return getNull(th);
}
Ejemplo n.º 21
0
Archivo: utility.c Proyecto: lenywv/xsm
int performLoadStore(int X, int flagX, int Y, int flagY, int instruction) {
	if (mode == USER_MODE) {
		raiseException(newException(EX_ILLINSTR, "Call to Privileged Instruction in USER mode", 0));		
		return 0;
	}
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case IP:
		case PTBR:
		case PTLR:
		case EFR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			if (getType(reg[X]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
			} else X = getInteger(reg[X]);					
			break;
		case NUM:
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
			return 0;
			break;
	}
	switch (flagY) {
		case REG:
		case SP:
		case BP:
		case IP:
		case PTBR:
		case PTLR:
		case EFR:
			e = isRegisterInaccessible(Y);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			if (getType(reg[Y]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
			} else Y = getInteger(reg[Y]);					
			break;
		case NUM:
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
			return 0;
			break;
	}
	if (instruction == LOAD) {			
		emptyPage(X);
		readFromDisk(X, Y);
	} else if (instruction == STORE) writeToDisk(Y, X);
	return 1;
}
Ejemplo n.º 22
0
Archivo: utility.c Proyecto: lenywv/xsm
Exception isRestrictedMemoryLocation(int x) {
	if (x < 0 || x >= SIZE_OF_MEM || (mode == USER_MODE && x >= getInteger(reg[PTLR_REG]) * PAGE_SIZE)) {
		return newException(EX_ILLMEM, "Illegal Memory Access", 0);
	}
	return newException(EX_NONE, "", 0);
}
Ejemplo n.º 23
0
Archivo: utility.c Proyecto: lenywv/xsm
char * resolveOperand(int r, int flag1, int flag2, char * string) {
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return NULL;
	}
	if (flag1 != NUM && flag1 != STRING && flag1 != MEM_DIR) {
		if (flag1 != MEM_DIR_IN) {
			int reg = (flag2 != ILLREG) ? flag2 : r;
			e = isRegisterInaccessible(reg);
			if (e.code != EX_NONE) {
				raiseException(e);
				return NULL;
			}
		}
	}
	char * result;
	Address translatedAddress;
	switch (flag1) {
		case REG:
		case SP:
		case BP:
		case IP:
		case PTBR:
		case PTLR:
		case EFR:
			return reg[r];
			break;
		case NUM:
			result = malloc(WORD_SIZE);
			sprintf(result, "%d", r);
			return result;
			break;
		case STRING:
			return string;
			break;
		case MEM_REG:
			if (getType(reg[r]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "String value supplied in lieu of Memory Address", 0));
				return NULL;
			}
			e = isRestrictedMemoryLocation(getInteger(reg[r]));
			if (e.code != EX_NONE) {
				raiseException(e);
				return NULL;
			}
			return getWordFromMemoryLocation(getInteger(reg[r]));
			break;
		case MEM_SP:
		case MEM_BP:
			return getWordFromMemoryLocation(getInteger(reg[r]));
			break;
		case MEM_PTBR:
		case MEM_PTLR:
			return getWordFromMemoryLocation(getInteger(reg[r]));
			break;
		case MEM_IP:
		case MEM_DIR_IP:		
			raiseException(newException(EX_ILLOPERAND, "Cannot use memory reference with IP in any mode", 0));
			return NULL;
			break;
		case MEM_EFR:
		case MEM_DIR_EFR:
			raiseException(newException(EX_ILLOPERAND, "Cannot use memory reference with EFR in any mode", 0));
			return NULL;
			break;
		case MEM_DIR:
			return getWordFromMemoryLocation(r);
			break;
		case MEM_DIR_REG:
			if (getType(reg[flag2]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "Illegal register value", 0));
				return NULL;
			}
			r += getInteger(reg[flag2]);
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return NULL;
			}
			return getWordFromMemoryLocation(r);
			break;
		case MEM_DIR_SP:
		case MEM_DIR_BP:
		case MEM_DIR_PTBR:
		case MEM_DIR_PTLR:
			r += getInteger(reg[flag2]);
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return NULL;
			}
			return getWordFromMemoryLocation(r);
			break;
		case MEM_DIR_IN:
			r += flag2;
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return NULL;
			}
			return getWordFromMemoryLocation(r);
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal Source Operand", 0));
			return NULL;
			break;
	}
}
Ejemplo n.º 24
0
Archivo: utility.c Proyecto: lenywv/xsm
int storeValue(int r, int flag1, int flag2, char * value) {
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	if (flag1 != NUM && flag1 != STRING && flag1 != MEM_DIR) {
		if (flag1 != MEM_DIR_IN) {
			int reg = (flag2 != ILLREG) ? flag2 : r;
			e = isRegisterInaccessible(reg);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
		}
	}
	switch (flag1) {
		case REG:
		case SP:
		case BP: 
		case PTBR:
		case PTLR:
			strcpy(reg[r], value);
			return 1;
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Cannot alter read-only register IP", 0));
			return 0;
			break;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Cannot alter read-only register EFR", 0));
			return 0;					
			break;
		case MEM_REG:
			if (getType(reg[r]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "String value supplied in lieu of Memory Address", 0));
				return 0;
			}
			e = isRestrictedMemoryLocation(getInteger(reg[r]));
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			return storeWordToMemoryLocation(getInteger(reg[r]), value);
			break;
		case MEM_SP:
		case MEM_BP:
		case MEM_PTBR:
		case MEM_PTLR:
			return storeWordToMemoryLocation(getInteger(reg[r]), value);
			break;
		case MEM_IP:
		case MEM_DIR_IP:
			raiseException(newException(EX_ILLOPERAND, "Cannot use memory reference with IP in any mode", 0));
			return 0;
			break;
		case MEM_EFR:
		case MEM_DIR_EFR:						
			raiseException(newException(EX_ILLOPERAND, "Cannot use memory reference with EFR in any mode", 0));
			return 0;
			break;
		case MEM_DIR:
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			return storeWordToMemoryLocation(r, value);
			break;
		case MEM_DIR_REG:
			if (getType(reg[flag2]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "Illegal register value", 0));
				return 0;
			}
			r += getInteger(reg[flag2]);
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			return storeWordToMemoryLocation(r, value);
			break;
		case MEM_DIR_SP:
		case MEM_DIR_BP:
		case MEM_DIR_PTBR:
		case MEM_DIR_PTLR:
			r += getInteger(reg[flag2]);
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			return storeWordToMemoryLocation(r, value);
			break;
		case MEM_DIR_IN:
			r += flag2;
			e = isRestrictedMemoryLocation(r);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			return storeWordToMemoryLocation(r, value);
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal Target Operand", 0));
			return 0;
			break;
	}
}
Ejemplo n.º 25
0
Archivo: utility.c Proyecto: lenywv/xsm
int performArithmetic(int X, int flagX, int Y, int flagY, int operation) {
	int valueX, valueY;
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case PTBR:
		case PTLR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			if (getType(reg[X]) == TYPE_STR) {
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
			}
			valueX = X;
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
			return 0;
			break;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
			return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
			return 0;
			break;
	}

	if (operation != INR && operation != DCR) {
		switch (flagY) {
			case REG:
			case SP:
			case BP:
			case PTBR:
			case PTLR:
				e = isRegisterInaccessible(Y);
				if (e.code != EX_NONE) {
					raiseException(e);
					return 0;
				}
				if (getType(reg[Y]) == TYPE_STR) {
					raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
					return 0;
				}
				valueY = getInteger(reg[Y]);
				break;
			case NUM:
				valueY = Y;
				break;
			case IP:
				raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
				return 0;
				break;
			case EFR:
				raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
				return 0;
				break;
			default:
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
				break;
		}
	}

	switch (operation) {
		case ADD:
			storeInteger(reg[valueX], getInteger(reg[valueX]) + valueY);
			break;			
		case SUB:
			storeInteger(reg[valueX], getInteger(reg[valueX]) - valueY);
			break;
		case MUL:
			storeInteger(reg[valueX], getInteger(reg[valueX]) * valueY);
			break;
		case DIV:
			if (valueY == 0) {
				raiseException(newException(EX_ILLOPERAND, "Divide by ZERO", 0));
				return 0;
			}
			storeInteger(reg[valueX], getInteger(reg[valueX]) / valueY);
			break;
		case MOD:
			if (valueY == 0) {
				raiseException(newException(EX_ILLOPERAND, "Divide by ZERO", 0));
				return 0;
			}
			storeInteger(reg[valueX], getInteger(reg[valueX]) % valueY);
			break;
		case INR:
			storeInteger(reg[valueX], getInteger(reg[valueX]) + 1);
			break;
		case DCR:
			storeInteger(reg[valueX], getInteger(reg[valueX]) - 1);
			break;
		default:
			raiseException(newException(EX_ILLINSTR, "Illegal Instruction", 0));
			return 0;
			break;
	}
	return 1;
}
Ejemplo n.º 26
0
Archivo: utility.c Proyecto: lenywv/xsm
int performLogic(int X, int flagX, int Y, int flagY, int operation) {
	int valueX, valueY;
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}

	switch (flagX) {
		case REG:
		case SP:
		case BP:
		case PTBR:
		case PTLR:
			e = isRegisterInaccessible(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
			return 0;
			break;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
			return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
			return 0;
			break;
	}

	switch (flagY) {
		case REG:
		case SP:
		case BP:
		case PTBR:
		case PTLR:
			e = isRegisterInaccessible(Y);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			break;
		case IP:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand IP. Cannot alter readonly register", 0));
			return 0;
			break;
		case EFR:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand EFR. Cannot alter readonly register", 0));
			return 0;
			break;
		default:
			raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
			return 0;
			break;
	}
	if (getType(reg[X]) != getType(reg[Y])) {
		raiseException(newException(EX_ILLOPERAND, "Operand Type Mismatch to logical expression", 0));
		return 0;
	}
	switch (operation) {
		case LT:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) < getInteger(reg[Y])) : (strcmp(reg[X], reg[Y]) < 0);
			break;
		case GT:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) > getInteger(reg[Y])) : (strcmp(reg[X], reg[Y]) > 0);
			break;
		case EQ:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) == getInteger(reg[Y])) : (!strcmp(reg[X], reg[Y]));
			break;
		case NE:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) != getInteger(reg[Y])) : (!!strcmp(reg[X], reg[Y]));
			break;
		case LE:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) <= getInteger(reg[Y])) : (strcmp(reg[X], reg[Y]) >= 0);
			break;
		case GE:
			valueX = (getType(reg[X]) == TYPE_INT) ? (getInteger(reg[X]) >= getInteger(reg[Y])) : (strcmp(reg[X], reg[Y]) >= 0);
			break;
		default:
			raiseException(newException(EX_ILLINSTR, "Illegal Instruction", 0));
			return;
			break;
	}
	storeInteger(reg[X], valueX);
	return 1;
}
Ejemplo n.º 27
0
Archivo: utility.c Proyecto: lenywv/xsm
int performBranching(int X, int flagX, int Y, int flagY, int operation) {
	int valueX, valueY;
	Exception e = isSafeState2();
	if (e.code != EX_NONE) {
		raiseException(e);
		return 0;
	}
	switch (operation) {
		case JZ:
		case JNZ:
			switch (flagX) {
				case REG:
				case SP:
				case BP:
				case IP:
				case PTBR:
				case PTLR:
				case EFR:
					e = isRegisterInaccessible(X);
					if (e.code != EX_NONE) {
						raiseException(e);
						return 0;
					}
					break;					
				default:
					raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
					return 0;
					break;
			}
			if (flagY != NUM) {
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
			}
			e = isRestrictedMemoryLocation(Y);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			if ((getType(reg[X]) == TYPE_INT && operation == JZ && getInteger(reg[X]) == 0) 
				|| ((getType(reg[X]) == TYPE_STR) || (operation == JNZ && getInteger(reg[X])))) storeInteger(reg[IP_REG], Y);
			else storeInteger(reg[IP_REG], getInteger(reg[IP_REG]) + WORDS_PER_INSTR);
			break;
		case JMP:
			if (flagX != NUM) {
				raiseException(newException(EX_ILLOPERAND, "Illegal operand", 0));
				return 0;
			}		
			e = isRestrictedMemoryLocation(X);
			if (e.code != EX_NONE) {
				raiseException(e);
				return 0;
			}
			storeInteger(reg[IP_REG], X);
			break;
		default:
			raiseException(newException(EX_ILLINSTR, "Illegal Instruction", 0));
			return 0;
			break;		
	}
	return 1;
}