From 2e8d413817260ce7b50ca4cedeb44f2eddd0dc2c Mon Sep 17 00:00:00 2001 From: nicksavers Date: Sat, 7 Jun 2014 21:11:44 +0200 Subject: [PATCH] Document class and indentation to comply with convention http://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html --- .../src/main/java/org/ethereum/vm/VM.java | 230 +++++++----------- 1 file changed, 90 insertions(+), 140 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java index b515ffbe..668be1a6 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -10,21 +10,47 @@ import java.nio.ByteBuffer; import static org.ethereum.vm.OpCode.PUSH1; /** - * www.ethereumJ.com - * User: Roman Mandeleil - * Created on: 01/06/2014 10:44 + * The Ethereum Virtual Machine (EVM) is responsible for initialization + * and executing a transaction on a contract. + * + * It is a quasi-Turing-complete machine; the quasi qualification + * comes from the fact that the computation is intrinsically bounded + * through a parameter, gas, which limits the total amount of computation done. + * + * The EVM is a simple stack-based architecture. The word size of the machine + * (and thus size of stack item) is 256-bit. This was chosen to facilitate + * the SHA3-256 hash scheme and elliptic-curve computations. The memory model + * is a simple word-addressed byte array. The stack has an unlimited size. + * The machine also has an independent storage model; this is similar in concept + * to the memory but rather than a byte array, it is a word-addressable word array. + * + * Unlike memory, which is volatile, storage is non volatile and is + * maintained as part of the system state. All locations in both storage + * and memory are well-defined initially as zero. + * + * The machine does not follow the standard von Neumann architecture. + * Rather than storing program code in generally-accessible memory or storage, + * it is stored separately in a virtual ROM interactable only though + * a specialised instruction. + * + * The machine can have exceptional execution for several reasons, + * including stack underflows and invalid instructions. These unambiguously + * and validly result in immediate halting of the machine with all state changes + * left intact. The one piece of exceptional execution that does not leave + * state changes intact is the out-of-gas (OOG) exception. + * + * Here, the machine halts immediately and reports the issue to + * the execution agent (either the transaction processor or, recursively, + * the spawning execution environment) and which will deal with it separately. */ - public class VM { static private BigInteger _32_ = BigInteger.valueOf(32); - Logger logger = LoggerFactory.getLogger("VM"); - + private Logger logger = LoggerFactory.getLogger("VM"); public void step(Program program) { - try { byte op = program.getCurrentOp(); @@ -35,73 +61,63 @@ public class VM { switch (OpCode.code(op)) { case SHA3: program.spendGas(GasCost.SHA3); - break; + break; case SLOAD: program.spendGas(GasCost.SLOAD); - break; + break; case SSTORE: // todo: calc gas in the execution // todo: according to the size - break; + break; case BALANCE: program.spendGas(GasCost.BALANCE); - break; + break; case CREATE: program.spendGas(GasCost.CREATE); - break; + break; case CALL: program.spendGas(GasCost.CALL); - break; + break; case MSTORE8: case MSTORE: // todo: calc gas in the execution // todo: according to the size - break; + break; default: program.spendGas(GasCost.STEP); - break; + break; } - switch (OpCode.code(op)) { - /** * Stop and Arithmetic Operations */ - case STOP:{ program.setHReturn(ByteBuffer.allocate(0)); program.stop(); - } - break; + } break; case ADD:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.add(word2); program.stackPush(word1); program.step(); - } - break; + } break; case MUL:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.mul(word2); program.stackPush(word1); program.step(); - } - break; + } break; case SUB:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.sub(word2); program.stackPush(word1); program.step(); - } - break; + } break; case DIV:{ DataWord word1 = program.stackPop(); @@ -109,8 +125,7 @@ public class VM { word1.div(word2); program.stackPush(word1); program.step(); - } - break; + } break; case SDIV:{ DataWord word1 = program.stackPop(); @@ -118,44 +133,35 @@ public class VM { word1.sDiv(word2); program.stackPush(word1); program.step(); - } - break; + } break; case MOD:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.mod(word2); program.stackPush(word1); program.step(); - } - break; + } break; case SMOD:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.sMod(word2); program.stackPush(word1); program.step(); - } - break; + } break; case EXP:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.exp(word2); program.stackPush(word1); program.step(); - } - break; + } break; case NEG:{ DataWord word1 = program.stackPop(); word1.negate(); program.stackPush(word1); program.step(); - } - break; + } break; case LT:{ - // todo: can be improved by not using BigInteger DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); @@ -167,10 +173,8 @@ public class VM { } program.stackPush(word1); program.step(); - } - break; + } break; case SLT:{ - // todo: can be improved by not using BigInteger DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); @@ -182,9 +186,8 @@ public class VM { } program.stackPush(word1); program.step(); - }break; + } break; case SGT:{ - // todo: can be improved by not using BigInteger DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); @@ -196,9 +199,8 @@ public class VM { } program.stackPush(word1); program.step(); - }break; + } break; case GT:{ - // todo: can be improved by not using BigInteger DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); @@ -210,7 +212,7 @@ public class VM { } program.stackPush(word1); program.step(); - }break; + } break; case EQ:{ DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); @@ -222,8 +224,7 @@ public class VM { } program.stackPush(word1); program.step(); - } - break; + } break; case NOT: { DataWord word1 = program.stackPop(); if (word1.isZero()){ @@ -233,42 +234,35 @@ public class VM { } program.stackPush(word1); program.step(); - } - break; + } break; /** * Bitwise Logic Operations */ - case AND:{ DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.and(word2); program.stackPush(word1); program.step(); - } - break; + } break; case OR: { DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.or(word2); program.stackPush(word1); program.step(); - } - break; + } break; case XOR: { DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); word1.xor(word2); program.stackPush(word1); program.step(); - } - break; + } break; case BYTE:{ - DataWord word1 = program.stackPop(); DataWord word2 = program.stackPop(); - DataWord result = null; if (word1.value().compareTo(_32_) == -1){ byte tmp = word2.getData()[word1.value().intValue()]; @@ -280,13 +274,11 @@ public class VM { } program.stackPush(result); program.step(); - } - break; + } break; /** * SHA3 */ - case SHA3:{ DataWord memOffsetData = program.stackPop(); DataWord lengthData = program.stackPop(); @@ -297,60 +289,50 @@ public class VM { program.stackPush(word); program.step(); - } - break; + } break; /** * Environmental Information */ - case ADDRESS:{ DataWord address = program.getOwnerAddress(); program.stackPush(address); program.step(); - } - break; + } break; case BALANCE:{ DataWord balance = program.getBalance(); program.stackPush(balance); program.step(); - } - break; + } break; case ORIGIN:{ DataWord originAddress = program.getOriginAddress(); program.stackPush(originAddress); program.step(); - } - break; + } break; case CALLER:{ DataWord callerAddress = program.getCallerAddress(); program.stackPush(callerAddress); program.step(); - } - break; + } break; case CALLVALUE:{ DataWord callValue = program.getCallValue(); program.stackPush(callValue); program.step(); - } - break; + } break; case CALLDATALOAD:{ DataWord dataOffs = program.stackPop(); DataWord value = program.getDataValue(dataOffs); program.stackPush(value); program.step(); - } - break; + } break; case CALLDATASIZE:{ DataWord dataSize = program.getDataSize(); program.stackPush(dataSize); program.step(); - } - break; + } break; case CALLDATACOPY:{ - DataWord memOffsetData = program.stackPop(); DataWord dataOffsetData = program.stackPop(); DataWord lengthData = program.stackPop(); @@ -358,15 +340,12 @@ public class VM { byte[] msgData = program.getDataCopy(dataOffsetData, lengthData); program.memorySave(memOffsetData.data, msgData); program.step(); - - } break; + } break; case CODESIZE:{ - DataWord length = new DataWord(program.ops.length); program.stackPush(length); program.step(); - } - break; + } break; case CODECOPY:{ DataWord memOffsetData = program.stackPop(); DataWord codeOffsetData = program.stackPop(); @@ -377,7 +356,6 @@ public class VM { int memOffset = memOffsetData.value().intValue(); if (program.ops.length < length + codeOffset){ - program.stop(); break; } @@ -387,8 +365,7 @@ public class VM { program.memorySave(memOffsetData.getData(), code); program.step(); - } - break; + } break; case GASPRICE: break; @@ -408,52 +385,43 @@ public class VM { break; case GASLIMIT: break; - - case POP:{ program.stackPop(); program.step(); - } - break; + } break; case DUP:{ DataWord word_1 = program.stackPop(); DataWord word_2 = word_1.clone(); program.stackPush(word_1); program.stackPush(word_2); program.step(); - } - break; + } break; case SWAP:{ DataWord word_1 = program.stackPop(); DataWord word_2 = program.stackPop(); program.stackPush(word_1); program.stackPush(word_2); program.step(); - } - break; + } break; case MLOAD:{ DataWord addr = program.stackPop(); DataWord data = program.memoryLoad(addr); program.stackPush(data); program.step(); - } - break; + } break; case MSTORE:{ DataWord addr = program.stackPop(); DataWord value = program.stackPop(); program.memorySave(addr, value); program.step(); - } - break; + } break; case MSTORE8:{ - DataWord addr = program.stackPop(); DataWord value = program.stackPop(); byte[] byteVal = {value.getData()[31]}; program.memorySave(addr.getData(), byteVal); program.step(); - } - break; + } break; case SLOAD:{ DataWord key = program.stackPop(); DataWord val = program.storageLoad(key); @@ -462,8 +430,7 @@ public class VM { } program.stackPush(val); program.step(); - } - break; + } break; case SSTORE:{ DataWord addr = program.stackPop(); DataWord value = program.stackPop(); @@ -477,15 +444,12 @@ public class VM { program.spendGas(GasCost.SSTORE * 0); } else program.spendGas(GasCost.SSTORE); - program.step(); - } - break; + } break; case JUMP:{ DataWord pos = program.stackPop(); program.setPC(pos); - } - break; + } break; case JUMPI:{ DataWord pos = program.stackPop(); DataWord cond = program.stackPop(); @@ -495,23 +459,19 @@ public class VM { } else{ program.step(); } - } - break; + } break; case PC:{ int pc = program.getPC(); DataWord pcWord = new DataWord(pc); program.stackPush(pcWord); program.step(); - } - break; + } break; case MSIZE:{ - int memSize = program.getMemSize(); DataWord wordMemSize = new DataWord(memSize); program.stackPush(wordMemSize); program.step(); - } - break; + } break; case GAS: break; @@ -519,14 +479,12 @@ public class VM { case PUSH9: case PUSH10: case PUSH11: case PUSH12: case PUSH13: case PUSH14: case PUSH15: case PUSH16: case PUSH17: case PUSH18: case PUSH19: case PUSH20: case PUSH21: case PUSH22: case PUSH23: case PUSH24: case PUSH25: case PUSH26: case PUSH27: case PUSH28: case PUSH29: case PUSH30: case PUSH31: case PUSH32:{ - program.step(); int nPush = op - PUSH1.val() + 1; byte[] data = program.sweep(nPush); program.stackPush(data); - } - break; + } break; case CREATE:{ DataWord gas = program.stackPop(); DataWord inOffset = program.stackPop(); @@ -535,8 +493,7 @@ public class VM { // todo: implement contract creation program.step(); - } - break; + } break; case CALL:{ DataWord gas = program.stackPop(); DataWord toAddress = program.stackPop(); @@ -548,10 +505,8 @@ public class VM { // todo: the contract for real program.step(); - } - break; + } break; case RETURN:{ - DataWord offset = program.stackPop(); DataWord size = program.stackPop(); @@ -560,14 +515,12 @@ public class VM { program.step(); program.stop(); - } - break; + } break; case SUICIDE:{ DataWord address = program.stackPop(); // todo: transfer left balance to the address program.stop(); - } - break; + } break; default:{ } @@ -583,15 +536,12 @@ public class VM { } - - public void play(Program program){ + public void play(Program program) { try { while(!program.isStopped()) this.step(program); } catch (RuntimeException e) { program.setRuntimeFailure(e); } - } - }