jdk/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java
author henryjen
Wed, 09 Oct 2013 09:41:40 -0700
changeset 20748 fbf53402134d
parent 18716 9723e722b955
child 21300 9a71d04b2d02
permissions -rw-r--r--
8023524: Mechanism to dump generated lambda classes / log lambda code generation Reviewed-by: plevart, mchung, forax, jjb Contributed-by: brian.goetz@oracle.com, henry.jen@oracle.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     1
/*
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     2
 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     4
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    10
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    15
 * accompanied this code).
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    16
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    20
 *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    23
 * questions.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    24
 */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    25
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    26
package java.lang.invoke;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    27
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    28
import jdk.internal.org.objectweb.asm.*;
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    29
import sun.misc.Unsafe;
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    30
import sun.security.action.GetPropertyAction;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    31
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    32
import java.io.FilePermission;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    33
import java.lang.reflect.Constructor;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    34
import java.security.AccessController;
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    35
import java.security.PrivilegedAction;
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    36
import java.security.ProtectionDomain;
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    37
import java.util.concurrent.atomic.AtomicInteger;
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    38
import java.util.PropertyPermission;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    39
18284
e281a0a2583e 8017044: anti-delta fix for 8015402
chegar
parents: 18182
diff changeset
    40
import static jdk.internal.org.objectweb.asm.Opcodes.*;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    41
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    42
/**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    43
 * Lambda metafactory implementation which dynamically creates an
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    44
 * inner-class-like class per lambda callsite.
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    45
 *
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    46
 * @see LambdaMetafactory
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    47
 */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    48
/* package */ final class InnerClassLambdaMetafactory extends AbstractValidatingLambdaMetafactory {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    49
    private static final Unsafe UNSAFE = Unsafe.getUnsafe();
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    50
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    51
    private static final int CLASSFILE_VERSION = 51;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    52
    private static final String METHOD_DESCRIPTOR_VOID = Type.getMethodDescriptor(Type.VOID_TYPE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    53
    private static final String NAME_MAGIC_ACCESSOR_IMPL = "java/lang/invoke/MagicLambdaImpl";
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    54
    private static final String NAME_CTOR = "<init>";
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    55
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    56
    //Serialization support
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    57
    private static final String NAME_SERIALIZED_LAMBDA = "java/lang/invoke/SerializedLambda";
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    58
    private static final String DESCR_METHOD_WRITE_REPLACE = "()Ljava/lang/Object;";
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    59
    private static final String NAME_METHOD_WRITE_REPLACE = "writeReplace";
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    60
    private static final String NAME_OBJECT = "java/lang/Object";
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    61
    private static final String DESCR_CTOR_SERIALIZED_LAMBDA
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    62
            = MethodType.methodType(void.class,
16034
cb5fbea1ecec 8008770: SerializedLambda incorrect class loader for lambda deserializing class
rfield
parents: 16001
diff changeset
    63
                                    Class.class,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    64
                                    String.class, String.class, String.class,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    65
                                    int.class, String.class, String.class, String.class,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    66
                                    String.class,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
    67
                                    Object[].class).toMethodDescriptorString();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    68
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    69
    // Used to ensure that each spun class name is unique
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    70
    private static final AtomicInteger counter = new AtomicInteger(0);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    71
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    72
    // For dumping generated classes to disk, for debugging purposes
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    73
    private static final ProxyClassesDumper dumper;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    74
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    75
    static {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    76
        final String key = "jdk.internal.lambda.dumpProxyClasses";
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    77
        String path = AccessController.doPrivileged(
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    78
                new GetPropertyAction(key), null,
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    79
                new PropertyPermission(key , "read"));
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    80
        dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    81
    }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    82
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    83
    // See context values in AbstractValidatingLambdaMetafactory
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    84
    private final String implMethodClassName;        // Name of type containing implementation "CC"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    85
    private final String implMethodName;             // Name of implementation method "impl"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    86
    private final String implMethodDesc;             // Type descriptor for implementation methods "(I)Ljava/lang/String;"
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    87
    private final Type[] implMethodArgumentTypes;    // ASM types for implementation method parameters
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
    88
    private final Type implMethodReturnType;         // ASM type for implementation method return type "Ljava/lang/String;"
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    89
    private final MethodType constructorType;        // Generated class constructor type "(CC)void"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    90
    private final String constructorDesc;            // Type descriptor for constructor "(LCC;)V"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    91
    private final ClassWriter cw;                    // ASM class writer
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    92
    private final Type[] argTypes;                   // ASM types for the constructor arguments
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    93
    private final String[] argNames;                 // Generated names for the constructor arguments
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    94
    private final String lambdaClassName;            // Generated name for the generated class "X$$Lambda$1"
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    95
    private final Type[] instantiatedArgumentTypes;  // ASM types for the functional interface arguments
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    96
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
    97
    /**
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    98
     * General meta-factory constructor, supporting both standard cases and
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
    99
     * allowing for uncommon options such as serialization or bridging.
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   100
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   101
     * @param caller Stacked automatically by VM; represents a lookup context
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   102
     *               with the accessibility privileges of the caller.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   103
     * @param invokedType Stacked automatically by VM; the signature of the
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   104
     *                    invoked method, which includes the expected static
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   105
     *                    type of the returned lambda object, and the static
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   106
     *                    types of the captured arguments for the lambda.  In
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   107
     *                    the event that the implementation method is an
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   108
     *                    instance method, the first argument in the invocation
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   109
     *                    signature will correspond to the receiver.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   110
     * @param samMethodName Name of the method in the functional interface to
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   111
     *                      which the lambda or method reference is being
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   112
     *                      converted, represented as a String.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   113
     * @param samMethodType Type of the method in the functional interface to
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   114
     *                      which the lambda or method reference is being
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   115
     *                      converted, represented as a MethodType.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   116
     * @param implMethod The implementation method which should be called (with
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   117
     *                   suitable adaptation of argument types, return types,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   118
     *                   and adjustment for captured arguments) when methods of
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   119
     *                   the resulting functional interface instance are invoked.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   120
     * @param instantiatedMethodType The signature of the primary functional
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   121
     *                               interface method after type variables are
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   122
     *                               substituted with their instantiation from
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   123
     *                               the capture site
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   124
     * @param isSerializable Should the lambda be made serializable?  If set,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   125
     *                       either the target type or one of the additional SAM
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   126
     *                       types must extend {@code Serializable}.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   127
     * @param markerInterfaces Additional interfaces which the lambda object
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   128
     *                       should implement.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   129
     * @param additionalBridges Method types for additional signatures to be
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   130
     *                          bridged to the implementation method
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   131
     * @throws ReflectiveOperationException
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   132
     * @throws LambdaConversionException If any of the meta-factory protocol
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   133
     * invariants are violated
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   134
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   135
    public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   136
                                       MethodType invokedType,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   137
                                       String samMethodName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   138
                                       MethodType samMethodType,
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   139
                                       MethodHandle implMethod,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   140
                                       MethodType instantiatedMethodType,
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   141
                                       boolean isSerializable,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   142
                                       Class<?>[] markerInterfaces,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   143
                                       MethodType[] additionalBridges)
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   144
            throws ReflectiveOperationException, LambdaConversionException {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   145
        super(caller, invokedType, samMethodName, samMethodType,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   146
              implMethod, instantiatedMethodType,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   147
              isSerializable, markerInterfaces, additionalBridges);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   148
        implMethodClassName = implDefiningClass.getName().replace('.', '/');
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   149
        implMethodName = implInfo.getName();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   150
        implMethodDesc = implMethodType.toMethodDescriptorString();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   151
        Type implMethodAsmType = Type.getMethodType(implMethodDesc);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   152
        implMethodArgumentTypes = implMethodAsmType.getArgumentTypes();
18556
0fe397a41c18 8016761: Lambda metafactory - incorrect type conversion of constructor method handle
rfield
parents: 18284
diff changeset
   153
        implMethodReturnType = (implKind == MethodHandleInfo.REF_newInvokeSpecial)
0fe397a41c18 8016761: Lambda metafactory - incorrect type conversion of constructor method handle
rfield
parents: 18284
diff changeset
   154
                ? Type.getObjectType(implMethodClassName)
0fe397a41c18 8016761: Lambda metafactory - incorrect type conversion of constructor method handle
rfield
parents: 18284
diff changeset
   155
                : implMethodAsmType.getReturnType();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   156
        constructorType = invokedType.changeReturnType(Void.TYPE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   157
        constructorDesc = constructorType.toMethodDescriptorString();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   158
        lambdaClassName = targetClass.getName().replace('.', '/') + "$$Lambda$" + counter.incrementAndGet();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   159
        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   160
        argTypes = Type.getArgumentTypes(constructorDesc);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   161
        argNames = new String[argTypes.length];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   162
        for (int i = 0; i < argTypes.length; i++) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   163
            argNames[i] = "arg$" + (i + 1);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   164
        }
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   165
        instantiatedArgumentTypes = Type.getArgumentTypes(
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   166
                instantiatedMethodType.toMethodDescriptorString());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   167
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   168
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   169
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   170
     * Build the CallSite. Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   171
     * interface, define the class, if there are no parameters create an instance
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   172
     * of the class which the CallSite will return, otherwise, generate handles
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   173
     * which will call the class' constructor.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   174
     *
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   175
     * @return a CallSite, which, when invoked, will return an instance of the
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   176
     * functional interface
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   177
     * @throws ReflectiveOperationException
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   178
     * @throws LambdaConversionException If properly formed functional interface
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   179
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   180
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   181
    @Override
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   182
    CallSite buildCallSite() throws ReflectiveOperationException, LambdaConversionException {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   183
        final Class<?> innerClass = spinInnerClass();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   184
        if (invokedType.parameterCount() == 0) {
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   185
            final Constructor[] ctrs = AccessController.doPrivileged(
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   186
                    new PrivilegedAction<Constructor[]>() {
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   187
                @Override
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   188
                public Constructor[] run() {
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   189
                    return innerClass.getDeclaredConstructors();
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   190
                }
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   191
            });
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   192
            if (ctrs.length != 1) {
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   193
                throw new ReflectiveOperationException("Expected one lambda constructor for "
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   194
                        + innerClass.getCanonicalName() + ", got " + ctrs.length);
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   195
            }
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   196
            // The lambda implementing inner class constructor is private, set
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   197
            // it accessible (by us) before creating the constant sole instance
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   198
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   199
                @Override
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   200
                public Void run() {
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   201
                    ctrs[0].setAccessible(true);
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   202
                    return null;
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   203
                }
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   204
            });
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   205
            Object inst = ctrs[0].newInstance();
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   206
            return new ConstantCallSite(MethodHandles.constant(samBase, inst));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   207
        } else {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   208
            return new ConstantCallSite(
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   209
                    MethodHandles.Lookup.IMPL_LOOKUP
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   210
                         .findConstructor(innerClass, constructorType)
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   211
                         .asType(constructorType.changeReturnType(samBase)));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   212
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   213
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   214
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   215
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   216
     * Generate a class file which implements the functional
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   217
     * interface, define and return the class.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   218
     *
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   219
     * @implNote The class that is generated does not include signature
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   220
     * information for exceptions that may be present on the SAM method.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   221
     * This is to reduce classfile size, and is harmless as checked exceptions
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   222
     * are erased anyway, no one will ever compile against this classfile,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   223
     * and we make no guarantees about the reflective properties of lambda
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   224
     * objects.
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   225
     *
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   226
     * @return a Class which implements the functional interface
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   227
     * @throws LambdaConversionException If properly formed functional interface
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   228
     * is not found
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   229
     */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   230
    private Class<?> spinInnerClass() throws LambdaConversionException {
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   231
        String[] interfaces = new String[markerInterfaces.length + 1];
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   232
        interfaces[0] = samBase.getName().replace('.', '/');
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   233
        for (int i=0; i<markerInterfaces.length; i++) {
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   234
            interfaces[i+1] = markerInterfaces[i].getName().replace('.', '/');
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   235
        }
16859
45fbee947921 8012028: Metafactory-generated lambda classes should be final
rfield
parents: 16854
diff changeset
   236
        cw.visit(CLASSFILE_VERSION, ACC_SUPER + ACC_FINAL + ACC_SYNTHETIC,
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   237
                 lambdaClassName, null,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   238
                 NAME_MAGIC_ACCESSOR_IMPL, interfaces);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   239
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   240
        // Generate final fields to be filled in by constructor
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   241
        for (int i = 0; i < argTypes.length; i++) {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   242
            FieldVisitor fv = cw.visitField(ACC_PRIVATE + ACC_FINAL,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   243
                                            argNames[i],
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   244
                                            argTypes[i].getDescriptor(),
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   245
                                            null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   246
            fv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   247
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   248
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   249
        generateConstructor();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   250
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   251
        // Forward the SAM method
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   252
        String methodDescriptor = samMethodType.toMethodDescriptorString();
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   253
        MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, samMethodName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   254
                                          methodDescriptor, null, null);
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   255
        new ForwardingMethodGenerator(mv).generate(methodDescriptor);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   256
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   257
        // Forward the bridges
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   258
        if (additionalBridges != null) {
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   259
            for (MethodType mt : additionalBridges) {
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   260
                methodDescriptor = mt.toMethodDescriptorString();
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   261
                mv = cw.visitMethod(ACC_PUBLIC|ACC_BRIDGE, samMethodName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   262
                                    methodDescriptor, null, null);
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   263
                new ForwardingMethodGenerator(mv).generate(methodDescriptor);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   264
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   265
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   266
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   267
        if (isSerializable)
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   268
            generateWriteReplace();
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   269
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   270
        cw.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   271
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   272
        // Define the generated class in this VM.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   273
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   274
        final byte[] classBytes = cw.toByteArray();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   275
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   276
        // If requested, dump out to a file for debugging purposes
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   277
        if (dumper != null) {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   278
            AccessController.doPrivileged(new PrivilegedAction<Void>() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   279
                @Override
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   280
                public Void run() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   281
                    dumper.dumpClass(lambdaClassName, classBytes);
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   282
                    return null;
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   283
                }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   284
            }, null,
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   285
            new FilePermission("<<ALL FILES>>", "read, write"),
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   286
            // createDirectories may need it
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   287
            new PropertyPermission("user.dir", "read"));
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   288
        }
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   289
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   290
        ClassLoader loader = targetClass.getClassLoader();
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   291
        ProtectionDomain pd = (loader == null)
20748
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   292
                              ? null
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   293
                              : AccessController.doPrivileged(
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   294
                                      new PrivilegedAction<ProtectionDomain>() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   295
                                          @Override
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   296
                                          public ProtectionDomain run() {
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   297
                                              return targetClass.getProtectionDomain();
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   298
                                          }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   299
                                      }
fbf53402134d 8023524: Mechanism to dump generated lambda classes / log lambda code generation
henryjen
parents: 18716
diff changeset
   300
                              );
14762
34956da26ceb 8003881: Prevent lambda implementing inner classes from allowing the creation of new instances
rfield
parents: 14680
diff changeset
   301
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   302
        return UNSAFE.defineClass(lambdaClassName,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   303
                                  classBytes, 0, classBytes.length,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   304
                                  loader, pd);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   305
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   306
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   307
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   308
     * Generate the constructor for the class
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   309
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   310
    private void generateConstructor() {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   311
        // Generate constructor
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   312
        MethodVisitor ctor = cw.visitMethod(ACC_PRIVATE, NAME_CTOR,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   313
                                            constructorDesc, null, null);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   314
        ctor.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   315
        ctor.visitVarInsn(ALOAD, 0);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   316
        ctor.visitMethodInsn(INVOKESPECIAL, NAME_MAGIC_ACCESSOR_IMPL, NAME_CTOR,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   317
                             METHOD_DESCRIPTOR_VOID);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   318
        int lvIndex = 0;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   319
        for (int i = 0; i < argTypes.length; i++) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   320
            ctor.visitVarInsn(ALOAD, 0);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   321
            ctor.visitVarInsn(argTypes[i].getOpcode(ILOAD), lvIndex + 1);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   322
            lvIndex += argTypes[i].getSize();
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   323
            ctor.visitFieldInsn(PUTFIELD, lambdaClassName, argNames[i],
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   324
                                argTypes[i].getDescriptor());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   325
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   326
        ctor.visitInsn(RETURN);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   327
        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   328
        ctor.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   329
        ctor.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   330
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   331
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   332
    /**
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   333
     * Generate the writeReplace method (if needed for serialization)
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   334
     */
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   335
    private void generateWriteReplace() {
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   336
        TypeConvertingMethodAdapter mv
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   337
                = new TypeConvertingMethodAdapter(
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   338
                    cw.visitMethod(ACC_PRIVATE + ACC_FINAL,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   339
                    NAME_METHOD_WRITE_REPLACE, DESCR_METHOD_WRITE_REPLACE,
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   340
                    null, null));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   341
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   342
        mv.visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   343
        mv.visitTypeInsn(NEW, NAME_SERIALIZED_LAMBDA);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   344
        mv.visitInsn(DUP);
16034
cb5fbea1ecec 8008770: SerializedLambda incorrect class loader for lambda deserializing class
rfield
parents: 16001
diff changeset
   345
        mv.visitLdcInsn(Type.getType(targetClass));
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   346
        mv.visitLdcInsn(invokedType.returnType().getName().replace('.', '/'));
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   347
        mv.visitLdcInsn(samMethodName);
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   348
        mv.visitLdcInsn(samMethodType.toMethodDescriptorString());
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   349
        mv.visitLdcInsn(implInfo.getReferenceKind());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   350
        mv.visitLdcInsn(implInfo.getDeclaringClass().getName().replace('.', '/'));
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   351
        mv.visitLdcInsn(implInfo.getName());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   352
        mv.visitLdcInsn(implInfo.getMethodType().toMethodDescriptorString());
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   353
        mv.visitLdcInsn(instantiatedMethodType.toMethodDescriptorString());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   354
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   355
        mv.iconst(argTypes.length);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   356
        mv.visitTypeInsn(ANEWARRAY, NAME_OBJECT);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   357
        for (int i = 0; i < argTypes.length; i++) {
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   358
            mv.visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   359
            mv.iconst(i);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   360
            mv.visitVarInsn(ALOAD, 0);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   361
            mv.visitFieldInsn(GETFIELD, lambdaClassName, argNames[i],
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   362
                              argTypes[i].getDescriptor());
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   363
            mv.boxIfTypePrimitive(argTypes[i]);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   364
            mv.visitInsn(AASTORE);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   365
        }
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   366
        mv.visitMethodInsn(INVOKESPECIAL, NAME_SERIALIZED_LAMBDA, NAME_CTOR,
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   367
                DESCR_CTOR_SERIALIZED_LAMBDA);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   368
        mv.visitInsn(ARETURN);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   369
        // Maxs computed by ClassWriter.COMPUTE_MAXS, these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   370
        mv.visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   371
        mv.visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   372
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   373
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   374
    /**
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   375
     * This class generates a method body which calls the lambda implementation
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   376
     * method, converting arguments, as needed.
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   377
     */
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   378
    private class ForwardingMethodGenerator extends TypeConvertingMethodAdapter {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   379
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   380
        ForwardingMethodGenerator(MethodVisitor mv) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   381
            super(mv);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   382
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   383
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   384
        void generate(String methodDescriptor) {
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   385
            visitCode();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   386
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   387
            if (implKind == MethodHandleInfo.REF_newInvokeSpecial) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   388
                visitTypeInsn(NEW, implMethodClassName);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   389
                visitInsn(DUP);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   390
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   391
            for (int i = 0; i < argTypes.length; i++) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   392
                visitVarInsn(ALOAD, 0);
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   393
                visitFieldInsn(GETFIELD, lambdaClassName, argNames[i],
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   394
                               argTypes[i].getDescriptor());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   395
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   396
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   397
            convertArgumentTypes(Type.getArgumentTypes(methodDescriptor));
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   398
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   399
            // Invoke the method we want to forward to
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   400
            visitMethodInsn(invocationOpcode(), implMethodClassName, implMethodName, implMethodDesc);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   401
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   402
            // Convert the return value (if any) and return it
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   403
            // Note: if adapting from non-void to void, the 'return'
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   404
            // instruction will pop the unneeded result
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   405
            Type samReturnType = Type.getReturnType(methodDescriptor);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   406
            convertType(implMethodReturnType, samReturnType, samReturnType);
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   407
            visitInsn(samReturnType.getOpcode(Opcodes.IRETURN));
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   408
            // Maxs computed by ClassWriter.COMPUTE_MAXS,these arguments ignored
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   409
            visitMaxs(-1, -1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   410
            visitEnd();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   411
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   412
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   413
        private void convertArgumentTypes(Type[] samArgumentTypes) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   414
            int lvIndex = 0;
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   415
            boolean samIncludesReceiver = implIsInstanceMethod &&
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   416
                                                   argTypes.length == 0;
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   417
            int samReceiverLength = samIncludesReceiver ? 1 : 0;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   418
            if (samIncludesReceiver) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   419
                // push receiver
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   420
                Type rcvrType = samArgumentTypes[0];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   421
                Type instantiatedRcvrType = instantiatedArgumentTypes[0];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   422
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   423
                visitVarInsn(rcvrType.getOpcode(ILOAD), lvIndex + 1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   424
                lvIndex += rcvrType.getSize();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   425
                convertType(rcvrType, Type.getType(implDefiningClass), instantiatedRcvrType);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   426
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   427
            int argOffset = implMethodArgumentTypes.length - samArgumentTypes.length;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   428
            for (int i = samReceiverLength; i < samArgumentTypes.length; i++) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   429
                Type argType = samArgumentTypes[i];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   430
                Type targetType = implMethodArgumentTypes[argOffset + i];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   431
                Type instantiatedArgType = instantiatedArgumentTypes[i];
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   432
16001
fd4c8d3becf8 8004970: Implement serialization in the lambda metafactory
rfield
parents: 14762
diff changeset
   433
                visitVarInsn(argType.getOpcode(ILOAD), lvIndex + 1);
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   434
                lvIndex += argType.getSize();
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   435
                convertType(argType, targetType, instantiatedArgType);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   436
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   437
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   438
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   439
        private void convertType(Type argType, Type targetType, Type functionalType) {
18716
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   440
            convertType(argType.getDescriptor(),
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   441
                        targetType.getDescriptor(),
9723e722b955 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle
mcimadamore
parents: 18556
diff changeset
   442
                        functionalType.getDescriptor());
14323
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   443
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   444
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   445
        private int invocationOpcode() throws InternalError {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   446
            switch (implKind) {
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   447
                case MethodHandleInfo.REF_invokeStatic:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   448
                    return INVOKESTATIC;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   449
                case MethodHandleInfo.REF_newInvokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   450
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   451
                 case MethodHandleInfo.REF_invokeVirtual:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   452
                    return INVOKEVIRTUAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   453
                case MethodHandleInfo.REF_invokeInterface:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   454
                    return INVOKEINTERFACE;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   455
                case MethodHandleInfo.REF_invokeSpecial:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   456
                    return INVOKESPECIAL;
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   457
                default:
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   458
                    throw new InternalError("Unexpected invocation kind: " + implKind);
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   459
            }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   460
        }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   461
    }
5acca3d1f124 8000806: Implement runtime lambda metafactory
rfield
parents:
diff changeset
   462
}