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. --- src/compiler/scala/reflect/runtime/ToolBoxes.scala | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/reflect/runtime/ToolBoxes.scala b/src/compiler/scala/reflect/runtime/ToolBoxes.scala index e617239398..1114c908e6 100644 --- a/src/compiler/scala/reflect/runtime/ToolBoxes.scala +++ b/src/compiler/scala/reflect/runtime/ToolBoxes.scala @@ -42,11 +42,10 @@ trait ToolBoxes extends { self: Universe => def wrapInObject(expr: Tree, fvs: List[Symbol]): ModuleDef = { val obj = EmptyPackageClass.newModule(NoPosition, nextWrapperModuleName()) - val minfo = ClassInfoType(List(ObjectClass.tpe), new Scope, obj.moduleClass) + val minfo = ClassInfoType(List(ObjectClass.tpe, ScalaObjectClass.tpe), new Scope, obj.moduleClass) obj.moduleClass setInfo minfo obj setInfo obj.moduleClass.tpe val meth = obj.moduleClass.newMethod(NoPosition, wrapperMethodName) - meth setFlag Flags.STATIC def makeParam(fv: Symbol) = meth.newValueParameter(NoPosition, fv.name) setInfo fv.tpe meth setInfo MethodType(fvs map makeParam, expr.tpe) minfo.decls enter meth @@ -92,7 +91,9 @@ trait ToolBoxes extends { self: Universe => if (settings.debug.value) println("generated: "+className) val jclazz = jClass.forName(moduleFileName(className), true, classLoader) val jmeth = jclazz.getDeclaredMethods.find(_.getName == wrapperMethodName).get - val result = jmeth.invoke(null, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) + val jfield = jclazz.getDeclaredFields.find(_.getName == NameTransformer.MODULE_INSTANCE_NAME).get + val singleton = jfield.get(null) + val result = jmeth.invoke(singleton, fvs map (sym => sym.asInstanceOf[FreeVar].value.asInstanceOf[AnyRef]): _*) if (etpe.typeSymbol != FunctionClass(0)) result else { val applyMeth = result.getClass.getMethod("apply") -- cgit v1.2.3