Exemplo n.º 1
0
void
setupInitialEnvironment(){	

	globalEnvironmentPut(symbolTableGetOrAdd("a"), newInteger(10));
	globalEnvironmentPut(symbolTableGetOrAdd("b"), newInteger(20));
	
	// builtin functions
	globalEnvironmentPut(symbolTableGetOrAdd("+"), newBuiltinFunction("+", builtin_plus));
	globalEnvironmentPut(symbolTableGetOrAdd("-"), newBuiltinFunction("-", builtin_minus));
	globalEnvironmentPut(symbolTableGetOrAdd("*"), newBuiltinFunction("*", builtin_times));
	globalEnvironmentPut(symbolTableGetOrAdd("/"), newBuiltinFunction("/", builtin_quotient));
	globalEnvironmentPut(symbolTableGetOrAdd("eq?"), newBuiltinFunction("eq?", builtin_eqP));
	globalEnvironmentPut(symbolTableGetOrAdd("cons?"), newBuiltinFunction("cons?", builtin_consP));
	globalEnvironmentPut(symbolTableGetOrAdd("car"), newBuiltinFunction("car", builtin_car));
	globalEnvironmentPut(symbolTableGetOrAdd("cdr"), newBuiltinFunction("cdr", builtin_cdr));
	globalEnvironmentPut(symbolTableGetOrAdd("cons"), newBuiltinFunction("cons", builtin_cons));
	
	globalEnvironmentPut(symbolTableGetOrAdd("include"), newBuiltinFunction("include", builtin_include));
	globalEnvironmentPut(symbolTableGetOrAdd(">"), newBuiltinFunction(">", builtin_gThanNrP));
	globalEnvironmentPut(symbolTableGetOrAdd("set-car!"), newBuiltinFunction("set-car!", builtin_set_car));
	globalEnvironmentPut(symbolTableGetOrAdd("set-cdr!"), newBuiltinFunction("set-cdr!", builtin_set_cdr));
	globalEnvironmentPut(symbolTableGetOrAdd("display"), newBuiltinFunction("display", builtin_display));
	globalEnvironmentPut(symbolTableGetOrAdd("write"), newBuiltinFunction("write", builtin_write));
	globalEnvironmentPut(symbolTableGetOrAdd("string=?"), newBuiltinFunction("string=?", builtin_eqStringP));
	
}
Exemplo n.º 2
0
object sysPrimitive(int number, object* arguments)
{   
  ObjectHandle returnedObject = nilobj;

  /* someday there will be more here */
  switch(number - 150) {
    case 0:     /* do a system() call */
      returnedObject = newInteger(system(
            objectRef(arguments[0]).charPtr()));
      break;

    case 1: /* editline, with history support */
      {
        char* command = linenoise_nb(objectRef(arguments[0]).charPtr());
        returnedObject = newStString(command);
        if(command) 
        {
          linenoiseHistoryAdd(command);
          free(command);
        }
      }
      break;

    case 2: /* get last error */ 
      {
        returnedObject = newStString(gLastError);
      }
      break;

    case 3: /* force garbage collect */
      {
        MemoryManager::Instance()->garbageCollect();
      }
      break;

    case 4:
      {
        returnedObject = newInteger(MemoryManager::Instance()->objectCount());
      }
      break;

    case 5:
      {
        returnedObject = newStString(MemoryManager::Instance()->statsString().c_str());
      }
      break;

    default:
      sysError("unknown primitive","sysPrimitive");
  }
  return(returnedObject);
}
Exemplo n.º 3
0
/*
 readDeclaration reads a declaration of a class
 */
static void readClassDeclaration()
{
    object classObj, super, vars;
    int i, size, instanceTop;
    object instanceVariables[15];

    if (nextToken() != nameconst)
        sysError("bad file format", "no name in declaration");
    classObj = findClass(tokenString);
    size = 0;
    if (nextToken() == nameconst)   /* read superclass name */
    {
        super = findClass(tokenString);
        basicAtPut(classObj, superClassInClass, super);
        size = intValue(basicAt(super, sizeInClass));
        nextToken();
    }
    if (token == nameconst)   /* read instance var names */
    {
        instanceTop = 0;
        while (token == nameconst)
        {
            instanceVariables[instanceTop++] = newSymbol(tokenString);
            size++;
            nextToken();
        }
        vars = newArray(instanceTop);
        for (i = 0; i < instanceTop; i++)
        {
            basicAtPut(vars, i+1, instanceVariables[i]);
        }
        basicAtPut(classObj, variablesInClass, vars);
    }
    basicAtPut(classObj, sizeInClass, newInteger(size));
}
Exemplo n.º 4
0
OBJ
readNumber(OBJ inStream, char firstChar, int isNegative){
	//printf(YEL "\nreadNumber>" RESET);

	/*
 	* TO-DO refactor!	
 	*/	
	jscheme_int64 *iVal = NULL;
	char ch;
	OBJ retVal;

	// substract the ASCII value of '0' from char to get the actual value between 0 and 9.
	jscheme_int64 start = (jscheme_int64) firstChar - '0';
	if(isNegative) start *= -1;

	iVal = &start;
	while( isDigit( ch = nextChar(inStream) )){
		//iVal = iVal * 10 + ( (int)ch - '0');

		jscheme_int64 ch_val = (jscheme_int64) ch - '0';
		
		if(isNegative){
			int mul = __builtin_smull_overflow(*iVal, 10, iVal);
			int sub = __builtin_ssubl_overflow(*iVal, ch_val, iVal);
			if( mul || sub ){
				if(thisIsTheEnd(inStream)){
					prompt_on();
				}
				js_error("readNumber: integer underflow", newInteger(*iVal));
			}
		}else{
			int mul = __builtin_smull_overflow(*iVal, 10, iVal);
			int add = __builtin_saddl_overflow(*iVal, ch_val, iVal);
			if( mul || add ){
				if(thisIsTheEnd(inStream)){
					prompt_on();
				}
				js_error("readNumber: integer overflow", newInteger(*iVal));
			}
		
		}
	}
	unreadChar(inStream, ch);
	retVal = newInteger( *iVal );
	return retVal;
}
Exemplo n.º 5
0
	void testFreeingSectors(){
		RuntimeErrorValidator * validator = buildErrorSuccessValidator();

		Bool aSortingCriteria(int * i , int * x){
			return (*i < *x);
		}

		Bool equalityCriteria(int * a , int * b){
			return (*a == *b);
		}

		List lista = createList(NULL ,
				(Bool (*)(void* , void*))equalityCriteria,
				(Bool (*)(void* , void*))aSortingCriteria);

		addNode(lista , newInteger(18));
		addNode(lista , newInteger(20));
		addNode(lista , newInteger(2));
		addNode(lista , newInteger(11));
		addNode(lista , newInteger(13));
		addNode(lista , newInteger(1));
		addNode(lista , newInteger(17));

		freeSectors("VDA1" , lista , validator);

		if(hasError(validator)){
			error(validator->errorDescription);
			return ;
		}
	}
Exemplo n.º 6
0
OBJ
builtin_minus(int numArgs){
	OBJ theArg;
	
	switch (numArgs){
		case 0:
			js_error("(-): at least one arg expected", js_nil);
			/* NOT REACHED */
		case 1:
			theArg = POP();
			if( !ISINTEGER(theArg)){
				js_error("(-): non-integer argument", theArg);
			}
			return newInteger( -INTVAL(theArg) );
		default:
			theArg = NTH_ARG(numArgs, 0);

			if( !ISINTEGER(theArg)){
				POPN(numArgs);
				js_error("(-): non-integer argument", theArg);
			}
			
			jscheme_int64 *difference = NULL;
			jscheme_int64 start = INTVAL(theArg);
			difference = &start;

			for(int i = 1; i < numArgs; i++){
				OBJ nextArg = NTH_ARG(numArgs, i);
				if( !ISINTEGER(nextArg)){
					POPN(numArgs);
					js_error("(-): non-integer argument", theArg);
				}
				if(__builtin_ssubl_overflow(*difference, INTVAL(nextArg), difference)){
					// clean stack
					POPN(numArgs);
					js_error("(-): integer overflow", newInteger(*difference));
				};
			}
			POPN(numArgs);
			return newInteger(*difference);
	}	
	/* NOT REACHED */
	return js_nil;
}
Exemplo n.º 7
0
OBJ
builtin_times(int numArgs){
	jscheme_int64 *product= NULL;
	jscheme_int64 start = 1;
	product = &start;

	for(int i = 0; i < numArgs; i++){
		OBJ theArg = POP();
		
		if( !ISINTEGER(theArg)){
			POPN((numArgs - 1) - i);
			js_error("(*): non-integer argument", theArg);
		}
		if(__builtin_smull_overflow(*product,INTVAL(theArg),product)){
			// clean stack
			POPN((numArgs - 1) - i);
			js_error("(*): integer overflow", newInteger(*product));
		}
	}
	return newInteger(*product);
}
Exemplo n.º 8
0
/*
    readDeclaration reads a declaration of a class
*/
static void readClassDeclaration()
{   
    ObjectHandle classObj, metaObj, vars;
    std::string className, superName;
    int i, size, instanceTop;
    // todo: fixed length variables array!
    ObjectHandle instanceVariables[15];
    // todo: horrible fixed length arrays!
    char metaClassName[100];
    char metaSuperClassName[100];

    if (ll.nextToken() != nameconst)
        sysError("bad file format","no name in declaration");
    className = ll.strToken();
    if (ll.nextToken() == nameconst) 
    { /* read superclass name */
        superName = ll.strToken();
        ll.nextToken();
    }
    // todo: sprintf eradication!
    sprintf(metaClassName, "Meta%s", className.c_str());
    if(!superName.empty())
        sprintf(metaSuperClassName, "Meta%s", superName.c_str());
    else
        sprintf(metaSuperClassName, "Class");

    metaObj = createRawClass(metaClassName, "Class", metaSuperClassName);
    classObj = createRawClass(className.c_str(), metaClassName, superName.c_str());
    classObj->_class = metaObj;

    // Get the current class size, we'll build on this as 
    // we add instance variables.
    size = getInteger(classObj->basicAt(sizeInClass));

    if (ll.currentToken() == nameconst) 
    {     /* read instance var names */
        instanceTop = 0;
        while (ll.currentToken() == nameconst) 
        {
            instanceVariables[instanceTop++] = createSymbol(ll.strToken().c_str());
            size++;
            ll.nextToken();
        }
        vars = newArray(instanceTop);
        for (i = 0; i < instanceTop; i++) 
        {
            vars->basicAtPut(i+1, instanceVariables[i]);
        }
        classObj->basicAtPut(variablesInClass, vars);
    }
    classObj->basicAtPut(sizeInClass, newInteger(size));
    classObj->basicAtPut(methodsInClass, newDictionary(39));
}
Exemplo n.º 9
0
/*
 findClass gets a class object,
 either by finding it already or making it
 in addition, it makes sure it has a size, by setting
 the size to zero if it is nil.
 */
static object findClass(char *name)
{
    object newobj;

    newobj = globalSymbol(name);
    if (newobj == nilobj)
        newobj = newClass(name);
    if (basicAt(newobj, sizeInClass) == nilobj)
    {
        basicAtPut(newobj, sizeInClass, newInteger(0));
    }
    return newobj;
}
Exemplo n.º 10
0
/*
    findClass gets a class object,
    either by finding it already or making it
    in addition, it makes sure it has a size, by setting
    the size to zero if it is nil.
*/
static ObjectHandle findClass(const char* name)
{   
    ObjectHandle newObj;

    newObj = globalSymbol(name);
    if (newObj == nilobj) {
        newObj = createAndRegisterNewClass(name);
    }
    if (newObj->basicAt(sizeInClass) == nilobj) 
    {
        newObj->basicAtPut(sizeInClass, newInteger(0));
    }
    return newObj;
}
Exemplo n.º 11
0
YArray* Array_find(YArray* arr, YValue* val, YThread* th) {
	arr->parent.o.linkc++;
	val->o.linkc++;
	YArray* out = newArray(th);
	out->parent.o.linkc++;
	for (size_t i = 0; i < arr->size(arr, th); i++) {
		YValue* v = arr->get(arr, i, th);
		if (CHECK_EQUALS(val, v, th))
			out->add(out, newInteger((int64_t) i, th), th);
	}
	out->parent.o.linkc--;
	val->o.linkc--;
	arr->parent.o.linkc--;
	return out;
}
Exemplo n.º 12
0
OBJ
builtin_plus(int numArgs){

	jscheme_int64  start = 0;
	jscheme_int64 *sum = NULL;
	sum = &start;
	int i;

	for(i = 0; i < numArgs; i++){
		OBJ theArg  = POP();

		if( !ISINTEGER(theArg)){
			POPN((numArgs - 1) - i);
			js_error("(+): non-integer argument", theArg);
		}
		
	       	if(__builtin_saddl_overflow( *sum, INTVAL(theArg), sum)){
			// clean evalStack
			POPN((numArgs - 1) - i);
			js_error("(+): integer overflow", newInteger(*sum));	
		};
	}
	return newInteger(*sum);
}
Exemplo n.º 13
0
object sysPrimitive(int number, object * arguments)
{
    object returnedObject;

    /* someday there will be more here */
    switch (number - 150) {
    case 0:			/* do a system() call */
	returnedObject = newInteger(system(charPtr(arguments[0])));
	break;

    default:
	sysError("unknown primitive", "sysPrimitive");
    }
    return (returnedObject);
}
Exemplo n.º 14
0
YValue* DefaultArray_get(YArray* a, size_t index, YThread* th) {
	DefaultArray* arr = (DefaultArray*) a;
	MUTEX_LOCK(&arr->access_mutex);
	if (index >= arr->size) {
		YValue* yint = newInteger(index, th);
		wchar_t* wstr = toString(yint, th);
		throwException(L"WrongArrayIndex", &wstr, 1, th);
		free(wstr);
		MUTEX_UNLOCK(&arr->access_mutex);
		return getNull(th);
	}
	YValue* val = arr->array[index];
	MUTEX_UNLOCK(&arr->access_mutex);
	return val;
}
Exemplo n.º 15
0
/*
    readRawDeclaration reads a declaration of a class
*/
static void readRawClassDeclaration()
{   
    ObjectHandle classObj, vars;
    std::string className, metaName, superName;
    int i, size, instanceTop;
    // todo: fixed length variables array!
    ObjectHandle instanceVariables[15];

    if (ll.nextToken() != nameconst)
        sysError("bad file format","no name in declaration");
    className = ll.strToken();
    size = 0;
    if (ll.nextToken() == nameconst) 
    { /* read metaclass name */
        metaName = ll.strToken();
        ll.nextToken();
    }
    if (ll.currentToken() == nameconst) 
    { /* read superclass name */
        superName = ll.strToken();
        ll.nextToken();
    }

    classObj = createRawClass(className.c_str(), metaName.c_str(), superName.c_str());

    // Get the current class size, we'll build on this as 
    // we add instance variables.
    size = getInteger(classObj->basicAt(sizeInClass));

    if (ll.currentToken() == nameconst) 
    {     /* read instance var names */
        instanceTop = 0;
        while (ll.currentToken() == nameconst) 
        {
            instanceVariables[instanceTop++] = createSymbol(ll.strToken().c_str());
            size++;
            ll.nextToken();
        }
        vars = newArray(instanceTop);
        for (i = 0; i < instanceTop; i++) 
        {
            vars->basicAtPut(i+1, instanceVariables[i]);
        }
        classObj->basicAtPut(variablesInClass, vars);
    }
    classObj->basicAtPut(sizeInClass, newInteger(size));
    classObj->basicAtPut(methodsInClass, newDictionary(39));
}
Exemplo n.º 16
0
/*
 *  tjoin   - Interface for users to call join on their threads in SCAM
 *
 *  @args   - The thread ID to join on
 */
int
tjoin (int args)
    {
    int tid = ival(car(args));

    // Might garbage collect and then wait with pthread_join
    T_P();
    --WorkingThreads;
    T_V();

    pthread_join(Thread[tid], NULL);

    // I can now garbage collect again
    T_P();
    ++WorkingThreads;
    T_V();
    return newInteger(tid);
    }
Exemplo n.º 17
0
void DefaultArray_insert(YArray* arr, size_t index, YValue* val, YThread* th) {
	DefaultArray* array = (DefaultArray*) arr;
	if (index > array->size) {
		YValue* yint = newInteger(index, th);
		wchar_t* wstr = toString(yint, th);
		throwException(L"WrongArrayIndex", &wstr, 1, th);
		free(wstr);
		return;
	}
	MUTEX_LOCK(&array->access_mutex);
	DefaultArray_prepare(array, array->size, th);
	for (size_t i = array->size - 1; i > index; i--) {
		array->array[i] = array->array[i - 1];
	}
	array->array[index] = val;

	MUTEX_UNLOCK(&array->access_mutex);
}
Exemplo n.º 18
0
static ObjectHandle findClassWithMeta(const char* name, ObjectHandle metaObj)
{   
    ObjectHandle newObj, nameObj, methTable;
    int size;

    newObj = globalSymbol(name);
    if (newObj == nilobj)
    {
        size = getInteger(metaObj->basicAt(sizeInClass));
        newObj = MemoryManager::Instance()->allocObject(size);
        newObj->_class = metaObj;

        /* now make name */
        nameObj = createSymbol(name);
        newObj->basicAtPut(nameInClass, nameObj);
        methTable = newDictionary(39);
        newObj->basicAtPut(methodsInClass, methTable);
        newObj->basicAtPut(sizeInClass, newInteger(size));

        /* now put in global symbols table */
        nameTableInsert(symbols, strHash(name), nameObj, newObj);
    }
    return newObj;
}
Exemplo n.º 19
0
	void testListImplementation2(){


		Bool equling(int * f1 , int * f2){
			return *f1 == *f2;
		}

		Bool sorting(int * f1 , int * f2){
			return *f1<*f2;
		}

		void listing(int * e){
			if(e != NULL) logInfo( "linux-commons" , itoa(*e));
		}

		List list = createList(listing , equling , sorting);

		addNode(list , newInteger(1));
		addNode(list , newInteger(2));
		addNode(list , newInteger(3));
		addNode(list , newInteger(4));
		addNode(list , newInteger(5));
		addNode(list , newInteger(6));

		logInfo("linux-commons" , concatAll(2 , "list size: " , itoa(list->size)));

		listNodes(list);

		//otra forma de listar elementos

		Iterator * iterator = buildIterator(list);

		while(hasMoreElements(iterator)){
			int * element = next(iterator);
			logInfo("linux-commons" , concatAll(2 , "element: " , itoa(*element)));
		}
	}
Exemplo n.º 20
0
OBJ
builtin_quotient(int numArgs){

#ifdef DEBUG	
	if( DETAILED_TYPES->state) printf(RED "WARNING:" RESET " division is implemented for integers only and will truncate fractions!\n");
#endif
	OBJ theArg;
	switch (numArgs){
		
		case 0:
			js_error("(/): at least one arg expected", js_nil);
			/* NOT REACHED */
		case 1:
			theArg = POP();
			if( !ISINTEGER(theArg)){
				js_error("(/): non-integer argument", theArg);
				/* NOT REACHED */
			}
			if( INTVAL(theArg) == 0){
				js_error("(/): division by zero", theArg);
				/* NOT REACHED */
			}
			return newInteger( 1 / INTVAL(theArg) );
		default:
			theArg = NTH_ARG(numArgs, 0);

			if( !ISINTEGER(theArg)){
				POPN(numArgs);
				js_error("(/): non-integer argument", theArg);
				/* NOT REACHED */
			}
			if( INTVAL(theArg) == 0){

				for(int i = 1; i < numArgs; i++){
					
					OBJ nextArg = NTH_ARG(numArgs, i);
					if( !ISINTEGER(nextArg) ){
						POPN(numArgs);
						js_error("(/): non-integer argument", theArg);
						/* NOT REACHED */
					}
					if( INTVAL(nextArg) == 0){
						POPN(numArgs);
						js_error("(/): division by zero", nextArg);
						/* NOT REACHED */
					}
				}
				POPN(numArgs);
				return newInteger(0);
			}
			
			jscheme_int64 quotient = INTVAL(theArg);
			for(int i = 1; i < numArgs; i++){
				
				OBJ nextArg = NTH_ARG(numArgs, i);
				if( !ISINTEGER(nextArg) ){
					POPN(numArgs);
					js_error("(/): non-integer argument", theArg);
					/* NOT REACHED */
				}
				if( INTVAL(nextArg) == 0){
					POPN(numArgs);
					js_error("(/): division by zero", nextArg);
					/* NOT REACHED */
				}

				quotient = quotient / INTVAL(nextArg);
			}
			POPN(numArgs);
			return newInteger(quotient);
	}
	/* NOT REACHED */
	return js_nil;
}
Exemplo n.º 21
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);
}
Exemplo n.º 22
0
/* If there is an error in a thread this will return the thread id */
int
getThreadError(int args)
    {
    return newInteger(ThreadError);
    }