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
+ '''
+ }
+}