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