This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY_3_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY_3_0_X by this push:
     new 089590d7a3 GROOVY-11782: indy guard for null alternation of primitive 
parameters
089590d7a3 is described below

commit 089590d7a316fd103a2bf4a2a7d45561b8898ff2
Author: Eric Milles <[email protected]>
AuthorDate: Sun Oct 12 13:09:37 2025 -0500

    GROOVY-11782: indy guard for null alternation of primitive parameters
    
    3_0_X backport
---
 .../v7/IndyGuardsFiltersAndSignatures.java         |  4 +-
 .../org/codehaus/groovy/vmplugin/v7/Selector.java  | 18 ++++----
 .../v8/IndyGuardsFiltersAndSignatures.java         |  4 +-
 .../org/codehaus/groovy/vmplugin/v8/Selector.java  | 22 ++++------
 src/test/groovy/bugs/Groovy11782.groovy            | 50 ++++++++++++++++++++++
 5 files changed, 73 insertions(+), 25 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyGuardsFiltersAndSignatures.java
 
b/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyGuardsFiltersAndSignatures.java
index 08ef8f9a13..ce0018bd61 100644
--- 
a/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyGuardsFiltersAndSignatures.java
+++ 
b/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyGuardsFiltersAndSignatures.java
@@ -44,6 +44,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 
 import static org.codehaus.groovy.vmplugin.v7.IndyInterface.LOOKUP;
 
@@ -71,7 +72,7 @@ public class IndyGuardsFiltersAndSignatures {
 
     protected static final MethodHandle
             SAME_CLASS, UNWRAP_METHOD,
-            SAME_MC, IS_NULL,
+            SAME_MC, IS_NULL, NON_NULL,
             UNWRAP_EXCEPTION, META_METHOD_INVOKER,
             GROOVY_OBJECT_INVOKER, GROOVY_OBJECT_GET_PROPERTY,
             HAS_CATEGORY_IN_CURRENT_THREAD_GUARD,
@@ -91,6 +92,7 @@ public class IndyGuardsFiltersAndSignatures {
             UNWRAP_METHOD = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, "unwrap", 
OBJECT_FILTER);
             SAME_MC = LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, 
"isSameMetaClass", METACLASS1_GUARD);
             IS_NULL = LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, 
"isNull", OBJECT_GUARD);
+            NON_NULL = LOOKUP.findStatic(Objects.class, "nonNull", 
MethodType.methodType(boolean.class, Object.class));
             UNWRAP_EXCEPTION = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, "unwrap", GRE_GUARD);
             GROOVY_OBJECT_INVOKER = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, 
"invokeGroovyObjectInvoker", INVOKER.insertParameterTypes(0, 
MissingMethodException.class));
 
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v7/Selector.java 
b/src/main/java/org/codehaus/groovy/vmplugin/v7/Selector.java
index 7633a2492b..18f01fdca2 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v7/Selector.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v7/Selector.java
@@ -85,6 +85,7 @@ import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.MET
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.MOP_GET;
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.MOP_INVOKE_CONSTRUCTOR;
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.MOP_INVOKE_METHOD;
+import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.NON_NULL;
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.NULL_REF;
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.SAME_CLASS;
 import static 
org.codehaus.groovy.vmplugin.v7.IndyGuardsFiltersAndSignatures.SAME_MC;
@@ -880,8 +881,7 @@ public abstract class Selector {
          * Sets all argument and receiver guards.
          */
         public void setGuards(Object receiver) {
-            if (handle == null) return;
-            if (!cache) return;
+            if (!cache || handle == null) return;
 
             MethodHandle fallback;
             if (callSite instanceof CacheableCallSite) {
@@ -906,7 +906,7 @@ public abstract class Selector {
                 if (LOG_ENABLED) LOG.info("added class equality check");
             }
 
-            if (!useMetaClass && isCategoryMethod) {
+            if (isCategoryMethod && !useMetaClass) {
                 // category method needs Thread check
                 // cases:
                 // (1) method is a category method
@@ -935,14 +935,12 @@ public abstract class Selector {
                 if (arg == null) {
                     test = IS_NULL.asType(MethodType.methodType(boolean.class, 
pt[i]));
                     if (LOG_ENABLED) LOG.info("added null argument check at 
pos " + i);
+                } else if (pt[i].isPrimitive()) { // GROOVY-11782: if null 
then uncache
+                    test = 
NON_NULL.asType(MethodType.methodType(boolean.class, pt[i]));
+                    if (LOG_ENABLED) LOG.info("added non-null argument check 
at pos " + i);
                 } else {
-                    Class<?> argClass = arg.getClass();
-                    if (pt[i].isPrimitive()) continue;
-                    //if (Modifier.isFinal(argClass.getModifiers()) && 
TypeHelper.argumentClassIsParameterClass(argClass,pt[i])) continue;
-                    test = SAME_CLASS.
-                            bindTo(argClass).
-                            asType(MethodType.methodType(boolean.class, 
pt[i]));
-                    if (LOG_ENABLED) LOG.info("added same class check at pos " 
+ i);
+                    test = 
SAME_CLASS.bindTo(arg.getClass()).asType(MethodType.methodType(boolean.class, 
pt[i]));
+                    if (LOG_ENABLED) LOG.info("added same-class argument check 
at pos " + i);
                 }
                 Class<?>[] drops = new Class[i];
                 System.arraycopy(pt, 0, drops, 0, drops.length);
diff --git 
a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
 
b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
index b358d6e4b9..83975de065 100644
--- 
a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
+++ 
b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyGuardsFiltersAndSignatures.java
@@ -44,6 +44,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.Map;
+import java.util.Objects;
 
 import static org.codehaus.groovy.vmplugin.v8.IndyInterface.LOOKUP;
 
@@ -59,7 +60,7 @@ public class IndyGuardsFiltersAndSignatures {
             INVOKER = MethodType.methodType(Object.class, Object.class, 
String.class, Object[].class);
 
     protected static final MethodHandle
-            SAME_CLASS, SAME_MC, IS_NULL,
+            SAME_CLASS, SAME_MC, IS_NULL, NON_NULL,
             UNWRAP_METHOD, UNWRAP_EXCEPTION,
             HAS_CATEGORY_IN_CURRENT_THREAD_GUARD,
             META_METHOD_INVOKER, GROOVY_OBJECT_INVOKER, 
GROOVY_OBJECT_GET_PROPERTY,
@@ -80,6 +81,7 @@ public class IndyGuardsFiltersAndSignatures {
             SAME_CLASS = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, "sameClass", 
MethodType.methodType(boolean.class, Class.class, Object.class));
             SAME_MC = LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, 
"isSameMetaClass", MethodType.methodType(boolean.class, MetaClass.class, 
Object.class));
             IS_NULL = LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, 
"isNull", OBJECT_GUARD);
+            NON_NULL = LOOKUP.findStatic(Objects.class, "nonNull", 
MethodType.methodType(boolean.class, Object.class));
             UNWRAP_METHOD = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, "unwrap", 
OBJECT_FILTER);
             UNWRAP_EXCEPTION = 
LOOKUP.findStatic(IndyGuardsFiltersAndSignatures.class, "unwrap", 
MethodType.methodType(Object.class, GroovyRuntimeException.class));
             HAS_CATEGORY_IN_CURRENT_THREAD_GUARD = 
LOOKUP.findStatic(GroovyCategorySupport.class, "hasCategoryInCurrentThread", 
MethodType.methodType(boolean.class));
diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java 
b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
index ae5d01c905..fa71703405 100644
--- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
+++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java
@@ -86,6 +86,7 @@ import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.MET
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.MOP_GET;
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.MOP_INVOKE_CONSTRUCTOR;
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.MOP_INVOKE_METHOD;
+import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.NON_NULL;
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.NULL_REF;
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.SAME_CLASS;
 import static 
org.codehaus.groovy.vmplugin.v8.IndyGuardsFiltersAndSignatures.SAME_MC;
@@ -899,8 +900,7 @@ public abstract class Selector {
          * Sets all argument and receiver guards.
          */
         public void setGuards(Object receiver) {
-            if (handle == null) return;
-            if (!cache) return;
+            if (!cache || handle == null) return;
 
             MethodHandle fallback;
             if (callSite instanceof CacheableCallSite) {
@@ -925,7 +925,7 @@ public abstract class Selector {
                 if (LOG_ENABLED) LOG.info("added class equality check");
             }
 
-            if (!useMetaClass && isCategoryMethod) {
+            if (isCategoryMethod && !useMetaClass) {
                 // category method needs Thread check
                 // cases:
                 // (1) method is a category method
@@ -950,20 +950,16 @@ public abstract class Selector {
             Class<?>[] pt = handle.type().parameterArray();
             for (int i = 0; i < args.length; i++) {
                 Object arg = args[i];
-                Class<?> paramType = pt[i];
                 MethodHandle test;
-
                 if (arg == null) {
-                    test = IS_NULL.asType(MethodType.methodType(boolean.class, 
paramType));
+                    test = IS_NULL.asType(MethodType.methodType(boolean.class, 
pt[i]));
                     if (LOG_ENABLED) LOG.info("added null argument check at 
pos " + i);
+                } else if (pt[i].isPrimitive()) { // GROOVY-11782: if null 
then uncache
+                    test = 
NON_NULL.asType(MethodType.methodType(boolean.class, pt[i]));
+                    if (LOG_ENABLED) LOG.info("added non-null argument check 
at pos " + i);
                 } else {
-                    Class<?> argClass = arg.getClass();
-                    if (paramType.isPrimitive()) continue;
-                    //if (Modifier.isFinal(argClass.getModifiers()) && 
TypeHelper.argumentClassIsParameterClass(argClass,pt[i])) continue;
-                    test = SAME_CLASS.
-                            bindTo(argClass).
-                            asType(MethodType.methodType(boolean.class, 
paramType));
-                    if (LOG_ENABLED) LOG.info("added same class check at pos " 
+ i);
+                    test = 
SAME_CLASS.bindTo(arg.getClass()).asType(MethodType.methodType(boolean.class, 
pt[i]));
+                    if (LOG_ENABLED) LOG.info("added same-class argument check 
at pos " + i);
                 }
                 Class<?>[] drops = new Class[i];
                 System.arraycopy(pt, 0, drops, 0, drops.length);
diff --git a/src/test/groovy/bugs/Groovy11782.groovy 
b/src/test/groovy/bugs/Groovy11782.groovy
new file mode 100644
index 0000000000..45edaa8d05
--- /dev/null
+++ b/src/test/groovy/bugs/Groovy11782.groovy
@@ -0,0 +1,50 @@
+/*
+ *  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 groovy.bugs
+
+import org.codehaus.groovy.control.CompilerConfiguration
+import org.junit.Test
+
+final class Groovy11782 {
+
+    @Test
+    void testNullForPrimitiveParameter() {
+        def config = new CompilerConfiguration()
+        config.optimizationOptions.indy = true
+        new GroovyShell(config).evaluate '''
+            class C11782 {
+                private static int inc(int i) {
+                    ++i
+                }
+            }
+
+            def functor = { Integer i ->
+                C11782.inc(i)
+            }
+
+            10000.times {
+                assert functor(0) == 1
+            }
+            groovy.test.GroovyAssert.shouldFail(MissingMethodException) {
+                functor(null)
+            }
+            assert functor(1) == 2
+        '''
+    }
+}

Reply via email to