From b561a7890d13e4074eb42106e065cc5d74e761b3 Mon Sep 17 00:00:00 2001 From: romanman Date: Mon, 2 Jun 2014 11:16:22 +0300 Subject: [PATCH] VM impl: POP, DUP , MSTORE, MLOAD ops implemented & unit tested --- .../main/java/org/ethereum/util/Utils.java | 2 +- .../main/java/org/ethereum/vm/DataWord.java | 14 +- .../main/java/org/ethereum/vm/Program.java | 61 ++- .../src/main/java/org/ethereum/vm/VM.java | 47 +- .../src/test/java/org/ethereum/vm/VMTest.java | 422 +++++++++++++++--- 5 files changed, 462 insertions(+), 84 deletions(-) diff --git a/ethereumj-core/src/main/java/org/ethereum/util/Utils.java b/ethereumj-core/src/main/java/org/ethereum/util/Utils.java index 6c2841d5..53273654 100644 --- a/ethereumj-core/src/main/java/org/ethereum/util/Utils.java +++ b/ethereumj-core/src/main/java/org/ethereum/util/Utils.java @@ -92,7 +92,7 @@ public class Utils { public static String oneByteToHexString(byte value){ - String retVal = Integer.toString(value, 16); + String retVal = Integer.toString(value & 0xFF, 16); if (retVal.length() == 1) retVal = "0" + retVal; return retVal; } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/DataWord.java b/ethereumj-core/src/main/java/org/ethereum/vm/DataWord.java index a04bb881..365b0401 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/DataWord.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/DataWord.java @@ -1,5 +1,7 @@ package org.ethereum.vm; +import com.fasterxml.jackson.databind.ser.std.ArraySerializerBase; +import org.spongycastle.util.Arrays; import org.spongycastle.util.encoders.Hex; import java.math.BigInteger; @@ -46,10 +48,6 @@ public class DataWord { return result == 0; } - public String toString(){ - return Hex.toHexString(data); - } - public DataWord and(DataWord w2){ for (int i = 0; i < this.data.length; ++i){ @@ -93,4 +91,12 @@ public class DataWord { } + public String toString(){ + return Hex.toHexString(data); + } + + public DataWord clone(){ + return new DataWord(Arrays.clone(data)); + } + } diff --git a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java index 4e3c6262..a9dcc60f 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/Program.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/Program.java @@ -26,7 +26,7 @@ public class Program { ByteBuffer memory = null; byte[] ops; - int pc = 0; + int pc = 0; public Program(byte[] ops) { @@ -69,26 +69,59 @@ public class Program { return stack.pop(); }; - public void memorySave(byte[] addrB, byte[] value){ + public void memorySave(DataWord addrB, DataWord value){ + memorySave(addrB.data, value.data); + } - BigInteger address = new BigInteger(1, addrB); + public void memorySave(byte[] addr, byte[] value){ + + int address = new BigInteger(1, addr).intValue(); + allocateMemory(address, value); + + System.arraycopy(value, 0, memory.array(), address, value.length); + } + + public DataWord memoryLoad(DataWord addr){ + + int address = new BigInteger(1, addr.getData()).intValue(); + allocateMemory(address, DataWord.ZERO.data); + + byte[] data = new byte[32]; + System.arraycopy(memory.array(), address, data , 0 ,32); + + return new DataWord(data); + } + + private void allocateMemory(int address, byte[] value){ int memSize = 0; if (memory != null) memSize = memory.limit(); - if (memSize < address.intValue()){ + // check if you need to allocate + if (memSize < (address + value.length)){ + + int sizeToAllocate = 0; + if (memSize > address){ + + sizeToAllocate = memSize + value.length; + } else { + sizeToAllocate = memSize + (address - memSize) + value.length; + } + + // complete to 32 + sizeToAllocate = (sizeToAllocate % 32)==0 ? sizeToAllocate : + sizeToAllocate + (32 - sizeToAllocate % 32); + + sizeToAllocate = (sizeToAllocate == 0)? 32: sizeToAllocate; - int sizeToAllocate = address.intValue() + (32 - address.intValue() % 32); ByteBuffer tmpMem = ByteBuffer.allocate(sizeToAllocate); - if (memory != null) tmpMem.put(memory); + if (memory != null) + System.arraycopy(memory.array(), 0, tmpMem.array(), 0, memory.limit()); + memory = tmpMem; } - System.arraycopy(value, 0, memory.array(), address.intValue(), value.length); } - - public void memoryLoad(){}; - public void storageSave(byte[] key, byte[] val){ DataWord keyWord = new DataWord(key); @@ -127,10 +160,10 @@ public class Program { if ((i + 1) % 16 == 0) { - String tmp = String.format(" [%4s]-[%4s]", Integer.toString(i, 16), - Integer.toString(i - 15, 16)).replace(" ", "0"); - memoryData.append(tmp).append(" "); - memoryData.append(oneLine.reverse()); + String tmp = String.format("[%4s]-[%4s]", Integer.toString(i - 15, 16), + Integer.toString(i, 16)).replace(" ", "0"); + memoryData.append("" ).append(tmp).append(" "); + memoryData.append(oneLine); if (i < memory.limit()) memoryData.append("\n"); oneLine.setLength(0); } 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 0e06ef2e..3e0a2a9b 100644 --- a/ethereumj-core/src/main/java/org/ethereum/vm/VM.java +++ b/ethereumj-core/src/main/java/org/ethereum/vm/VM.java @@ -212,16 +212,43 @@ public class VM { break; - case POP: - break; - case DUP: - break; - case SWAP: - break; - case MLOAD: - break; - case MSTORE: - break; + case POP:{ + program.stackPull(); + program.step(); + } + break; + case DUP:{ + DataWord word_1 = program.stackPull(); + DataWord word_2 = word_1.clone(); + program.stackPush(word_1); + program.stackPush(word_2); + program.step(); + } + break; + case SWAP:{ + DataWord word_1 = program.stackPull(); + DataWord word_2 = program.stackPull(); + + program.stackPush(word_1); + program.stackPush(word_2); + program.step(); + } + break; + case MLOAD:{ + DataWord addr = program.stackPull(); + DataWord data = program.memoryLoad(addr); + program.stackPush(data); + program.step(); + } + break; + case MSTORE:{ + DataWord addr = program.stackPull(); + DataWord value = program.stackPull(); + + program.memorySave(addr, value); + program.step(); + } + break; case MSTORE8: break; case SLOAD: diff --git a/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java b/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java index 512de9c8..f9b3cc2a 100644 --- a/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java +++ b/ethereumj-core/src/test/java/org/ethereum/vm/VMTest.java @@ -25,7 +25,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH2 OP @@ -38,7 +38,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH3 OP @@ -51,7 +51,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH4 OP @@ -64,7 +64,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH5 OP @@ -77,7 +77,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH6 OP @@ -90,7 +90,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH7 OP @@ -103,7 +103,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH8 OP @@ -116,7 +116,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH9 OP @@ -129,7 +129,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -143,7 +143,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH11 OP @@ -156,7 +156,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH12 OP @@ -169,7 +169,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH13 OP @@ -182,7 +182,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH14 OP @@ -195,7 +195,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH15 OP @@ -208,7 +208,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH16 OP @@ -221,7 +221,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH17 OP @@ -234,7 +234,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH18 OP @@ -247,7 +247,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH19 OP @@ -260,7 +260,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH20 OP @@ -273,7 +273,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH21 OP @@ -286,7 +286,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH22 OP @@ -299,7 +299,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH23 OP @@ -312,7 +312,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH24 OP @@ -325,7 +325,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH25 OP @@ -338,7 +338,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH26 OP @@ -351,7 +351,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH27 OP @@ -364,7 +364,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH28 OP @@ -377,7 +377,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH29 OP @@ -390,7 +390,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH30 OP @@ -403,7 +403,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH31 OP @@ -416,7 +416,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSH32 OP @@ -429,7 +429,7 @@ public class VMTest { program.fullTrace(); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // PUSHN OP mal data @@ -475,7 +475,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // AND OP @@ -489,7 +489,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // AND OP mal data @@ -519,7 +519,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // OR OP @@ -533,7 +533,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // OR OP mal data @@ -563,7 +563,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // XOR OP @@ -577,7 +577,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -609,7 +609,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // BYTE OP @@ -623,7 +623,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // BYTE OP @@ -637,7 +637,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @@ -667,7 +667,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // NOT OP @@ -680,7 +680,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // NOT OP mal data @@ -710,7 +710,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // EQ OP @@ -724,7 +724,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() ); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase() ); } @Test // EQ OP @@ -738,7 +738,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // EQ OP mal data @@ -769,7 +769,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // GT OP @@ -783,7 +783,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // GT OP @@ -797,7 +797,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // GT OP mal data @@ -829,7 +829,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // LT OP @@ -843,7 +843,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // LT OP @@ -857,7 +857,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // LT OP mal data @@ -888,7 +888,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // NEG OP @@ -901,7 +901,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // NEG OP @@ -914,7 +914,7 @@ public class VMTest { vm.step(program); vm.step(program); - Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase()); + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); } @Test // NEG OP @@ -933,4 +933,316 @@ public class VMTest { fail(); } + + @Test // POP OP + public void testPOP_1(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("61000060016200000250")); + String expected = "0000000000000000000000000000000000000000000000000000000000000001"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + @Test // POP OP + public void testPOP_2(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("6100006001620000025050")); + String expected = "0000000000000000000000000000000000000000000000000000000000000000"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + @Test // POP OP mal data + public void testPOP_3(){ + + try { + VM vm = new VM(); + Program program = new Program(Hex.decode("61000060016200000250505050")); + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + } catch (RuntimeException e) { + return; + } + fail(); + } + + @Test // DUP OP + public void testDUP_1(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("601251")); + String expected = "0000000000000000000000000000000000000000000000000000000000000012"; + int expectedLen = 2; + + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + Assert.assertEquals(expectedLen, program.stack.toArray().length); + + } + + + @Test // DUP OP mal data + public void testDUP_2(){ + + try { + VM vm = new VM(); + Program program = new Program(Hex.decode("51")); + + vm.step(program); + vm.step(program); + vm.step(program); + + } catch (RuntimeException e) { + return; + } + fail(); + } + + + @Test // SWAP OP + public void testSWAP_1(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("6011602252")); + String expected = "0000000000000000000000000000000000000000000000000000000000000011"; + + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + @Test // SWAP OP + public void testSWAP_2(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("60116022623333335252")); + String expected = "0000000000000000000000000000000000000000000000000000000000333333"; + int expectedLen = 3; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + Assert.assertEquals(expectedLen, program.stack.toArray().length); + } + + @Test // MSTORE OP + public void testMSTORE_1(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("611234600054")); + String expected = "0000000000000000000000000000000000000000000000000000000000001234"; + + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.memory.array())); + } + + @Test // MSTORE OP + public void testMSTORE_2(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("611234600054615566602054")); + String expected = "0000000000000000000000000000000000000000000000000000000000001234" + + "0000000000000000000000000000000000000000000000000000000000005566"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.memory.array())); + } + + @Test // MSTORE OP + public void testMSTORE_3(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("611234600054615566602054618888600054")); + String expected = "0000000000000000000000000000000000000000000000000000000000008888" + + "0000000000000000000000000000000000000000000000000000000000005566"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.memory.array())); + } + + @Test // MSTORE OP + public void testMSTORE_4(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("61123460A054")); + String expected = "" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000001234"; + + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(expected, Hex.toHexString(program.memory.array())); + } + + + @Test // MSTORE OP + public void testMSTORE_5(){ + + try { + VM vm = new VM(); + Program program = new Program(Hex.decode("61123454")); + + vm.step(program); + vm.step(program); + } catch (RuntimeException e) { + return; + } + fail(); + } + + @Test // MLOAD OP + public void testMLOAD_1(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("600053")); + String m_expected = "0000000000000000000000000000000000000000000000000000000000000000"; + String s_expected = "0000000000000000000000000000000000000000000000000000000000000000"; + + vm.step(program); + vm.step(program); + + Assert.assertEquals(m_expected, Hex.toHexString(program.memory.array())); + Assert.assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + @Test // MLOAD OP + public void testMLOAD_2(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("602253")); + String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000"; + String s_expected = "0000000000000000000000000000000000000000000000000000000000000000"; + + vm.step(program); + vm.step(program); + + Assert.assertEquals(m_expected, Hex.toHexString(program.memory.array())); + Assert.assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + + @Test // MLOAD OP + public void testMLOAD_3(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("602053")); + String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000"; + String s_expected = "0000000000000000000000000000000000000000000000000000000000000000"; + + vm.step(program); + vm.step(program); + + Assert.assertEquals(m_expected, Hex.toHexString(program.memory.array())); + Assert.assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + + } + + @Test // MLOAD OP + public void testMLOAD_4(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("611234602054602053")); + String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000001234"; + String s_expected = "0000000000000000000000000000000000000000000000000000000000001234"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(m_expected, Hex.toHexString(program.memory.array())); + Assert.assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + @Test // MLOAD OP + public void testMLOAD_5(){ + + VM vm = new VM(); + Program program = new Program(Hex.decode("611234602054601F53")); + String m_expected = "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000001234"; + String s_expected = "0000000000000000000000000000000000000000000000000000000000000012"; + + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + vm.step(program); + + Assert.assertEquals(m_expected, Hex.toHexString(program.memory.array())); + Assert.assertEquals(s_expected, Hex.toHexString(program.stack.peek().data).toUpperCase()); + } + + + @Test // MLOAD OP mal data + public void testMLOAD_6(){ + + try { + VM vm = new VM(); + Program program = new Program(Hex.decode("53")); + + vm.step(program); + } catch (RuntimeException e) { + return; + } + fail(); + } + }