Skip to content

Commit

Permalink
Add headers expload#245
Browse files Browse the repository at this point in the history
  • Loading branch information
nevgeny committed Oct 17, 2018
1 parent 2527439 commit 7260429
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 31 deletions.
22 changes: 19 additions & 3 deletions evm/src/main/scala/pravda/evm/EVM.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2018 Expload.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package pravda.evm

import fastparse.byte.all._
Expand Down Expand Up @@ -76,7 +93,7 @@ object EVM {
case object Invalid extends Op
case object SelfDestruct extends Op

val singleOps: Map[Int, Op] = Map(
val singleOps: Map[Int, Op] = Map(
0x00 -> Stop,
0x01 -> Add,
0x02 -> Mul,
Expand Down Expand Up @@ -151,11 +168,10 @@ object EVM {
0xff -> SelfDestruct
)

val rangeOps: List[(Range, Int => Op)] = List(
val rangeOps: List[(Range, Int => Op)] = List(
(0x80 to 0x8f, i => Dup(i - 0x80 + 1)),
(0x90 to 0x9f, i => Swap(i - 0x90 + 1)),
(0xa0 to 0xa4, i => Log(i - 0xa0))
)


}
19 changes: 18 additions & 1 deletion evm/src/main/scala/pravda/evm/parse/Parser.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2018 Expload.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package pravda.evm.parse

import fastparse.byte.all._
Expand All @@ -6,7 +23,7 @@ import pravda.evm.EVM._

object Parser {

def apply(bytes: Bytes):Either[String,List[EVM.Op]] = {
def apply(bytes: Bytes): Either[String, List[EVM.Op]] = {
ops.parse(bytes).get.value
}

Expand Down
40 changes: 29 additions & 11 deletions evm/src/main/scala/pravda/evm/translate/Translator.scala
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2018 Expload.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package pravda.evm.translate

import pravda.evm.EVM
Expand All @@ -6,20 +23,21 @@ import pravda.vm.asm

object Translator {

private def listToEither[L, R](eithers: List[Either[L, List[R]]]): Either[List[L], List[R]] = {
eithers.partition(_.isLeft) match {
case (Nil, rights) =>
Right(
for {
Right(list) <- rights
el <- list
} yield el
)
case (lefts, _) => Left(for (Left(message) <- lefts) yield message)

private def listToEither[L,R](eithers: List[Either[L,List[R]]]): Either[List[L],List[R]] = {
eithers.partition(_.isLeft) match {
case (Nil,rights) => Right(
for {Right(list) <- rights
el <- list
} yield el
)
case (lefts,_) => Left(for(Left(message) <- lefts)yield message)

}
}
}

def apply(ops: List[EVM.Op]):Either[List[String], List[asm.Operation]] = {
def apply(ops: List[EVM.Op]): Either[List[String], List[asm.Operation]] = {
listToEither(
ops.map(SimpleTranslation.evmOpToOps)
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* Copyright (C) 2018 Expload.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

package pravda.evm.translate.opcode

import pravda.evm.EVM
Expand All @@ -15,17 +32,17 @@ object SimpleTranslation {

case Pop => codeToOps(Opcodes.POP)

case Add => codeToOps(Opcodes.ADD)
case Mul => codeToOps(Opcodes.ADD)
case Div => codeToOps(Opcodes.DIV) //FIXME 0 if stack[1] == 0 othervise s[0] / s[1]
case Mod => codeToOps(Opcodes.MOD) //FIXME 0 if stack[1] == 0 othervise s[0] % s[1]
case Sub => sub
case Add => codeToOps(Opcodes.ADD)
case Mul => codeToOps(Opcodes.ADD)
case Div => codeToOps(Opcodes.DIV) //FIXME 0 if stack[1] == 0 othervise s[0] / s[1]
case Mod => codeToOps(Opcodes.MOD) //FIXME 0 if stack[1] == 0 othervise s[0] % s[1]
case Sub => sub
case AddMod => codeToOps(Opcodes.ADD, Opcodes.MOD)
case MulMod => codeToOps(Opcodes.MUL, Opcodes.MOD)

// case Not => codeToOps(Opcodes.NOT)
// case Not => codeToOps(Opcodes.NOT)
case And => codeToOps(Opcodes.AND)
case Or => codeToOps(Opcodes.OR)
case Or => codeToOps(Opcodes.OR)
case Xor => codeToOps(Opcodes.XOR)

//FIXME need exp function
Expand All @@ -52,25 +69,24 @@ object SimpleTranslation {
sub,
codeToOps(Opcodes.XOR),
codeToOps(Opcodes.AND)
).flatten
).flatten

case IsZero => pushBigInt(BigInt(0)) :: codeToOps(Opcodes.EQ) ::: cast(Data.Type.BigInt)
case Lt => codeToOps(Opcodes.LT) ::: cast(Data.Type.BigInt)
case Gt => codeToOps(Opcodes.GT) ::: cast(Data.Type.BigInt)
case Eq => codeToOps(Opcodes.EQ) ::: cast(Data.Type.BigInt)
case Lt => codeToOps(Opcodes.LT) ::: cast(Data.Type.BigInt)
case Gt => codeToOps(Opcodes.GT) ::: cast(Data.Type.BigInt)
case Eq => codeToOps(Opcodes.EQ) ::: cast(Data.Type.BigInt)

//case Jump => codeToOps(Opcodes.JUMP)
//case JumpI => codeToOps(Opcodes.SWAP) ::: cast(Data.Type.Boolean) ::: codeToOps(Opcodes.JUMP)
case Stop => codeToOps(Opcodes.STOP)

case Dup(n) => if (n > 1) dupn(n) else codeToOps(Opcodes.DUP)
case Dup(n) => if (n > 1) dupn(n) else codeToOps(Opcodes.DUP)
case Swap(n) => if (n > 1) swapn(n) else codeToOps(Opcodes.SWAP)

case Balance => codeToOps(Opcodes.BALANCE)
case Address => codeToOps(Opcodes.PADDR)
}


def evmOpToOps(op: EVM.Op): Either[String, List[asm.Operation]] =
translate.lift(op).toRight(s"Unknown opcode $op")
}
7 changes: 4 additions & 3 deletions evm/src/main/scala/pravda/evm/translate/opcode/opcode.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ import pravda.vm.{Data, Opcodes, asm}
//TODO merge with pravda.dotnet.translation.opcode.opcode
package object opcode {


def push[T](value: T, toPrimitive: T => Data.Primitive): asm.Operation =
asm.Operation.Push(toPrimitive(value))

def sub: List[asm.Operation] = pushBigInt(BigInt(-1)) :: asm.Operation(Opcodes.MUL) :: asm.Operation(Opcodes.ADD) :: pushBigInt(BigInt(-1)) :: asm.Operation(Opcodes.MUL) :: Nil
def sub: List[asm.Operation] =
pushBigInt(BigInt(-1)) :: asm.Operation(Opcodes.MUL) :: asm.Operation(Opcodes.ADD) :: pushBigInt(BigInt(-1)) :: asm
.Operation(Opcodes.MUL) :: Nil

def pushBigInt(value: scala.BigInt): asm.Operation =
push(value,Data.Primitive.BigInt)
push(value, Data.Primitive.BigInt)

def pushInt(i: Int): asm.Operation =
push(i, Data.Primitive.Int32)
Expand Down

0 comments on commit 7260429

Please sign in to comment.