From a6152b4c2c0a26835e60a8ef209cca87bec8510e Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Wed, 7 Dec 2011 21:18:25 +0100 Subject: Fix reflective toolbox producing invalid bytecode Wrapper method for AST undergoing a reflective compilation has been incorrectly marked as static. This was off the radars until one day the code being compiled declared a top-level method. During flatten that method got hoisted into the wrapper module, and its invocation got translated into an instance call upon the module. This led to static wrapper method trying to call an instance method, and that blew up the bytecode verifier. More info: https://issues.scala-lang.org/browse/SI-5266. Fixes SI-5266, review by @odersky. --- test/pending/run/t5266_1.check | 2 -- test/pending/run/t5266_1.scala | 23 ----------------------- test/pending/run/t5266_2.check | 2 -- test/pending/run/t5266_2.scala | 17 ----------------- 4 files changed, 44 deletions(-) delete mode 100644 test/pending/run/t5266_1.check delete mode 100644 test/pending/run/t5266_1.scala delete mode 100644 test/pending/run/t5266_2.check delete mode 100644 test/pending/run/t5266_2.scala (limited to 'test/pending') diff --git a/test/pending/run/t5266_1.check b/test/pending/run/t5266_1.check deleted file mode 100644 index 3feac16a0b..0000000000 --- a/test/pending/run/t5266_1.check +++ /dev/null @@ -1,2 +0,0 @@ -2 -evaluated = null \ No newline at end of file diff --git a/test/pending/run/t5266_1.scala b/test/pending/run/t5266_1.scala deleted file mode 100644 index 06a81a04ea..0000000000 --- a/test/pending/run/t5266_1.scala +++ /dev/null @@ -1,23 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - val code = scala.reflect.Code.lift{ - def x = 2 - println(x) - }; - - val settings = new Settings - settings.debug.value = true - settings.Xshowtrees.value = true - settings.Xprint.value = List("typer") - settings.printtypes.value = true - settings.Ytyperdebug.value = true - - val reporter = new ConsoleReporter(settings) - val toolbox = new ToolBox(reporter) - val ttree = toolbox.typeCheck(code.tree) - val evaluated = toolbox.runExpr(ttree) - println("evaluated = " + evaluated) -} \ No newline at end of file diff --git a/test/pending/run/t5266_2.check b/test/pending/run/t5266_2.check deleted file mode 100644 index 3feac16a0b..0000000000 --- a/test/pending/run/t5266_2.check +++ /dev/null @@ -1,2 +0,0 @@ -2 -evaluated = null \ No newline at end of file diff --git a/test/pending/run/t5266_2.scala b/test/pending/run/t5266_2.scala deleted file mode 100644 index cd841da021..0000000000 --- a/test/pending/run/t5266_2.scala +++ /dev/null @@ -1,17 +0,0 @@ -import scala.tools.nsc.reporters._ -import scala.tools.nsc.Settings -import reflect.runtime.Mirror.ToolBox - -object Test extends App { - val code = scala.reflect.Code.lift{ - def x = 2 - def y = x - println(y) - }; - - val reporter = new ConsoleReporter(settings) - val toolbox = new ToolBox(reporter) - val ttree = toolbox.typeCheck(code.tree) - val evaluated = toolbox.runExpr(ttree) - println("evaluated = " + evaluated) -} -- cgit v1.2.3 From 98b0bcc74430015dc2f35b9bfa681ef9b8b093d8 Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Fri, 23 Dec 2011 17:56:53 +0100 Subject: Tests for recently submitted SI-5334 --- test/pending/run/t5334_1.scala | 15 +++++++++++++++ test/pending/run/t5334_2.scala | 15 +++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 test/pending/run/t5334_1.scala create mode 100644 test/pending/run/t5334_2.scala (limited to 'test/pending') diff --git a/test/pending/run/t5334_1.scala b/test/pending/run/t5334_1.scala new file mode 100644 index 0000000000..c1eba89c2b --- /dev/null +++ b/test/pending/run/t5334_1.scala @@ -0,0 +1,15 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class C + new C + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} diff --git a/test/pending/run/t5334_2.scala b/test/pending/run/t5334_2.scala new file mode 100644 index 0000000000..361b8c85f2 --- /dev/null +++ b/test/pending/run/t5334_2.scala @@ -0,0 +1,15 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + val code = scala.reflect.Code.lift{ + class C + List((new C, new C)) + }; + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(code.tree) + toolbox.runExpr(ttree) +} -- cgit v1.2.3 From 8f2d318ee2e09baee4e42da73aafb6999ff3874c Mon Sep 17 00:00:00 2001 From: Eugene Burmako Date: Sun, 25 Dec 2011 11:06:04 +0100 Subject: A handful of tests for closures under reification --- test/pending/run/reify_closure1.check | 2 ++ test/pending/run/reify_closure1.scala | 20 ++++++++++++++++++++ test/pending/run/reify_closure2a.check | 2 ++ test/pending/run/reify_closure2a.scala | 20 ++++++++++++++++++++ test/pending/run/reify_closure2b.check | 2 ++ test/pending/run/reify_closure2b.scala | 22 ++++++++++++++++++++++ test/pending/run/reify_closure3a.check | 2 ++ test/pending/run/reify_closure3a.scala | 22 ++++++++++++++++++++++ test/pending/run/reify_closure3b.check | 2 ++ test/pending/run/reify_closure3b.scala | 24 ++++++++++++++++++++++++ test/pending/run/reify_closure4a.check | 2 ++ test/pending/run/reify_closure4a.scala | 22 ++++++++++++++++++++++ test/pending/run/reify_closure4b.check | 2 ++ test/pending/run/reify_closure4b.scala | 24 ++++++++++++++++++++++++ test/pending/run/reify_closure5a.check | 2 ++ test/pending/run/reify_closure5a.scala | 20 ++++++++++++++++++++ test/pending/run/reify_closure5b.check | 2 ++ test/pending/run/reify_closure5b.scala | 22 ++++++++++++++++++++++ test/pending/run/reify_closure6.check | 3 +++ test/pending/run/reify_closure6.scala | 26 ++++++++++++++++++++++++++ 20 files changed, 243 insertions(+) create mode 100644 test/pending/run/reify_closure1.check create mode 100644 test/pending/run/reify_closure1.scala create mode 100644 test/pending/run/reify_closure2a.check create mode 100644 test/pending/run/reify_closure2a.scala create mode 100644 test/pending/run/reify_closure2b.check create mode 100644 test/pending/run/reify_closure2b.scala create mode 100644 test/pending/run/reify_closure3a.check create mode 100644 test/pending/run/reify_closure3a.scala create mode 100644 test/pending/run/reify_closure3b.check create mode 100644 test/pending/run/reify_closure3b.scala create mode 100644 test/pending/run/reify_closure4a.check create mode 100644 test/pending/run/reify_closure4a.scala create mode 100644 test/pending/run/reify_closure4b.check create mode 100644 test/pending/run/reify_closure4b.scala create mode 100644 test/pending/run/reify_closure5a.check create mode 100644 test/pending/run/reify_closure5a.scala create mode 100644 test/pending/run/reify_closure5b.check create mode 100644 test/pending/run/reify_closure5b.scala create mode 100644 test/pending/run/reify_closure6.check create mode 100644 test/pending/run/reify_closure6.scala (limited to 'test/pending') diff --git a/test/pending/run/reify_closure1.check b/test/pending/run/reify_closure1.check new file mode 100644 index 0000000000..b2f7f08c17 --- /dev/null +++ b/test/pending/run/reify_closure1.check @@ -0,0 +1,2 @@ +10 +10 diff --git a/test/pending/run/reify_closure1.scala b/test/pending/run/reify_closure1.scala new file mode 100644 index 0000000000..825a38dc1d --- /dev/null +++ b/test/pending/run/reify_closure1.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure2a.check b/test/pending/run/reify_closure2a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure2a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure2a.scala b/test/pending/run/reify_closure2a.scala new file mode 100644 index 0000000000..b88bec005d --- /dev/null +++ b/test/pending/run/reify_closure2a.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + y + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure2b.check b/test/pending/run/reify_closure2b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure2b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure2b.scala b/test/pending/run/reify_closure2b.scala new file mode 100644 index 0000000000..e9fb40bede --- /dev/null +++ b/test/pending/run/reify_closure2b.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + val fun: reflect.Code[Int => Int] = x => { + x + y + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure3a.check b/test/pending/run/reify_closure3a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure3a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure3a.scala b/test/pending/run/reify_closure3a.scala new file mode 100644 index 0000000000..6414fa58a3 --- /dev/null +++ b/test/pending/run/reify_closure3a.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + def y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure3b.check b/test/pending/run/reify_closure3b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure3b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure3b.scala b/test/pending/run/reify_closure3b.scala new file mode 100644 index 0000000000..5c4f3c81b9 --- /dev/null +++ b/test/pending/run/reify_closure3b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + def y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure4a.check b/test/pending/run/reify_closure4a.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure4a.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure4a.scala b/test/pending/run/reify_closure4a.scala new file mode 100644 index 0000000000..99e9d82706 --- /dev/null +++ b/test/pending/run/reify_closure4a.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + val y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure4b.check b/test/pending/run/reify_closure4b.check new file mode 100644 index 0000000000..c1f3abd7e6 --- /dev/null +++ b/test/pending/run/reify_closure4b.check @@ -0,0 +1,2 @@ +11 +12 diff --git a/test/pending/run/reify_closure4b.scala b/test/pending/run/reify_closure4b.scala new file mode 100644 index 0000000000..24dfa9fe17 --- /dev/null +++ b/test/pending/run/reify_closure4b.scala @@ -0,0 +1,24 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo(y: Int): Int => Int = { + class Foo(y: Int) { + val y1 = y + + val fun: reflect.Code[Int => Int] = x => { + x + y1 + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(y).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(1)(10)) + println(foo(2)(10)) +} diff --git a/test/pending/run/reify_closure5a.check b/test/pending/run/reify_closure5a.check new file mode 100644 index 0000000000..df9e19c591 --- /dev/null +++ b/test/pending/run/reify_closure5a.check @@ -0,0 +1,2 @@ +13 +14 diff --git a/test/pending/run/reify_closure5a.scala b/test/pending/run/reify_closure5a.scala new file mode 100644 index 0000000000..0ac53d5479 --- /dev/null +++ b/test/pending/run/reify_closure5a.scala @@ -0,0 +1,20 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + val fun: reflect.Code[Int => Int] = x => { + x + ys.length + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure5b.check b/test/pending/run/reify_closure5b.check new file mode 100644 index 0000000000..df9e19c591 --- /dev/null +++ b/test/pending/run/reify_closure5b.check @@ -0,0 +1,2 @@ +13 +14 diff --git a/test/pending/run/reify_closure5b.scala b/test/pending/run/reify_closure5b.scala new file mode 100644 index 0000000000..02eb771f0c --- /dev/null +++ b/test/pending/run/reify_closure5b.scala @@ -0,0 +1,22 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + def foo[T](ys: List[T]): Int => Int = { + class Foo[T](ys: List[T]) { + val fun: reflect.Code[Int => Int] = x => { + x + ys.length + } + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(new Foo(ys).fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println(foo(List(1, 2, 3))(10)) + println(foo(List(1, 2, 3, 4))(10)) +} diff --git a/test/pending/run/reify_closure6.check b/test/pending/run/reify_closure6.check new file mode 100644 index 0000000000..3526d04b0e --- /dev/null +++ b/test/pending/run/reify_closure6.check @@ -0,0 +1,3 @@ +first invocation = 15 +second invocation = 18 +q after second invocation = 2 diff --git a/test/pending/run/reify_closure6.scala b/test/pending/run/reify_closure6.scala new file mode 100644 index 0000000000..909071aa44 --- /dev/null +++ b/test/pending/run/reify_closure6.scala @@ -0,0 +1,26 @@ +import scala.tools.nsc.reporters._ +import scala.tools.nsc.Settings +import reflect.runtime.Mirror.ToolBox + +object Test extends App { + var q = 0 + def foo[T](ys: List[T]): Int => Int = { + val z = 1 + var y = 0 + val fun: reflect.Code[Int => Int] = x => { + y += 1 + q += 1 + x + ys.length * z + q + y + } + + val reporter = new ConsoleReporter(new Settings) + val toolbox = new ToolBox(reporter) + val ttree = toolbox.typeCheck(fun.tree) + val dyn = toolbox.runExpr(ttree) + dyn.asInstanceOf[Int => Int] + } + + println("first invocation = " + foo(List(1, 2, 3))(10)) + println("second invocation = " + foo(List(1, 2, 3, 4))(10)) + println("q after second invocation = " + q) +} -- cgit v1.2.3