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(); }
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++; } }
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++; } }
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++; } }