VM impl: AND, OR, XOR ops implemented

This commit is contained in:
romanman 2014-06-01 19:39:06 +03:00
parent 79bc9bb28a
commit 953acf417f
3 changed files with 239 additions and 46 deletions

View File

@ -41,11 +41,15 @@ public class Program {
public void stackPush(byte[] data){
DataWord stackWord = new DataWord(data);
stack.push(stackWord);
}
public void stackPush(DataWord stackWord){
stack.push(stackWord);
}
public void step(){
++pc;
}
@ -59,7 +63,11 @@ public class Program {
return data;
}
public void stackPull(){};
public DataWord stackPull(){
if (stack.size() == 0) throw new RuntimeException("required pull for empty stack");
return stack.pop();
};
public void memorySave(byte[] addrB, byte[] value){
@ -171,5 +179,32 @@ public class Program {
public String toString(){
return Hex.toHexString(data);
}
public DataWord and(DataWord w2){
for (int i = 0; i < this.data.length; ++i){
this.data[i] &= w2.data[i];
}
return this;
}
public DataWord or(DataWord w2){
for (int i = 0; i < this.data.length; ++i){
this.data[i] |= w2.data[i];
}
return this;
}
public DataWord xor(DataWord w2){
for (int i = 0; i < this.data.length; ++i){
this.data[i] ^= w2.data[i];
}
return this;
}
}
}

View File

@ -2,6 +2,9 @@ package org.ethereum.vm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.ethereum.vm.Program.DataWord;
import java.math.BigInteger;
import static org.ethereum.vm.OpCode.PUSH1;
@ -28,38 +31,38 @@ public class VM {
* Stop and Arithmetic Operations
*/
case STOP:
break;
case ADD:
break;
case MUL:
break;
case SUB:
break;
case DIV:
break;
case SDIV:
break;
case MOD:
break;
case SMOD:
break;
case EXP:
break;
case NEG:
break;
case LT:
break;
case SLT:
break;
case SGT:
break;
case GT:
break;
case EQ:
break;
case NOT:
break;
// case STOP:
// break;
// case ADD:
// break;
// case MUL:
// break;
// case SUB:
// break;
// case DIV:
// break;
// case SDIV:
// break;
// case MOD:
// break;
// case SMOD:
// break;
// case EXP:
// break;
// case NEG:
// break;
// case LT:
// break;
// case SLT:
// break;
// case SGT:
// break;
// case GT:
// break;
// case EQ:
// break;
// case NOT:
// break;
@ -67,21 +70,36 @@ public class VM {
* Bitwise Logic Operations
*/
case AND:
case AND:{
DataWord word1 = program.stackPull();
DataWord word2 = program.stackPull();
word1.and(word2);
program.stackPush(word1);
}
break;
case OR:
case OR: {
DataWord word1 = program.stackPull();
DataWord word2 = program.stackPull();
word1.or(word2);
program.stackPush(word1);
}
break;
case XOR:
break;
case BYTE:
case XOR: {
DataWord word1 = program.stackPull();
DataWord word2 = program.stackPull();
word1.xor(word2);
program.stackPush(word1);
}
break;
// case BYTE:
// break;
/**
* SHA3
*/
case SHA3:
break;
// case SHA3:
// break;
/**
* Environmental Information
@ -194,11 +212,19 @@ public class VM {
byte[] data = program.sweep(nPush);
program.stackPush(data);
program.fullTrace();
break;
case CREATE:
break;
case CALL:
break;
case RETURN:
break;
case SUICIDE:
break;
default:
}
program.fullTrace();

View File

@ -464,5 +464,137 @@ public class VMTest {
fail();
}
@Test // AND OP
public void testAND_1(){
VM vm = new VM();
Program program = new Program(Hex.decode("600A600A10"));
String expected = "000000000000000000000000000000000000000000000000000000000000000A";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // AND OP
public void testAND_2(){
VM vm = new VM();
Program program = new Program(Hex.decode("60C0600A10"));
String expected = "0000000000000000000000000000000000000000000000000000000000000000";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // AND OP mal data
public void testAND_3(){
try {
VM vm = new VM();
Program program = new Program(Hex.decode("60C010"));
vm.step(program);
vm.step(program);
vm.step(program);
} catch (RuntimeException e) {
return;
}
fail();
}
@Test // OR OP
public void testOR_1(){
VM vm = new VM();
Program program = new Program(Hex.decode("60F0600F11"));
String expected = "00000000000000000000000000000000000000000000000000000000000000FF";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // OR OP
public void testOR_2(){
VM vm = new VM();
Program program = new Program(Hex.decode("60C3603C11"));
String expected = "00000000000000000000000000000000000000000000000000000000000000FF";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // OR OP mal data
public void testOR_3(){
try {
VM vm = new VM();
Program program = new Program(Hex.decode("60C011"));
vm.step(program);
vm.step(program);
vm.step(program);
} catch (RuntimeException e) {
return;
}
fail();
}
@Test // XOR OP
public void testXOR_1(){
VM vm = new VM();
Program program = new Program(Hex.decode("60FF60FF12"));
String expected = "0000000000000000000000000000000000000000000000000000000000000000";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // XOR OP
public void testXOR_2(){
VM vm = new VM();
Program program = new Program(Hex.decode("600F60F012"));
String expected = "00000000000000000000000000000000000000000000000000000000000000FF";
vm.step(program);
vm.step(program);
vm.step(program);
Assert.assertEquals(expected, Hex.toHexString(program.stack.get(0).data).toUpperCase() );
}
@Test // XOR OP mal data
public void testXOR_3(){
try {
VM vm = new VM();
Program program = new Program(Hex.decode("60C012"));
vm.step(program);
vm.step(program);
vm.step(program);
} catch (RuntimeException e) {
return;
}
fail();
}
}