Esempio n. 1
0
        // macro-arrNotEndOrExit
        // advance array index and reset and return/terminate if its over
        // else jump relative
        public static void macroArrayNotEndOrExit(GlobalInterpreterState globalState, LocalInterpreterState localState, int ipDelta, out bool success)
        {
            if (globalState.arrayState == null)
            {
                success = false;
                return;
            }

            bool isIndexValid = globalState.arrayState.isIndexValid;

            if (!isIndexValid)
            {
                globalState.arrayState.index = 0;
                Operations.@return(localState, out success);
                return;
            }

            localState.instructionPointer++;
            localState.instructionPointer += ipDelta;

            success = true;
        }
Esempio n. 2
0
        // \param indirectCall is not -1 if the instruction is an indirect call to another function
        public static void dispatch(
            GlobalInterpreterState globalState,
            LocalInterpreterState localState,
            Instruction instr,
            out bool success,
            out int indirectCall
            )
        {
            indirectCall = -1;

            uint instructionWithoutRelative;
            int  relative;

            decodeInstruction(instr.code, out instructionWithoutRelative, out relative);

            switch (instructionWithoutRelative)
            {
            case INSTRUCTION_RET: Operations.@return(localState, out success); return;

            case 1: ArrayOperations.macroArrayAdvanceOrExit(globalState, localState, relative, out success); return;

            case 2: ArrayOperations.macroArrayNotEndOrExit(globalState, localState, relative, out success); return;

            case 3: Operations.jump(localState, relative); success = true; return;

            case 4: Operations.jumpIfNotFlag(localState, relative); success = true; return;

            case 5: Operations.call(localState, relative); success = true; return;

            case 6: ArrayOperationsTwoArgumentWrapper.arrayMove(globalState, localState, -1, int.MaxValue, out success); return;

            case 7: ArrayOperationsTwoArgumentWrapper.arrayMove(globalState, localState, 1, int.MaxValue, out success); return;

            case 8: ArrayOperationsTwoArgumentWrapper.arrayRemove(globalState, localState, int.MaxValue, int.MaxValue, out success); return;

            case 9: ArrayOperationsTwoArgumentWrapper.arrayCompareWithRegister(globalState, localState, 0, int.MaxValue, out success); return;

            case 10: ArrayOperationsTwoArgumentWrapper.arrayCompareWithRegister(globalState, localState, 1, int.MaxValue, out success); return;

            case 11: ArrayOperations.insert(globalState, localState, /*reg*/ 0, out success); return;

            case 12: ArrayOperations.insert(globalState, localState, /*reg*/ 1, out success); return;

            case 13: ArrayOperations.insert(globalState, localState, /*reg*/ 2, out success); return;

            case 14: ArrayOperations.setIdxRelative(globalState, localState, 0, 0, out success); return;

            case 15: ArrayOperations.setIdxRelative(globalState, localState, 0, -1, out success); return; // -1 is end of array

            case 16: ArrayOperations.idxFlag(globalState, localState, 0, 1, out success); return;         // TODO< should be an intrinsic command which gets added by default >

            case 17: ArrayOperations.valid(globalState, localState, /*array*/ 0, out success); return;

            case 18: ArrayOperations.read(globalState, localState, /*array*/ 0, /*register*/ 0, out success); return;

            case 19: ArrayOperations.idx2Reg(globalState, localState, /*array*/ 0, /*register*/ 0, out success); return;

            case 20: Operations.movImmediate(localState, /*register*/ 0, 0, out success); return;

            case 21: Operations.movImmediate(localState, /*register*/ 0, 1, out success); return;

            case 22: Operations.movImmediate(localState, /*register*/ 0, 3, out success); return;

            case 23: ArrayOperations.arrayMovToArray(globalState, localState, /*array*/ 0, /*register*/ 0, out success); return;

            case 24: Operations.mulRegisterImmediate(localState, /*register*/ 0, -1); success = true; return;

            case 25: Operations.binaryNegate(globalState, localState, /*register*/ 0); success = true; return;

            case 26: ArrayOperations.macroArrayAdvanceOrExit(globalState, localState, -4, out success); return;

            case 27: Operations.movImmediate(localState, /*register*/ 1, 0, out success); return;

            case 28: Operations.movImmediate(localState, /*register*/ 1, 1, out success); return;

            case 29: Operations.movImmediate(localState, /*register*/ 1, 3, out success); return;

            case 30: ArrayOperations.read(globalState, localState, /*array*/ 0, /*register*/ 1, out success); return;

            case 31: Operations.mulRegisterRegister(localState, 0, 1); success = true; return;

            case 32: Operations.addRegisterRegister(localState, 0, 1); success = true; return;

            case 33: ArrayOperations.arrayMovToArray(globalState, localState, /*array*/ 0, /*register*/ 1, out success); return;

            case 34: Operations.subRegisterRegister(localState, 1, 0); success = true; return;

            case 35: ArrayOperations.read(globalState, localState, /*array*/ 0, /*register*/ 1, out success); return;

            case 36: ArrayOperations.reg2idx(globalState, localState, /*register*/ 0, /*array*/ 0, out success); return;

            case 37: Operations.compareRegister(localState, /*register*/ 0, /*register*/ 1, /*type*/ -1); success = true; return;  // TODO< maybe using relative value as immediate >

            case 38: Operations.random(globalState, localState, 0, 0, out success); return;

            case 39: ArrayOperations.length(globalState, localState, /*destRegister*/ 0, out success); return;
            }

            // if we are here we have instrution with hardcoded parameters

            uint baseInstruction = InstructionInfo.getNumberOfHardcodedSingleInstructions();

            Debug.Assert(instructionWithoutRelative >= baseInstruction);
            int currentBaseInstruction = (int)baseInstruction;



            // add register constant
            if (instructionWithoutRelative <= currentBaseInstruction + 3)
            {
                int subInstruction = (int)instructionWithoutRelative - currentBaseInstruction; // which instruction do we choose from the pool

                if (subInstruction == 0)
                {
                    Operations.add(localState, /*register*/ 0, -1);
                    success = true;
                }
                else if (subInstruction == 1)
                {
                    Operations.add(localState, /*register*/ 0, 2);
                    success = true;
                }
                else if (subInstruction == 2)
                {
                    Operations.add(localState, /*register*/ 1, -1);
                    success = true;
                }
            }

            currentBaseInstruction += 3;


            // addFlag reg0 constant
            if (instructionWithoutRelative <= currentBaseInstruction + 1)
            {
                // currently just compare reg0 with zero
                Operations.addFlag(localState, /*register*/ 0, 1);
                success = true;
                return;
            }

            currentBaseInstruction += 1;



            // indirect table call
            if (instructionWithoutRelative <= currentBaseInstruction + 1)
            {
                // currently just compare reg0 with zero
                indirectCall = 0;
                success      = true;
                return;
            }

            currentBaseInstruction += 1;

            // additional instructions
            GlobalInterpreterState.AdditionalOperationsDelegateType additionalOperationDelegate;
            if (globalState.additionalOperations.TryGetValue(instructionWithoutRelative, out additionalOperationDelegate))
            {
                additionalOperationDelegate(globalState, localState, out success);
                return;
            }


            // unknown instruction
            success = false;
        }