Skip to content

Commit

Permalink
Fix SpEL generated code for default method invocation
Browse files Browse the repository at this point in the history
Closes gh-25706
  • Loading branch information
jhoeller committed Sep 5, 2020
1 parent eec4a6d commit 2d632ef
Showing 1 changed file with 13 additions and 6 deletions.
@@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -244,7 +244,7 @@ private void updateExitTypeDescriptor() {
Method method = ((ReflectiveMethodExecutor) executorToCheck.get()).getMethod();
String descriptor = CodeFlow.toDescriptor(method.getReturnType());
if (this.nullSafe && CodeFlow.isPrimitive(descriptor)) {
originalPrimitiveExitTypeDescriptor = descriptor;
this.originalPrimitiveExitTypeDescriptor = descriptor;
this.exitTypeDescriptor = CodeFlow.toBoxedDescriptor(descriptor);
}
else {
Expand Down Expand Up @@ -296,7 +296,7 @@ public boolean isCompilable() {

return true;
}

@Override
public void generateCode(MethodVisitor mv, CodeFlow cf) {
CachedMethodExecutor executorToCheck = this.cachedExecutor;
Expand Down Expand Up @@ -327,7 +327,7 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
// Something on the stack when nothing is needed
mv.visitInsn(POP);
}

if (CodeFlow.isPrimitive(descriptor)) {
CodeFlow.insertBoxIfNecessary(mv, descriptor.charAt(0));
}
Expand All @@ -340,8 +340,10 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
}

generateCodeForArguments(mv, cf, method, this.children);
mv.visitMethodInsn((isStaticMethod ? INVOKESTATIC : INVOKEVIRTUAL), classDesc, method.getName(),
CodeFlow.createSignatureDescriptor(method), method.getDeclaringClass().isInterface());
mv.visitMethodInsn(
(isStaticMethod ? INVOKESTATIC : (isJava8DefaultMethod(method) ? INVOKEINTERFACE : INVOKEVIRTUAL)),
classDesc, method.getName(), CodeFlow.createSignatureDescriptor(method),
method.getDeclaringClass().isInterface());
cf.pushDescriptor(this.exitTypeDescriptor);

if (this.originalPrimitiveExitTypeDescriptor != null) {
Expand All @@ -354,6 +356,11 @@ public void generateCode(MethodVisitor mv, CodeFlow cf) {
}
}

private static boolean isJava8DefaultMethod(Method method) {
return (method.getDeclaringClass().isInterface() && Modifier.isPublic(method.getModifiers()) &&
!Modifier.isAbstract(method.getModifiers()) && !Modifier.isStatic(method.getModifiers()));
}


private class MethodValueRef implements ValueRef {

Expand Down

0 comments on commit 2d632ef

Please sign in to comment.