Exemple #1
0
void sameRight()
{
	InterCode h=code_h;
	while(h!=NULL)
	{
		if(h->kind==ADD_K||h->kind==SUB_K||h->kind==MUL_K||h->kind==DIV_K)
		{
			if(h->u.binop.result->kind==TEMPVAR)
			{
				Operand r=h->u.binop.result;
				Operand op1=h->u.binop.op1;
				Operand op2=h->u.binop.op2;
				InterCode p=h->next;
				while(p!=NULL&&p->kind!=RETURN_K&&p->kind!=GOTO_K&&p->kind!=IFGOTO_K&&p->kind!=CALL_K&&p->kind!=LABEL_K&&p->kind!=FUNCTION_K)
				{
					if(p->kind==READ_K&&(p->u.one.op->kind==TADDRESS||p->u.one.op->kind==VADDRESS||opEqual(p->u.one.op,op1)||opEqual(p->u.one.op,op2)))break;
					if((p->kind==CALL_K||p->kind==ASSIGN_K||p->kind==RIGHTAT_K)&&(p->u.assign.left->kind==TADDRESS||p->u.assign.left->kind==VADDRESS||opEqual(p->u.assign.left,op1)||opEqual(p->u.assign.left,op2)))break;
					if((p->kind==ADD_K||p->kind==SUB_K||p->kind==MUL_K||p->kind==DIV_K)&&(p->u.binop.result->kind==TADDRESS||p->u.binop.result->kind==VADDRESS||opEqual(p->u.binop.result,op1)||opEqual(p->u.binop.result,op2)))break;
					if(p->kind==h->kind&&p->u.binop.result->kind==TEMPVAR&&opEqual(p->u.binop.op1,op1)&&opEqual(p->u.binop.op2,op2))
					{
						p->u.binop.result->u.var_no=r->u.var_no;
						InterCode temp=p;
						p=p->next;
						deleteCode(temp);
						continue;
					}
					p=p->next;
				}
			}
		}
		h=h->next;
	}
}
Exemple #2
0
void VirtualMachine::execute(std::string function) {

    NamespaceEntry functionEntry;

    if (!VM::NamespaceEntry::searchNamespace(namespace_, function,
            functionEntry) || functionEntry.getType() != Function) {
        VM_PRINTF_FATAL("%s is not a registered function\n", function.c_str());
    }

    currentFunction = functionEntry.getFunction();

    if (currentFunction->isNative()) {
        currentFunction->getFunction()->execute(this);
        return;
    }

    InstructionSet instructionSet = currentFunction->getInstructions();

    currentInstruction = instructionSet.getStartLocation();

    shouldReturn = false;

    while (!shouldReturn) {

        //If the current PC is above the number of instructions in this function then attempt to return. Else execute the instruction at the PC.
        if (currentInstruction >= instructionSet.getSizeInBytes()) {

            if (!returnToPreviousFunction(currentFunction, instructionSet)) {
                shouldReturn = true;
            }

        } else {

            switch (instructionSet.getByte(currentInstruction)) {

            /**
             *  Loads the constant data at the specified constant index into the given register.
             *  Capable of loading elements into the heap and assigning their reference if their initial data is already known ( Such as pushing strings ).
             */

            case OpLoadConstant: {
                opLoadConstant(instructionSet);
                break;
            }

            /**
             * Copy whatever is in the target register into the destination register copying over whether it is a reference or not.
             */

            case OpMove: {
                opMove(instructionSet);
                break;
            }

            /**
             * Jump to a different instruction
             */

            case OpJump: {
                opJump(instructionSet);
                break;
            }

            /**
             * Add the left and right registers and place the result in the dest register.
             */

            case OpAdd: {
                opAdd(instructionSet);
                break;
            }

            /**
             * Subtract the left and right registers and place the result in the dest register.
             */

            case OpSub: {
                opSub(instructionSet);
                break;
            }

            /**
             * Multiply the left and right registers and place the result in the dest register.
             */

            case OpMul: {
                opMul(instructionSet);
                break;
            }

            /**
             * Divide the left and right registers and place the result in the dest register.
             */

            case OpDiv: {
                opDiv(instructionSet);
                break;
            }

            case OpInc: {
                opInc(instructionSet);
                break;
            }

            case OpDec: {
                opDec(instructionSet);
                break;
            }

            case OpNot: {
                opNot(instructionSet);
                break;
            }

            case OpAddFloat32: {
                opAddFloat32(instructionSet);
                break;
            }

            case OpSubFloat32: {
                opSubFloat32(instructionSet);
                break;
            }

            case OpMulFloat32: {
                opMulFloat32(instructionSet);
                break;
            }

            case OpDivFloat32: {
                opDivFloat32(instructionSet);
                break;
            }

            case OpCmpFloat32: {
                opCmpFloat32(instructionSet);
                break;
            }

            /**
             * Test if two registers are equal. If true then execute the next instruction else skip it.
             */

            case OpEqual: {
                opEqual(instructionSet);
                break;
            }

            case OpNotEqual: {
                opNotEqual(instructionSet);
                break;
            }

            case OpEqualZero: {
                opEqualZero(instructionSet);
                break;
            }

            /**
             *  Test if one register is less than another. If true execute next instruction otherwise skip it.
             */

            case OpLessThan: {
                opLessThan(instructionSet);
                break;
            }

            case OpGreaterThan: {
                opGreaterThan(instructionSet);
                break;
            }

            case OpGreaterThanOrEqual: {
                opGreaterThanOrEqual(instructionSet);
                break;
            }

            /**
             * OpPushRegisters
             * Push registers, starting from the start register and pushing numregisters sequentially from it
             * StartRegister - Offset 1 - 1 byte
             * NumRegisters - Offset 2 - 1 byte
             */
            case OpPushRegisters: {
                opPushRegisters(instructionSet);
                break;
            }

            /**
             * Pop n registers starting from the start+nth register and the last pop acting on the start register
             */
            case OpPopRegisters: {
                opPopRegisters(instructionSet);
                break;
            }

            /**
             * Pop a long from the stack and ignore it ( Don't put it in any registers ).
             */

            case OpPopNil: {
                opPopNil(instructionSet);
                break;
            }

            /**
             * Test whether the register left's value is <= than the register right.
             * If true execute the next instruction
             * Else skip the next function.
             */

            case OpLessThanOrEqual: {
                opLessThanOrEqual(instructionSet);
                break;
            }

            case OpStructGetField: {
                opStructGetField(instructionSet);
                break;
            }

            case OpStructSetField: {
                opStructSetField(instructionSet);
                break;
            }

            /**
             * Set the specified element in the target array to the given data value.
             */

            case OpArraySet: {
                opArraySet(instructionSet);
                break;
            }

            /**
             * Set the dataRegisters value to be the value of the array at the specified index.
             */

            case OpArrayGet: {
                opArrayGet(instructionSet);
                break;
            }

            case OpNewStruct: {
                opNewStruct(instructionSet);
                break;
            }

            /**
             * Create a new array of the specified type ( Stored in constants ) and length ( The value of lengthRegister ) and set its reference to the specified register.
             */

            case OpNewArray: {
                opNewArray(instructionSet);
                break;
            }

            /**
             * Set the value of dest register to be the length of the array pointed to by the value of the array length register.
             */

            case OpArrayLength: {
                opArrayLength(instructionSet);
                break;
            }

            /**
             * Call the specified function. Two modes Constant or Heap. If Constant mode name of function is stored in constant instruction set zone otherwise name of function is pointed to by string in heap specified by register.
             */

            case OpCallFn: {
                opCallFn(instructionSet);
                break;
            }

            /**
             * Return to the previous function that was running or exit.
             */

            case OpReturn: {
                opReturn(instructionSet);
                break;
            }

            default: {
                VM_PRINTF_FATAL("Invalid instruction %li. %ii\n",
                                currentInstruction, instructionSet.getByte(currentInstruction));
                return;
            }

            }

            //After each instruction check the gcStat and
            //if it has hit the hit limit then run the garbage collector.

            if (gcStat_ > GarbageCollectHitLimit) {
                garbageCollection();
                gcStat_ = 0;
            }

        }

    }

    //As the function exits run the garbage collector and reset the GC stat value
    garbageCollection();
    gcStat_ = 0;

}
Exemple #3
0
void rddCode()
{
	InterCode top=code_t;
	InterCode bottom=code_t;
	//from buttom to top
	while(1)
	{
		//find a block
		bottom=top->pre;
		if(bottom==NULL)break;
		top=bottom->pre;
		if(top==NULL)break;
		while(top!=NULL)
		{
			if(top->kind==RETURN_K||top->kind==GOTO_K||top->kind==IFGOTO_K||top->kind==CALL_K)
			{
				top=top->next;
				break;
			}
			else if(top->kind==LABEL_K||top->kind==FUNCTION_K)
				break;
			top=top->pre;
		}
		if(top==NULL)top=code_h;
		if(bottom==top)continue;

		//deal with this block
		while(bottom!=NULL&&bottom!=top->pre)
		{
			Operand noAct=NULL;
			InterCode p=bottom;
			int flag=0;
			if(p->kind==ASSIGN_K)
			{
				if(p->u.assign.left->kind==VARIABLE&&!opEqual(p->u.assign.left,p->u.assign.right))
				{
					noAct=p->u.assign.left;
					flag=1;
				}
			}
			else if(p->kind==ADD_K||p->kind==SUB_K||p->kind==MUL_K||p->kind==DIV_K)
			{
				if(p->u.binop.result->kind==VARIABLE&&!opEqual(p->u.binop.result,p->u.binop.op1)&&!opEqual(p->u.binop.result,p->u.binop.op2))
				{
					noAct=p->u.binop.result;
					flag=1;
				}
			}

			if(flag)
			{
				p=p->pre;
				while(p!=NULL&&p!=top->pre)
				{
					if(p->kind==ASSIGN_K||p->kind==CALL_K)
					{
						if(opEqual(noAct,p->u.assign.right)||p->u.assign.left->kind==VADDRESS)break;
						if(p->u.assign.right->kind==VADDRESS||p->u.assign.right->kind==TADDRESS)break;
						if(opEqual(noAct,p->u.assign.left))
						{
							InterCode temp=p;
							p=p->pre;
							deleteCode(temp);
							continue;
						}
					}
					else if(p->kind==ADD_K||p->kind==SUB_K||p->kind==MUL_K||p->kind==DIV_K)
					{
						if(opEqual(noAct,p->u.binop.op1)||opEqual(noAct,p->u.binop.op2))
							break;
						if(p->u.binop.result->kind==VADDRESS)break;
						if(p->u.binop.op1->kind==VADDRESS||p->u.binop.op1->kind==TADDRESS)break;
						if(p->u.binop.op2->kind==VADDRESS||p->u.binop.op2->kind==TADDRESS)break;
						if(opEqual(noAct,p->u.binop.result))
						{
							InterCode temp=p;
							p=p->pre;
							deleteCode(temp);
							continue;
						}
					}
					else if(p->kind==READ_K)
					{
						if(p->u.one.op->kind==VADDRESS)break;
						if(opEqual(noAct,p->u.one.op))
						{
							InterCode temp=p;
							p=p->pre;
							deleteCode(temp);
							continue;
						}
					}
					else if(p->kind==WRITE_K||p->kind==ARG_K||p->kind==PARAM_K)
					{
						if(opEqual(noAct,p->u.one.op)||p->u.one.op->kind==VADDRESS||p->u.one.op->kind==TADDRESS)
							break;
					}
					else if(p->kind==RIGHTAT_K)
					{
						if(opEqual(noAct,p->u.assign.right)||p->u.assign.left->kind==VADDRESS)break;
						if(p->u.assign.right->kind==VADDRESS||p->u.assign.right->kind==TADDRESS)break;
						if(opEqual(noAct,p->u.assign.left))
						{
							InterCode temp=p;
							p=p->pre;
							deleteCode(temp);
							continue;
						}
					}
					p=p->pre;
				}
			}
			bottom=bottom->pre;
		}
	}
}