예제 #1
0
        public void insertInstructionPositive1()   // test if insertion of an instruction in the positive side works correctly
        {
            InstructionOffsetPreservingArray arr = new InstructionOffsetPreservingArray();

            arr.append((int)InstructionInterpreter.convInstructionAndRelativeToInstruction(3, 0)); // jump 0
            arr.append(10);

            arr.insert(1, 11);

            Assert.AreEqual(arr[0], (int)InstructionInterpreter.convInstructionAndRelativeToInstruction(3, 1)); // must be jump 1
            Assert.AreEqual(arr[1], 11);
            Assert.AreEqual(arr[2], 10);
        }
예제 #2
0
        public void insertInstructionNegative2()   // test if insertion of an instruction in the negative side works correctly
        {
            InstructionOffsetPreservingArray arr = new InstructionOffsetPreservingArray();

            arr.append(10);
            arr.append((int)InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -2)); // jump -2

            arr.insert(1, 11);

            Assert.AreEqual(arr[0], 10);
            Assert.AreEqual(arr[1], 11);
            Assert.AreEqual(arr[2], (int)InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -3));
        }
        void fillUsedInstructionSet(LevinSearchContext levinSearchContext)
        {
            levinSearchContext.instructionIndexToInstruction.Clear();

            uint instructionIndex = 0;

            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = 0; // RET

            // add all nonspecial instructions
            for (uint instruction = 6; instruction <= 37; instruction++)
            {
                levinSearchContext.instructionIndexToInstruction[instructionIndex++] = instruction;
            }

            // add some special jump instructions

            // advance or exit
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(1, -4);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(1, -3);

            // not end or exit
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(2, -4);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(2, -5);

            // jump
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -0); // nop
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -2);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -3);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -4);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -5);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(3, -6);
            // TODO< jump ahead >

            // jump if not flag
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, -2);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, -3);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, -4);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, -5);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, -6);

            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, +1);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, +2);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, +3);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, +4);
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = InstructionInterpreter.convInstructionAndRelativeToInstruction(4, +5);

            // call indirect
            levinSearchContext.instructionIndexToInstruction[instructionIndex++] = 42;

            int breakpointHere1 = 1;
        }
예제 #4
0
        public static void interpret(
            GlobalInterpreterState globalState,
            LocalInterpreterState localState,
            bool debugExecution,
            out bool programExecutedSuccessful,
            out bool hardExecutionError
            )
        {
            programExecutedSuccessful = false;
            hardExecutionError        = false;

            /*
             * if( arguments.lengthOfProgram >= 4 ) {
             *  if( arguments.program[0] == 3 && arguments.program[1] == 62 && arguments.program[2] == 2 && arguments.program[3] == 31 ) {
             *      int debugHere = 5;
             *  }
             * }
             * //*/

            if (localState.program.length >= 3)
            {
                if (localState.program[0] == 35 && localState.program[1] == 32 && localState.program[2] == InstructionInterpreter.convInstructionAndRelativeToInstruction(1, -3))
                {
                    int debugHere = 5;
                }
            }

            for (int instructionsRetired = 0; instructionsRetired < localState.maxNumberOfRetiredInstructions; instructionsRetired++)
            {
                bool instructionPointerValid = localState.instructionPointer >= 0 && localState.instructionPointer < localState.program.length;
                if (!instructionPointerValid)
                {
                    hardExecutionError = true;
                    break;
                }

                uint currentInstruction = localState.program[localState.instructionPointer];

                if (debugExecution)
                {
                    Console.WriteLine("program=");

                    throw new NotImplementedException(); // TODO< logger >
                    //Program2.debug(null, arguments.program);

                    Console.WriteLine("ip={0}", localState.instructionPointer);
                    Console.Write("arr=");

                    throw new NotImplementedException(); // TODO< logger >
                    //Program2.debug(null, arguments.interpreterState.arrayState.array);
                    Console.WriteLine("array index={0}", globalState.arrayState.index);
                }

                if (InstructionInterpreter.isTerminating(globalState, localState, currentInstruction))
                {
                    programExecutedSuccessful = true; // the program executed successfully only if we return
                    break;
                }

                bool instructionExecutedSuccessfull;
                int  indirectCallIndex;
                InstructionInterpreter.dispatch(globalState, localState, new Instruction(currentInstruction), out instructionExecutedSuccessfull, out indirectCallIndex);
                if (!instructionExecutedSuccessfull)
                {
                    hardExecutionError = true;
                    break;
                }

                if (indirectCallIndex != -1)
                {
                    // an indirect call is a call to an (interpreted) function

                    // try to dispatch indirect call
                    LocalInterpreterState indirectLocalInterpreterState;
                    if (!localState.indirectCallTable.TryGetValue((uint)indirectCallIndex, out indirectLocalInterpreterState))
                    {
                        hardExecutionError = true;
                        break;
                    }

                    indirectLocalInterpreterState.reset();

                    bool calleeExecutedSuccessfully, calleeHardExecutionError;
                    interpret(globalState, indirectLocalInterpreterState, debugExecution, out calleeExecutedSuccessfully, out calleeHardExecutionError);
                    if (calleeExecutedSuccessfully)
                    {
                        // do nothing
                    }
                    else if (calleeHardExecutionError)
                    {
                        hardExecutionError = true;
                        break;
                    }
                }
            }

            if (hardExecutionError)
            {
                programExecutedSuccessful = false;
            }
        }