Skip to content

Commit

Permalink
PropertyCallSerializer fix, explicitTypeArgs fix, more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
kushti committed Oct 8, 2024
1 parent 08b02c7 commit 2ba5a4f
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 11 deletions.
6 changes: 4 additions & 2 deletions data/shared/src/main/scala/sigma/ast/methods.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1844,8 +1844,10 @@ case object SGlobalMethods extends MonoTypeMethods {
ArgInfo("value", "value to be serialized"))

lazy val noneMethod = SMethod(this, "none",
SFunc(Array(SGlobal, tT), SOption(tT), Array(paramT)), 9, FixedCost(JitCost(5))) // todo: cost
.withIRInfo(MethodCallIrBuilder)
SFunc(Array(SGlobal), SOption(tT), Array(paramT)), 9, FixedCost(JitCost(5)), Seq(tT)) // todo: cost
.withIRInfo(MethodCallIrBuilder,
javaMethodOf[SigmaDslBuilder, RType[_]]("none"),
{ mtype => Array(mtype.tRange) })
.withInfo(MethodCall, "")

protected override def getMethods() = super.getMethods() ++ {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ import sigma.serialization.CoreByteWriter.{ArgInfo, DataInfo}
import sigma.ast._
import sigma.ast.syntax.SValue
import SigmaByteWriter._
import debox.cfor
import sigma.util.safeNewArray

import scala.collection.compat.immutable.ArraySeq

case class PropertyCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value[SType]], STypeSubst) => Value[SType])
extends ValueSerializer[MethodCall] {
Expand All @@ -17,14 +21,33 @@ case class PropertyCallSerializer(cons: (Value[SType], SMethod, IndexedSeq[Value
w.put(mc.method.objType.typeId, typeCodeInfo)
w.put(mc.method.methodId, methodCodeInfo)
w.putValue(mc.obj, objInfo)
mc.method.explicitTypeArgs.foreach { a =>
val tpe = mc.typeSubst(a) // existence is checked in MethodCall constructor
w.putType(tpe)
}
}

override def parse(r: SigmaByteReader): Value[SType] = {
val typeId = r.getByte()
val methodId = r.getByte()
val obj = r.getValue()
val method = SMethod.fromIds(typeId, methodId)
val specMethod = method.specializeFor(obj.tpe, SType.EmptySeq)
cons(obj, specMethod, Value.EmptySeq, EmptySubst)

val (explicitTypeSubst: Map[STypeVar, SType], specMethod: SMethod) = if (method.hasExplicitTypeArgs) {
val nTypes = method.explicitTypeArgs.length
val res = safeNewArray[SType](nTypes)
cfor(0)(_ < nTypes, _ + 1) { i =>
res(i) = r.getType()
}
val explicitTypes = ArraySeq.unsafeWrapArray(res)
val explicitTypeSubst = method.explicitTypeArgs.zip(explicitTypes).toMap
val specMethod = method.withConcreteTypes(explicitTypeSubst)
(explicitTypeSubst, specMethod)
} else {
val specMethod = method.specializeFor(obj.tpe, SType.EmptySeq)
(EmptySubst, specMethod)
}

cons(obj, specMethod, Value.EmptySeq, explicitTypeSubst)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,9 @@ trait GraphBuilding extends Base with DefRewriting { IR: IRContext =>
val value = asRep[tT.WrappedType](argsV(0))
val cT = stypeToElem(typeSubst.apply(tT)).asInstanceOf[Elem[tT.WrappedType]]
g.some(value)(cT)
case SGlobalMethods.noneMethod.name =>
val cT = stypeToElem(typeSubst.apply(tT)).asInstanceOf[Elem[tT.WrappedType]]
g.none()(cT)
case _ => throwError()
}
case (x: Ref[tNum], _: SNumericTypeMethods) => method.name match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1974,22 +1974,22 @@ object SigmaDslBuilder extends EntityObject("SigmaDslBuilder") {
override def fromBigEndianBytes[T](bytes: Ref[Coll[Byte]])(implicit cT: Elem[T]): Ref[T] = {
asRep[T](mkMethodCall(self,
SigmaDslBuilderClass.getMethod("fromBigEndianBytes", classOf[Sym], classOf[Elem[T]]),
Array[AnyRef](bytes, cT, Map(tT -> Evaluation.rtypeToSType(cT.sourceType))),
true, false, cT))
Array[AnyRef](bytes, cT),
true, false, cT, Map(tT -> Evaluation.rtypeToSType(cT.sourceType))))
}

override def some[T](value: Ref[T])(implicit cT: Elem[T]): Ref[WOption[T]] = {
asRep[WOption[T]](mkMethodCall(self,
SigmaDslBuilderClass.getMethod("some", classOf[Sym], classOf[Elem[T]]),
Array[AnyRef](value, cT, Map(tT -> Evaluation.rtypeToSType(cT.sourceType))),
true, false, element[WOption[T]]))
Array[AnyRef](value, cT),
true, false, element[WOption[T]], Map(tT -> Evaluation.rtypeToSType(cT.sourceType))))
}

override def none[T]()(implicit cT: Elem[T]): Ref[WOption[T]] = {
asRep[WOption[T]](mkMethodCall(self,
SigmaDslBuilderClass.getMethod("none", classOf[Elem[T]]),
Array[AnyRef](cT, Map(tT -> Evaluation.rtypeToSType(cT.sourceType))),
true, false, element[WOption[T]]))
Array[AnyRef](cT),
true, false, element[WOption[T]], Map(tT -> Evaluation.rtypeToSType(cT.sourceType))))
}

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -989,7 +989,6 @@ class BasicOpsSpecification extends CompilerTestingCommons
}
}

// todo: failing, needs for Header (de)serialization support from https://github.com/ScorexFoundation/sigmastate-interpreter/pull/972
property("serialize - collection of collection of headers") {
val td = new SigmaTestingData {}
val h1 = td.TestData.h1
Expand Down Expand Up @@ -1755,4 +1754,48 @@ class BasicOpsSpecification extends CompilerTestingCommons
}
}

property("Global.some - computable value") {
val ext: Seq[VarBinding] = Seq(
(intVar1, IntConstant(0))
)
def someTest(): Assertion = {
test("some", env, ext,
"""{
| val i = getVar[Int](1)
| val xo = Global.some[Int](i.get)
| xo == i
|}""".stripMargin,
null
)
}

if (VersionContext.current.isV6SoftForkActivated) {
someTest()
} else {
an[Exception] should be thrownBy someTest()
}
}

property("Global.none") {
val ext: Seq[VarBinding] = Seq(
(intVar1, IntConstant(0))
)
def someTest(): Assertion = {
test("some", env, ext,
"""{
| val xo = Global.some[Long](5L)
| val xn = Global.none[Long]()
| xn.isDefined == false && xn != xo
|}""".stripMargin,
null
)
}

if (VersionContext.current.isV6SoftForkActivated) {
someTest()
} else {
an[Exception] should be thrownBy someTest()
}
}

}

0 comments on commit 2ba5a4f

Please sign in to comment.