Esempio n. 1
0
        private void Step()
        {
            // Verify we're not at the end of the stream
            if (ExecutionState.PC >= Code.Length)
            {
                // If we reached the end, exit with the remainder of the gas and a success status.
                ExecutionState.Result = new EVMExecutionResult(this, null, true);
                return;
            }

            // Set our position back to the start of the instruction, grab our opcode and verify it.
            InstructionOpcode opcode = (InstructionOpcode)Code.Span[(int)ExecutionState.PC];

            // Obtain our base cost for this opcode. If we fail to, the instruction isn't implemented yet.
            uint?instructionBaseGasCost = GasDefinitions.GetInstructionBaseGasCost(State.Configuration.Version, opcode);

            if (instructionBaseGasCost == null)
            {
                throw new EVMException($"Invalid opcode {opcode.ToString()} read when executing!");
            }

            // If we just jumped, then this next opcode should be a JUMPDEST.
            if (ExecutionState.JumpedLastInstruction && opcode != InstructionOpcode.JUMPDEST)
            {
                throw new EVMException($"Invalid jump to offset {ExecutionState.PC} in code!");
            }

            // Obtain our instruction implementation for this opcode
            var             opcodeDescriptor = opcode.GetDescriptor();
            InstructionBase instruction      = opcodeDescriptor.GetInstructionImplementation(this);

            // Record our code coverage for this execution.
            CoverageMap?.RecordExecution(instruction.Offset, (ExecutionState.PC - instruction.Offset));

            // Record our instruction execution tracing
            if (State.Configuration.DebugConfiguration.IsTracing)
            {
                State.Configuration.DebugConfiguration.ExecutionTrace?.RecordExecution(this, instruction, GasState.Gas, (BigInteger)instructionBaseGasCost);
            }

            // Deduct base gas cost
            GasState.Deduct((BigInteger)instructionBaseGasCost);

            // Debug: Print out instruction execution information.
            //if (opcode == InstructionOpcode.JUMPDEST)
            //    Console.WriteLine($"\r\n---------------------------------------------------------------\r\n");
            //Console.WriteLine($"0x{instruction.Offset.ToString("X4")}: {instruction}");
            //Console.WriteLine($"Stack: {ExecutionState.Stack}");

            // Execute the instruction
            instruction.Execute();
        }
Esempio n. 2
0
        public void Execute(List <InstructionBase> instructions)
        {
            // Set open/close instruction ptr
            Stack <int> loopStack = new Stack <int>();

            for (int instructionPtr = 0; instructionPtr < instructions.Count; instructionPtr++)
            {
                InstructionBase instruction = instructions[instructionPtr];
                switch (instruction)
                {
                case OpenInstruction _:
                    loopStack.Push(instructionPtr);     // save OpenInstructionPtr, will be set later
                    break;

                case CloseInstruction _ when loopStack.Count == 0:
                    throw new InvalidOperationException($"Unmatched CloseInstruction at position {instructionPtr}.");

                case CloseInstruction closeInstruction:
                {
                    int loopStartPtr = loopStack.Pop();
                    closeInstruction.OpenInstructionPtr = loopStartPtr;                                 // set OpenInstructionPtr to previously saved ptr
                    ((OpenInstruction)instructions[loopStartPtr]).CloseInstructionPtr = instructionPtr; // set CloseInstructionPtr to current ptr
                    break;
                }
                }
            }
            if (loopStack.Count > 0)
            {
                throw new InvalidOperationException($"Unmatched OpenInstruction at position { loopStack.Peek()}.");
            }
            //
            int[] memory    = new int[65536];
            int   memoryPtr = 32765; // starts in the middle
            int   ip        = 0;

            while (true)
            {
                if (ip >= instructions.Count)
                {
                    break; // stop program
                }
                InstructionBase instruction = instructions[ip];
                instruction.Execute(memory, ref memoryPtr, ref ip);
                ip++;
            }
        }
Esempio n. 3
0
        public void Execute()
        {
            byte[] memory         = new byte[65536];
            int    memoryPtr      = 0;
            int    instructionPtr = 0;

            while (true)
            {
                if (instructionPtr >= Instructions.Count)
                {
                    break; // stop program
                }
                InstructionBase instruction = Instructions[instructionPtr];
                if (instruction == null)
                {
                    throw new InvalidOperationException("Null instruction found");
                }
                instruction.Execute(memory, ref memoryPtr, ref instructionPtr);
                instructionPtr++;
            }
        }
Esempio n. 4
0
        public void Execute()
        {
            // Tree is only used for code optimisation
            // Set open/close instruction ptr
            List <InstructionBase> instructions = Instructions.ToList();
            Stack <int>            loopStack    = new Stack <int>();

            for (int instructionPtr = 0; instructionPtr < instructions.Count; instructionPtr++)
            {
                InstructionBase instruction = instructions[instructionPtr];
                if (instruction is OpenInstruction)
                {
                    loopStack.Push(instructionPtr); // save OpenInstructionPtr, will be set later
                }
                else if (instruction is CloseInstruction)
                {
                    int loopStartPtr = loopStack.Pop();
                    ((CloseInstruction)instruction).OpenInstructionPtr = loopStartPtr;                  // set OpenInstructionPtr to previously saved ptr
                    ((OpenInstruction)instructions[loopStartPtr]).CloseInstructionPtr = instructionPtr; // set CloseInstructionPtr to current ptr
                }
            }
            byte[] memory    = new byte[65536];
            int    memoryPtr = 0;
            int    ip        = 0;

            while (true)
            {
                if (ip >= instructions.Count)
                {
                    break; // stop program
                }
                InstructionBase instruction = instructions[ip];
                if (instruction == null)
                {
                    throw new InvalidOperationException("Null instruction found");
                }
                instruction.Execute(memory, ref memoryPtr, ref ip);
                ip++;
            }
        }