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 2022/05/07 15:20:43 UTC

[groovy] branch master updated: minor edits

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 7a5a7a359f minor edits
7a5a7a359f is described below

commit 7a5a7a359f52a46db10b58bb1dbdfbfca00c26d4
Author: Eric Milles <er...@thomsonreuters.com>
AuthorDate: Sat May 7 10:14:58 2022 -0500

    minor edits
---
 .../groovy/classgen/asm/StatementWriter.java       |  20 +--
 .../classgen/asm/indy/InvokeDynamicWriter.java     | 151 ++++++++++-----------
 .../java/org/codehaus/groovy/syntax/Token.java     |   5 +-
 3 files changed, 78 insertions(+), 98 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
index 36c6579522..8075892112 100644
--- a/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
+++ b/src/main/java/org/codehaus/groovy/classgen/asm/StatementWriter.java
@@ -20,7 +20,6 @@ package org.codehaus.groovy.classgen.asm;
 
 import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.BooleanExpression;
 import org.codehaus.groovy.ast.expr.ClosureListExpression;
 import org.codehaus.groovy.ast.expr.ConstantExpression;
@@ -54,16 +53,8 @@ import java.util.Optional;
 import java.util.function.Consumer;
 
 import static org.apache.groovy.ast.tools.ExpressionUtils.isNullConstant;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.maybeFallsThrough;
-import static org.objectweb.asm.Opcodes.ALOAD;
-import static org.objectweb.asm.Opcodes.ATHROW;
-import static org.objectweb.asm.Opcodes.CHECKCAST;
-import static org.objectweb.asm.Opcodes.GOTO;
-import static org.objectweb.asm.Opcodes.IFEQ;
-import static org.objectweb.asm.Opcodes.MONITORENTER;
-import static org.objectweb.asm.Opcodes.MONITOREXIT;
-import static org.objectweb.asm.Opcodes.NOP;
-import static org.objectweb.asm.Opcodes.RETURN;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.*;
+import static org.objectweb.asm.Opcodes.*;
 
 public class StatementWriter {
 
@@ -111,14 +102,13 @@ public class StatementWriter {
         writeStatementLabel(statement);
 
         CompileStack compileStack = controller.getCompileStack();
-        OperandStack operandStack = controller.getOperandStack();
-
         compileStack.pushLoop(statement.getVariableScope(), statement.getStatementLabels());
 
         // then get the iterator and generate the loop control
-        MethodCallExpression iterator = new MethodCallExpression(statement.getCollectionExpression(), "iterator", new ArgumentListExpression());
+        Expression iterator = callX(statement.getCollectionExpression(), "iterator");
+        ((MethodCallExpression) iterator).setImplicitThis(false);
+        iterator = castX(ClassHelper.Iterator_TYPE, iterator);
         iterator.visit(controller.getAcg());
-        operandStack.doGroovyCast(ClassHelper.Iterator_TYPE);
 
         writeForInLoopControlAndBlock(statement);
         compileStack.pop();
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 5dd84082f4..70fbbc5d05 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
@@ -18,9 +18,7 @@
  */
 package org.codehaus.groovy.classgen.asm.indy;
 
-import org.codehaus.groovy.ast.ClassHelper;
 import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
 import org.codehaus.groovy.ast.expr.CastExpression;
 import org.codehaus.groovy.ast.expr.ClassExpression;
 import org.codehaus.groovy.ast.expr.ConstantExpression;
@@ -29,7 +27,6 @@ import org.codehaus.groovy.ast.expr.EmptyExpression;
 import org.codehaus.groovy.ast.expr.Expression;
 import org.codehaus.groovy.ast.tools.WideningCategories;
 import org.codehaus.groovy.classgen.AsmClassGenerator;
-import org.codehaus.groovy.classgen.asm.BytecodeHelper;
 import org.codehaus.groovy.classgen.asm.CompileStack;
 import org.codehaus.groovy.classgen.asm.InvocationWriter;
 import org.codehaus.groovy.classgen.asm.MethodCallerMultiAdapter;
@@ -42,19 +39,24 @@ import org.objectweb.asm.Handle;
 import java.lang.invoke.CallSite;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.invoke.MethodType;
+import java.util.List;
 
-import static org.codehaus.groovy.classgen.asm.BytecodeHelper.getTypeDescription;
+import static org.codehaus.groovy.ast.ClassHelper.OBJECT_TYPE;
+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.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.METHOD;
+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;
 import static org.codehaus.groovy.vmplugin.v8.IndyInterface.IMPLICIT_THIS;
 import static org.codehaus.groovy.vmplugin.v8.IndyInterface.SAFE_NAVIGATION;
 import static org.codehaus.groovy.vmplugin.v8.IndyInterface.SPREAD_CALL;
 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.METHOD;
 import static org.objectweb.asm.Opcodes.H_INVOKESTATIC;
 
 /**
@@ -63,36 +65,29 @@ import static org.objectweb.asm.Opcodes.H_INVOKESTATIC;
  */
 public class InvokeDynamicWriter extends InvocationWriter {
 
+    private static final String BSM_DESCRIPTOR = MethodType.methodType(
+            CallSite.class, Lookup.class, String.class, MethodType.class, String.class, int.class
+    ).toMethodDescriptorString();
+
+    private static final Handle BSM = new Handle(H_INVOKESTATIC,
+        IndyInterface.class.getName().replace('.', '/'), "bootstrap", BSM_DESCRIPTOR, false
+    );
+
+    private static final Object[] CAST_ARGS = {"()", 0};
 
-    private static final String INDY_INTERFACE_NAME = IndyInterface.class.getName().replace('.', '/');
-    private static final String BSM_METHOD_TYPE_DESCRIPTOR = 
-        MethodType.methodType(
-                CallSite.class, Lookup.class, String.class, MethodType.class,
-                String.class, int.class
-        ).toMethodDescriptorString();
-    private static final Handle BSM = 
-        new Handle(
-                H_INVOKESTATIC,
-                INDY_INTERFACE_NAME,
-                "bootstrap",
-                BSM_METHOD_TYPE_DESCRIPTOR,
-                false);
-
-    private final WriterController controller;
-
-    public InvokeDynamicWriter(WriterController wc) {
-        super(wc);
-        this.controller = wc;
+    //--------------------------------------------------------------------------
+
+    public InvokeDynamicWriter(final WriterController controller) {
+        super(controller);
     }
 
     @Override
-    protected boolean makeCachedCall(Expression origin, ClassExpression sender,
-            Expression receiver, Expression message, Expression arguments,
-            MethodCallerMultiAdapter adapter, boolean safe, boolean spreadSafe,
-            boolean implicitThis, boolean containsSpreadExpression
-    ) {
+    protected boolean makeCachedCall(final Expression origin, final ClassExpression sender,
+            final Expression receiver, final Expression message, final Expression arguments,
+            final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spreadSafe,
+            final boolean implicitThis, final boolean containsSpreadExpression) {
         // fixed number of arguments && name is a real String and no GString
-        if ((adapter == null || adapter == invokeMethod || adapter == invokeMethodOnCurrent || adapter == invokeStaticMethod) && !spreadSafe) {
+        if (!spreadSafe && (adapter == null || adapter == invokeMethod || adapter == invokeMethodOnCurrent || adapter == invokeStaticMethod)) {
             String methodName = getMethodName(message);
             if (methodName != null) {
                 makeIndyCall(adapter, receiver, implicitThis, safe, methodName, arguments);
@@ -102,7 +97,7 @@ public class InvokeDynamicWriter extends InvocationWriter {
         return false;
     }
 
-    private String prepareIndyCall(Expression receiver, boolean implicitThis) {
+    private String prepareIndyCall(final Expression receiver, final boolean implicitThis) {
         CompileStack compileStack = controller.getCompileStack();
         OperandStack operandStack = controller.getOperandStack();
 
@@ -112,34 +107,35 @@ public class InvokeDynamicWriter extends InvocationWriter {
         compileStack.pushImplicitThis(implicitThis);
         receiver.visit(controller.getAcg());
         compileStack.popImplicitThis();
-        return "("+getTypeDescription(operandStack.getTopOperand());
+
+        return "(" + getTypeDescription(operandStack.getTopOperand());
     }
 
-    private void finishIndyCall(Handle bsmHandle, String methodName, String sig, int numberOfArguments, Object... bsmArgs) {
+    private void finishIndyCall(final Handle bsmHandle, final String methodName, final String sig, final int numberOfArguments, final Object... bsmArgs) {
         CompileStack compileStack = controller.getCompileStack();
         OperandStack operandStack = controller.getOperandStack();
 
         controller.getMethodVisitor().visitInvokeDynamicInsn(methodName, sig, bsmHandle, bsmArgs);
 
-        operandStack.replace(ClassHelper.OBJECT_TYPE, numberOfArguments);
+        operandStack.replace(OBJECT_TYPE, numberOfArguments);
         compileStack.popLHS();
     }
 
-    private void makeIndyCall(MethodCallerMultiAdapter adapter, Expression receiver, boolean implicitThis, boolean safe, String methodName, Expression arguments) {
+    private void makeIndyCall(final MethodCallerMultiAdapter adapter, final Expression receiver, final boolean implicitThis, final boolean safe, final String methodName, final Expression arguments) {
         OperandStack operandStack = controller.getOperandStack();
 
         StringBuilder sig = new StringBuilder(prepareIndyCall(receiver, implicitThis));
 
         // load arguments
         int numberOfArguments = 1;
-        ArgumentListExpression ae = makeArgumentList(arguments);
+        List<Expression> args = makeArgumentList(arguments).getExpressions();
         boolean containsSpreadExpression = AsmClassGenerator.containsSpreadExpression(arguments);
         AsmClassGenerator acg = controller.getAcg();
         if (containsSpreadExpression) {
-            acg.despreadList(ae.getExpressions(), true);
+            acg.despreadList(args, true);
             sig.append(getTypeDescription(Object[].class));
         } else {
-            for (Expression arg : ae.getExpressions()) {
+            for (Expression arg : args) {
                 arg.visit(acg);
                 if (arg instanceof CastExpression) {
                     operandStack.box();
@@ -148,7 +144,7 @@ public class InvokeDynamicWriter extends InvocationWriter {
                 } else {
                     sig.append(getTypeDescription(operandStack.getTopOperand()));
                 }
-                numberOfArguments++;
+                numberOfArguments += 1;
             }
         }
 
@@ -159,77 +155,70 @@ public class InvokeDynamicWriter extends InvocationWriter {
         finishIndyCall(BSM, callSiteName, sig.toString(), numberOfArguments, methodName, flags);
     }
 
-    private static int getMethodCallFlags(MethodCallerMultiAdapter adapter, boolean safe, boolean spread) {
-        int ret = 0;
-        if (safe)                           ret |= SAFE_NAVIGATION;
-        if (adapter==invokeMethodOnCurrent) ret |= THIS_CALL;
-        if (spread)                         ret |= SPREAD_CALL;
-        return ret;
+    private static int getMethodCallFlags(final MethodCallerMultiAdapter adapter, final boolean safe, final boolean spread) {
+        int flags = 0;
+        if (safe)                           flags |= SAFE_NAVIGATION;
+        if (adapter==invokeMethodOnCurrent) flags |= THIS_CALL;
+        if (spread)                         flags |= SPREAD_CALL;
+
+        return flags;
     }
 
     @Override
-    public void makeSingleArgumentCall(Expression receiver, String message, Expression arguments, boolean safe) {
+    public void makeSingleArgumentCall(final Expression receiver, final String message, final Expression arguments, final boolean safe) {
         makeIndyCall(invokeMethod, receiver, false, safe, message, arguments);
     }
 
-    private static int getPropertyFlags(boolean safe, boolean implicitThis, boolean groovyObject) {
+    private static int getPropertyFlags(final boolean safe, final boolean implicitThis, final boolean groovyObject) {
         int flags = 0;
-        if (implicitThis)   flags |= IMPLICIT_THIS;
-        if (groovyObject)   flags |= GROOVY_OBJECT;
-        if (safe)           flags |= SAFE_NAVIGATION;
+        if (implicitThis) flags |= IMPLICIT_THIS;
+        if (groovyObject) flags |= GROOVY_OBJECT;
+        if (safe)         flags |= SAFE_NAVIGATION;
+
         return flags;
     }
 
-    protected void writeGetProperty(Expression receiver, String propertyName, boolean safe, boolean implicitThis, boolean groovyObject) {
-        String sig = prepareIndyCall(receiver, implicitThis);
-        sig += ")Ljava/lang/Object;";
+    protected void writeGetProperty(final Expression receiver, final String propertyName, final boolean safe, final boolean implicitThis, final boolean groovyObject) {
+        String descriptor = prepareIndyCall(receiver, implicitThis) + ")Ljava/lang/Object;";
         int flags = getPropertyFlags(safe,implicitThis,groovyObject);
-        finishIndyCall(BSM, GET.getCallSiteName(), sig, 1, propertyName, flags);
+        finishIndyCall(BSM, GET.getCallSiteName(), descriptor, 1, propertyName, flags);
     }
 
     @Override
-    protected void writeNormalConstructorCall(ConstructorCallExpression call) {
+    protected void writeNormalConstructorCall(final ConstructorCallExpression call) {
         makeCall(call, new ClassExpression(call.getType()), new ConstantExpression("<init>"), call.getArguments(), null, false, false, false);
     }
 
     @Override
-    public void coerce(ClassNode from, ClassNode target) {
-        ClassNode wrapper = ClassHelper.getWrapper(target);
+    public void coerce(final ClassNode from, final ClassNode target) {
+        ClassNode wrapper = getWrapper(target);
         makeIndyCall(invokeMethod, EmptyExpression.INSTANCE, false, false, "asType", new ClassExpression(wrapper));
         if (isPrimitiveBoolean(target) || isWrapperBoolean(target)) {
-            writeIndyCast(ClassHelper.OBJECT_TYPE,target);
+            writeIndyCast(OBJECT_TYPE, target);
         } else {
-            BytecodeHelper.doCast(controller.getMethodVisitor(), wrapper);
+            doCast(controller.getMethodVisitor(),wrapper);
             controller.getOperandStack().replace(wrapper);
             controller.getOperandStack().doGroovyCast(target);
         }
     }
 
     @Override
-    public void castToNonPrimitiveIfNecessary(ClassNode sourceType, ClassNode targetType) {
-        ClassNode boxedType = ClassHelper.getWrapper(sourceType);
-        if (WideningCategories.implementsInterfaceOrSubclassOf(boxedType, targetType)) {
+    public void castToNonPrimitiveIfNecessary(final ClassNode sourceType, final ClassNode targetType) {
+        if (WideningCategories.implementsInterfaceOrSubclassOf(getWrapper(sourceType), targetType)) {
             controller.getOperandStack().box();
-            return;
+        } else {
+            writeIndyCast(sourceType, targetType);
         }
-        writeIndyCast(sourceType, targetType);
-    }
-
-    private void writeIndyCast(ClassNode sourceType, ClassNode targetType) {
-
-        String sig = "(" +
-                getTypeDescription(sourceType) +
-                ')' +
-                getTypeDescription(targetType);
-        controller.getMethodVisitor().visitInvokeDynamicInsn(
-                //TODO: maybe use a different bootstrap method since no arguments are needed here
-                CAST.getCallSiteName(), sig, BSM, "()", 0);
-        controller.getOperandStack().replace(targetType);
     }
 
     @Override
-    public void castNonPrimitiveToBool(ClassNode sourceType) {
-        writeIndyCast(sourceType, ClassHelper.boolean_TYPE);
+    public void castNonPrimitiveToBool(final ClassNode sourceType) {
+        writeIndyCast(sourceType, boolean_TYPE);
     }
 
+    private void writeIndyCast(final ClassNode sourceType, final ClassNode targetType) {
+        String descriptor = "(" + getTypeDescription(sourceType) + ')' + getTypeDescription(targetType);
+        controller.getMethodVisitor().visitInvokeDynamicInsn(CAST.getCallSiteName(), descriptor, BSM, CAST_ARGS);
+        controller.getOperandStack().replace(targetType); // cast converts top operand from source to target type
+    }
 }
diff --git a/src/main/java/org/codehaus/groovy/syntax/Token.java b/src/main/java/org/codehaus/groovy/syntax/Token.java
index b7ceec03ee..658da3c98c 100644
--- a/src/main/java/org/codehaus/groovy/syntax/Token.java
+++ b/src/main/java/org/codehaus/groovy/syntax/Token.java
@@ -84,7 +84,8 @@ public class Token extends CSTNode {
      */
     @Override
     public CSTNode setMeaning(final int meaning) {
-        this.meaning = meaning;
+        if (this != EOF && this != NULL)
+            this.meaning = meaning;
         return this;
     }
 
@@ -153,7 +154,7 @@ public class Token extends CSTNode {
      * will do it.
      */
     public void setText(String text) {
-        this.text = text;
+        if (this != EOF && this != NULL) this.text = text;
     }
 
     /**