Repository: groovy
Updated Branches:
  refs/heads/GROOVY_2_5_X 83d2f1078 -> e2ec90380


GROOVY-8338: JDK9 requires at least JDK8 bytecode to invokestatic a static 
interface method


Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/e2ec9038
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/e2ec9038
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/e2ec9038

Branch: refs/heads/GROOVY_2_5_X
Commit: e2ec903809b53fcde2602d9d3965dae5a9075de3
Parents: 83d2f10
Author: Jochen Theodorou <blackd...@gmx.org>
Authored: Sat Dec 23 23:24:03 2017 +0100
Committer: paulk <pa...@asert.com.au>
Committed: Wed Mar 7 10:01:29 2018 +1000

----------------------------------------------------------------------
 .../runtime/callsite/CallSiteGenerator.java     | 33 +++++++++++++++-----
 .../v8/InterfaceStaticMethodCallTest.groovy     | 30 ++++++++++++++++++
 2 files changed, 55 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/groovy/blob/e2ec9038/src/main/java/org/codehaus/groovy/runtime/callsite/CallSiteGenerator.java
----------------------------------------------------------------------
diff --git 
a/src/main/java/org/codehaus/groovy/runtime/callsite/CallSiteGenerator.java 
b/src/main/java/org/codehaus/groovy/runtime/callsite/CallSiteGenerator.java
index 7b616c9..8931d19 100644
--- a/src/main/java/org/codehaus/groovy/runtime/callsite/CallSiteGenerator.java
+++ b/src/main/java/org/codehaus/groovy/runtime/callsite/CallSiteGenerator.java
@@ -25,6 +25,7 @@ import org.codehaus.groovy.classgen.asm.BytecodeHelper;
 import org.codehaus.groovy.reflection.CachedClass;
 import org.codehaus.groovy.reflection.CachedMethod;
 import org.codehaus.groovy.reflection.android.AndroidSupport;
+import org.codehaus.groovy.vmplugin.VMPluginFactory;
 import org.objectweb.asm.ClassWriter;
 import org.objectweb.asm.Label;
 import org.objectweb.asm.MethodVisitor;
@@ -90,7 +91,7 @@ public class CallSiteGenerator {
         }        
         
         // make call
-        mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), 
descriptor, invokeMethodCode == Opcodes.INVOKEINTERFACE);
+        mv.visitMethodInsn(invokeMethodCode, type, cachedMethod.getName(), 
descriptor, useInterface);
 
         // produce result
         BytecodeHelper.box(mv, cachedMethod.getReturnType());
@@ -158,11 +159,19 @@ public class CallSiteGenerator {
         mv.visitEnd();
     }
 
+    private static void classHeader(ClassWriter cw, String internalName, 
String superName) {
+        if (VMPluginFactory.getPlugin().getVersion()>=8) {
+            cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, 
internalName, null, superName, null);
+        } else {
+            cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, 
internalName, null, superName, null);
+        }
+    }
+
     public static byte[] genPogoMetaMethodSite(CachedMethod cachedMethod, 
ClassWriter cw, String name) {
         String internalName = name.replace('.', '/');
-        cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, 
internalName, null, "org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", 
null);
+        classHeader(cw, internalName, 
"org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite");
         cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, 
"__constructor__", "Ljava/lang/reflect/Constructor;", null, null);
- 
+
         genConstructor(cw, 
"org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", internalName);
 
         genCallXxxWithArray(cw, "Current", 
"org/codehaus/groovy/runtime/callsite/PogoMetaMethodSite", cachedMethod, 
"groovy/lang/GroovyObject");
@@ -179,7 +188,7 @@ public class CallSiteGenerator {
 
     public static byte[] genPojoMetaMethodSite(CachedMethod cachedMethod, 
ClassWriter cw, String name) {
         String internalName = name.replace('.', '/');
-        cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, 
internalName, null, "org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite", 
null);
+        classHeader(cw, internalName, 
"org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite");
         cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, 
"__constructor__", "Ljava/lang/reflect/Constructor;", null, null);
 
         genConstructor(cw, 
"org/codehaus/groovy/runtime/callsite/PojoMetaMethodSite", internalName);
@@ -194,7 +203,7 @@ public class CallSiteGenerator {
 
     public static byte[] genStaticMetaMethodSite(CachedMethod cachedMethod, 
ClassWriter cw, String name) {
         String internalName = name.replace('.', '/');
-        cw.visit(Opcodes.V1_4, Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, 
internalName, null, 
"org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", null);
+        classHeader(cw, internalName, 
"org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite");
         cw.visitField(Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC, 
"__constructor__", "Ljava/lang/reflect/Constructor;", null, null);
  
         genConstructor(cw, 
"org/codehaus/groovy/runtime/callsite/StaticMetaMethodSite", internalName);
@@ -209,8 +218,16 @@ public class CallSiteGenerator {
         return cw.toByteArray();
     }
 
+    private static ClassWriter makeClassWriter() {
+        if (VMPluginFactory.getPlugin().getVersion()>=8) {
+            return new ClassWriter(ClassWriter.COMPUTE_MAXS | 
ClassWriter.COMPUTE_FRAMES);
+        } else {
+            return new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        }
+    }
+
     public static Constructor compilePogoMethod(CachedMethod cachedMethod) {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        ClassWriter cw = makeClassWriter();
 
         final CachedClass declClass = cachedMethod.getDeclaringClass();
         final CallSiteClassLoader callSiteLoader = 
declClass.getCallSiteLoader();
@@ -222,7 +239,7 @@ public class CallSiteGenerator {
     }
 
     public static Constructor compilePojoMethod(CachedMethod cachedMethod) {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        ClassWriter cw = makeClassWriter();
 
         final CachedClass declClass = cachedMethod.getDeclaringClass();
         final CallSiteClassLoader callSiteLoader = 
declClass.getCallSiteLoader();
@@ -234,7 +251,7 @@ public class CallSiteGenerator {
     }
 
     public static Constructor compileStaticMethod(CachedMethod cachedMethod) {
-        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        ClassWriter cw = makeClassWriter();
 
         final CachedClass declClass = cachedMethod.getDeclaringClass();
         final CallSiteClassLoader callSiteLoader = 
declClass.getCallSiteLoader();

http://git-wip-us.apache.org/repos/asf/groovy/blob/e2ec9038/src/test/org/codehaus/groovy/vmplugin/v8/InterfaceStaticMethodCallTest.groovy
----------------------------------------------------------------------
diff --git 
a/src/test/org/codehaus/groovy/vmplugin/v8/InterfaceStaticMethodCallTest.groovy 
b/src/test/org/codehaus/groovy/vmplugin/v8/InterfaceStaticMethodCallTest.groovy
new file mode 100644
index 0000000..80ad66a
--- /dev/null
+++ 
b/src/test/org/codehaus/groovy/vmplugin/v8/InterfaceStaticMethodCallTest.groovy
@@ -0,0 +1,30 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package org.codehaus.groovy.vmplugin.v8
+
+class InterfaceStaticMethodCallTest extends GroovyTestCase {
+    void testStreamOf() {
+        // "of" is a static method declared on the interface, we only want to 
be sure we can call the method
+        assertScript '''
+            import java.util.stream.Stream
+
+            assert Stream.of("1") instanceof Stream
+        '''
+    }
+}

Reply via email to