This is an automated email from the ASF dual-hosted git repository. blackdrag pushed a commit to branch feature/GROOVY-8299/default_methods in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/feature/GROOVY-8299/default_methods by this push: new 0817795573 GRPPVY-8299: implement dynamic path for default interface methods 0817795573 is described below commit 08177955736e9ed0952be3f2343b87e370dec346 Author: Jochen Theodorou <blackd...@gmx.org> AuthorDate: Fri Sep 29 21:51:08 2023 +0200 GRPPVY-8299: implement dynamic path for default interface methods --- .../classgen/asm/indy/InvokeDynamicWriter.java | 22 ++++++- .../codehaus/groovy/vmplugin/v7/IndyInterface.java | 6 +- .../groovy/vmplugin/v8/CacheableCallSite.java | 9 ++- .../codehaus/groovy/vmplugin/v8/IndyInterface.java | 41 +++++++----- .../org/codehaus/groovy/vmplugin/v8/Selector.java | 74 +++++++++++++--------- 5 files changed, 103 insertions(+), 49 deletions(-) diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/indy/InvokeDynamicWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/indy/InvokeDynamicWriter.java index 74aee3209d..041b177c3a 100644 --- a/src/main/java/org/codehaus/groovy/classgen/asm/indy/InvokeDynamicWriter.java +++ b/src/main/java/org/codehaus/groovy/classgen/asm/indy/InvokeDynamicWriter.java @@ -25,6 +25,7 @@ import org.codehaus.groovy.ast.expr.ConstantExpression; import org.codehaus.groovy.ast.expr.ConstructorCallExpression; import org.codehaus.groovy.ast.expr.EmptyExpression; import org.codehaus.groovy.ast.expr.Expression; +import org.codehaus.groovy.ast.expr.PropertyExpression; import org.codehaus.groovy.ast.tools.WideningCategories; import org.codehaus.groovy.classgen.AsmClassGenerator; import org.codehaus.groovy.classgen.asm.CompileStack; @@ -35,6 +36,7 @@ import org.codehaus.groovy.classgen.asm.WriterController; import org.codehaus.groovy.runtime.wrappers.Wrapper; import org.codehaus.groovy.vmplugin.v8.IndyInterface; import org.objectweb.asm.Handle; +import org.objectweb.asm.Opcodes; import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandles.Lookup; @@ -47,6 +49,7 @@ import static org.codehaus.groovy.ast.ClassHelper.boolean_TYPE; import static org.codehaus.groovy.ast.ClassHelper.getWrapper; import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveBoolean; import static org.codehaus.groovy.ast.ClassHelper.isWrapperBoolean; +import static org.codehaus.groovy.ast.tools.GeneralUtils.bytecodeX; import static org.codehaus.groovy.classgen.asm.BytecodeHelper.doCast; import static org.codehaus.groovy.classgen.asm.BytecodeHelper.getTypeDescription; import static org.codehaus.groovy.vmplugin.v8.IndyInterface.GROOVY_OBJECT; @@ -57,6 +60,7 @@ import static org.codehaus.groovy.vmplugin.v8.IndyInterface.THIS_CALL; import static org.codehaus.groovy.vmplugin.v8.IndyInterface.CallType.CAST; import static org.codehaus.groovy.vmplugin.v8.IndyInterface.CallType.GET; import static org.codehaus.groovy.vmplugin.v8.IndyInterface.CallType.INIT; +import static org.codehaus.groovy.vmplugin.v8.IndyInterface.CallType.INTERFACE; import static org.codehaus.groovy.vmplugin.v8.IndyInterface.CallType.METHOD; import static org.objectweb.asm.Opcodes.H_INVOKESTATIC; @@ -122,9 +126,10 @@ public class InvokeDynamicWriter extends InvocationWriter { compileStack.popLHS(); } - private void makeIndyCall(final MethodCallerMultiAdapter adapter, final Expression receiver, final boolean implicitThis, final boolean safe, final String methodName, final Expression arguments) { + private void makeIndyCall(final MethodCallerMultiAdapter adapter, final Expression origReceiver, final boolean implicitThis, final boolean safe, final String methodName, final Expression arguments) { OperandStack operandStack = controller.getOperandStack(); + Expression receiver = correctReceiverForInterfaceCall(origReceiver, operandStack); StringBuilder sig = new StringBuilder(prepareIndyCall(receiver, implicitThis)); // load arguments @@ -150,12 +155,27 @@ public class InvokeDynamicWriter extends InvocationWriter { } sig.append(")Ljava/lang/Object;"); + String callSiteName = METHOD.getCallSiteName(); if (adapter == null) callSiteName = INIT.getCallSiteName(); + // receiver != origReceiver interface default method call + if (receiver != origReceiver) callSiteName = INTERFACE.getCallSiteName(); + int flags = getMethodCallFlags(adapter, safe, containsSpreadExpression); + finishIndyCall(BSM, callSiteName, sig.toString(), numberOfArguments, methodName, flags); } + private Expression correctReceiverForInterfaceCall(Expression exp, OperandStack operandStack) { + if (exp instanceof PropertyExpression) { + PropertyExpression pexp = (PropertyExpression) exp; + if (pexp.getObjectExpression() instanceof ClassExpression && "super".equals(pexp.getPropertyAsString())) { + return bytecodeX(pexp.getObjectExpression().getType(), mv -> mv.visitIntInsn(Opcodes.ALOAD, 0)); + } + } + return exp; + } + private static int getMethodCallFlags(final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spread) { int flags = 0; if (safe) flags |= SAFE_NAVIGATION; diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyInterface.java b/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyInterface.java index 2583aeaf68..57e8da6e18 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyInterface.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v7/IndyInterface.java @@ -18,6 +18,8 @@ */ package org.codehaus.groovy.vmplugin.v7; +import org.codehaus.groovy.vmplugin.v8.CacheableCallSite; + import java.lang.invoke.CallSite; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles.Lookup; @@ -121,14 +123,14 @@ public class IndyInterface { * Get the cached methodhandle. if the related methodhandle is not found in the inline cache, cache and return it. */ public static Object fromCache(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { - return org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); + return org.codehaus.groovy.vmplugin.v8.IndyInterface.fromCache((CacheableCallSite)callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); } /** * Core method for indy method selection using runtime types. */ public static Object selectMethod(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { - return org.codehaus.groovy.vmplugin.v8.IndyInterface.selectMethod(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); + return org.codehaus.groovy.vmplugin.v8.IndyInterface.selectMethod((CacheableCallSite)callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); } /** diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java index a356f0a20c..9e00ccfa8e 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/CacheableCallSite.java @@ -22,6 +22,7 @@ import org.apache.groovy.util.SystemUtil; import org.codehaus.groovy.runtime.memoize.MemoizeCache; import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.invoke.MutableCallSite; import java.lang.ref.SoftReference; @@ -38,6 +39,7 @@ public class CacheableCallSite extends MutableCallSite { private static final int CACHE_SIZE = SystemUtil.getIntegerSafe("groovy.indy.callsite.cache.size", 4); private static final float LOAD_FACTOR = 0.75f; private static final int INITIAL_CAPACITY = (int) Math.ceil(CACHE_SIZE / LOAD_FACTOR) + 1; + private final MethodHandles.Lookup lookup; private volatile SoftReference<MethodHandleWrapper> latestHitMethodHandleWrapperSoftReference = null; private final AtomicLong fallbackCount = new AtomicLong(); private MethodHandle defaultTarget; @@ -52,8 +54,9 @@ public class CacheableCallSite extends MutableCallSite { } }; - public CacheableCallSite(MethodType type) { + public CacheableCallSite(MethodType type, MethodHandles.Lookup lookup) { super(type); + this.lookup = lookup; } public MethodHandleWrapper getAndPut(String className, MemoizeCache.ValueProvider<? super String, ? extends MethodHandleWrapper> valueProvider) { @@ -124,4 +127,8 @@ public class CacheableCallSite extends MutableCallSite { public void setFallbackTarget(MethodHandle fallbackTarget) { this.fallbackTarget = fallbackTarget; } + + public MethodHandles.Lookup getLookup() { + return lookup; + } } diff --git a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java index 04a2d2d94a..b719d5e641 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/IndyInterface.java @@ -67,23 +67,28 @@ public class IndyInterface { /** * Method invocation type */ - METHOD("invoke"), + METHOD("invoke", 0), /** * Constructor invocation type */ - INIT("init"), + INIT("init", 1), /** * Get property invocation type */ - GET("getProperty"), + GET("getProperty", 2), /** * Set property invocation type */ - SET("setProperty"), + SET("setProperty", 3), /** * Cast invocation type */ - CAST("cast"); + CAST("cast", 4), + + /** + * call to interface method + */ + INTERFACE("interface", 5); private static final Map<String, CallType> NAME_CALLTYPE_MAP = Stream.of(CallType.values()).collect(Collectors.toMap(CallType::getCallSiteName, Function.identity())); @@ -92,8 +97,10 @@ public class IndyInterface { * The name of the call site type */ private final String name; + private final int orderNumber; - CallType(String callSiteName) { + CallType(String callSiteName, int orderNumber) { + this.orderNumber = orderNumber; this.name = callSiteName; } @@ -107,6 +114,10 @@ public class IndyInterface { public static CallType fromCallSiteName(String callSiteName) { return NAME_CALLTYPE_MAP.get(callSiteName); } + + public int getOrderNumber() { + return this.orderNumber; + } } /** @@ -153,14 +164,14 @@ public class IndyInterface { static { try { - MethodType mt = MethodType.methodType(Object.class, MutableCallSite.class, Class.class, String.class, int.class, Boolean.class, Boolean.class, Boolean.class, Object.class, Object[].class); + MethodType mt = MethodType.methodType(Object.class, CacheableCallSite.class, Class.class, String.class, int.class, Boolean.class, Boolean.class, Boolean.class, Object.class, Object[].class); FROM_CACHE_METHOD = LOOKUP.findStatic(IndyInterface.class, "fromCache", mt); } catch (Exception e) { throw new GroovyBugError(e); } try { - MethodType mt = MethodType.methodType(Object.class, MutableCallSite.class, Class.class, String.class, int.class, Boolean.class, Boolean.class, Boolean.class, Object.class, Object[].class); + MethodType mt = MethodType.methodType(Object.class, CacheableCallSite.class, Class.class, String.class, int.class, Boolean.class, Boolean.class, Boolean.class, Object.class, Object[].class); SELECT_METHOD = LOOKUP.findStatic(IndyInterface.class, "selectMethod", mt); } catch (Exception e) { throw new GroovyBugError(e); @@ -208,7 +219,7 @@ public class IndyInterface { CallType ct = CallType.fromCallSiteName(callType); if (null == ct) throw new GroovyBugError("Unknown call type: " + callType); - int callID = ct.ordinal(); + int callID = ct.getOrderNumber(); boolean safe = (flags & SAFE_NAVIGATION) != 0; boolean thisCall = (flags & THIS_CALL) != 0; boolean spreadCall = (flags & SPREAD_CALL) != 0; @@ -223,7 +234,7 @@ public class IndyInterface { // first produce a dummy call site, since indy doesn't give the runtime types; // the site then changes to the target when INDY_OPTIMIZE_THRESHOLD is reached // that does the method selection including the direct call to the real method - CacheableCallSite mc = new CacheableCallSite(type); + CacheableCallSite mc = new CacheableCallSite(type, caller); Class<?> sender = caller.lookupClass(); if (thisCall) { while (GeneratedClosure.class.isAssignableFrom(sender)) { @@ -258,7 +269,7 @@ public class IndyInterface { } private static class FallbackSupplier { - private final MutableCallSite callSite; + private final CacheableCallSite callSite; private final Class<?> sender; private final String methodName; private final int callID; @@ -269,7 +280,7 @@ public class IndyInterface { private final Object[] arguments; private MethodHandleWrapper result; - FallbackSupplier(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) { + FallbackSupplier(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) { this.callSite = callSite; this.sender = sender; this.methodName = methodName; @@ -293,7 +304,7 @@ public class IndyInterface { /** * Get the cached methodhandle. if the related methodhandle is not found in the inline cache, cache and return it. */ - public static Object fromCache(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { + public static Object fromCache(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { FallbackSupplier fallbackSupplier = new FallbackSupplier(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); MethodHandleWrapper mhw = @@ -334,7 +345,7 @@ public class IndyInterface { /** * Core method for indy method selection using runtime types. */ - public static Object selectMethod(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { + public static Object selectMethod(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) throws Throwable { final MethodHandleWrapper mhw = fallback(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, dummyReceiver, arguments); if (callSite instanceof CacheableCallSite) { @@ -359,7 +370,7 @@ public class IndyInterface { return mhw.getCachedMethodHandle().invokeExact(arguments); } - private static MethodHandleWrapper fallback(MutableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) { + private static MethodHandleWrapper fallback(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object dummyReceiver, Object[] arguments) { Selector selector = Selector.getSelector(callSite, sender, methodName, callID, safeNavigation, thisCall, spreadCall, arguments); selector.setCallSiteTarget(); 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 7585f70c8d..b7cbbff9c8 100644 --- a/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java +++ b/src/main/java/org/codehaus/groovy/vmplugin/v8/Selector.java @@ -18,7 +18,6 @@ */ package org.codehaus.groovy.vmplugin.v8; -import groovy.lang.AdaptingMetaClass; import groovy.lang.Closure; import groovy.lang.ExpandoMetaClass; import groovy.lang.GroovyInterceptable; @@ -57,7 +56,6 @@ import org.codehaus.groovy.vmplugin.VMPluginFactory; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; -import java.lang.invoke.MutableCallSite; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.lang.reflect.Method; @@ -108,7 +106,7 @@ public abstract class Selector { public String name; public MethodHandle handle; public boolean useMetaClass = false, cache = true; - public MutableCallSite callSite; + public CacheableCallSite callSite; public Class<?> sender; public boolean isVargs; public boolean safeNavigation, safeNavigationOrig, spread; @@ -126,7 +124,7 @@ public abstract class Selector { /** * Returns the Selector */ - public static Selector getSelector(MutableCallSite callSite, Class<?> sender, String methodName, int callID, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { + public static Selector getSelector(CacheableCallSite callSite, Class<?> sender, String methodName, int callID, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { CallType callType = CALL_TYPE_VALUES[callID]; switch (callType) { case INIT: @@ -139,6 +137,8 @@ public abstract class Selector { throw new GroovyBugError("your call tried to do a property set, which is not supported."); case CAST: return new CastSelector(callSite, arguments); + case INTERFACE: + return new InterfaceSelector(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments); default: throw new GroovyBugError("unexpected call type"); } @@ -165,7 +165,7 @@ public abstract class Selector { private static class CastSelector extends MethodSelector { private final Class<?> staticSourceType, staticTargetType; - public CastSelector(MutableCallSite callSite, Object[] arguments) { + public CastSelector(CacheableCallSite callSite, Object[] arguments) { super(callSite, Selector.class, "", CallType.CAST, Boolean.FALSE, Boolean.FALSE, Boolean.FALSE, arguments); this.staticSourceType = callSite.type().parameterType(0); this.staticTargetType = callSite.type().returnType(); @@ -284,7 +284,7 @@ public abstract class Selector { private static class PropertySelector extends MethodSelector { private boolean insertName; - public PropertySelector(MutableCallSite callSite, Class<?> sender, String methodName, CallType callType, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { + public PropertySelector(CacheableCallSite callSite, Class<?> sender, String methodName, CallType callType, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { super(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments); } @@ -384,7 +384,7 @@ public abstract class Selector { private static final MethodType MT_OBJECT = MethodType.methodType(Object.class); private boolean beanConstructor; - public InitSelector(MutableCallSite callSite, Class<?> sender, String methodName, CallType callType, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { + public InitSelector(CacheableCallSite callSite, Class<?> sender, String methodName, CallType callType, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { super(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments); } @@ -434,7 +434,7 @@ public abstract class Selector { if (LOG_ENABLED) LOG.info("meta method is MetaConstructor instance"); MetaConstructor mc = (MetaConstructor) method; isVargs = mc.isVargsMethod(); - Constructor con = mc.getCachedConstrcutor().getCachedConstructor(); + Constructor<?> con = mc.getCachedConstrcutor().getCachedConstructor(); try { handle = LOOKUP.unreflectConstructor(con); if (LOG_ENABLED) LOG.info("successfully unreflected constructor"); @@ -466,7 +466,7 @@ public abstract class Selector { /** * In case of a bean constructor we don't do any varags or implicit null argument - * transformations. Otherwise we do the same as for {@link MethodSelector#correctParameterLength()} + * transformations. Otherwise, we do the same as for {@link MethodSelector#correctParameterLength()} */ @Override public void correctParameterLength() { @@ -499,6 +499,31 @@ public abstract class Selector { } } + private static class InterfaceSelector extends MethodSelector { + public InterfaceSelector(CacheableCallSite callSite, Class<?> sender, String methodName, CallType callType, boolean safeNavigation, boolean thisCall, boolean spreadCall, Object[] arguments) { + super(callSite, sender, methodName, callType, safeNavigation, thisCall, spreadCall, arguments); + } + + @Override + public MetaClass getMetaClass() { + mc = GroovySystem.getMetaClassRegistry().getMetaClass(targetType.parameterType(0)); + mc.initialize(); + if (LOG_ENABLED) LOG.info("meta class is " + mc); + return mc; + } + + @Override + public void setSelectionBase() { + selectionBase = mc.getTheClass(); + if (LOG_ENABLED) LOG.info("selectionBase set to " + selectionBase); + } + + @Override + public MethodHandle unreflect(Method cachedMethod) throws IllegalAccessException { + return this.callSite.getLookup().unreflectSpecial(cachedMethod, this.sender); // throws if sender cannot invoke method + } + } + /** * Method invocation based {@link Selector}. * This Selector is called for method invocations and is base for constructor @@ -509,7 +534,7 @@ public abstract class Selector { private boolean isCategoryMethod; protected MetaClass mc; - public MethodSelector(MutableCallSite callSite, Class<?> sender, String methodName, CallType callType, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object[] arguments) { + public MethodSelector(CacheableCallSite callSite, Class<?> sender, String methodName, CallType callType, Boolean safeNavigation, Boolean thisCall, Boolean spreadCall, Object[] arguments) { this.callType = callType; this.targetType = callSite.type(); this.name = methodName; @@ -654,8 +679,7 @@ public abstract class Selector { } else if (parameterCount == 1 && name.equals("forName") && declaringClass == Class.class) { handle = MethodHandles.insertArguments(CLASS_FOR_NAME, 1, Boolean.TRUE, sender.getClassLoader()); } else { - MethodHandles.Lookup lookup = cm.isPublic() ? LOOKUP : ((Java8)vmplugin).newLookup(sender); // GROOVY-10070, et al. - handle = lookup.unreflect(cm.getCachedMethod()); // throws if sender cannot invoke method + handle = unreflect(cm.getCachedMethod()); } } catch (ReflectiveOperationException e) { throw new GroovyBugError(e); @@ -686,6 +710,10 @@ public abstract class Selector { } } + protected MethodHandle unreflect(Method cachedMethod) throws IllegalAccessException { + return this.callSite.getLookup().unreflect(cachedMethod); // throws if sender cannot invoke method + } + /** * Helper method to manipulate the given type to replace Wrapper with Object. */ @@ -834,10 +862,10 @@ public abstract class Selector { // equal in terms of an assignment in Java. That means according to Java widening rules, or // a subclass, interface, superclass relation, this case then handles also - // primitive to primitive conversion. Those case are also solved by explicitCastArguments. + // primitive to primitive conversion. Those cases are also solved by explicitCastArguments. if (parameterType.isAssignableFrom(got)) continue; - // to aid explicitCastArguments we convert to the wrapper type to let is only unbox + // to aid explicitCastArguments we convert to the wrapper type to let it only unbox handle = TypeTransformers.addTransformer(handle, i, arg, wrappedPara); if (LOG_ENABLED) LOG.info("added transformer at pos " + i + " for type " + got + " to type " + wrappedPara); @@ -885,12 +913,7 @@ public abstract class Selector { if (handle == null) return; if (!cache) return; - MethodHandle fallback; - if (callSite instanceof CacheableCallSite) { - fallback = ((CacheableCallSite) callSite).getFallbackTarget(); - } else { - throw new GroovyBugError("CacheableCallSite is expected, but the actual callsite is: " + callSite); - } + MethodHandle fallback = callSite.getFallbackTarget(); // special guards for receiver if (receiver instanceof GroovyObject) { @@ -970,14 +993,6 @@ public abstract class Selector { */ public void doCallSiteTargetSet() { if (LOG_ENABLED) LOG.info("call site stays uncached"); - /* - if (!cache) { - if (LOG_ENABLED) LOG.info("call site stays uncached"); - } else { - callSite.setTarget(handle); - if (LOG_ENABLED) LOG.info("call site target set, preparing outside invocation"); - } - */ } /** @@ -1049,11 +1064,10 @@ public abstract class Selector { private static MetaClassImpl getMetaClassImpl(final MetaClass mc, final boolean includeEMC) { Class<?> mcc = mc.getClass(); boolean valid = mcc == MetaClassImpl.class - || mcc == AdaptingMetaClass.class || mcc == ClosureMetaClass.class || (includeEMC && mcc == ExpandoMetaClass.class); if (!valid) { - if (LOG_ENABLED) LOG.info("meta class is neither MetaClassImpl, nor AdoptingMetaClass, nor ClosureMetaClass, normal method selection path disabled."); + if (LOG_ENABLED) LOG.info("meta class is neither MetaClassImpl, nor ClosureMetaClass, normal method selection path disabled."); return null; } if (LOG_ENABLED) LOG.info("meta class is a recognized MetaClassImpl");