Skip to content

Commit 3ad38d1

Browse files
committed
Miniev implementation
1 parent d7c0785 commit 3ad38d1

File tree

108 files changed

+2640
-2197
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+2640
-2197
lines changed

benchmark/src/main/scala/com/wavesplatform/state/DBState.scala

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import com.wavesplatform.lang.directives.DirectiveSet
88
import com.wavesplatform.settings.WavesSettings
99
import com.wavesplatform.transaction.smart.WavesEnvironment
1010
import com.wavesplatform.utils.ScorexLogging
11-
import monix.eval.Coeval
1211
import org.openjdk.jmh.annotations.{Param, Scope, State, TearDown}
1312

1413
import java.io.File
@@ -33,14 +32,13 @@ abstract class DBState extends ScorexLogging {
3332
AddressScheme.current = new AddressScheme { override val chainId: Byte = 'W' }
3433

3534
lazy val environment = WavesEnvironment(
36-
AddressScheme.current.chainId,
37-
Coeval.raiseError(new NotImplementedError("`tx` is not implemented")),
38-
Coeval(rocksDBWriter.height),
39-
rocksDBWriter,
40-
null,
41-
DirectiveSet.contractDirectiveSet,
42-
ByteStr.empty
43-
)
35+
???,
36+
???,
37+
ByteStr.empty,
38+
DirectiveSet.contractDirectiveSet,
39+
) {
40+
override def blockchain: Blockchain = ???
41+
}
4442

4543
@TearDown
4644
def close(): Unit = {

benchmark/src/test/scala/com/wavesplatform/lang/v1/EnvironmentFunctionsBenchmark.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ object EnvironmentFunctionsBenchmark {
169169

170170
@State(Scope.Benchmark)
171171
class AddressFromString {
172-
val ctx: EvaluationContext[Environment, Id] =
172+
val ctx: EvaluationContext[Id] =
173173
WavesContext
174174
.build(Global, DirectiveSet(V4, Account, DApp).explicitGet(), true)
175175
.evaluationContext(environment)

benchmark/src/test/scala/com/wavesplatform/lang/v1/EvaluatorV2Benchmark.scala

Lines changed: 82 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
11
package com.wavesplatform.lang.v1
22

33
import com.wavesplatform.lang.Common
4-
import com.wavesplatform.lang.directives.values.{V1, V3}
4+
import com.wavesplatform.lang.directives.values.{V1, V3, V5, V6}
55
import com.wavesplatform.lang.v1.EvaluatorV2Benchmark.*
6-
import com.wavesplatform.lang.v1.compiler.Terms.{EXPR, IF, TRUE}
6+
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_LONG, EXPR, IF, TRUE}
77
import com.wavesplatform.lang.v1.compiler.TestCompiler
88
import com.wavesplatform.lang.v1.evaluator.EvaluatorV2
99
import com.wavesplatform.lang.v1.evaluator.ctx.DisabledLogEvaluationContext
1010
import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext
11-
import com.wavesplatform.lang.v1.traits.Environment
11+
import com.wavesplatform.lang.v1.evaluator.ctx.{DisabledLogEvaluationContext, EvaluationContext, LoggedEvaluationContext}
1212
import org.openjdk.jmh.annotations.*
1313
import org.openjdk.jmh.infra.Blackhole
1414

1515
import java.util.concurrent.TimeUnit
1616
import scala.annotation.tailrec
1717

1818
object EvaluatorV2Benchmark {
19-
val pureContext = PureContext.build(V1, useNewPowPrecision = true).withEnvironment[Environment]
20-
val pureEvalContext = pureContext.evaluationContext(Common.emptyBlockchainEnvironment())
21-
val evaluatorV2 = new EvaluatorV2(DisabledLogEvaluationContext(pureEvalContext), V1, Int.MaxValue, true, false, true, true, true)
19+
val pureContext: CTX = PureContext.build(V1, useNewPowPrecision = true)
20+
val pureEvalContext: EvaluationContext[Id] = pureContext.evaluationContext(Common.emptyBlockchainEnvironment())
21+
val evaluatorV2: EvaluatorV2 = new EvaluatorV2(DisabledLogEvaluationContext(pureEvalContext), V1, true, true, false)
2222
}
2323

2424
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@@ -42,6 +42,45 @@ class EvaluatorV2Benchmark {
4242

4343
@Benchmark
4444
def conditions(st: Conditions, bh: Blackhole): Unit = bh.consume(eval(pureEvalContext, st.expr, V1))
45+
46+
@Benchmark
47+
def recFunc(st: RecFunc, bh: Blackhole): Unit = bh.consume {
48+
val (_, _, res) = eval(pureEvalContext, st.expr, V1)
49+
require(res == Right(CONST_LONG(13631488)), s"$res")
50+
}
51+
52+
@Benchmark
53+
def overheadCallable(st: OverheadTest, bh: Blackhole): Unit = bh.consume {
54+
val (_, comp, res) = eval(pureEvalContext, st.expr.expr, V6)
55+
require((Int.MaxValue - comp) == 1048576, s"$comp")
56+
}
57+
58+
@Benchmark
59+
def mini_funcs(st: Funcs, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))
60+
61+
@Benchmark
62+
def mini_lets(st: Lets, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))
63+
64+
@Benchmark
65+
def mini_custom(st: CustomFunc, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))
66+
67+
@Benchmark
68+
def mini_littleCustom(st: LittleCustomFunc, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))
69+
70+
@Benchmark
71+
def mini_conditions(st: Conditions, bh: Blackhole): Unit = bh.consume(miniEv(st.expr, pureEvalContext))
72+
73+
@Benchmark
74+
def mini_recFunc(st: RecFunc, bh: Blackhole): Unit = bh.consume {
75+
val (log, spentComplexity, res) = miniEv(st.expr, pureEvalContext)
76+
require(res == Right(CONST_LONG(13631488)), s"$res")
77+
}
78+
79+
@Benchmark
80+
def mini_overheadCallable(st: OverheadTest, bh: Blackhole): Unit = bh.consume {
81+
val (_, comp, res) = miniEv(st.expr.expr, pureEvalContext, 52000)
82+
require(comp == 1048576, s"$comp")
83+
}
4584
}
4685

4786
@State(Scope.Benchmark)
@@ -56,7 +95,10 @@ class Funcs {
5695
| a$count() == a$count()
5796
""".stripMargin
5897

59-
val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
98+
val expr = {
99+
val sc = TestCompiler(V6).compileExpression(script, checkSize = false)
100+
sc.expr
101+
}
60102
}
61103

62104
@State(Scope.Benchmark)
@@ -69,7 +111,22 @@ class Lets {
69111
| a$count == a$count
70112
""".stripMargin
71113

72-
val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
114+
val expr = TestCompiler(V3).compileExpression(script, checkSize = false).expr
115+
}
116+
117+
@State(Scope.Benchmark)
118+
class RecFunc {
119+
def scriptStr(size: Int) =
120+
s"""func f1(i: Int) = i + 1
121+
|${(2 to size)
122+
.map { i =>
123+
s"func f$i(${(0 until i).map(idx => s"i$idx: Int").mkString(",")}) = ${(1 until i).map(fi => s"f$fi(${(1 to fi).map(ii => s"i$ii").mkString(",")})").mkString("+")}"
124+
}
125+
.mkString("\n")}
126+
|f${size}(${(1 to size).mkString(",")})
127+
|""".stripMargin
128+
private val script: String = scriptStr(22)
129+
val expr = TestCompiler(V6).compileExpression(script, checkSize = false).expr
73130
}
74131

75132
@State(Scope.Benchmark)
@@ -113,7 +170,7 @@ class CustomFunc {
113170
| f() && f() && f() && f() && f() && f() && f()
114171
""".stripMargin
115172

116-
val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
173+
val expr = TestCompiler(V6).compileExpression(script).expr
117174
}
118175

119176
@State(Scope.Benchmark)
@@ -157,7 +214,22 @@ class LittleCustomFunc {
157214
| f()
158215
""".stripMargin
159216

160-
val expr = TestCompiler(V3).compileExpression(script).expr.asInstanceOf[EXPR]
217+
val expr = TestCompiler(V3).compileExpression(script).expr
218+
}
219+
220+
@State(Scope.Benchmark)
221+
class OverheadTest {
222+
val expr = {
223+
val n = 20
224+
val scriptTest =
225+
s"""
226+
| func f0() = true
227+
| ${(0 until n).map(i => s"func f${i + 1}() = if (f$i()) then f$i() else f$i()").mkString("\n")}
228+
| f$n()
229+
""".stripMargin
230+
println(scriptTest)
231+
TestCompiler(V5).compileExpression(scriptTest)
232+
}
161233
}
162234

163235
@State(Scope.Benchmark)

benchmark/src/test/scala/com/wavesplatform/lang/v1/PureFunctionsRebenchmark.scala

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,19 @@ import java.util.concurrent.{ThreadLocalRandom, TimeUnit}
55
import cats.Id
66
import com.google.common.primitives.Longs
77
import com.wavesplatform.common.state.ByteStr
8-
import com.wavesplatform.common.utils._
8+
import com.wavesplatform.common.utils.*
99
import com.wavesplatform.lang.directives.DirectiveSet
10-
import com.wavesplatform.lang.directives.values._
11-
import com.wavesplatform.lang.utils._
10+
import com.wavesplatform.lang.directives.values.*
11+
import com.wavesplatform.lang.utils.*
1212
import com.wavesplatform.lang.v1.FunctionHeader.Native
13-
import com.wavesplatform.lang.v1.PureFunctionsRebenchmark._
13+
import com.wavesplatform.lang.v1.PureFunctionsRebenchmark.*
1414
import com.wavesplatform.lang.v1.compiler.Terms
15-
import com.wavesplatform.lang.v1.compiler.Terms._
15+
import com.wavesplatform.lang.v1.compiler.Terms.*
1616
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
1717
import com.wavesplatform.lang.v1.evaluator.ctx.impl.PureContext
1818
import com.wavesplatform.lang.v1.evaluator.{FunctionIds, Log}
19-
import com.wavesplatform.lang.v1.traits.Environment
2019
import com.wavesplatform.lang.{Common, ExecutionError, v1}
21-
import org.openjdk.jmh.annotations._
20+
import org.openjdk.jmh.annotations.*
2221
import org.openjdk.jmh.infra.Blackhole
2322

2423
import scala.util.Random
@@ -217,7 +216,7 @@ class PureFunctionsRebenchmark {
217216
}
218217

219218
object PureFunctionsRebenchmark {
220-
val context: EvaluationContext[Environment, Id] =
219+
val context: EvaluationContext[Id] =
221220
lazyContexts((DirectiveSet(V5, Account, Expression).explicitGet(), true, true))()
222221
.evaluationContext(Common.emptyBlockchainEnvironment())
223222

benchmark/src/test/scala/com/wavesplatform/lang/v1/ScriptEvaluatorBenchmark.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ import com.wavesplatform.lang.v1.EnvironmentFunctionsBenchmark.{curve25519, rand
99
import com.wavesplatform.lang.v1.FunctionHeader.Native
1010
import com.wavesplatform.lang.v1.ScriptEvaluatorBenchmark.*
1111
import com.wavesplatform.lang.v1.compiler.Terms.*
12+
import com.wavesplatform.lang.v1.evaluator.EvaluatorV1.*
1213
import com.wavesplatform.lang.v1.evaluator.FunctionIds
1314
import com.wavesplatform.lang.v1.evaluator.FunctionIds.{FROMBASE58, SIGVERIFY, TOBASE58}
1415
import com.wavesplatform.lang.v1.evaluator.ctx.impl.{CryptoContext, PureContext}
1516
import com.wavesplatform.lang.v1.traits.Environment
1617
import com.wavesplatform.lang.{Common, Global}
18+
import com.wavesplatform.lang.{Common, Global}
1719
import org.openjdk.jmh.annotations.*
1820
import org.openjdk.jmh.infra.Blackhole
1921

@@ -22,11 +24,10 @@ import scala.concurrent.duration.SECONDS
2224
import scala.util.Random
2325

2426
object ScriptEvaluatorBenchmark {
25-
val lastVersion = StdLibVersion.VersionDic.all.max
26-
val context =
27-
(PureContext.build(lastVersion, useNewPowPrecision = true) |+| CryptoContext.build(Global, lastVersion))
28-
.withEnvironment[Environment]
29-
.evaluationContext(Common.emptyBlockchainEnvironment())
27+
val version = V1
28+
val pureEvalContext: EvaluationContext[Id] =
29+
PureContext.build(V1, useNewPowPrecision = true).evaluationContext(Common.emptyBlockchainEnvironment())
30+
val evaluatorV1: EvaluatorV1[Id] = new EvaluatorV1[Id]()
3031
}
3132

3233
@OutputTimeUnit(TimeUnit.MICROSECONDS)

benchmark/src/test/scala/com/wavesplatform/lang/v1/package.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.wavesplatform.lang
22

33
import cats.Id
44
import com.wavesplatform.lang.directives.values.StdLibVersion
5+
import com.wavesplatform.lang.miniev.{Ev, State}
56
import com.wavesplatform.lang.v1.FunctionHeader.Native
67
import com.wavesplatform.lang.v1.compiler.Terms
78
import com.wavesplatform.lang.v1.compiler.Terms.{CONST_BIGINT, CONST_LONG, EXPR, FUNCTION_CALL}
@@ -10,7 +11,6 @@ import com.wavesplatform.lang.v1.evaluator.FunctionIds.POW_BIGINT
1011
import com.wavesplatform.lang.v1.evaluator.ctx.EvaluationContext
1112
import com.wavesplatform.lang.v1.evaluator.ctx.impl.Rounding
1213
import com.wavesplatform.lang.v1.evaluator.{EvaluatorV2, Log}
13-
import com.wavesplatform.lang.v1.traits.Environment
1414

1515
package object v1 {
1616
def pow(base: BigInt, basePrecision: Int, exponent: BigInt, exponentPrecision: Int, resultPrecision: Int): EXPR =
@@ -27,7 +27,7 @@ package object v1 {
2727
)
2828

2929
def eval(
30-
ctx: EvaluationContext[Environment, Id],
30+
ctx: EvaluationContext[Id],
3131
expr: EXPR,
3232
stdLibVersion: StdLibVersion = StdLibVersion.VersionDic.all.max
3333
): (Log[Id], Int, Either[ExecutionError, Terms.EVALUATED]) =
@@ -41,4 +41,7 @@ package object v1 {
4141
enableExecutionLog = false,
4242
fixedThrownError = true
4343
)
44+
45+
def miniEv(expr: EXPR, ctx: EvaluationContext[Id], limit: Int = Int.MaxValue): (Log[Id], Int, Either[ExecutionError, Terms.EVALUATED]) =
46+
Ev.run(expr, ???)
4447
}

benchmark/src/test/scala/com/wavesplatform/state/WavesEnvironmentBenchmark.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ object WavesEnvironmentBenchmark {
134134
RDB.open(wavesSettings.dbSettings)
135135
}
136136

137-
val environment: Environment[Id] = {
137+
val environment: Environment[Id] = ???/*{
138138
val state = new RocksDBWriter(rdb, wavesSettings.blockchainSettings, wavesSettings.dbSettings, wavesSettings.enableLightMode)
139139
WavesEnvironment(
140140
AddressScheme.current.chainId,
@@ -145,7 +145,7 @@ object WavesEnvironmentBenchmark {
145145
DirectiveSet.contractDirectiveSet,
146146
ByteStr.empty
147147
)
148-
}
148+
}*/
149149

150150
@TearDown
151151
def close(): Unit = {

build.sbt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,13 @@ lazy val lang =
3737

3838
lazy val `lang-jvm` = lang.jvm
3939
.settings(
40-
name := "RIDE Compiler",
41-
normalizedName := "lang",
42-
description := "The RIDE smart contract language compiler",
43-
libraryDependencies += "org.scala-js" %% "scalajs-stubs" % "1.1.0" % Provided
40+
name := "RIDE Compiler",
41+
normalizedName := "lang",
42+
description := "The RIDE smart contract language compiler",
43+
libraryDependencies ++= Seq(
44+
"org.scala-js" %% "scalajs-stubs" % "1.1.0" % Provided,
45+
Dependencies.scalaLogging
46+
)
4447
)
4548

4649
lazy val `lang-js` = lang.js
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.wavesplatform.lang.utils
2+
3+
trait Logging {
4+
def trace(message: => String): Unit = println(message)
5+
}

lang/jvm/src/main/scala/com/wavesplatform/lang/Global.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ object Global extends BaseGlobal {
103103
} else {
104104
BigDecimalMath.pow(baseBD, expBD, context)
105105
}
106-
if (useNewPrecision)
106+
(if (useNewPrecision)
107107
setScale(resultPrecision, round, context.getPrecision, result)
108108
else {
109-
val value = result.setScale(resultPrecision.toInt, round.mode).unscaledValue
109+
val value = result.setScale(resultPrecision, round.mode).unscaledValue
110110
Right(BigInt(value))
111-
}
112-
}.flatten.map(_.bigInteger.longValueExact())
111+
}).map(_.bigInteger.longValueExact())
112+
}.flatten
113113

114114
def log(b: Long, bp: Long, e: Long, ep: Long, rp: Long, round: Rounding): Either[String, Long] =
115115
tryEither {
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.wavesplatform.lang.utils
2+
3+
import com.typesafe.scalalogging.StrictLogging
4+
5+
trait Logging extends StrictLogging {
6+
def trace(message: => String): Unit = logger.trace(message)
7+
}

lang/shared/src/main/scala/com/wavesplatform/lang/ExecutionError.scala

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,15 @@ sealed trait ExecutionError {
44
def message: String
55
}
66
case class CommonError(details: String, cause: Option[ValidationError] = None) extends ExecutionError {
7-
override def toString: String = s"CommonError($message)"
87
override def message: String = cause.map(_.toString).getOrElse(details)
98
}
109
case class ThrownError(message: String) extends ExecutionError
1110
case class FailOrRejectError(message: String, skipInvokeComplexity: Boolean = true) extends ExecutionError with ValidationError
11+
12+
case class EvaluationException(cause: Throwable) extends ExecutionError {
13+
override lazy val message: String = s"class ${cause.getClass} ${String.valueOf(cause.getMessage)}"
14+
}
15+
16+
case object SoftLimitReached extends ExecutionError {
17+
override val message = "Soft limit reached"
18+
}

lang/shared/src/main/scala/com/wavesplatform/lang/ValidationError.scala

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,4 @@ object ValidationError {
66
type Validation[T] = Either[ValidationError, T]
77

88
case class ScriptParseError(m: String) extends ValidationError
9-
case class ScriptRunsLimitError(m: String) extends ValidationError
10-
119
}

0 commit comments

Comments
 (0)