groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Daniel Sun <realblue...@hotmail.com>
Subject Re: About the native-lambda branch
Date Mon, 15 Jan 2018 09:53:30 GMT
Hi Jochen,

     `ArrayIndexOutOfBoundsException` is fixed. I encounter another
problem(i.e. How to load arguments according to some specified order): I
want to load local variables[1] according to the order in which the local
variables appear in lambda body. For example:
      
(1)
```
String x = 'x'
Integer y = 2
Stream.of(1, 2, 3).map(e -> '' + x + y + e) // Note the order of `x` and
`y`(`x` is before `y`)
```
I hope load `x`, then load `y` before invokedynamic.

(2)
```
String x = 'x'
Integer y = 2
Stream.of(1, 2, 3).map(e -> '' + y + x + e) // Note the order of `x` and
`y`(`y` is before `x`)
```
I hope  load `y`, then load `x` before invokedynamic.

    Here is how I try to archieve[2], but I can not get the expected
result[3], i.e. I get `groovy.lang.Reference` instances... not String
instances.

    The following bytecode is generated for java code[4] by javac. The key
part is shown as follows and is what I want to generate via ASM utilities of
Groovy(e.g. `CompileStack`, `OperandStack`, etc):

```
    ALOAD 0
    INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [
      // handle kind 0x6 : INVOKESTATIC
     
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)Ljava/lang/Object;, 
      // handle kind 0x6 : INVOKESTATIC
     
Test2.lambda$p$0(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String;, 
      (Ljava/lang/Integer;)Ljava/lang/String;
    ]
```

The complete bytecode:
```
// class version 52.0 (52)
// access flags 0x21
public class Test2 {

  // compiled from: Test2.java
  // access flags 0x19
  public final static INNERCLASS java/lang/invoke/MethodHandles$Lookup
java/lang/invoke/MethodHandles Lookup

  // access flags 0x1
  public <init>()V
   L0
    LINENUMBER 4 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object.<init> ()V
    RETURN
    MAXSTACK = 1
    MAXLOCALS = 1

  // access flags 0x9
  public static main([Ljava/lang/String;)V
   L0
    LINENUMBER 6 L0
    INVOKESTATIC Test2.p ()V
   L1
    LINENUMBER 7 L1
    RETURN
    MAXSTACK = 0
    MAXLOCALS = 1

  // access flags 0x9
  public static p()V
   L0
    LINENUMBER 10 L0
    LDC "#"
    ASTORE 0
   L1
    LINENUMBER 12 L1
    ICONST_3
    ANEWARRAY java/lang/Integer
    DUP
    ICONST_0
    ICONST_1
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    AASTORE
    DUP
    ICONST_1
    ICONST_2
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    AASTORE
    DUP
    ICONST_2
    ICONST_3
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    AASTORE
    INVOKESTATIC java/util/stream/Stream.of
([Ljava/lang/Object;)Ljava/util/stream/Stream;
    ALOAD 0
    INVOKEDYNAMIC apply(Ljava/lang/String;)Ljava/util/function/Function; [
      // handle kind 0x6 : INVOKESTATIC
     
java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)Ljava/lang/Object;, 
      // handle kind 0x6 : INVOKESTATIC
     
Test2.lambda$p$0(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String;, 
      (Ljava/lang/Integer;)Ljava/lang/String;
    ]
    INVOKEINTERFACE java/util/stream/Stream.map
(Ljava/util/function/Function;)Ljava/util/stream/Stream;
    POP
   L2
    LINENUMBER 13 L2
    RETURN
    MAXSTACK = 4
    MAXLOCALS = 1

  // access flags 0x100A
  private static synthetic
lambda$p$0(Ljava/lang/String;Ljava/lang/Integer;)Ljava/lang/String;
   L0
    LINENUMBER 12 L0
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 0
    INVOKEVIRTUAL java/lang/StringBuilder.append
(Ljava/lang/String;)Ljava/lang/StringBuilder;
    ALOAD 1
    INVOKEVIRTUAL java/lang/StringBuilder.append
(Ljava/lang/Object;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    ARETURN
    MAXSTACK = 2
    MAXLOCALS = 2
}

```

    Thanks in advance for your help :-)

Cheers,
Daniel.Sun

[1]
https://github.com/apache/groovy/blob/fb8e3d10b9bcce46ebb474657d67036b14c2bffc/src/test/groovy/transform/stc/LambdaTest.groovy#L218
[2]
https://github.com/apache/groovy/blob/fb8e3d10b9bcce46ebb474657d67036b14c2bffc/src/main/java/org/codehaus/groovy/classgen/asm/sc/StaticTypesLambdaWriter.java#L104-L109
[3]
https://github.com/apache/groovy/blob/fb8e3d10b9bcce46ebb474657d67036b14c2bffc/src/test/groovy/transform/stc/LambdaTest.groovy#L203
[4] 
```
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Test2 {
    public static void main(String[] args) {
        p();
    }

    public static void p() {
        String x = "#";
        
        Stream.of(1, 2, 3).map(e -> x + e);
    }
}
```



--
Sent from: http://groovy.329449.n5.nabble.com/Groovy-Dev-f372993.html

Mime
View raw message