Exemplo n.º 1
0
void Interpreter::subInts() {
    int64_t top = popInt();
    int64_t down = popInt();
    int64_t sub = top - down;

    pushInt(sub);
}
Exemplo n.º 2
0
void Interpreter::iMul() {
	int64_t i1 = popInt();
	int64_t i2 = popInt();

	//cout << "Multiplying " << i1 << " " << i2 << endl;
    pushInt(i1*i2);
}
Exemplo n.º 3
0
void Interpreter::divInts() {
	int64_t right = popInt();
	int64_t left = popInt();

	//cout << "Dividing " << left << " " << right << endl;
    pushInt(left / right);
}
Exemplo n.º 4
0
Arquivo: field.c Projeto: ahua/java
/*
 * Execute the PUTFIELD instruction
 */
void op_putfield() {
    Ref field = resolve(u16(1), ID_FIELD);
    if (field == NULL) { return; } // rollback

    // read values from stack
    Int size = getInt(field, FIELD_SIZE);
    Int flag = getInt(field, FIELD_REFERENCE_FLAG);
    Int value2 = (size == 2) ? popInt() : 0;
    Word value1;
    if (flag) { value1.r = popRef(); }
    else { value1.i = popInt(); }
    Ref object = popRef();

    // check for null pointer
    if (object == NULL) {
        throwException(CORE_THROW_NULL_POINTER);
        return;
    }

    // store the values
    Int index = getInt(field, FIELD_INDEX) + OBJECT_FIELDS;
    if (flag) { setRef(object, index, value1.r); }
    else { setInt(object, index, value1.i); }
    if (size == 2) { setInt(object, index + 1, value2); }
    pc += 3;
}
Exemplo n.º 5
0
void Interpreter::addInts() {
	int64_t top = popInt();
	int64_t down = popInt();
	int64_t sum = top + down;
	pushInt(sum);

	//cout << "adding ints" << endl;
}
Exemplo n.º 6
0
void Interpreter::GJump() {
	int64_t top = popInt();
	int64_t down = popInt();

	int16_t offset = getNext2SBytes();
	if (down > top) {
	    jump(offset);
	    //cout << "Jumping " << offset << endl;
	}
}
Exemplo n.º 7
0
void Interpreter::intsNotEqualJMP() {
	int64_t top = popInt();
	int64_t down = popInt();

	int16_t offset = getNext2SBytes();
	if (top != down) {
        jump(offset);
	    //cout << "Jumping " << offset << endl;
	}
}
int get_integer_parameter( StackFrame *stack, SimpleConstantPool *p)
{
    int value = 0;
    if ( is_ref_entry(stack) ) {
        int index = popInt(stack);
        value = get_integer_from_constant_pool(p, index);
    } else {
        value = popInt(stack);
    }
    return value;
}
// isub
int op_isub( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    int value2 = popInt(stack);
    int value1 = popInt(stack);
    int result = 0;
    result = value1 - value2;
#if SIMPLE_JVM_DEBUG
    printf("isub : %d - %d = %d\n", value1, value2, result);
#endif
    pushInt(stack, result); 
    *opCode = *opCode + 1;
    return 0;
}
Exemplo n.º 10
0
void Interpreter::compareInts() {
    //cout << "Comparing ";

    int64_t top = popInt();
    int64_t down = popInt();

    //cout << down << " " << top << endl;

    int64_t result = (down > top) ? 1 : (down == top) ? 0 : -1;

    pushInt(result);
}
Exemplo n.º 11
0
/* irem */
static int op_irem(unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p)
{
    int value1 = popInt(stack);
    int value2 = popInt(stack);
    int result = 0;
    result = value2 % value1;
#if SIMPLE_JVM_DEBUG
    printf("irem: %d mod %d = %d\n", value2, value1, result);
#endif
    pushInt(stack, result);
    *opCode = *opCode + 1;
    return 0;
}
Exemplo n.º 12
0
Arquivo: instance.c Projeto: ahua/java
/*
 * Execute the ANEWARRAY instruction
 */
void op_anewarray() {
    Ref type = resolve(u16(1), ID_TYPE);
    if (type == NULL) { return; } // rollback, gc done
    Ref arrayType = getRef(type, TYPE_ARRAY_TYPE);

    // resolve array type
    if (arrayType == NULL) {
        Ref target = getRef(core, OBJECT_TYPE);
        Ref method = getRef(core, CORE_RESOLVE_METHOD);
        executeMethod(target, method, 0);
        return; // rollback
    }

    // allocate space
    int length = peekInt(); // don't pop yet in case gc runs
    int numWords = ARRAY_DATA + length;
    Ref array = allocate(numWords, HEADER_OBJECT_ARRAY);
    if (array == NULL) { return; } // rollback, gc done
    popInt(); // pop length

    // initialise array object and push on stack
    int hash = (char*) array - (char*) core;
    setInt(array, OBJECT_HASHCODE, hash);
    setRef(array, OBJECT_TYPE, arrayType);
    setInt(array, ARRAY_LENGTH, length);
    pushRef(array);
    pc += 3;
}
Exemplo n.º 13
0
void Interpreter::loadFunParamsInCtx(uint16_t id) {
    BytecodeFunction* fun = ((BytecodeFunction*)_code->functionById(id));
	uint16_t n = fun->parametersNumber();
    FunctionContext* ctx = this->topContext();

    //cout << "loading params: " << n << endl;
    //cout << "stack size " << _stack.size() << endl;


    for (uint16_t i = 0; i < n; ++i) {
        VarType type = fun->parameterType(i);
        switch (type) {
            case VT_INT:
                ctx->storeInt(ctx->getId(), i, popInt());
                //cout << "int loaded from bc" << endl;
                break;
            case VT_DOUBLE:
            	ctx->storeDouble(ctx->getId(), i, popDouble());
            	//cout << "double loaded from bc" << endl;
            	break;
            default:
            	//cout << "loading STRIG or INVALID from bc" << endl;
            	assert(false);
            	break;
        }
    }
}
Exemplo n.º 14
0
Arquivo: field.c Projeto: ahua/java
/*
 * Execute the PUTSTATIC instruction
 */
void op_putstatic() {
    Ref field = resolve(u16(1), ID_FIELD);
    if (field == NULL) { return; } // rollback
    
    // read field values
    Ref type = getRef(field, ENTRY_OWNER);
    Ref statics = getRef(type, TYPE_STATICS);
    Int index = getInt(field, FIELD_INDEX);
    Int flag = getInt(field, FIELD_REFERENCE_FLAG);
    Int size = getInt(field, FIELD_SIZE);
    int offset = STATICS_FIELDS + index;
    
    // pop values from stack and store
    if (size == 2) { setInt(statics, offset, popInt()); }
    if (flag) { setRef(statics, offset, popRef()); }
    else { setInt(statics, offset, popInt()); }
    pc += 3;
}
//istore_3
int op_istore_3( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    int value = popInt(stack);
#if SIMPLE_JVM_DEBUG
    printf("istore_3: store value into local variable 3(%d)\n", value);
#endif
    localVariables.integer[3] = value;
    *opCode = *opCode + 1;
    return 0;
}
//istore
int op_istore( unsigned char **opCode, StackFrame *stack, SimpleConstantPool *p ) {
    int value = popInt(stack);
    int index = opCode[0][1];
#if SIMPLE_JVM_DEBUG
    printf("istore: store value into local variable %d(%d)\n", index, value);
#endif
    localVariables.integer[index] = value;
    *opCode = *opCode + 2;
    return 0;
}
long long get_long_parameter( StackFrame *stack, SimpleConstantPool *p)
{
    long long value = 0;
    if ( is_ref_entry(stack) ) {
        int index = popInt(stack);
        value = get_long_from_constant_pool(p, index);
    } else {
        value = popLong(stack);
    }
    return value;
}
Exemplo n.º 18
0
static double get_double_parameter(StackFrame *stack, SimpleConstantPool *p)
{
    double value = 0.0f;
    if (is_ref_entry(stack)) {
        int index = popInt(stack);
        value = get_double_from_constant_pool(p, index);
#if SIMPLE_JVM_DEBUG
        printf("index %d\n", index);
        printf("get value from constant pool = %f\n", value);
#endif
    } else {
        value = popDouble(stack);
#if SIMPLE_JVM_DEBUG
        printf("get value from stack = %f\n", value);
#endif
    }
    return value;
}
Exemplo n.º 19
0
Arquivo: instance.c Projeto: ahua/java
/*
 * Execute the NEWARRAY instruction
 */
void op_newarray() {
    // figure out the required size
    int atype = u8(1);
    int width = getWidth(atype);
    int length = peekInt(); // don't pop in case rolled back later
    int numBytes = length * width;
    int extra = ((numBytes % 4) == 0) ? 0 : 1;
    int numDataWords = (numBytes / 4) + extra;
    int numWords = numDataWords + ARRAY_DATA;

    // allocate space
    Ref array = allocate(numWords, HEADER_DATA_ARRAY);
    if (array == NULL) { return; } // rollback, gc done
    popInt(); // can pop the length now

    // initialise new array and push address on stack
    int hash = (char*) array - (char*) core;
    Ref type = getRef(core, CORE_ARRAYS + atype);
    setInt(array, OBJECT_HASHCODE, hash);
    setRef(array, OBJECT_TYPE, type);
    setInt(array, ARRAY_LENGTH, length);
    pushRef(array);
    pc += 2;
}
Exemplo n.º 20
0
/*************************************************************
 * Function: postfixEvaluation ()
 * Created: February 6th, 2012
 * Last Revised: February 10th, 2012
 * Description: This function evaluates a postfix expression
 * Input parameters: the postfix expression
 * Returns: the value of the expression
 * Preconditions: an expression needs to be evaluated
 * Postconditions: an expression has been evaluated
 *************************************************************/
int postfixEvaluation (char *postfixEquation)
{
	// variables
	char *pPostfix, tempMulti[256] = "", tempSingle;
	IntDataStack *tempStack = NULL;
	int value = 0, numA = 0, numB = 0, i = 0, j = 0;

	// setup the infix pointers
	pPostfix = &postfixEquation[0];

	// while we're not at the end of the postfix string...
	while (*pPostfix != '\0')
	{
		// remove any spaces if necessary...
		while(*pPostfix == ' ')
		{
			pPostfix++;
		}
		// if the next character is a digit...
		if(isdigit(*pPostfix))
		{
			// build the integer...
			while (isdigit(*pPostfix))
			{
				tempSingle = *pPostfix;
				tempMulti[i] = tempSingle;
				*pPostfix++;
				i++;
			}
			// push the built integer onto the stack
			pushInt(&tempStack, atoi(tempMulti));
			// move through the integer builder array and clear it
			for (j = 0; j <= i; j++)
			{
				tempMulti[j] = '\0';
			}
			// set i to 0
			i = 0;
		}
		// otherwise...
		else
		{
			// if the next character is an operator...
			if ((*pPostfix == '+') || (*pPostfix == '-') || (*pPostfix == '/') ||
				(*pPostfix == '*') || (*pPostfix == '%'))
			{
				// pop off the last two numbers from the stack
				numB = popInt(&tempStack);
				numA = popInt(&tempStack);

				// if the operator is a +, add the two numbers and push the value onto the stack
				if (*pPostfix == '+')
				{
					value = numA + numB;
					pushInt(&tempStack,value);
				}
				// if the operator is a -, add the two numbers and push the value onto the stack
				else if (*pPostfix ==  '-')
				{
					value = numA - numB;
					pushInt(&tempStack,value);
				}
				// if the operator is a *, add the two numbers and push the value onto the stack
				else if (*pPostfix ==  '*')
				{
					value = numA * numB;
					pushInt(&tempStack,value);
				}
				// if the operator is a /, add the two numbers and push the value onto the stack
				else if (*pPostfix ==  '/')
				{
					value = numA / numB;
					pushInt(&tempStack,value);
				}
				// if the operator is a %, add the two numbers and push the value onto the stack
				else if (*pPostfix ==  '%')
				{
					value = numA % numB;
					pushInt(&tempStack,value);
				}
				// otherwise, say that there was a problem evaluating the expression...
				else
				{
					printf ("Failed to evaluate Expression!\n");
					return -1;
				}
			}
		}
		// if the character is not a null character move to the next
		if (*pPostfix != '\0')
		{
			pPostfix++;
		}
	}
	// pop the final value off the  stack and return it...
	value = popInt(&tempStack);
	return value;
}
Exemplo n.º 21
0
Arquivo: invoke.c Projeto: ahua/java
/*
 * Execute the specified native method. Return true if the method
 * is executed, false if it is rolled back for garbage collection.
 */
int executeNativeMethod(Ref target, Ref method, int offset) {
    int magic = getInt(method, METHOD_MAGIC);
    if (magic == 0) {
        printf("Native method not supported\n");
        debugTrace();
        exit(1);
    }
    switch (magic) {
        // print a debug message
        case MAGIC_RUNTIME_CORE_DEBUG:
            debugLine(popRef());
            pc += offset;
            break;

        // execute the given static method
        case MAGIC_RUNTIME_CORE_EXECUTE_STATIC:
            {
                Ref staticMethod = popRef();
                if (staticMethod  == NULL) {
                    throwException(CORE_THROW_NULL_POINTER);
                    return;
                }
                Ref owner = getRef(staticMethod, ENTRY_OWNER);
                if (!executeMethod(owner, staticMethod, offset)) {
                    // restore stack if rolled back for gc
                    pushRef(staticMethod); 
                }
            }
            break;

        // return the current frame
        case MAGIC_RUNTIME_FRAME_CURRENT:
            pushRef(frame);
            pc += offset;
            break;

        // return the core object
        case MAGIC_RUNTIME_CORE_GET:
            pushRef(core);
            pc += offset;
            break;

        // create a statics object
        case MAGIC_RUNTIME_STATICS_CREATE:
            {
                // allocate space for statics object
                Ref type = popRef();
                Int numStaticFields = getInt(type, TYPE_STATIC_FIELD_COUNT);
                Int numWords = STATICS_FIELDS + numStaticFields;
                Ref statics = allocate(numWords, HEADER_STATIC_FIELDS);
                if (statics == NULL) {
                    pushRef(type); // restore stack
                    return; // rollback, gc done
                }

                // initialise statics object and set in type object
                int hash = (char*) statics - (char*) core;
                setInt(statics, OBJECT_HASHCODE, hash);
                Ref staticsType = getRef(core, CORE_STATICS_TYPE);
                setRef(statics, OBJECT_TYPE, staticsType);
                Ref map = getRef(type, TYPE_STATIC_MAP);
                setRef(statics, STATICS_MAP, map);
                setRef(type, TYPE_STATICS, statics);
            }
            pc += offset;
            break;

        // read the type from a class
        case MAGIC_RUNTIME_CORE_GET_TYPE:
            {
                Ref class = popRef();
                // type is first field in class...
                Ref type = getRef(class, OBJECT_FIELDS);
                pushRef(type);
            }
            pc += offset;
            break;

        // put system to sleep to avoid wasting processor time while idle
        case MAGIC_RUNTIME_IDLE_SLEEP:
            idleSleep();
            pc += offset;
            break;

        // return the currently executing thread
        case MAGIC_RUNTIME_THREAD_CURRENT:
            pushRef(thread);
            pc += offset;
            break;

        // start a new thread
        case MAGIC_RUNTIME_THREAD_START_HOOK:
            startNewThread(offset);
            break;

        // return an object's class
        case MAGIC_JAVA_OBJECT_GET_CLASS:
            {
                Ref obj = popRef();
                Ref type = getRef(obj, OBJECT_TYPE);
                Ref peer = getRef(type, TYPE_PEER);
                pushRef(peer);
            }
            pc += offset;
            break;

        // set system output stream
        case MAGIC_JAVA_SYSTEM_SET_OUT:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_OUT, arg);
            }
            pc += offset;
            break;

        // set system error stream
        case MAGIC_JAVA_SYSTEM_SET_ERR:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_ERR, arg);
            }
            pc += offset;
            break;

        // set system input stream
        case MAGIC_JAVA_SYSTEM_SET_IN:
            {
                Ref arg = popRef();
                Ref type = getRef(method, ENTRY_OWNER);
                Ref statics = getRef(type, TYPE_STATICS);
                setRef(statics, STATICS_FIELDS + SYSTEM_IN, arg);
            }
            pc += offset;
            break;

        // read an ascii character from the console
        case MAGIC_TEST_READ_FROM_CONSOLE:
            {
                char c = readFromConsole();
                pushInt(c);
            }
            pc += offset;
            break;
            
        // write an ascii character to the console
        case MAGIC_TEST_WRITE_TO_CONSOLE:
            {
                char c = popInt() & 0xFF;
                printf("%c", c);
            }
            pc += offset;
            break;

        // read a byte from the floppy drive
        case MAGIC_TEST_READ_FROM_FLOPPY:
            {
                Int pos = popInt();
                pushInt(readFromFloppy(pos));
            }
            pc += offset;
            break;
			
        // magic id not recognised
        default:
            printf("Invalid magic method id: %d\n", magic);
            exit(1);
            break;
    }
}
Exemplo n.º 22
0
/* Read Type 13 charstring. Initial seek to offset performed if offset != -1 */
static void t13Read(cffCtx h, Offset offset, int init, int csLen)
	{
	unsigned length;

	switch (init)
		{
	case cstr_GLYPH:
		/* Initialize glyph charstring */
		h->stack.cnt = 0;
		h->path.nStems = 0;
		h->path.flags = GET_WIDTH|FIRST_MOVE|FIRST_MASK;
		break;
	case cstr_DICT:
		/* Initialize DICT charstring */
		h->path.flags = DICT_CSTR;
		break;
	case cstr_METRIC:
		/* Initialize metric charstring */
		h->stack.cnt = 0;
		h->path.flags = 0;
		break;
		}

	if (offset != -1)
		/* Seek to position of charstring if not already positioned */
		seekbyte(h, offset);

	for (;;)
		{
		int j;
		Fixed a;
		Fixed b;
		int byte0 = GETBYTE(h);
		switch (byte0)
			{
		case t13_endchar:
			if (!(h->path.flags & DICT_CSTR))
				{
				if (h->path.flags & FIRST_MOVE)
					{
					/* Non-marking glyph; set bounds */
					h->path.left = h->path.right = 0;
					h->path.bottom = h->path.top = 0;
					}
				if ((h->path.flags & GET_WIDTH) && setAdvance(h))
					return;	/* Stop after getting width */
				if (h->stack.cnt > 1)
					{
					/* Process seac components */
					int base;
					int accent;
					j = (h->stack.cnt == 4)? 0: 1;
					a = indexFix(h, j++);
					b = indexFix(h, j++);
					base = indexInt(h, j++);
					accent = indexInt(h, j);
					setComponentBounds(h, 0, base, 0, 0);
					setComponentBounds(h, 1, accent, a, b);
					}
				}
			PATH_FUNC_CALL(endchar,(h->cb.ctx));
			h->path.flags |= SEEN_END;
			return;
		case t13_reserved0:
		case t13_reserved236:
		case t13_reserved237:
		case t13_reserved244:
		case t13_reserved255:
			fatal(h, "reserved charstring op");
		case t13_rlineto:
			for (j = 0; j < h->stack.cnt; j += 2)
				addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			h->stack.cnt = 0;
			break;
		case t13_hlineto:
		case t13_vlineto:
			{
			int horz = byte0 == t13_hlineto;
			for (j = 0; j < h->stack.cnt; j++)
				if (horz++ & 1)
					addLine(h, indexFix(h, j), 0);
				else
					addLine(h, 0, indexFix(h, j));
			}
			h->stack.cnt = 0;
			break;
		case t13_rrcurveto:
			for (j = 0; j < h->stack.cnt; j += 6)
				addCurve(h, 0,
						 indexFix(h, j + 0), indexFix(h, j + 1), 
						 indexFix(h, j + 2), indexFix(h, j + 3), 
						 indexFix(h, j + 4), indexFix(h, j + 5));
			h->stack.cnt = 0;
			break;
		case t13_callsubr:
			{
			Offset save = TELL(h);
			Offset localOffset = INDEXGet(h, &h->index.Subrs, popInt(h) + 
										  h->index.Subrs.bias, &length);
			t13Read(h, localOffset, cstr_NONE, length);
			if (h->path.flags & SEEN_END)
				return;		/* endchar operator terminated subr */
			seekbyte(h, save);
			}
			break;
		case t13_return:
			return;
		case t13_rcurveline:
			for (j = 0; j < h->stack.cnt - 2; j += 6)
				addCurve(h, 0,
						 indexFix(h, j + 0), indexFix(h, j + 1), 
						 indexFix(h, j + 2), indexFix(h, j + 3), 
						 indexFix(h, j + 4), indexFix(h, j + 5));
			addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			h->stack.cnt = 0;
			break;
		case t13_rlinecurve:
			for (j = 0; j < h->stack.cnt - 6; j += 2)
				addLine(h, indexFix(h, j + 0), indexFix(h, j + 1));
			addCurve(h, 0,
					 indexFix(h, j + 0), indexFix(h, j + 1), 
					 indexFix(h, j + 2), indexFix(h, j + 3), 
					 indexFix(h, j + 4), indexFix(h, j + 5));
			h->stack.cnt = 0;
			break;
		case t13_vvcurveto:
			if (h->stack.cnt & 1)
				{
				/* Add initial curve */
				addCurve(h, 0,
						 indexFix(h, 0), indexFix(h, 1), 
						 indexFix(h, 2), indexFix(h, 3), 
						 0,				 indexFix(h, 4));
				j = 5;
				}
			else
				j = 0;

			/* Add remaining curve(s) */
			for (; j < h->stack.cnt; j += 4)
				addCurve(h, 0,
						 0, 				 indexFix(h, j + 0), 
						 indexFix(h, j + 1), indexFix(h, j + 2), 
						 0, 				 indexFix(h, j + 3));
			h->stack.cnt = 0;
			break;
		case t13_hhcurveto:
			if (h->stack.cnt & 1)
				{
				/* Add initial curve */
				addCurve(h, 0,
						 indexFix(h, 1), indexFix(h, 0), 
						 indexFix(h, 2), indexFix(h, 3), 
						 indexFix(h, 4), 0);
				j = 5;
				}
			else
				j = 0;

			/* Add remaining curve(s) */
			for (; j < h->stack.cnt; j += 4)
				addCurve(h, 0,
						 indexFix(h, j + 0), 0,
						 indexFix(h, j + 1), indexFix(h, j + 2), 
						 indexFix(h, j + 3), 0);
			h->stack.cnt = 0;
			break;
		case t13_callgsubr:
			{
			Offset save = TELL(h);
			Offset localOffset = INDEXGet(h, &h->index.global, popInt(h) + 
											  h->index.global.bias, &length);
			t13Read(h, localOffset, cstr_NONE, length);
			if (h->path.flags & SEEN_END)
				return;		/* endchar operator terminated subr */
			seekbyte(h, save);
			}
			break;
		case t13_vhcurveto:
		case t13_hvcurveto:
			{
			int adjust = (h->stack.cnt & 1)? 5: 0;
			int horz = byte0 == t13_hvcurveto;

			/* Add initial curve(s) */
			for (j = 0; j < h->stack.cnt - adjust; j += 4)
				if (horz++ & 1)
					addCurve(h, 0,
							 indexFix(h, j + 0), 0,
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 0,				     indexFix(h, j + 3));
				else
					addCurve(h, 0,
							 0,				     indexFix(h, j + 0),
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 3), 0);

			if (j < h->stack.cnt)
				{
				/* Add last curve */
				if (horz & 1)
					addCurve(h, 0,
							 indexFix(h, j + 0), 0,
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 4), indexFix(h, j + 3));
				else
					addCurve(h, 0,
							 0,				     indexFix(h, j + 0),
							 indexFix(h, j + 1), indexFix(h, j + 2), 
							 indexFix(h, j + 3), indexFix(h, j + 4));
				}
			h->stack.cnt = 0;
			}
			break;
		case t13_rmoveto:
			b = popFix(h);
			a = popFix(h);
			if (addMove(h, a, b))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_hmoveto:
			if (addMove(h, popFix(h), 0))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_vmoveto:
			if (addMove(h, 0, popFix(h)))
				return;	/* Stop after getting width */
			h->stack.cnt = 0;
			break;
		case t13_hstem:
		case t13_vstem:
		case t13_hstemhm:
		case t13_vstemhm:
			if ((h->path.flags & GET_WIDTH) && setAdvance(h))
				return;	/* Stop after getting width */
			h->path.nStems += h->stack.cnt / 2;
			if (PATH_FUNC_DEFINED(hintstem))
				{
				int vert = byte0 == tx_vstem || byte0 == t2_vstemhm;
				b = vert? h->path.vstem: h->path.hstem;
				for (j = h->stack.cnt & 1; j < h->stack.cnt; j += 2)
					{
					a = b + indexFix(h, j);
					b = a + indexFix(h, j + 1);
					h->path.cb->hintstem(h->cb.ctx, vert, a, b);
					}
				if (vert)
					h->path.vstem = b;
				else
					h->path.hstem = b;
				}
			h->stack.cnt = 0;
			break;
		case t13_hintmask:
		case t13_cntrmask:
			{
			int cnt;
			if (h->path.flags & FIRST_MASK)
				{
				/* The vstem(hm) op may be omitted if stem list is followed by
				   a mask op. In this case count the additional stems */
				if (PATH_FUNC_DEFINED(hintstem))
					{
					b = h->path.vstem;
					for (j = h->stack.cnt & 1; j < h->stack.cnt; j += 2)
						{
						a = b + indexFix(h, j);
						b = a + indexFix(h, j + 1);
						h->path.cb->hintstem(h->cb.ctx, 1, a, b);
						}
					}
				h->path.nStems += h->stack.cnt / 2;
				h->stack.cnt = 0;
				h->path.flags &= ~FIRST_MASK;
				}
			cnt = (h->path.nStems + 7) / 8;
			if (PATH_FUNC_DEFINED(hintmask))
				{
				char mask[CFF_MAX_MASK_BYTES];
				for (j = 0; j < cnt; j++)
					mask[j] = GETBYTE(h);
				h->path.cb->hintmask(h->cb.ctx, 
									 byte0 == t2_cntrmask, cnt, mask);
				}
			else
				while (cnt--)
					(void)GETBYTE(h);	/* Discard mask bytes */
			}
			break;
		case t13_escape:
			{
			double x;
			double y;
			switch (t13_ESC(GETBYTE(h)))
				{
			case t13_dotsection:
				break;
			default:
			case t13_reservedESC255:
			case t13_cntron:
				fatal(h, "reserved charstring op");
			case t13_and:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a && b);
				break;
			case t13_or:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a || b);
				break;
			case t13_not:
				a = popFix(h);
				pushInt(h, !a);
				break;
			case t13_store:
				{
				int count = popInt(h);
				int i = popInt(h);
				int j = popInt(h);
				int iReg = popInt(h);
				int regSize;
				Fixed *reg = selRegItem(h, iReg, &regSize);
				if (i < 0 || i + count - 1 >= h->BCA.size ||
					j < 0 || j + count - 1 >= regSize)
					fatal(h, "bounds check (store)\n");
				memcpy(&reg[j], &h->BCA.array[i], sizeof(Fixed) * count);
				}
				break;
			case t13_abs:
				a = popFix(h);
				pushFix(h, (a < 0)? -a: a);
				break;
			case t13_add:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, a + b);
				break;
			case t13_sub:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, a - b);
				break;
			case t13_div:
				y = popDbl(h);
				x = popDbl(h);
				if (y == 0.0)
					fatal(h, "divide by zero (div)");
				pushFix(h, DBL2FIX(x / y));
				break;
			case t13_load:
				{
				int regSize;
				int count = popInt(h);
				int i = popInt(h);
				int iReg = popInt(h);
				Fixed *reg = selRegItem(h, iReg, &regSize);
				if (i < 0 || i + count - 1 >= h->BCA.size || count > regSize)
					fatal(h, "bounds check (load)\n");
				memcpy(&h->BCA.array[i], reg, sizeof(Fixed) * count);
				}
				break;
			case t13_neg:
				a = popFix(h);
				pushFix(h, -a);
				break;
			case t13_eq:
				b = popFix(h);
				a = popFix(h);
				pushInt(h, a == b);
				break;
			case t13_drop:
				(void)popFix(h);
				break;
			case t13_put:
				{
				int i = popInt(h);
				if (i < 0 || i >= h->BCA.size)
					fatal(h, "bounds check (put)\n");
				h->BCA.array[i] = popFix(h);
				}
				break;
			case t13_get:
				{
				int i = popInt(h);
				if (i < 0 || i >= h->BCA.size)
					fatal(h, "bounds check (get)\n");
				pushFix(h, h->BCA.array[i]);
				}
				break;
			case t13_ifelse:
				{
				Fixed v2 = popFix(h);
				Fixed v1 = popFix(h);
				Fixed s2 = popFix(h);
				Fixed s1 = popFix(h);
				pushFix(h, (v1 > v2)? s2: s1);
				}
				break;
			case t13_random:	
				pushFix(h, PMRand());
				break;
			case t13_mul:
				y = popDbl(h);
				x = popDbl(h);
				pushFix(h, DBL2FIX(x * y));
				break;
			case t13_sqrt:
				pushFix(h, FixedSqrt(popFix(h)));
				break;
			case t13_dup:
				pushFix(h, h->stack.array[h->stack.cnt - 1].f);
				break;
			case t13_exch:
				b = popFix(h);
				a = popFix(h);
				pushFix(h, b);
				pushFix(h, a);
				break;
			case t13_index:
				{
				int i = popInt(h);
				if (i < 0)
					i = 0;	/* Duplicate top element */
				if (i >= h->stack.cnt)
					fatal(h, "limit check (index)");
				pushFix(h, h->stack.array[h->stack.cnt - 1 - i].f);
				}
				break;
			case t13_roll:
				{
				int j = popInt(h);
				int n = popInt(h);
				int iTop = h->stack.cnt - 1;
				int iBottom = h->stack.cnt - n;

				if (n < 0 || iBottom < 0)
					fatal(h, "limit check (roll)");

				/* Constrain j to [0,n) */
				if (j < 0)
					j = n - (-j % n);
				j %= n;

				reverse(h, iTop - j + 1, iTop);
				reverse(h, iBottom, iTop - j);
				reverse(h, iBottom, iTop);
				}
				break;
			case t13_hflex:
				addCurve(h, 1,
						 indexFix(h, 0),  0,
						 indexFix(h, 1),  indexFix(h, 2),
						 indexFix(h, 3),  0);
				addCurve(h, 1,
						 indexFix(h, 4),  0,
						 indexFix(h, 5),  0,
						 indexFix(h, 6), -indexFix(h, 2));
				h->stack.cnt = 0;
				break;
			case t13_flex:
				addCurve(h, 1,
						 indexFix(h, 0),  indexFix(h, 1),
						 indexFix(h, 2),  indexFix(h, 3),
						 indexFix(h, 4),  indexFix(h, 5));
				addCurve(h, 1,
						 indexFix(h, 6),  indexFix(h, 7),
						 indexFix(h, 8),  indexFix(h, 9),
						 indexFix(h, 10), indexFix(h, 11));
				h->stack.cnt = 0;
				break;
			case t13_hflex1:
				{
				Fixed dy1 = indexFix(h, 1);
				Fixed dy2 = indexFix(h, 3);
				Fixed dy5 = indexFix(h, 7);
				addCurve(h, 1,
						 indexFix(h, 0),  dy1,
						 indexFix(h, 2),  dy2,
						 indexFix(h, 4),  0);		  
				addCurve(h, 1,
						 indexFix(h, 5),  0,		  
						 indexFix(h, 6),  dy5,
						 indexFix(h, 8),  -(dy1 + dy2 + dy5));
				}
				h->stack.cnt = 0;
				break;
			case t13_flex1:
				{
				Fixed dx1 = indexFix(h, 0);
				Fixed dy1 = indexFix(h, 1);
				Fixed dx2 = indexFix(h, 2);
				Fixed dy2 = indexFix(h, 3);
				Fixed dx3 = indexFix(h, 4);
				Fixed dy3 = indexFix(h, 5);
				Fixed dx4 = indexFix(h, 6);
				Fixed dy4 = indexFix(h, 7);
				Fixed dx5 = indexFix(h, 8);
				Fixed dy5 = indexFix(h, 9);
				Fixed dx = dx1 + dx2 + dx3 + dx4 + dx5;
				Fixed dy = dy1 + dy2 + dy3 + dy4 + dy5;
				if (ABS(dx) > ABS(dy))
					{
					dx = indexFix(h, 10);
					dy = -dy;
					}
				else
					{
					dx = -dx;
					dy = indexFix(h, 10);
					}
				addCurve(h, 1, dx1, dy1, dx2, dy2, dx3, dy3);
				addCurve(h, 1, dx4, dy4, dx5, dy5,  dx,  dy);
				}
				h->stack.cnt = 0;
				break;
				}
			}
			break;
		case t13_blend:
			blendValues(h);
			break;
		default:
			/* Matches 1..215, result -107..107 */
			pushInt(h, 108 - byte0);
			break;
		case 241:
			/* 108..363 */
			pushInt(h, 363 - GETBYTE(h));
			break;
		case 239:
			/* 364..619 */
			pushInt(h, 619 - GETBYTE(h));
			break;
		case 246:
			/* 620..875 */
			pushInt(h, GETBYTE(h) + 620);
			break;
		case 235:
			/* 876..1131 */
			pushInt(h, 1131 - GETBYTE(h));
			break;
		case 232:
			/* -108..-363 */
			pushInt(h, GETBYTE(h) - 363);
			break;
		case 228:
			/* -364..-619 */
			pushInt(h, GETBYTE(h) - 619);
			break;
		case 224:
			/* -620..-875 */
			pushInt(h, GETBYTE(h) - 875);
			break;
		case 220:
			/* -876..-1131 */
			pushInt(h, GETBYTE(h) - 1131);
			break;
		case t13_shortint:
			{
			/* 2 byte number */
			long byte1 = GETBYTE(h);
			pushInt(h, byte1<<8 | GETBYTE(h));
			}
			break;
		case t13_shftshort:
			{
			long byte1 = GETBYTE(h);
			pushFix(h, byte1<<23 | GETBYTE(h)<<15);
			}
			break;
		case 254:
			{
			/* 5 byte number */
			long byte1 = GETBYTE(h);
			long byte2 = GETBYTE(h);
			long byte3 = GETBYTE(h);
			pushFix(h, byte1<<24 | byte2<<16 | byte3<<8 | GETBYTE(h));
			}
			break;
			}
		}
	}
Exemplo n.º 23
0
Arquivo: invoke.c Projeto: ahua/java
/*
 * Execute the specified method. Return true if the method is executed,
 * false if it is rolled back for garbage collection.
 *
 * target: object for instance methods, class for static
 * method: the method to be run
 * offset: amount to increment program counter
 */
int executeMethod(Ref target, Ref method, int offset) {
/*
printf("[");
if (method[ENTRY_FLAGS].i & ACC_STATIC) { debugString(target[TYPE_NAME].s); }
else { debugString(method[ENTRY_OWNER].s[TYPE_NAME].s); }
printf(".");
debugString(method[ENTRY_NAME].s);
debugString(method[ENTRY_DESCRIPTOR].s);
printf("]\n");
*/
    // check for native method
    Int argcount = getInt(method, METHOD_ARG_COUNT);
    Int flags = getInt(method, ENTRY_FLAGS);
    if (flags & ACC_NATIVE) {
        return executeNativeMethod(target, method, offset);
    }

    // if synchronized, acquire the lock
    Ref lock = NULL;
    if (flags & ACC_SYNCHRONIZED) {
        lock = getLock(target);
        if (lock == NULL) { return FALSE; } // rollback, gc done
        acquireLock(thread, lock, 0);
        if (thread == NULL) { return FALSE; } // rollback, wait for lock 
    }

    // allocate space for new frame
    Int maxLocals = getInt(method, METHOD_MAX_LOCALS);
    Int maxStack = getInt(method, METHOD_MAX_STACK);
    int numWords = FRAME_LOCALS + 2*maxLocals + 2*maxStack;
    Ref newFrame = allocate(numWords, HEADER_STACK_FRAME);
    if (newFrame == NULL) { return FALSE; } // rollback, gc done

    // increment lock count now that instruction can't be rolled back
    if (flags & ACC_SYNCHRONIZED) {
        Int count = getInt(lock, LOCK_COUNT);
        setInt(lock, LOCK_COUNT, count + 1);
    }

    // initialise new frame
    int hash = (char*) newFrame - (char*) core;
    Ref frameType = getRef(frame, OBJECT_TYPE);
    setInt(newFrame, OBJECT_HASHCODE, hash);
    setRef(newFrame, OBJECT_LOCK, lock);
    setRef(newFrame, OBJECT_TYPE, frameType);
    setRef(newFrame, FRAME_RETURN_FRAME, frame);
    setRef(newFrame, FRAME_METHOD, method);
    setInt(newFrame, FRAME_RETURN_PC, pc + offset);
    setInt(newFrame, FRAME_PC, 0);
    setInt(newFrame, FRAME_SP, numWords * 4);

    // pop arguments off current stack and write to new frame
    int index = argcount;
    while (--index >= 0) {
        if (refOnStack()) { setLocalRef(index, popRef(), newFrame); }
        else { setLocalInt(index, popInt(), newFrame); }
    }

    // point current thread to new frame
    saveRegisters();
    setRef(thread, THREAD_FRAME, newFrame);
    loadRegisters();
    return TRUE;
}
Exemplo n.º 24
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.º 25
0
void BenchmarkTcpClient::handle(Event &event, long long) {
	if (&event == &eventRead) {
		int prevSize = readBuffer.size();
		readBuffer.reserve(1024);
		readBuffer.push(socket->read(readBuffer.end(), 1024));
		receviedSize += readBuffer.size() - prevSize;
		eventRead.setTimeRelativeNow();

		if (readBuffer.empty()) return;
		if (!writeBuffer.empty())
			{ formatError(); return; }

		if (server) {
			if (hasInt() && !requestsCount) {
				requestsCount = popInt();
				if (requestsCount <= 0)
					{ formatError(); return; }
				requestsCountRemain = requestsCount;
			}
			if (hasInt() && !requestSize) {
				requestSize = popInt();
				if (requestSize <= 0)
					{ formatError(); return; }
				if (requestsCountRemain <= 0)
					{ formatError(); return; }
				--requestsCountRemain;
			}
			if (hasInt() && !answerSize) {
				answerSize = popInt();
				if (answerSize <= 0)
					{ formatError(); return; }
				requestSizeRemain = requestSize;
			}
			if (requestSizeRemain > 0) {
				currentCrc32 = Packet::crc32(readBuffer.begin(), readBuffer.size(), currentCrc32);
				requestSizeRemain -= readBuffer.size();
				readBuffer.clear();
				if (requestSizeRemain < 0)
					{ formatError(); return; }
				if (requestSizeRemain == 0) {
					currentSeed = currentCrc32;
					currentCrc32 = 0;
					answerSizeRemain = answerSize;
					buildWriteChunk();
				}
			}
		} else {
			while(!empty()) {
				if (answerSizeRemain <= 0 || pop() != (char)((int)random(currentSeed)%256 - 128))
					{ formatError(); return; }
				--answerSizeRemain;
			}
			if (answerSizeRemain == 0) {
				if (requestsCountRemain == 0)
					{ socket->close(); return; }
				requestSizeRemain = requestSize;
				buildWriteChunk();
			}
		}
	} else
	if (&event == &eventWrite) {
		if (writeBuffer.empty()) return;
		if (!readBuffer.empty())
			{ formatError(); return ; }

		if (!writeBuffer.empty())
			writeBuffer.pop(socket->write(writeBuffer.begin(), writeBuffer.size()));
		buildWriteChunk();
		if (!writeBuffer.empty())
			eventWrite.setTimeRelativeNow();
	} else
	if (&event == &eventClose) {
		if ( !socket->wasError()
		  && requestsCountRemain == 0
		  && requestSizeRemain == 0
		  && answerSizeRemain == 0
		  && readBuffer.empty()
		  && writeBuffer.empty())
			endUs = Platform::nowUs();
		delete this;
	}
}
Exemplo n.º 26
0
Arquivo: control.c Projeto: ahua/java
/*
 * Execute the IF_ICMPEQ instruction
 */
void op_if_icmpeq() {
    int value2 = popInt();
    int value1 = popInt();
    if (value1 == value2) { pc += s16(1); }
    else { pc += 3; }
}
Exemplo n.º 27
0
Arquivo: control.c Projeto: ahua/java
/*
 * Execute the IFLE instruction
 */
void op_ifle() {
    if (popInt() <= 0) { pc += s16(1); }
    else { pc += 3; }
}
Exemplo n.º 28
0
Arquivo: control.c Projeto: ahua/java
/*
 * Execute the IFGT instruction
 */
void op_ifgt() {
    if (popInt() > 0) { pc += s16(1); }
    else { pc += 3; }
}
Exemplo n.º 29
0
Arquivo: control.c Projeto: ahua/java
/*
 * Execute the IFNE instruction
 */
void op_ifne() {
    if (popInt() != 0) { pc += s16(1); }
    else { pc += 3; }
}
Exemplo n.º 30
0
Arquivo: control.c Projeto: ahua/java
/*
 * Execute the IFEQ instruction
 */
void op_ifeq() {
    if (popInt() == 0) { pc += s16(1); }
    else { pc += 3; }
}