Skip to content

Instantly share code, notes, and snippets.

@mhyee
Last active July 12, 2017 18:10
Show Gist options
  • Save mhyee/cad8f34f50b4343bc85b781c74752e1d to your computer and use it in GitHub Desktop.
Save mhyee/cad8f34f50b4343bc85b781c74752e1d to your computer and use it in GitHub Desktop.
Repro of a bug in Flix v0.1
package ca.uwaterloo.flix
import ca.uwaterloo.flix.api.{Flix, InvokableUnsafe, WrappedType}
import ca.uwaterloo.flix.language.ast.Type
import ca.uwaterloo.flix.runtime.{Model, Value}
object BugRepro {
// To run this repro:
// Drop this file in main/src/ca/uwaterloo/flix/BugRepro.scala
// In IntelliJ, set up a configuration with the main class set to ca.uwaterloo.flix.BugRepro
//
// The bug only shows up when using <- (the "loop" operator) and interop.
// The stack offsets for environment are computed incorrectly, so the wrong variables are evaluated.
def main(argv: Array[String]): Unit = {
val flix = new Flix().addStr(
"""
|def g(i: Int): Set[Int] = Set((i + 1) :: Nil)
|
|rel A(a: Int)
|rel B(b: Int)
|
|A(1).
|B(x) :- A(y), x <- f(y). // CRASH
|//B(x) :- A(y), x <- f(2). // CRASH
|//B(x) :- A(y), x <- g(y). // OK
|//B(x) :- A(y), x <- g(2). // CRASH
|//B(x) :- x <- g(2). // OK
""".stripMargin)
flix.addHookUnsafe(
"f",
flix.mkFunctionType(Array(flix.mkInt32Type), new WrappedType(Type.mkFSet(Type.Int32))),
new InvokableUnsafe {
def apply(args: Array[AnyRef]): AnyRef = {
val i = args(0).asInstanceOf[Integer]
val res = new java.lang.Integer(i+1)
Value.mkTag("Set", Value.mkList(List(res)))
}})
val model = flix.solve().get
printRelation(model, "B")
}
def printRelation(model: Model, name: String): Unit = {
val rel = model.getRelation(name)
rel.foreach(t => println(s"""$name(${t.mkString(",")})."""))
}
}
package ca.uwaterloo.flix
import ca.uwaterloo.flix.api.{Flix, InvokableUnsafe}
import ca.uwaterloo.flix.language.ast.Type
import ca.uwaterloo.flix.runtime.Value.{Unit, mkTag}
import ca.uwaterloo.flix.runtime.{Model, Value}
import ca.uwaterloo.flix.util.{Evaluation, Options}
object BugRepro {
// To run this repro:
// Drop this file in main/src/ca/uwaterloo/flix/BugRepro.scala
// In IntelliJ, set up a configuration with the main class set to ca.uwaterloo.flix.BugRepro
//
// This is a modified version for commit 4842ed938d6c36a1053222ac2add8e3fbf592dc1
// 'unsafe native method' seems to work, but there's still an underlying bug with x <- f(2)
// There's also a problem with using compiled sets (enums.Set), but interpreted sets are fine (Value.Tag)
def main(argv: Array[String]): Unit = {
val flix = new Flix()//.setOptions(Options.Default.copy(evaluation = Evaluation.Interpreted))
flix.addStr(
"""
|def g(i: Int): Set[Int] = Set((i + 1) :: Nil)
|def f(i: Int): Set[Int] = unsafe native method ca.uwaterloo.flix.BugRepro.f(i)
|
|rel A(a: Int)
|rel B(b: Int)
|
|A(1).
|//B(x) :- A(y), x <- f(y). // OK
|//B(x) :- A(y), x <- f(2). // CRASH compiled, OK interpreted
|//B(x) :- A(y), x <- g(y). // CRASH compiled, OK interpreted
|//B(x) :- A(y), x <- g(2). // CRASH compiled, OK interpreted
|//B(x) :- x <- g(2). // CRASH compiled, OK interpreted
""".stripMargin)
// flix.addHookUnsafe(
// "f",
// flix.mkFunctionType(Array(flix.mkInt32Type), new WrappedType(Type.mkFSet(Type.Int32))),
// new InvokableUnsafe {
// def apply(args: Array[AnyRef]): AnyRef = {
// val i = args(0).asInstanceOf[Integer]
// val res = new java.lang.Integer(i+1)
// Value.mkTag("Set", Value.mkList(List(res)))
// }})
val model = flix.solve().get
printRelation(model, "B")
}
def printRelation(model: Model, name: String): Unit = {
val rel = model.getRelation(name)
rel.foreach(t => println(s"""$name(${t.mkString(",")})."""))
}
def mkList(as: List[AnyRef]): Value.Tag = as.foldRight(mkTag("Nil", Unit)) {
case (a, l) => mkTag("Cons", Array(a, l))
}
def f(i: Int): AnyRef = {
val res = new java.lang.Integer(i+1)
Value.mkTag("Set", mkList(List(res)))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment