You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by em...@apache.org on 2021/03/10 22:19:13 UTC
[groovy] branch master updated: rework invoke method
implicitThis/thisObject
This is an automated email from the ASF dual-hosted git repository.
emilles pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/groovy.git
The following commit(s) were added to refs/heads/master by this push:
new e91f18c rework invoke method implicitThis/thisObject
e91f18c is described below
commit e91f18c3dc55ae4f9ee378c2d30fd8fd04270ae7
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Wed Mar 10 15:36:37 2021 -0600
rework invoke method implicitThis/thisObject
---
.../groovy/classgen/AsmClassGenerator.java | 7 +---
.../groovy/classgen/asm/InvocationWriter.java | 43 ++++++++++------------
.../groovy/classgen/asm/WriterController.java | 8 ++++
.../classgen/asm/sc/StaticInvocationWriter.java | 21 ++++++-----
.../classgen/asm/sc/StaticTypesLambdaWriter.java | 7 +---
5 files changed, 41 insertions(+), 45 deletions(-)
diff --git a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
index ae99861..bfbd856 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AsmClassGenerator.java
@@ -1343,12 +1343,7 @@ public class AsmClassGenerator extends ClassGenerator {
// "this" in static context is Class instance
if (controller.isStaticMethod() || controller.getCompileStack().isInSpecialConstructorCall()
|| (!controller.getCompileStack().isImplicitThis() && controller.isStaticContext())) {
- ClassNode thisType = controller.getClassNode();
- if (controller.isInGeneratedFunction()) {
- do { thisType = thisType.getOuterClass();
- } while (ClassHelper.isGeneratedFunction(thisType));
- }
- classX(thisType).visit(this);
+ classX(controller.getThisType()).visit(this);
} else {
loadThis(expression);
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
index eaa920c..ef8c0c3 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/InvocationWriter.java
@@ -56,7 +56,6 @@ import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
import static org.apache.groovy.ast.tools.ExpressionUtils.isSuperExpression;
import static org.apache.groovy.ast.tools.ExpressionUtils.isThisExpression;
import static org.codehaus.groovy.ast.ClassHelper.isFunctionalInterface;
-import static org.codehaus.groovy.ast.ClassHelper.isGeneratedFunction;
import static org.codehaus.groovy.ast.ClassHelper.isPrimitiveType;
import static org.codehaus.groovy.transform.stc.StaticTypeCheckingSupport.isClassClassNodeWrappingConcreteType;
import static org.objectweb.asm.Opcodes.AALOAD;
@@ -106,16 +105,16 @@ public class InvocationWriter {
}
public void makeCall(final Expression origin, final Expression receiver, final Expression message, final Expression arguments, final MethodCallerMultiAdapter adapter, boolean safe, final boolean spreadSafe, boolean implicitThis) {
- ClassNode sender = controller.getClassNode();
+ ClassNode sender;
if (isSuperExpression(receiver) || (isThisExpression(receiver) && !implicitThis)) {
- while (isGeneratedFunction(sender)) {
- sender = sender.getOuterClass();
- }
+ sender = controller.getThisType();
if (isSuperExpression(receiver)) {
sender = sender.getSuperClass(); // GROOVY-4035
implicitThis = false; // prevent recursion
safe = false; // GROOVY-6045
}
+ } else {
+ sender = controller.getClassNode();
}
makeCall(origin, new ClassExpression(sender), receiver, message, arguments, adapter, safe, spreadSafe, implicitThis);
@@ -126,13 +125,15 @@ public class InvocationWriter {
ClassNode declaringClass = target.getDeclaringClass();
String methodName = target.getName();
- int opcode = INVOKEVIRTUAL;
+ int opcode;
if (target.isStatic()) {
opcode = INVOKESTATIC;
} else if (declaringClass.isInterface()) {
opcode = INVOKEINTERFACE;
} else if (target.isPrivate() || isSuperExpression(receiver)) {
opcode = INVOKESPECIAL;
+ } else {
+ opcode = INVOKEVIRTUAL;
}
CompileStack compileStack = controller.getCompileStack();
@@ -143,43 +144,37 @@ public class InvocationWriter {
// handle receiver
int argumentsToRemove = 0;
if (opcode != INVOKESTATIC) {
+ argumentsToRemove = 1;
if (receiver != null) {
- // load receiver if not static invocation
- // TODO: fix inner class case
+ Expression objectExpression = receiver;
if (implicitThis
&& classNode.getOuterClass() != null
&& !classNode.isDerivedFrom(declaringClass)
&& !classNode.implementsInterface(declaringClass)) {
- // we are calling an outer class method
+ // outer class method invocation
compileStack.pushImplicitThis(false);
- if (controller.isInGeneratedFunction()) {
- new VariableExpression("thisObject").visit(controller.getAcg());
- } else { // TODO: handle implicitThis && !isThisExpression(receiver)
- Expression expr = new PropertyExpression(new ClassExpression(declaringClass), "this");
- expr.visit(controller.getAcg());
+ if (!controller.isInGeneratedFunction()) {
+ objectExpression = new PropertyExpression(new ClassExpression(declaringClass), "this");
}
} else {
compileStack.pushImplicitThis(implicitThis);
- receiver.visit(controller.getAcg());
}
+ objectExpression.visit(controller.getAcg());
operandStack.doGroovyCast(declaringClass);
compileStack.popImplicitThis();
- argumentsToRemove += 1;
} else {
mv.visitIntInsn(ALOAD, 0);
operandStack.push(classNode);
- argumentsToRemove += 1;
}
}
ClassNode receiverType;
- if (receiver == null) {
- receiverType = declaringClass;
- } else {
+ if (receiver != null) {
receiverType = controller.getTypeChooser().resolveType(receiver, classNode);
- if (isClassClassNodeWrappingConcreteType(receiverType) && target.isStatic()) {
+ if (isClassClassNodeWrappingConcreteType(receiverType) && target.isStatic())
receiverType = receiverType.getGenericsTypes()[0].getType();
- }
+ } else {
+ receiverType = declaringClass;
}
int stackLen = operandStack.getStackLength();
@@ -215,8 +210,8 @@ public class InvocationWriter {
mv.visitInsn(ACONST_NULL);
}
argumentsToRemove += (operandStack.getStackLength() - stackLen);
- controller.getOperandStack().remove(argumentsToRemove);
- controller.getOperandStack().push(returnType);
+ operandStack.remove(argumentsToRemove);
+ operandStack.push(returnType);
return true;
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/WriterController.java b/src/main/java/org/codehaus/groovy/classgen/asm/WriterController.java
index dd8ba29..d5a59e1 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/WriterController.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/WriterController.java
@@ -287,6 +287,14 @@ public class WriterController {
this.methodNode = null;
}
+ public ClassNode getThisType() {
+ ClassNode thisType = getClassNode();
+ while (isGeneratedFunction(thisType)) {
+ thisType = thisType.getOuterClass();
+ }
+ return thisType;
+ }
+
public ClassNode getReturnType() {
if (methodNode != null) {
return methodNode.getReturnType();
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
index b9712a7..aff3014 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticInvocationWriter.java
@@ -84,6 +84,7 @@ import static org.codehaus.groovy.ast.tools.GeneralUtils.nullX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+import static org.codehaus.groovy.transform.trait.Traits.isTrait;
import static org.objectweb.asm.Opcodes.ACONST_NULL;
import static org.objectweb.asm.Opcodes.ALOAD;
import static org.objectweb.asm.Opcodes.CHECKCAST;
@@ -364,18 +365,20 @@ public class StaticInvocationWriter extends InvocationWriter {
}
} else if (target.isPublic() && receiver != null) {
if (implicitThis
+ && controller.isInGeneratedFunction()
&& !classNode.isDerivedFrom(target.getDeclaringClass())
- && !classNode.implementsInterface(target.getDeclaringClass())
- && classNode.getOuterClass() != null && controller.isInGeneratedFunction()) {
- ClassNode current = classNode.getOuterClass();
- fixedReceiver = varX("thisObject", current);
- // adjust for multiple levels of nesting if needed
- while (current.getOuterClass() != null && !target.getDeclaringClass().equals(current)) {
- FieldNode thisField = current.getField("this$0");
- current = current.getOuterClass();
+ && !classNode.implementsInterface(target.getDeclaringClass())) {
+ ClassNode thisType = controller.getThisType();
+ if (isTrait(thisType.getOuterClass())) thisType = ClassHelper.DYNAMIC_TYPE; // GROOVY-7242
+
+ fixedReceiver = varX("thisObject", thisType);
+ // account for multiple levels of inner types
+ while (thisType.getOuterClass() != null && !target.getDeclaringClass().equals(thisType)) {
+ FieldNode thisField = thisType.getField("this$0");
+ thisType = thisType.getOuterClass();
if (thisField != null) {
fixedReceiver = propX(fixedReceiver, "this$0");
- fixedReceiver.setType(current);
+ fixedReceiver.setType(thisType);
fixedImplicitThis = false;
}
}
diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
index 1cf4f5b..a92770f 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java
@@ -60,7 +60,6 @@ import static org.codehaus.groovy.ast.ClassHelper.SERIALIZABLE_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.SERIALIZEDLAMBDA_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.VOID_TYPE;
import static org.codehaus.groovy.ast.ClassHelper.findSAM;
-import static org.codehaus.groovy.ast.ClassHelper.isGeneratedFunction;
import static org.codehaus.groovy.ast.ClassHelper.long_TYPE;
import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
import static org.codehaus.groovy.ast.tools.GeneralUtils.classX;
@@ -175,11 +174,7 @@ public class StaticTypesLambdaWriter extends LambdaWriter implements AbstractFun
mv.visitInsn(DUP);
if (controller.isStaticMethod() || compileStack.isInSpecialConstructorCall() || !accessingInstanceMembers) {
- ClassNode classNode = controller.getClassNode();
- while (isGeneratedFunction(classNode)) {
- classNode = classNode.getOuterClass();
- }
- classX(classNode).visit(controller.getAcg());
+ classX(controller.getThisType()).visit(controller.getAcg());
} else {
loadThis();
}