jdk/test/java/lang/invoke/indify/Indify.java
author ohair
Wed, 06 Apr 2011 22:06:11 -0700
changeset 9035 1255eb81cc2f
parent 8822 8145ab9f5f86
child 9050 26c2c1de1631
permissions -rw-r--r--
7033660: Update copyright year to 2011 on any files changed in 2011 Reviewed-by: dholmes
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     1
/*
9035
1255eb81cc2f 7033660: Update copyright year to 2011 on any files changed in 2011
ohair
parents: 8822
diff changeset
     2
 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     4
 *
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    10
 *
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    15
 * accompanied this code).
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    16
 *
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    20
 *
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    23
 * questions.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    24
 */
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    25
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    26
package indify;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    27
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    28
import java.util.*;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    29
import java.io.*;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    30
import java.lang.reflect.Modifier;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    31
import java.util.regex.*;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    32
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    33
/**
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    34
 * Transform one or more class files to incorporate JSR 292 features,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    35
 * such as {@code invokedynamic}.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    36
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    37
 * This is a standalone program in a single source file.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    38
 * In this form, it may be useful for test harnesses, small experiments, and javadoc examples.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    39
 * Copies of this file may show up in multiple locations for standalone usage.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    40
 * The primary maintained location of this file is as follows:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    41
 * <a href="http://kenai.com/projects/ninja/sources/indify-repo/content/src/indify/Indify.java">
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    42
 * http://kenai.com/projects/ninja/sources/indify-repo/content/src/indify/Indify.java</a>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    43
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    44
 * Static private methods named MH_x and MT_x (where x is arbitrary)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    45
 * must be stereotyped generators of MethodHandle and MethodType
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    46
 * constants.  All calls to them are transformed to {@code CONSTANT_MethodHandle}
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    47
 * and {@code CONSTANT_MethodType} "ldc" instructions.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    48
 * The stereotyped code must create method types by calls to {@code methodType} or
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    49
 * {@code fromMethodDescriptorString}.  The "lookup" argument must be created
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
    50
 * by calls to {@code java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    51
 * The class and string arguments must be constant.
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
    52
 * The following methods of {@code java.lang.invoke.MethodHandle.Lookup Lookup} are
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    53
 * allowed for method handle creation: {@code findStatic}, {@code findVirtual},
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    54
 * {@code findConstructor}, {@code findSpecial},
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    55
 * {@code findGetter}, {@code findSetter},
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    56
 * {@code findStaticGetter}, or {@code findStaticSetter}.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    57
 * The call to one of these methods must be followed immediately
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    58
 * by an {@code areturn} instruction.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    59
 * The net result of the call to the MH_x or MT_x method must be
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    60
 * the creation of a constant method handle.  Thus, replacing calls
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    61
 * to MH_x or MT_x methods by {@code ldc} instructions should leave
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    62
 * the meaning of the program unchanged.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    63
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    64
 * Static private methods named INDY_x must be stereotyped generators
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    65
 * of {@code invokedynamic} call sites.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    66
 * All calls to them must be immediately followed by
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    67
 * {@code invokeExact} calls.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    68
 * All such pairs of calls are transformed to {@code invokedynamic}
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    69
 * instructions.  Each INDY_x method must begin with a call to a
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    70
 * MH_x method, which is taken to be its bootstrap method.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    71
 * The method must be immediately invoked (via {@code invokeGeneric}
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    72
 * on constant lookup, name, and type arguments.  An object array of
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    73
 * constants may also be appended to the {@code invokeGeneric call}.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    74
 * This call must be cast to {@code CallSite}, and the result must be
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    75
 * immediately followed by a call to {@code dynamicInvoker}, with the
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    76
 * resulting method handle returned.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    77
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    78
 * The net result of all of these actions is equivalent to the JVM's
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    79
 * execution of an {@code invokedynamic} instruction in the unlinked state.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    80
 * Running this code once should produce the same results as running
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    81
 * the corresponding {@code invokedynamic} instruction.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    82
 * In order to model the caching behavior, the code of an INDY_x
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    83
 * method is allowed to begin with getstatic, aaload, and if_acmpne
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    84
 * instructions which load a static method handle value and return it
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    85
 * if the value is non-null.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    86
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    87
 * Example usage:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    88
 * <blockquote><pre>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    89
$ JAVA_HOME=(some recent OpenJDK 7 build)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    90
$ ant
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    91
$ $JAVA_HOME/bin/java -cp build/classes indify.Indify --overwrite --dest build/testout build/classes/indify/Example.class
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    92
$ $JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic -cp build/classes indify.Example
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    93
MT = (java.lang.Object)java.lang.Object
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    94
MH = adder(int,int)java.lang.Integer
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    95
adder(1,2) = 3
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    96
calling indy:  42
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    97
$ $JAVA_HOME/bin/java -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic -cp build/testout indify.Example
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    98
(same output as above)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
    99
 * </pre></blockquote>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   100
 * <p>
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   101
 * Before OpenJDK build b123, the format of {@code CONSTANT_InvokeDynamic} is in transition,
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   102
 * and the switch {@code --transitionalJSR292=yes} is recommended.
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   103
 * It is turned <em>off</em> by default, but users of earlier builds may need to turn it on.
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   104
 * <p>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   105
 * A version of this transformation built on top of <a href="http://asm.ow2.org/">http://asm.ow2.org/</a> would be welcome.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   106
 * @author John Rose
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   107
 */
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   108
public class Indify {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   109
    public static void main(String... av) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   110
        new Indify().run(av);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   111
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   112
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   113
    public File dest;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   114
    public String[] classpath = {"."};
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   115
    public boolean keepgoing = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   116
    public boolean expandProperties = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   117
    public boolean overwrite = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   118
    public boolean quiet = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   119
    public boolean verbose = false;
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   120
    public boolean transitionalJSR292 = false;  // final version is distributed
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   121
    public boolean all = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   122
    public int verifySpecifierCount = -1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   123
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   124
    public void run(String... av) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   125
        List<String> avl = new ArrayList<>(Arrays.asList(av));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   126
        parseOptions(avl);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   127
        if (avl.isEmpty())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   128
            throw new IllegalArgumentException("Usage: indify [--dest dir] [option...] file...");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   129
        if ("--java".equals(avl.get(0))) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   130
            avl.remove(0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   131
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   132
                runApplication(avl.toArray(new String[0]));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   133
            } catch (Exception ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   134
                if (ex instanceof RuntimeException)  throw (RuntimeException) ex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   135
                throw new RuntimeException(ex);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   136
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   137
            return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   138
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   139
        Exception err = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   140
        for (String a : avl) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   141
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   142
                indify(a);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   143
            } catch (Exception ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   144
                if (err == null)  err = ex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   145
                System.err.println("failure on "+a);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   146
                if (!keepgoing)  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   147
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   148
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   149
        if (err != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   150
            if (err instanceof IOException)  throw (IOException) err;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   151
            throw (RuntimeException) err;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   152
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   153
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   154
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   155
    /** Execute the given application under a class loader which indifies all application classes. */
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   156
    public void runApplication(String... av) throws Exception {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   157
        List<String> avl = new ArrayList<>(Arrays.asList(av));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   158
        String mainClassName = avl.remove(0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   159
        av = avl.toArray(new String[0]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   160
        Class<?> mainClass = Class.forName(mainClassName, true, makeClassLoader());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   161
        java.lang.reflect.Method main = mainClass.getMethod("main", String[].class);
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   162
        try { main.setAccessible(true); } catch (SecurityException ex) { }
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   163
        main.invoke(null, (Object) av);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   164
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   165
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   166
    public void parseOptions(List<String> av) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   167
        for (; !av.isEmpty(); av.remove(0)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   168
            String a = av.get(0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   169
            if (a.startsWith("-")) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   170
                String a2 = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   171
                int eq = a.indexOf('=');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   172
                if (eq > 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   173
                    a2 = maybeExpandProperties(a.substring(eq+1));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   174
                    a = a.substring(0, eq+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   175
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   176
                switch (a) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   177
                case "--java":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   178
                    return;  // keep this argument
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   179
                case "-d": case "--dest": case "-d=": case "--dest=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   180
                    dest = new File(a2 != null ? a2 : maybeExpandProperties(av.remove(1)));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   181
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   182
                case "-cp": case "--classpath":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   183
                    classpath = maybeExpandProperties(av.remove(1)).split("["+File.pathSeparatorChar+"]");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   184
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   185
                case "-k": case "--keepgoing": case "--keepgoing=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   186
                    keepgoing = booleanOption(a2);  // print errors but keep going
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   187
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   188
                case "--expand-properties": case "--expand-properties=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   189
                    expandProperties = booleanOption(a2);  // expand property references in subsequent arguments
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   190
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   191
                case "--verify-specifier-count": case "--verify-specifier-count=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   192
                    verifySpecifierCount = Integer.valueOf(a2);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   193
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   194
                case "--overwrite": case "--overwrite=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   195
                    overwrite = booleanOption(a2);  // overwrite output files
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   196
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   197
                case "--all": case "--all=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   198
                    all = booleanOption(a2);  // copy all classes, even if no patterns
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   199
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   200
                case "-q": case "--quiet": case "--quiet=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   201
                    quiet = booleanOption(a2);  // less output
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   202
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   203
                case "-v": case "--verbose": case "--verbose=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   204
                    verbose = booleanOption(a2);  // more output
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   205
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   206
                case "--transitionalJSR292": case "--transitionalJSR292=":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   207
                    transitionalJSR292 = booleanOption(a2);  // use older invokedynamic format
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   208
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   209
                default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   210
                    throw new IllegalArgumentException("unrecognized flag: "+a);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   211
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   212
                continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   213
            } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   214
                break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   215
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   216
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   217
        if (dest == null && !overwrite)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   218
            throw new RuntimeException("no output specified; need --dest d or --overwrite");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   219
        if (expandProperties) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   220
            for (int i = 0; i < av.size(); i++)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   221
                av.set(i, maybeExpandProperties(av.get(i)));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   222
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   223
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   224
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   225
    private boolean booleanOption(String s) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   226
        if (s == null)  return true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   227
        switch (s) {
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   228
        case "true":  case "yes": case "on":  case "1": return true;
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   229
        case "false": case "no":  case "off": case "0": return false;
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   230
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   231
        throw new IllegalArgumentException("unrecognized boolean flag="+s);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   232
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   233
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   234
    private String maybeExpandProperties(String s) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   235
        if (!expandProperties)  return s;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   236
        Set<String> propsDone = new HashSet<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   237
        while (s.contains("${")) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   238
            int lbrk = s.indexOf("${");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   239
            int rbrk = s.indexOf('}', lbrk);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   240
            if (rbrk < 0)  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   241
            String prop = s.substring(lbrk+2, rbrk);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   242
            if (!propsDone.add(prop))  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   243
            String value = System.getProperty(prop);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   244
            if (verbose)  System.err.println("expanding ${"+prop+"} => "+value);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   245
            if (value == null)  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   246
            s = s.substring(0, lbrk) + value + s.substring(rbrk+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   247
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   248
        return s;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   249
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   250
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   251
    public void indify(String a) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   252
        File f = new File(a);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   253
        String fn = f.getName();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   254
        if (fn.endsWith(".class") && f.isFile())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   255
            indifyFile(f, dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   256
        else if (fn.endsWith(".jar") && f.isFile())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   257
            indifyJar(f, dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   258
        else if (f.isDirectory())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   259
            indifyTree(f, dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   260
        else if (!keepgoing)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   261
            throw new RuntimeException("unrecognized file: "+a);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   262
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   263
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   264
    private void ensureDirectory(File dir) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   265
        if (dir.mkdirs() && !quiet)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   266
            System.err.println("created "+dir);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   267
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   268
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   269
    public void indifyFile(File f, File dest) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   270
        if (verbose)  System.err.println("reading "+f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   271
        ClassFile cf = new ClassFile(f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   272
        Logic logic = new Logic(cf);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   273
        boolean changed = logic.transform();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   274
        logic.reportPatternMethods(quiet, keepgoing);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   275
        if (changed || all) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   276
            File outfile;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   277
            if (dest != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   278
                ensureDirectory(dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   279
                outfile = classPathFile(dest, cf.nameString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   280
            } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   281
                outfile = f;  // overwrite input file, no matter where it is
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   282
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   283
            cf.writeTo(outfile);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   284
            if (!quiet)  System.err.println("wrote "+outfile);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   285
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   286
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   287
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   288
    File classPathFile(File pathDir, String className) {
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   289
        String qualname = className.replace('.','/')+".class";
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   290
        qualname = qualname.replace('/', File.separatorChar);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   291
        return new File(pathDir, qualname);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   292
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   293
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   294
    public void indifyJar(File f, Object dest) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   295
        throw new UnsupportedOperationException("Not yet implemented");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   296
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   297
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   298
    public void indifyTree(File f, File dest) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   299
        if (verbose)  System.err.println("reading directory: "+f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   300
        for (File f2 : f.listFiles(new FilenameFilter() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   301
                public boolean accept(File dir, String name) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   302
                    if (name.endsWith(".class"))  return true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   303
                    if (name.contains("."))  return false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   304
                    // return true if it might be a package name:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   305
                    return Character.isJavaIdentifierStart(name.charAt(0));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   306
                }})) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   307
            if (f2.getName().endsWith(".class"))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   308
                indifyFile(f2, dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   309
            else if (f2.isDirectory())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   310
                indifyTree(f2, dest);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   311
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   312
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   313
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   314
    public ClassLoader makeClassLoader() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   315
        return new Loader();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   316
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   317
    private class Loader extends ClassLoader {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   318
        Loader() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   319
            this(Indify.class.getClassLoader());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   320
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   321
        Loader(ClassLoader parent) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   322
            super(parent);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   323
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   324
        public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   325
            File f = findClassInPath(name);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   326
            if (f != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   327
                try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   328
                    Class<?> c = transformAndLoadClass(f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   329
                    if (c != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   330
                        if (resolve)  resolveClass(c);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   331
                        return c;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   332
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   333
                } catch (Exception ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   334
                    if (ex instanceof IllegalArgumentException)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   335
                        // pass error from reportPatternMethods
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   336
                        throw (IllegalArgumentException) ex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   337
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   338
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   339
            return super.loadClass(name, resolve);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   340
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   341
        private File findClassInPath(String name) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   342
            for (String s : classpath) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   343
                File f = classPathFile(new File(s), name);
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   344
                //System.out.println("Checking for "+f);
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   345
                if (f.exists() && f.canRead()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   346
                    return f;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   347
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   348
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   349
            return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   350
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   351
        protected Class<?> findClass(String name) throws ClassNotFoundException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   352
            try {
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   353
                File f = findClassInPath(name);
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   354
                if (f != null) {
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   355
                    Class<?> c = transformAndLoadClass(f);
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   356
                    if (c != null)  return c;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   357
                }
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   358
            } catch (IOException ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   359
                throw new ClassNotFoundException("IO error", ex);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   360
            }
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   361
            throw new ClassNotFoundException();
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   362
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   363
        private Class<?> transformAndLoadClass(File f) throws ClassNotFoundException, IOException {
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   364
            if (verbose)  System.err.println("Loading class from "+f);
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   365
            ClassFile cf = new ClassFile(f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   366
            Logic logic = new Logic(cf);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   367
            boolean changed = logic.transform();
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   368
            if (verbose && !changed)  System.err.println("(no change)");
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   369
            logic.reportPatternMethods(!verbose, keepgoing);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   370
            byte[] bytes = cf.toByteArray();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   371
            return defineClass(null, bytes, 0, bytes.length);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   372
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   373
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   374
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   375
    private class Logic {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   376
        // Indify logic, per se.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   377
        ClassFile cf;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   378
        final char[] poolMarks;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   379
        final Map<Method,Constant> constants = new HashMap<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   380
        final Map<Method,String> indySignatures = new HashMap<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   381
        Logic(ClassFile cf) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   382
            this.cf = cf;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   383
            poolMarks = new char[cf.pool.size()];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   384
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   385
        boolean transform() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   386
            if (!initializeMarks())  return false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   387
            if (!findPatternMethods())  return false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   388
            Pool pool = cf.pool;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   389
            //for (Constant c : cp)  System.out.println("  # "+c);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   390
            for (Method m : cf.methods) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   391
                if (constants.containsKey(m))  continue;  // don't bother
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   392
                // Transform references.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   393
                int blab = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   394
                for (Instruction i = m.instructions(); i != null; i = i.next()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   395
                    if (i.bc != opc_invokestatic)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   396
                    int methi = i.u2At(1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   397
                    if (poolMarks[methi] == 0)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   398
                    Short[] ref = pool.getMemberRef((short)methi);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   399
                    Method conm = findMember(cf.methods, ref[1], ref[2]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   400
                    if (conm == null)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   401
                    Constant con = constants.get(conm);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   402
                    if (con == null)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   403
                    if (blab++ == 0 && !quiet)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   404
                        System.err.println("patching "+cf.nameString()+"."+m);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   405
                    //if (blab == 1) { for (Instruction j = m.instructions(); j != null; j = j.next()) System.out.println("  |"+j); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   406
                    if (con.tag == CONSTANT_InvokeDynamic ||
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   407
                        con.tag == CONSTANT_InvokeDynamic_17) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   408
                        // need to patch the following instruction too,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   409
                        // but there are usually intervening argument pushes too
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   410
                        Instruction i2 = findPop(i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   411
                        Short[] ref2 = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   412
                        short ref2i = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   413
                        if (i2 != null && i2.bc == opc_invokevirtual &&
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   414
                                poolMarks[(char)(ref2i = (short) i2.u2At(1))] == 'D')
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   415
                            ref2 = pool.getMemberRef(ref2i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   416
                        if (ref2 == null || !"invokeExact".equals(pool.getString(ref2[1]))) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   417
                            System.err.println(m+": failed to create invokedynamic at "+i.pc);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   418
                            continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   419
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   420
                        String invType = pool.getString(ref2[2]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   421
                        String bsmType = indySignatures.get(conm);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   422
                        if (!invType.equals(bsmType)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   423
                            System.err.println(m+": warning: "+conm+" call type and local invoke type differ: "
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   424
                                    +bsmType+", "+invType);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   425
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   426
                        assert(i.len == 3 || i2.len == 3);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   427
                        if (!quiet)  System.err.println(i+" "+conm+";...; "+i2+" => invokedynamic "+con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   428
                        int start = i.pc + 3, end = i2.pc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   429
                        System.arraycopy(i.codeBase, start, i.codeBase, i.pc, end-start);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   430
                        i.forceNext(0);  // force revisit of new instruction
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   431
                        i2.u1AtPut(-3, opc_invokedynamic);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   432
                        i2.u2AtPut(-2, con.index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   433
                        i2.u2AtPut(0, (short)0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   434
                        i2.u1AtPut(2, opc_nop);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   435
                        //System.out.println(new Instruction(i.codeBase, i2.pc-3));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   436
                    } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   437
                        if (!quiet)  System.err.println(i+" "+conm+" => ldc "+con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   438
                        assert(i.len == 3);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   439
                        i.u1AtPut(0, opc_ldc_w);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   440
                        i.u2AtPut(1, con.index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   441
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   442
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   443
                //if (blab >= 1) { for (Instruction j = m.instructions(); j != null; j = j.next()) System.out.println("    |"+j); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   444
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   445
            cf.methods.removeAll(constants.keySet());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   446
            return true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   447
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   448
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   449
        // Scan forward from the instruction to find where the stack p
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   450
        // below the current sp at the instruction.
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   451
        Instruction findPop(Instruction i) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   452
            //System.out.println("findPop from "+i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   453
            Pool pool = cf.pool;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   454
            JVMState jvm = new JVMState();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   455
        decode:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   456
            for (i = i.clone().next(); i != null; i = i.next()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   457
                String pops = INSTRUCTION_POPS[i.bc];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   458
                //System.out.println("  "+i+" "+jvm.stack+" : "+pops.replace("$", " => "));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   459
                if (pops == null)  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   460
                if (jvm.stackMotion(i.bc))  continue decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   461
                if (pops.indexOf('Q') >= 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   462
                    Short[] ref = pool.getMemberRef((short) i.u2At(1));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   463
                    String type = simplifyType(pool.getString(CONSTANT_Utf8, ref[2]));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   464
                    switch (i.bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   465
                    case opc_getstatic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   466
                    case opc_getfield:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   467
                    case opc_putstatic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   468
                    case opc_putfield:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   469
                        pops = pops.replace("Q", type);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   470
                        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   471
                    default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   472
                        if (!type.startsWith("("))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   473
                            throw new InternalError(i.toString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   474
                        pops = pops.replace("Q$Q", type.substring(1).replace(")","$"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   475
                        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   476
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   477
                    //System.out.println("special type: "+type+" => "+pops);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   478
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   479
                int npops = pops.indexOf('$');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   480
                if (npops < 0)  throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   481
                if (npops > jvm.sp())  return i;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   482
                List<Object> args = jvm.args(npops);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   483
                int k = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   484
                for (Object x : args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   485
                    char have = (Character) x;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   486
                    char want = pops.charAt(k++);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   487
                    if (have == 'X' || want == 'X')  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   488
                    if (have != want)  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   489
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   490
                if (pops.charAt(k++) != '$')  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   491
                args.clear();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   492
                while (k < pops.length())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   493
                    args.add(pops.charAt(k++));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   494
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   495
            System.err.println("*** bailout on jvm: "+jvm.stack+" "+i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   496
            return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   497
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   498
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   499
        boolean findPatternMethods() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   500
            boolean found = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   501
            for (char mark : "THI".toCharArray()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   502
                for (Method m : cf.methods) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   503
                    if (!Modifier.isPrivate(m.access))  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   504
                    if (!Modifier.isStatic(m.access))  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   505
                    if (nameAndTypeMark(m.name, m.type) == mark) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   506
                        Constant con = scanPattern(m, mark);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   507
                        if (con == null)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   508
                        constants.put(m, con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   509
                        found = true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   510
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   511
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   512
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   513
            return found;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   514
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   515
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   516
        void reportPatternMethods(boolean quietly, boolean allowMatchFailure) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   517
            if (!quietly && !constants.keySet().isEmpty())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   518
                System.err.println("pattern methods removed: "+constants.keySet());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   519
            for (Method m : cf.methods) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   520
                if (nameMark(cf.pool.getString(m.name)) != 0 &&
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   521
                    constants.get(m) == null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   522
                    String failure = "method has special name but fails to match pattern: "+m;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   523
                    if (!allowMatchFailure)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   524
                        throw new IllegalArgumentException(failure);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   525
                    else if (!quietly)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   526
                        System.err.println("warning: "+failure);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   527
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   528
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   529
            if (verifySpecifierCount >= 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   530
                List<Object[]> specs = bootstrapMethodSpecifiers(false);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   531
                int specsLen = (specs == null ? 0 : specs.size());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   532
                if (specsLen != verifySpecifierCount) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   533
                    throw new IllegalArgumentException("BootstrapMethods length is "+specsLen+" but should be "+verifySpecifierCount);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   534
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   535
            }
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   536
            if (!quiet)  System.err.flush();
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   537
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   538
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   539
        // mark constant pool entries according to participation in patterns
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   540
        boolean initializeMarks() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   541
            boolean changed = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   542
            for (;;) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   543
                boolean changed1 = false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   544
                int cpindex = -1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   545
                for (Constant e : cf.pool) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   546
                    ++cpindex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   547
                    if (e == null)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   548
                    char mark = poolMarks[cpindex];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   549
                    if (mark != 0)  continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   550
                    switch (e.tag) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   551
                    case CONSTANT_Utf8:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   552
                        mark = nameMark(e.itemString()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   553
                    case CONSTANT_NameAndType:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   554
                        mark = nameAndTypeMark(e.itemIndexes()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   555
                    case CONSTANT_Class: {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   556
                        int n1 = e.itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   557
                        char nmark = poolMarks[(char)n1];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   558
                        if ("DJ".indexOf(nmark) >= 0)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   559
                            mark = nmark;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   560
                        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   561
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   562
                    case CONSTANT_Field:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   563
                    case CONSTANT_Method: {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   564
                        Short[] n12 = e.itemIndexes();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   565
                        short cl = n12[0];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   566
                        short nt = n12[1];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   567
                        char cmark = poolMarks[(char)cl];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   568
                        if (cmark != 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   569
                            mark = cmark;  // it is a java.dyn.* or java.lang.* method
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   570
                            break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   571
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   572
                        String cls = cf.pool.getString(CONSTANT_Class, cl);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   573
                        if (cls.equals(cf.nameString())) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   574
                            switch (poolMarks[(char)nt]) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   575
                            // it is a private MH/MT/INDY method
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   576
                            case 'T': case 'H': case 'I':
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   577
                                mark = poolMarks[(char)nt];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   578
                                break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   579
                            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   580
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   581
                        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   582
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   583
                    default:  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   584
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   585
                    if (mark != 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   586
                        poolMarks[cpindex] = mark;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   587
                        changed1 = true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   588
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   589
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   590
                if (!changed1)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   591
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   592
                changed = true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   593
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   594
            return changed;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   595
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   596
        char nameMark(String s) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   597
            if (s.startsWith("MT_"))                return 'T';
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   598
            else if (s.startsWith("MH_"))           return 'H';
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   599
            else if (s.startsWith("INDY_"))         return 'I';
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   600
            else if (transitionalJSR292 &&
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   601
                     s.startsWith("java/dyn/"))     return 'D';
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   602
            else if (s.startsWith("java/lang/invoke/"))  return 'D';
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   603
            else if (s.startsWith("java/lang/"))    return 'J';
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   604
            return 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   605
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   606
        char nameAndTypeMark(Short[] n12) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   607
            return nameAndTypeMark(n12[0], n12[1]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   608
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   609
        char nameAndTypeMark(short n1, short n2) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   610
            char mark = poolMarks[(char)n1];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   611
            if (mark == 0)  return 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   612
            String descr = cf.pool.getString(CONSTANT_Utf8, n2);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   613
            String requiredType;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   614
            switch (poolMarks[(char)n1]) {
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   615
            case 'H': requiredType = "()Ljava/lang/invoke/MethodHandle;";  break;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   616
            case 'T': requiredType = "()Ljava/lang/invoke/MethodType;";    break;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   617
            case 'I': requiredType = "()Ljava/lang/invoke/MethodHandle;";  break;
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   618
            default:  return 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   619
            }
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   620
            if (matchType(descr, requiredType))  return mark;
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   621
            return 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   622
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   623
8822
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   624
        boolean matchType(String descr, String requiredType) {
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   625
            if (descr.equals(requiredType))  return true;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   626
            if (transitionalJSR292) {
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   627
                String oldType = requiredType.replace("Ljava/lang/invoke/", "Ljava/dyn/");
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   628
                if (descr.equals(oldType))  return true;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   629
            }
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   630
            return false;
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   631
        }
8145ab9f5f86 7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents: 8345
diff changeset
   632
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   633
        private class JVMState {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   634
            final List<Object> stack = new ArrayList<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   635
            int sp() { return stack.size(); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   636
            void push(Object x) { stack.add(x); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   637
            void push2(Object x) { stack.add(EMPTY_SLOT); stack.add(x); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   638
            void pushAt(int pos, Object x) { stack.add(stack.size()+pos, x); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   639
            Object pop() { return stack.remove(sp()-1); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   640
            Object top() { return stack.get(sp()-1); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   641
            List<Object> args(boolean hasRecv, String type) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   642
                return args(argsize(type) + (hasRecv ? 1 : 0));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   643
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   644
            List<Object> args(int argsize) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   645
                return stack.subList(sp()-argsize, sp());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   646
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   647
            boolean stackMotion(int bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   648
                switch (bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   649
                case opc_pop:    pop();             break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   650
                case opc_pop2:   pop(); pop();      break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   651
                case opc_swap:   pushAt(-1, pop()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   652
                case opc_dup:    push(top());       break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   653
                case opc_dup_x1: pushAt(-2, top()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   654
                case opc_dup_x2: pushAt(-3, top()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   655
                // ? also: dup2{,_x1,_x2}
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   656
                default:  return false;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   657
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   658
                return true;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   659
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   660
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   661
        private final String EMPTY_SLOT = "_";
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   662
        private void removeEmptyJVMSlots(List<Object> args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   663
            for (;;) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   664
                int i = args.indexOf(EMPTY_SLOT);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   665
                if (i >= 0 && i+1 < args.size()
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   666
                    && (isConstant(args.get(i+1), CONSTANT_Long) ||
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   667
                        isConstant(args.get(i+1), CONSTANT_Double)))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   668
                    args.remove(i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   669
                else  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   670
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   671
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   672
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   673
        private Constant scanPattern(Method m, char patternMark) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   674
            if (verbose)  System.err.println("scan "+m+" for pattern="+patternMark);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   675
            int wantTag;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   676
            switch (patternMark) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   677
            case 'T': wantTag = CONSTANT_MethodType; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   678
            case 'H': wantTag = CONSTANT_MethodHandle; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   679
            case 'I': wantTag = CONSTANT_InvokeDynamic; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   680
            default: throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   681
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   682
            Instruction i = m.instructions();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   683
            JVMState jvm = new JVMState();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   684
            Pool pool = cf.pool;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   685
            int branchCount = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   686
            Object arg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   687
            List<Object> args;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   688
            List<Object> bsmArgs = null;  // args to invokeGeneric
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   689
        decode:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   690
            for (; i != null; i = i.next()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   691
                //System.out.println(jvm.stack+" "+i);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   692
                int bc = i.bc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   693
                switch (bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   694
                case opc_ldc:           jvm.push(pool.get(i.u1At(1)));   break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   695
                case opc_ldc_w:         jvm.push(pool.get(i.u2At(1)));   break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   696
                case opc_ldc2_w:        jvm.push2(pool.get(i.u2At(1)));  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   697
                case opc_aconst_null:   jvm.push(null);                  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   698
                case opc_bipush:        jvm.push((int)(byte) i.u1At(1)); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   699
                case opc_sipush:        jvm.push((int)(short)i.u2At(1)); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   700
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   701
                // these support creation of a restarg array
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   702
                case opc_anewarray:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   703
                    arg = jvm.pop();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   704
                    if (!(arg instanceof Integer))  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   705
                    arg = Arrays.asList(new Object[(Integer)arg]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   706
                    jvm.push(arg);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   707
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   708
                case opc_dup:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   709
                    jvm.push(jvm.top()); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   710
                case opc_aastore:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   711
                    args = jvm.args(3);  // array, index, value
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   712
                    if (args.get(0) instanceof List &&
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   713
                        args.get(1) instanceof Integer) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   714
                        ((List<Object>)args.get(0)).set( (Integer)args.get(1), args.get(2) );
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   715
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   716
                    args.clear();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   717
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   718
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   719
                case opc_new:
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   720
                {
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   721
                    String type = pool.getString(CONSTANT_Class, (short)i.u2At(1));
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   722
                    //System.out.println("new "+type);
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   723
                    switch (type) {
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   724
                    case "java/lang/StringBuilder":
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   725
                        jvm.push("StringBuilder");
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   726
                        continue decode;  // go to next instruction
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   727
                    }
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   728
                    break decode;  // bail out
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   729
                }
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   730
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   731
                case opc_getstatic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   732
                {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   733
                    // int.class compiles to getstatic Integer.TYPE
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   734
                    int fieldi = i.u2At(1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   735
                    char mark = poolMarks[fieldi];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   736
                    //System.err.println("getstatic "+fieldi+Arrays.asList(pool.getStrings(pool.getMemberRef((short)fieldi)))+mark);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   737
                    if (mark == 'J') {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   738
                        Short[] ref = pool.getMemberRef((short) fieldi);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   739
                        String name = pool.getString(CONSTANT_Utf8, ref[1]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   740
                        if ("TYPE".equals(name)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   741
                            String wrapperName = pool.getString(CONSTANT_Class, ref[0]).replace('/', '.');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   742
                            // a primitive type descriptor
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   743
                            Class<?> primClass;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   744
                            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   745
                                primClass = (Class<?>) Class.forName(wrapperName).getField(name).get(null);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   746
                            } catch (Exception ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   747
                                throw new InternalError("cannot load "+wrapperName+"."+name);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   748
                            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   749
                            jvm.push(primClass);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   750
                            break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   751
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   752
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   753
                    // unknown field; keep going...
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   754
                    jvm.push(UNKNOWN_CON);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   755
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   756
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   757
                case opc_putstatic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   758
                {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   759
                    if (patternMark != 'I')  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   760
                    jvm.pop();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   761
                    // unknown field; keep going...
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   762
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   763
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   764
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   765
                case opc_invokestatic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   766
                case opc_invokevirtual:
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   767
                case opc_invokespecial:
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   768
                {
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   769
                    boolean hasRecv = (bc != opc_invokestatic);
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   770
                    int methi = i.u2At(1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   771
                    char mark = poolMarks[methi];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   772
                    Short[] ref = pool.getMemberRef((short)methi);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   773
                    String type = pool.getString(CONSTANT_Utf8, ref[2]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   774
                    //System.out.println("invoke "+pool.getString(CONSTANT_Utf8, ref[1])+" "+Arrays.asList(ref)+" : "+type);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   775
                    args = jvm.args(hasRecv, type);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   776
                    String intrinsic = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   777
                    Constant con;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   778
                    if (mark == 'D' || mark == 'J') {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   779
                        intrinsic = pool.getString(CONSTANT_Utf8, ref[1]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   780
                        if (mark == 'J') {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   781
                            String cls = pool.getString(CONSTANT_Class, ref[0]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   782
                            cls = cls.substring(1+cls.lastIndexOf('/'));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   783
                            intrinsic = cls+"."+intrinsic;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   784
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   785
                        //System.out.println("recognized intrinsic "+intrinsic);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   786
                        byte refKind = -1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   787
                        switch (intrinsic) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   788
                        case "findGetter":          refKind = REF_getField;         break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   789
                        case "findStaticGetter":    refKind = REF_getStatic;        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   790
                        case "findSetter":          refKind = REF_putField;         break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   791
                        case "findStaticSetter":    refKind = REF_putStatic;        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   792
                        case "findVirtual":         refKind = REF_invokeVirtual;    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   793
                        case "findStatic":          refKind = REF_invokeStatic;     break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   794
                        case "findSpecial":         refKind = REF_invokeSpecial;    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   795
                        case "findConstructor":     refKind = REF_newInvokeSpecial; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   796
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   797
                        if (refKind >= 0 && (con = parseMemberLookup(refKind, args)) != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   798
                            args.clear(); args.add(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   799
                            continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   800
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   801
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   802
                    Method ownMethod = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   803
                    if (mark == 'T' || mark == 'H' || mark == 'I') {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   804
                        ownMethod = findMember(cf.methods, ref[1], ref[2]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   805
                    }
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   806
                    //if (intrinsic != null)  System.out.println("intrinsic = "+intrinsic);
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   807
                    switch (intrinsic == null ? "" : intrinsic) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   808
                    case "fromMethodDescriptorString":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   809
                        con = makeMethodTypeCon(args.get(0));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   810
                        args.clear(); args.add(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   811
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   812
                    case "methodType": {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   813
                        flattenVarargs(args);  // there are several overloadings, some with varargs
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   814
                        StringBuilder buf = new StringBuilder();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   815
                        String rtype = null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   816
                        for (Object typeArg : args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   817
                            if (typeArg instanceof Class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   818
                                Class<?> argClass = (Class<?>) typeArg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   819
                                if (argClass.isPrimitive()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   820
                                    char tchar;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   821
                                    switch (argClass.getName()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   822
                                    case "void":    tchar = 'V'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   823
                                    case "boolean": tchar = 'Z'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   824
                                    case "byte":    tchar = 'B'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   825
                                    case "char":    tchar = 'C'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   826
                                    case "short":   tchar = 'S'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   827
                                    case "int":     tchar = 'I'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   828
                                    case "long":    tchar = 'J'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   829
                                    case "float":   tchar = 'F'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   830
                                    case "double":  tchar = 'D'; break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   831
                                    default:  throw new InternalError(argClass.toString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   832
                                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   833
                                    buf.append(tchar);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   834
                                } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   835
                                    // should not happen, but...
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   836
                                    buf.append('L').append(argClass.getName().replace('.','/')).append(';');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   837
                                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   838
                            } else if (typeArg instanceof Constant) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   839
                                Constant argCon = (Constant) typeArg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   840
                                if (argCon.tag == CONSTANT_Class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   841
                                    String cn = pool.get(argCon.itemIndex()).itemString();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   842
                                    if (cn.endsWith(";"))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   843
                                        buf.append(cn);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   844
                                    else
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   845
                                        buf.append('L').append(cn).append(';');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   846
                                } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   847
                                    break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   848
                                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   849
                            } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   850
                                break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   851
                            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   852
                            if (rtype == null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   853
                                // first arg is treated differently
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   854
                                rtype = buf.toString();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   855
                                buf.setLength(0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   856
                                buf.append('(');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   857
                            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   858
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   859
                        buf.append(')').append(rtype);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   860
                        con = con = makeMethodTypeCon(buf.toString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   861
                        args.clear(); args.add(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   862
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   863
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   864
                    case "lookup":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   865
                    case "dynamicInvoker":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   866
                        args.clear(); args.add(intrinsic);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   867
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   868
                    case "lookupClass":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   869
                        if (args.equals(Arrays.asList("lookup"))) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   870
                            // fold lookup().lookupClass() to the enclosing class
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   871
                            args.clear(); args.add(pool.get(cf.thisc));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   872
                            continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   873
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   874
                        break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   875
                    case "invokeGeneric":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   876
                    case "invokeWithArguments":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   877
                        if (patternMark != 'I')  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   878
                        if ("invokeWithArguments".equals(intrinsic))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   879
                            flattenVarargs(args);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   880
                        bsmArgs = new ArrayList(args);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   881
                        args.clear(); args.add("invokeGeneric");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   882
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   883
                    case "Integer.valueOf":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   884
                    case "Float.valueOf":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   885
                    case "Long.valueOf":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   886
                    case "Double.valueOf":
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   887
                        removeEmptyJVMSlots(args);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   888
                        if (args.size() == 1) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   889
                            arg = args.remove(0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   890
                            assert(3456 == (CONSTANT_Integer*1000 + CONSTANT_Float*100 + CONSTANT_Long*10 + CONSTANT_Double));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   891
                            if (isConstant(arg, CONSTANT_Integer + "IFLD".indexOf(intrinsic.charAt(0)))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   892
                                || arg instanceof Number) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   893
                                args.add(arg); continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   894
                            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   895
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   896
                        break decode;
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   897
                    case "StringBuilder.append":
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   898
                        // allow calls like ("value = "+x)
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   899
                        removeEmptyJVMSlots(args);
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   900
                        args.subList(1, args.size()).clear();
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   901
                        continue;
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   902
                    case "StringBuilder.toString":
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   903
                        args.clear();
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   904
                        args.add(intrinsic);
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
   905
                        continue;
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   906
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   907
                    if (!hasRecv && ownMethod != null && patternMark != 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   908
                        con = constants.get(ownMethod);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   909
                        if (con == null)  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   910
                        args.clear(); args.add(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   911
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   912
                    } else if (type.endsWith(")V")) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   913
                        // allow calls like println("reached the pattern method")
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   914
                        args.clear();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   915
                        continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   916
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   917
                    break decode;  // bail out for most calls
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   918
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   919
                case opc_areturn:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   920
                {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   921
                    ++branchCount;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   922
                    if (bsmArgs != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   923
                        // parse bsmArgs as (MH, lookup, String, MT, [extra])
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   924
                        Constant indyCon = makeInvokeDynamicCon(bsmArgs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   925
                        if (indyCon != null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   926
                            Constant typeCon = (Constant) bsmArgs.get(3);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   927
                            indySignatures.put(m, pool.getString(typeCon.itemIndex()));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   928
                            return indyCon;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   929
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   930
                        System.err.println(m+": inscrutable bsm arguments: "+bsmArgs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   931
                        break decode;  // bail out
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   932
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   933
                    arg = jvm.pop();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   934
                    if (branchCount == 2 && UNKNOWN_CON.equals(arg))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   935
                        break;  // merge to next path
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   936
                    if (isConstant(arg, wantTag))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   937
                        return (Constant) arg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   938
                    break decode;  // bail out
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   939
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   940
                default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   941
                    if (jvm.stackMotion(i.bc))  break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   942
                    if (bc >= opc_nconst_MIN && bc <= opc_nconst_MAX)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   943
                        { jvm.push(INSTRUCTION_CONSTANTS[bc - opc_nconst_MIN]); break; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   944
                    if (patternMark == 'I') {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   945
                        // these support caching paths in INDY_x methods
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   946
                        if (bc == opc_aload || bc >= opc_aload_0 && bc <= opc_aload_MAX)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   947
                            { jvm.push(UNKNOWN_CON); break; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   948
                        if (bc == opc_astore || bc >= opc_astore_0 && bc <= opc_astore_MAX)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   949
                            { jvm.pop(); break; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   950
                        switch (bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   951
                        case opc_getfield:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   952
                        case opc_aaload:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   953
                            jvm.push(UNKNOWN_CON); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   954
                        case opc_ifnull:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   955
                        case opc_ifnonnull:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   956
                            // ignore branch target
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   957
                            if (++branchCount != 1)  break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   958
                            jvm.pop();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   959
                            break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   960
                        case opc_checkcast:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   961
                            arg = jvm.top();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   962
                            if ("invokeWithArguments".equals(arg) ||
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   963
                                "invokeGeneric".equals(arg))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   964
                                break;  // assume it is a helpful cast
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   965
                            break decode;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   966
                        default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   967
                            break decode;  // bail out
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   968
                        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   969
                        continue decode; // go to next instruction
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   970
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   971
                    break decode;  // bail out
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   972
                } //end switch
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   973
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   974
            System.err.println(m+": bailout on "+i+" jvm stack: "+jvm.stack);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   975
            return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   976
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   977
        private final String UNKNOWN_CON = "<unknown>";
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   978
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   979
        private void flattenVarargs(List<Object> args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   980
            int size = args.size();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   981
            if (size > 0 && args.get(size-1) instanceof List)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   982
                args.addAll((List<Object>) args.remove(size-1));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   983
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   984
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   985
        private boolean isConstant(Object x, int tag) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   986
            return x instanceof Constant && ((Constant)x).tag == tag;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   987
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   988
        private Constant makeMethodTypeCon(Object x) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   989
            short utfIndex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   990
            if (x instanceof String)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   991
                utfIndex = (short) cf.pool.addConstant(CONSTANT_Utf8, x).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   992
            else if (isConstant(x, CONSTANT_String))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   993
                utfIndex = ((Constant)x).itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   994
            else  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   995
            return cf.pool.addConstant(CONSTANT_MethodType, utfIndex);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   996
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   997
        private Constant parseMemberLookup(byte refKind, List<Object> args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   998
            // E.g.: lookup().findStatic(Foo.class, "name", MethodType)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
   999
            if (args.size() != 4)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1000
            int argi = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1001
            if (!"lookup".equals(args.get(argi++)))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1002
            short refindex, cindex, ntindex, nindex, tindex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1003
            Object con;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1004
            if (!isConstant(con = args.get(argi++), CONSTANT_Class))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1005
            cindex = (short)((Constant)con).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1006
            if (!isConstant(con = args.get(argi++), CONSTANT_String))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1007
            nindex = ((Constant)con).itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1008
            if (isConstant(con = args.get(argi++), CONSTANT_MethodType) ||
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1009
                isConstant(con, CONSTANT_Class)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1010
                tindex = ((Constant)con).itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1011
            } else return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1012
            ntindex = (short) cf.pool.addConstant(CONSTANT_NameAndType,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1013
                    new Short[]{ nindex, tindex }).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1014
            byte reftag = CONSTANT_Method;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1015
            if (refKind <= REF_putStatic)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1016
                reftag = CONSTANT_Field;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1017
            else if (refKind == REF_invokeInterface)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1018
                reftag = CONSTANT_InterfaceMethod;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1019
            Constant ref = cf.pool.addConstant(reftag, new Short[]{ cindex, ntindex });
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1020
            return cf.pool.addConstant(CONSTANT_MethodHandle, new Object[]{ refKind, (short)ref.index });
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1021
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1022
        private Constant makeInvokeDynamicCon(List<Object> args) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1023
            // E.g.: MH_bsm.invokeGeneric(lookup(), "name", MethodType, "extraArg")
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1024
            removeEmptyJVMSlots(args);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1025
            if (args.size() != 4 && args.size() != 5)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1026
            int argi = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1027
            short nindex, tindex, ntindex, bsmindex;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1028
            Object con;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1029
            if (!isConstant(con = args.get(argi++), CONSTANT_MethodHandle))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1030
            bsmindex = (short) ((Constant)con).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1031
            if (!"lookup".equals(args.get(argi++)))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1032
            if (!isConstant(con = args.get(argi++), CONSTANT_String))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1033
            nindex = ((Constant)con).itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1034
            if (!isConstant(con = args.get(argi++), CONSTANT_MethodType))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1035
            tindex = ((Constant)con).itemIndex();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1036
            ntindex = (short) cf.pool.addConstant(CONSTANT_NameAndType,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1037
                                                  new Short[]{ nindex, tindex }).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1038
            if (transitionalJSR292) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1039
                if (argi != args.size()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1040
                    System.err.println("BSM specifier has extra arguments but transitionalJSR292=1");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1041
                    return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1042
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1043
                return cf.pool.addConstant(CONSTANT_InvokeDynamic_17,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1044
                        new Short[]{ bsmindex, ntindex });
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1045
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1046
            List<Object> extraArgs = Collections.emptyList();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1047
            if (argi < args.size()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1048
                Object arg = args.get(argi);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1049
                if (arg instanceof List)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1050
                    extraArgs = (List<Object>) arg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1051
                else
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1052
                    extraArgs = Arrays.asList(arg);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1053
                removeEmptyJVMSlots(args);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1054
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1055
            List<Short> extraArgIndexes = new CountedList<>(Short.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1056
            for (Object x : extraArgs) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1057
                if (x instanceof Number) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1058
                    Object num = null; byte numTag = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1059
                    if (x instanceof Integer) { num = x; numTag = CONSTANT_Integer; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1060
                    if (x instanceof Float)   { num = Float.floatToRawIntBits((Float)x); numTag = CONSTANT_Float; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1061
                    if (x instanceof Long)    { num = x; numTag = CONSTANT_Long; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1062
                    if (x instanceof Double)  { num = Double.doubleToRawLongBits((Double)x); numTag = CONSTANT_Double; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1063
                    if (num != null)  x = cf.pool.addConstant(numTag, x);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1064
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1065
                if (!(x instanceof Constant))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1066
                extraArgIndexes.add((short) ((Constant)x).index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1067
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1068
            List<Object[]> specs = bootstrapMethodSpecifiers(true);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1069
            int specindex = -1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1070
            Object[] spec = new Object[]{ bsmindex, extraArgIndexes };
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1071
            for (Object[] spec1 : specs) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1072
                if (Arrays.equals(spec1, spec)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1073
                    specindex = specs.indexOf(spec1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1074
                    if (verbose)  System.err.println("reusing BSM specifier: "+spec1[0]+spec1[1]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1075
                    break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1076
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1077
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1078
            if (specindex == -1) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1079
                specindex = (short) specs.size();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1080
                specs.add(spec);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1081
                if (verbose)  System.err.println("adding BSM specifier: "+spec[0]+spec[1]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1082
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1083
            return cf.pool.addConstant(CONSTANT_InvokeDynamic,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1084
                        new Short[]{ (short)specindex, ntindex });
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1085
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1086
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1087
        List<Object[]> bootstrapMethodSpecifiers(boolean createIfNotFound) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1088
            Attr bsms = cf.findAttr("BootstrapMethods");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1089
            if (bsms == null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1090
                if (!createIfNotFound)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1091
                bsms = new Attr(cf, "BootstrapMethods", new byte[]{0,0});
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1092
                assert(bsms == cf.findAttr("BootstrapMethods"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1093
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1094
            if (bsms.item instanceof byte[]) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1095
                // unflatten
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1096
                List<Object[]> specs = new CountedList<>(Object[].class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1097
                DataInputStream in = new DataInputStream(new ByteArrayInputStream((byte[]) bsms.item));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1098
                try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1099
                    int len = (char) in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1100
                    for (int i = 0; i < len; i++) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1101
                        short bsm = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1102
                        int argc = (char) in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1103
                        List<Short> argv = new CountedList<>(Short.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1104
                        for (int j = 0; j < argc; j++)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1105
                            argv.add(in.readShort());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1106
                        specs.add(new Object[]{ bsm, argv });
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1107
                    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1108
                } catch (IOException ex) { throw new InternalError(); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1109
                bsms.item = specs;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1110
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1111
            return (List<Object[]>) bsms.item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1112
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1113
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1114
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1115
    private DataInputStream openInput(File f) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1116
        return new DataInputStream(new BufferedInputStream(new FileInputStream(f)));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1117
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1118
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1119
    private DataOutputStream openOutput(File f) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1120
        if (!overwrite && f.exists())
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1121
            throw new IOException("file already exists: "+f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1122
        ensureDirectory(f.getParentFile());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1123
        return new DataOutputStream(new BufferedOutputStream(new FileOutputStream(f)));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1124
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1125
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1126
    static byte[] readRawBytes(DataInputStream in, int size) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1127
        byte[] bytes = new byte[size];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1128
        int nr = in.read(bytes);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1129
        if (nr != size)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1130
            throw new InternalError("wrong size: "+nr);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1131
        return bytes;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1132
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1133
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1134
    private interface Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1135
        void readFrom(DataInputStream in) throws IOException;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1136
        void writeTo(DataOutputStream out) throws IOException;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1137
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1138
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1139
    private static class CountedList<T> extends ArrayList<T> implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1140
        final Class<? extends T> itemClass;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1141
        final int rowlen;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1142
        CountedList(Class<? extends T> itemClass, int rowlen) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1143
            this.itemClass = itemClass;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1144
            this.rowlen = rowlen;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1145
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1146
        CountedList(Class<? extends T> itemClass) { this(itemClass, -1); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1147
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1148
            int count = in.readUnsignedShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1149
            while (size() < count) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1150
                if (rowlen < 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1151
                    add(readInput(in, itemClass));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1152
                } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1153
                    Class<?> elemClass = itemClass.getComponentType();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1154
                    Object[] row = (Object[]) java.lang.reflect.Array.newInstance(elemClass, rowlen);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1155
                    for (int i = 0; i < rowlen; i++)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1156
                        row[i] = readInput(in, elemClass);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1157
                    add(itemClass.cast(row));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1158
                }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1159
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1160
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1161
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1162
            out.writeShort((short)size());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1163
            for (T item : this) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1164
                writeOutput(out, item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1165
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1166
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1167
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1168
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1169
    private static <T> T readInput(DataInputStream in, Class<T> dataClass) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1170
        Object data;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1171
        if (dataClass == Integer.class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1172
            data = in.readInt();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1173
        } else if (dataClass == Short.class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1174
            data = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1175
        } else if (dataClass == Byte.class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1176
            data = in.readByte();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1177
        } else if (dataClass == String.class) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1178
            data = in.readUTF();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1179
        } else if (Chunk.class.isAssignableFrom(dataClass)) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1180
            T obj;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1181
            try { obj = dataClass.newInstance(); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1182
                catch (Exception ex) { throw new RuntimeException(ex); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1183
            ((Chunk)obj).readFrom(in);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1184
            data = obj;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1185
        } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1186
            throw new InternalError("bad input datum: "+dataClass);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1187
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1188
        return dataClass.cast(data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1189
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1190
    private static <T> T readInput(byte[] bytes, Class<T> dataClass) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1191
        try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1192
            return readInput(new DataInputStream(new ByteArrayInputStream(bytes)), dataClass);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1193
        } catch (IOException ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1194
            throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1195
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1196
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1197
    private static void readInputs(DataInputStream in, Object... data) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1198
        for (Object x : data)  ((Chunk)x).readFrom(in);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1199
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1200
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1201
    private static void writeOutput(DataOutputStream out, Object data) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1202
        if (data == null) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1203
            return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1204
        } if (data instanceof Integer) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1205
            out.writeInt((Integer)data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1206
        } else if (data instanceof Long) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1207
            out.writeLong((Long)data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1208
        } else if (data instanceof Short) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1209
            out.writeShort((Short)data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1210
        } else if (data instanceof Byte) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1211
            out.writeByte((Byte)data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1212
        } else if (data instanceof String) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1213
            out.writeUTF((String)data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1214
        } else if (data instanceof byte[]) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1215
            out.write((byte[])data);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1216
        } else if (data instanceof Object[]) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1217
            for (Object x : (Object[]) data)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1218
                writeOutput(out, x);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1219
        } else if (data instanceof Chunk) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1220
            Chunk x = (Chunk) data;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1221
            x.writeTo(out);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1222
        } else if (data instanceof List) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1223
            for (Object x : (List<?>) data)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1224
                writeOutput(out, x);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1225
        } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1226
            throw new InternalError("bad output datum: "+data+" : "+data.getClass().getName());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1227
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1228
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1229
    private static void writeOutputs(DataOutputStream out, Object... data) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1230
        for (Object x : data)  writeOutput(out, x);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1231
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1232
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1233
    public static abstract class Outer {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1234
        public abstract List<? extends Inner> inners();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1235
        protected void linkInners() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1236
            for (Inner i : inners()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1237
                i.linkOuter(this);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1238
                if (i instanceof Outer)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1239
                    ((Outer)i).linkInners();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1240
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1241
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1242
        public <T extends Outer> T outer(Class<T> c) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1243
            for (Outer walk = this;; walk = ((Inner)walk).outer()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1244
                if (c.isInstance(walk))
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1245
                    return c.cast(walk);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1246
                //if (!(walk instanceof Inner))  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1247
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1248
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1249
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1250
        public abstract List<Attr> attrs();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1251
        public Attr findAttr(String name) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1252
            return findAttr(outer(ClassFile.class).pool.stringIndex(name, false));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1253
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1254
        public Attr findAttr(int name) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1255
            if (name == 0)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1256
            for (Attr a : attrs()) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1257
                if (a.name == name)  return a;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1258
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1259
            return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1260
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1261
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1262
    public interface Inner { Outer outer(); void linkOuter(Outer o); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1263
    public static abstract class InnerOuter extends Outer implements Inner {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1264
        public Outer outer;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1265
        public Outer outer() { return outer; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1266
        public void linkOuter(Outer o) { assert(outer == null); outer = o; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1267
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1268
    public static class Constant<T> implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1269
        public final byte tag;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1270
        public final T item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1271
        public final int index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1272
        public Constant(int index, byte tag, T item) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1273
            this.index = index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1274
            this.tag = tag;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1275
            this.item = item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1276
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1277
        public Constant checkTag(byte tag) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1278
            if (this.tag != tag)  throw new InternalError(this.toString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1279
            return this;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1280
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1281
        public String itemString() { return (String)item; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1282
        public Short itemIndex() { return (Short)item; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1283
        public Short[] itemIndexes() { return (Short[])item; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1284
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1285
            throw new InternalError("do not call");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1286
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1287
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1288
            writeOutputs(out, tag, item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1289
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1290
        public boolean equals(Object x) { return (x instanceof Constant && equals((Constant)x)); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1291
        public boolean equals(Constant that) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1292
            return (this.tag == that.tag && this.itemAsComparable().equals(that.itemAsComparable()));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1293
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1294
        public int hashCode() { return (tag * 31) + this.itemAsComparable().hashCode(); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1295
        public Object itemAsComparable() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1296
            switch (tag) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1297
            case CONSTANT_Double:   return Double.longBitsToDouble((Long)item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1298
            case CONSTANT_Float:    return Float.intBitsToFloat((Integer)item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1299
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1300
            return (item instanceof Object[] ? Arrays.asList((Object[])item) : item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1301
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1302
        public String toString() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1303
            String itstr = String.valueOf(itemAsComparable());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1304
            return (index + ":" + tagName(tag) + (itstr.startsWith("[")?"":"=") + itstr);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1305
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1306
        private static String[] TAG_NAMES;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1307
        public static String tagName(byte tag) {  // used for error messages
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1308
            if (TAG_NAMES == null)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1309
                TAG_NAMES = ("None Utf8 Unicode Integer Float Long Double Class String"
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1310
                             +" Fieldref Methodref InterfaceMethodref NameAndType #13 #14"
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1311
                             +" MethodHandle MethodType InvokeDynamic#17 InvokeDynamic").split(" ");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1312
            if ((tag & 0xFF) >= TAG_NAMES.length)  return "#"+(tag & 0xFF);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1313
            return TAG_NAMES[tag & 0xFF];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1314
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1315
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1316
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1317
    public static class Pool extends CountedList<Constant> implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1318
        private Map<String,Short> strings = new TreeMap<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1319
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1320
        public Pool() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1321
            super(Constant.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1322
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1323
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1324
            int count = in.readUnsignedShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1325
            add(null);  // always ignore first item
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1326
            while (size() < count) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1327
                readConstant(in);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1328
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1329
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1330
        public <T> Constant<T> addConstant(byte tag, T item) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1331
            Constant<T> con = new Constant<>(size(), tag, item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1332
            int idx = indexOf(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1333
            if (idx >= 0)  return get(idx);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1334
            add(con);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1335
            if (tag == CONSTANT_Utf8)  strings.put((String)item, (short) con.index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1336
            return con;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1337
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1338
        private void readConstant(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1339
            byte tag = in.readByte();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1340
            int index = size();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1341
            Object arg;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1342
            switch (tag) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1343
            case CONSTANT_Utf8:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1344
                arg = in.readUTF();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1345
                strings.put((String) arg, (short) size());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1346
                break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1347
            case CONSTANT_Integer:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1348
            case CONSTANT_Float:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1349
                arg = in.readInt(); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1350
            case CONSTANT_Long:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1351
            case CONSTANT_Double:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1352
                add(new Constant(index, tag, in.readLong()));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1353
                add(null);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1354
                return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1355
            case CONSTANT_Class:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1356
            case CONSTANT_String:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1357
                arg = in.readShort(); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1358
            case CONSTANT_Field:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1359
            case CONSTANT_Method:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1360
            case CONSTANT_InterfaceMethod:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1361
            case CONSTANT_NameAndType:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1362
            case CONSTANT_InvokeDynamic_17:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1363
            case CONSTANT_InvokeDynamic:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1364
                // read an ordered pair
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1365
                arg = new Short[] { in.readShort(), in.readShort() };
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1366
                break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1367
            case CONSTANT_MethodHandle:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1368
                // read an ordered pair; first part is a u1 (not u2)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1369
                arg = new Object[] { in.readByte(), in.readShort() };
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1370
                break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1371
            case CONSTANT_MethodType:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1372
                arg = in.readShort(); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1373
            default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1374
                throw new InternalError("bad CP tag "+tag);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1375
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1376
            add(new Constant(index, tag, arg));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1377
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1378
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1379
        // Access:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1380
        public Constant get(int index) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1381
            // extra 1-bits get into the shorts
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1382
            return super.get((char) index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1383
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1384
        String getString(byte tag, short index) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1385
            get(index).checkTag(tag);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1386
            return getString(index);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1387
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1388
        String getString(short index) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1389
            Object v = get(index).item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1390
            if (v instanceof Short)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1391
                v = get((Short)v).checkTag(CONSTANT_Utf8).item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1392
            return (String) v;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1393
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1394
        String[] getStrings(Short[] indexes) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1395
            String[] res = new String[indexes.length];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1396
            for (int i = 0; i < indexes.length; i++)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1397
                res[i] = getString(indexes[i]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1398
            return res;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1399
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1400
        int stringIndex(String name, boolean createIfNotFound) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1401
            Short x = strings.get(name);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1402
            if (x != null)  return (char)(int) x;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1403
            if (!createIfNotFound)  return 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1404
            return addConstant(CONSTANT_Utf8, name).index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1405
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1406
        Short[] getMemberRef(short index) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1407
            Short[] cls_nnt = get(index).itemIndexes();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1408
            Short[] name_type = get(cls_nnt[1]).itemIndexes();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1409
            return new Short[]{ cls_nnt[0], name_type[0], name_type[1] };
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1410
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1411
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1412
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1413
    public class ClassFile extends Outer implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1414
        ClassFile(File f) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1415
            DataInputStream in = openInput(f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1416
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1417
                readFrom(in);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1418
            } finally {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1419
                if (in != null)  in.close();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1420
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1421
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1422
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1423
        public int                magic, version;  // <min:maj>
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1424
        public final Pool         pool       = new Pool();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1425
        public short              access, thisc, superc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1426
        public final List<Short>  interfaces = new CountedList<>(Short.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1427
        public final List<Field>  fields     = new CountedList<>(Field.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1428
        public final List<Method> methods    = new CountedList<>(Method.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1429
        public final List<Attr>   attrs      = new CountedList<>(Attr.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1430
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1431
        public final void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1432
            magic = in.readInt(); version = in.readInt();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1433
            if (magic != 0xCAFEBABE)  throw new IOException("bad magic number");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1434
            pool.readFrom(in);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1435
            Code_index = pool.stringIndex("Code", false);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1436
            access = in.readShort(); thisc = in.readShort(); superc = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1437
            readInputs(in, interfaces, fields, methods, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1438
            if (in.read() >= 0)  throw new IOException("junk after end of file");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1439
            linkInners();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1440
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1441
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1442
        void writeTo(File f) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1443
            DataOutputStream out = openOutput(f);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1444
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1445
                writeTo(out);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1446
            } finally {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1447
                out.close();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1448
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1449
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1450
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1451
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1452
            writeOutputs(out, magic, version, pool,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1453
                         access, thisc, superc, interfaces,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1454
                         fields, methods, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1455
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1456
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1457
        public byte[] toByteArray() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1458
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1459
                ByteArrayOutputStream buf = new ByteArrayOutputStream();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1460
                writeTo(new DataOutputStream(buf));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1461
                return buf.toByteArray();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1462
            } catch (IOException ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1463
                throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1464
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1465
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1466
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1467
        public List<Inner> inners() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1468
            List<Inner> inns = new ArrayList<>();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1469
            inns.addAll(fields); inns.addAll(methods); inns.addAll(attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1470
            return inns;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1471
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1472
        public List<Attr> attrs() { return attrs; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1473
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1474
        // derived stuff:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1475
        public String nameString() { return pool.getString(CONSTANT_Class, thisc); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1476
        int Code_index;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1477
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1478
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1479
    private static <T extends Member> T findMember(List<T> mems, int name, int type) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1480
        if (name == 0 || type == 0)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1481
        for (T m : mems) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1482
            if (m.name == name && m.type == type)  return m;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1483
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1484
        return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1485
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1486
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1487
    public static class Member extends InnerOuter implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1488
        public short access, name, type;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1489
        public final List<Attr> attrs = new CountedList<>(Attr.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1490
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1491
            access = in.readShort(); name = in.readShort(); type = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1492
            readInputs(in, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1493
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1494
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1495
            writeOutputs(out, access, name, type, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1496
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1497
        public List<Attr> inners() { return attrs; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1498
        public List<Attr> attrs() { return attrs; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1499
        public ClassFile outer() { return (ClassFile) outer; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1500
        public String nameString() { return outer().pool.getString(CONSTANT_Utf8, name); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1501
        public String typeString() { return outer().pool.getString(CONSTANT_Utf8, type); }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1502
        public String toString() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1503
            if (outer == null)  return super.toString();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1504
            return nameString() + (this instanceof Method ? "" : ":")
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1505
                    + simplifyType(typeString());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1506
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1507
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1508
    public static class Field extends Member {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1509
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1510
    public static class Method extends Member {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1511
        public Code code() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1512
            Attr a = findAttr("Code");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1513
            if (a == null)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1514
            return (Code) a.item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1515
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1516
        public Instruction instructions() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1517
            Code code = code();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1518
            if (code == null)  return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1519
            return code.instructions();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1520
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1521
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1522
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1523
    public static class Attr extends InnerOuter implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1524
        public short name;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1525
        public int size = -1;  // no pre-declared size
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1526
        public Object item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1527
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1528
        public Attr() {}
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1529
        public Attr(Outer outer, String name, Object item) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1530
            ClassFile cf = outer.outer(ClassFile.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1531
            linkOuter(outer);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1532
            this.name = (short) cf.pool.stringIndex(name, true);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1533
            this.item = item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1534
            outer.attrs().add(this);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1535
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1536
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1537
            name = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1538
            size = in.readInt();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1539
            item = readRawBytes(in, size);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1540
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1541
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1542
            out.writeShort(name);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1543
            // write the 4-byte size header and then the contents:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1544
            byte[] bytes;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1545
            int trueSize;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1546
            if (item instanceof byte[]) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1547
                bytes = (byte[]) item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1548
                out.writeInt(trueSize = bytes.length);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1549
                out.write(bytes);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1550
            } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1551
                trueSize = flatten(out);
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
  1552
                //if (!(item instanceof Code))  System.err.println("wrote complex attr name="+(int)(char)name+" size="+trueSize+" data="+Arrays.toString(flatten()));
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1553
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1554
            if (trueSize != size && size >= 0)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1555
                System.err.println("warning: attribute size changed "+size+" to "+trueSize);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1556
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1557
        public void linkOuter(Outer o) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1558
            super.linkOuter(o);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1559
            if (item instanceof byte[] &&
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1560
                outer instanceof Method &&
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1561
                ((Method)outer).outer().Code_index == name) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1562
                    item = readInput((byte[])item, Code.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1563
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1564
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1565
        public List<Inner> inners() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1566
            if (item instanceof Inner)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1567
                return Collections.nCopies(1, (Inner)item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1568
            return Collections.emptyList();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1569
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1570
        public List<Attr> attrs() { return null; }  // Code overrides this
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1571
        public byte[] flatten() {
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
  1572
            ByteArrayOutputStream buf = new ByteArrayOutputStream(Math.max(20, size));
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1573
            flatten(buf);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1574
            return buf.toByteArray();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1575
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1576
        public int flatten(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1577
            ByteArrayOutputStream buf = new ByteArrayOutputStream(Math.max(20, size));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1578
            int trueSize = flatten(buf);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1579
            out.writeInt(trueSize);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1580
            buf.writeTo(out);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1581
            return trueSize;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1582
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1583
        private int flatten(ByteArrayOutputStream buf) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1584
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1585
                writeOutput(new DataOutputStream(buf), item);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1586
                return buf.size();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1587
            } catch (IOException ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1588
                throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1589
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1590
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1591
        public String nameString() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1592
            ClassFile cf = outer(ClassFile.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1593
            if (cf == null)  return "#"+name;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1594
            return cf.pool.getString(name);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1595
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1596
        public String toString() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1597
            return nameString()+(size < 0 ? "=" : "["+size+"]=")+item;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1598
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1599
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1600
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1601
    public static class Code extends InnerOuter implements Chunk {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1602
        public short stacks, locals;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1603
        public byte[] bytes;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1604
        public final List<Short[]> etable = new CountedList<>(Short[].class, 4);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1605
        public final List<Attr> attrs = new CountedList<>(Attr.class);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1606
        // etable[N] = (N)*{ startpc, endpc, handlerpc, catchtype }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1607
        public void readFrom(DataInputStream in) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1608
            stacks = in.readShort(); locals = in.readShort();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1609
            bytes = readRawBytes(in, in.readInt());
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1610
            readInputs(in, etable, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1611
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1612
        public void writeTo(DataOutputStream out) throws IOException {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1613
            writeOutputs(out, stacks, locals, bytes.length, bytes, etable, attrs);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1614
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1615
        public List<Attr> inners() { return attrs; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1616
        public List<Attr> attrs() { return attrs; }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1617
        public Instruction instructions() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1618
            return new Instruction(bytes, 0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1619
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1620
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1621
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1622
    // lots of constants
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1623
    private static final byte
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1624
        CONSTANT_Utf8              = 1,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1625
        CONSTANT_Integer           = 3,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1626
        CONSTANT_Float             = 4,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1627
        CONSTANT_Long              = 5,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1628
        CONSTANT_Double            = 6,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1629
        CONSTANT_Class             = 7,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1630
        CONSTANT_String            = 8,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1631
        CONSTANT_Field             = 9,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1632
        CONSTANT_Method            = 10,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1633
        CONSTANT_InterfaceMethod   = 11,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1634
        CONSTANT_NameAndType       = 12,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1635
        CONSTANT_MethodHandle      = 15,  // JSR 292
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1636
        CONSTANT_MethodType        = 16,  // JSR 292
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1637
        CONSTANT_InvokeDynamic_17  = 17,  // JSR 292, only occurs in old class files
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1638
        CONSTANT_InvokeDynamic     = 18;  // JSR 292
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1639
    private static final byte
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1640
        REF_getField               = 1,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1641
        REF_getStatic              = 2,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1642
        REF_putField               = 3,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1643
        REF_putStatic              = 4,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1644
        REF_invokeVirtual          = 5,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1645
        REF_invokeStatic           = 6,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1646
        REF_invokeSpecial          = 7,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1647
        REF_newInvokeSpecial       = 8,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1648
        REF_invokeInterface        = 9;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1649
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1650
    private static final int
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1651
        opc_nop                    = 0,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1652
        opc_aconst_null            = 1,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1653
        opc_nconst_MIN             = 2,  // iconst_m1
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1654
        opc_nconst_MAX             = 15, // dconst_1
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1655
        opc_bipush                 = 16,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1656
        opc_sipush                 = 17,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1657
        opc_ldc                    = 18,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1658
        opc_ldc_w                  = 19,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1659
        opc_ldc2_w                 = 20,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1660
        opc_aload                  = 25,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1661
        opc_aload_0                = 42,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1662
        opc_aload_MAX              = 45,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1663
        opc_aaload                 = 50,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1664
        opc_astore                 = 58,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1665
        opc_astore_0               = 75,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1666
        opc_astore_MAX             = 78,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1667
        opc_aastore                = 83,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1668
        opc_pop                    = 87,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1669
        opc_pop2                   = 88,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1670
        opc_dup                    = 89,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1671
        opc_dup_x1                 = 90,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1672
        opc_dup_x2                 = 91,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1673
        opc_dup2                   = 92,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1674
        opc_dup2_x1                = 93,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1675
        opc_dup2_x2                = 94,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1676
        opc_swap                   = 95,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1677
        opc_tableswitch            = 170,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1678
        opc_lookupswitch           = 171,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1679
        opc_areturn                = 176,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1680
        opc_getstatic              = 178,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1681
        opc_putstatic              = 179,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1682
        opc_getfield               = 180,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1683
        opc_putfield               = 181,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1684
        opc_invokevirtual          = 182,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1685
        opc_invokespecial          = 183,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1686
        opc_invokestatic           = 184,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1687
        opc_invokeinterface        = 185,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1688
        opc_invokedynamic          = 186,
8345
9e2483e6cfab 7013417: JSR 292 needs to support variadic method handle calls
jrose
parents: 7558
diff changeset
  1689
        opc_new                    = 187,
7558
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1690
        opc_anewarray              = 189,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1691
        opc_checkcast              = 192,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1692
        opc_ifnull                 = 198,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1693
        opc_ifnonnull              = 199,
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1694
        opc_wide                   = 196;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1695
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1696
    private static final Object[] INSTRUCTION_CONSTANTS = {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1697
        -1, 0, 1, 2, 3, 4, 5, 0L, 1L, 0.0F, 1.0F, 2.0F, 0.0D, 1.0D
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1698
    };
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1699
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1700
    private static final String INSTRUCTION_FORMATS =
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1701
        "nop$ aconst_null$L iconst_m1$I iconst_0$I iconst_1$I "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1702
        "iconst_2$I iconst_3$I iconst_4$I iconst_5$I lconst_0$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1703
        "lconst_1$J_ fconst_0$F fconst_1$F fconst_2$F dconst_0$D_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1704
        "dconst_1$D_ bipush=bx$I sipush=bxx$I ldc=bk$X ldc_w=bkk$X "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1705
        "ldc2_w=bkk$X_ iload=bl/wbll$I lload=bl/wbll$J_ fload=bl/wbll$F "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1706
        "dload=bl/wbll$D_ aload=bl/wbll$L iload_0$I iload_1$I "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1707
        "iload_2$I iload_3$I lload_0$J_ lload_1$J_ lload_2$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1708
        "lload_3$J_ fload_0$F fload_1$F fload_2$F fload_3$F dload_0$D_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1709
        "dload_1$D_ dload_2$D_ dload_3$D_ aload_0$L aload_1$L "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1710
        "aload_2$L aload_3$L iaload$LI$I laload$LI$J_ faload$LI$F "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1711
        "daload$LI$D_ aaload$LI$L baload$LI$I caload$LI$I saload$LI$I "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1712
        "istore=bl/wbll$I$ lstore=bl/wbll$J_$ fstore=bl/wbll$F$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1713
        "dstore=bl/wbll$D_$ astore=bl/wbll$L$ istore_0$I$ istore_1$I$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1714
        "istore_2$I$ istore_3$I$ lstore_0$J_$ lstore_1$J_$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1715
        "lstore_2$J_$ lstore_3$J_$ fstore_0$F$ fstore_1$F$ fstore_2$F$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1716
        "fstore_3$F$ dstore_0$D_$ dstore_1$D_$ dstore_2$D_$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1717
        "dstore_3$D_$ astore_0$L$ astore_1$L$ astore_2$L$ astore_3$L$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1718
        "iastore$LII$ lastore$LIJ_$ fastore$LIF$ dastore$LID_$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1719
        "aastore$LIL$ bastore$LII$ castore$LII$ sastore$LII$ pop$X$ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1720
        "pop2$XX$ dup$X$XX dup_x1$XX$XXX dup_x2$XXX$XXXX dup2$XX$XXXX "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1721
        "dup2_x1$XXX$XXXXX dup2_x2$XXXX$XXXXXX swap$XX$XX "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1722
        "iadd$II$I ladd$J_J_$J_ fadd$FF$F dadd$D_D_$D_ isub$II$I "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1723
        "lsub$J_J_$J_ fsub$FF$F dsub$D_D_$D_ imul$II$I lmul$J_J_$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1724
        "fmul$FF$F dmul$D_D_$D_ idiv$II$I ldiv$J_J_$J_ fdiv$FF$F "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1725
        "ddiv$D_D_$D_ irem$II$I lrem$J_J_$J_ frem$FF$F drem$D_D_$D_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1726
        "ineg$I$I lneg$J_$J_ fneg$F$F dneg$D_$D_ ishl$II$I lshl$J_I$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1727
        "ishr$II$I lshr$J_I$J_ iushr$II$I lushr$J_I$J_ iand$II$I "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1728
        "land$J_J_$J_ ior$II$I lor$J_J_$J_ ixor$II$I lxor$J_J_$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1729
        "iinc=blx/wbllxx$ i2l$I$J_ i2f$I$F i2d$I$D_ l2i$J_$I l2f$J_$F "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1730
        "l2d$J_$D_ f2i$F$I f2l$F$J_ f2d$F$D_ d2i$D_$I d2l$D_$J_ "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1731
        "d2f$D_$F i2b$I$I i2c$I$I i2s$I$I lcmp fcmpl fcmpg dcmpl dcmpg "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1732
        "ifeq=boo ifne=boo iflt=boo ifge=boo ifgt=boo ifle=boo "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1733
        "if_icmpeq=boo if_icmpne=boo if_icmplt=boo if_icmpge=boo "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1734
        "if_icmpgt=boo if_icmple=boo if_acmpeq=boo if_acmpne=boo "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1735
        "goto=boo jsr=boo ret=bl/wbll tableswitch=* lookupswitch=* "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1736
        "ireturn lreturn freturn dreturn areturn return "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1737
        "getstatic=bkf$Q putstatic=bkf$Q$ getfield=bkf$L$Q "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1738
        "putfield=bkf$LQ$ invokevirtual=bkm$LQ$Q "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1739
        "invokespecial=bkm$LQ$Q invokestatic=bkm$Q$Q "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1740
        "invokeinterface=bkixx$LQ$Q invokedynamic=bkd__$Q$Q new=bkc$L "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1741
        "newarray=bx$I$L anewarray=bkc$I$L arraylength$L$I athrow "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1742
        "checkcast=bkc$L$L instanceof=bkc$L$I monitorenter$L "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1743
        "monitorexit$L wide=* multianewarray=bkcx ifnull=boo "+
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1744
        "ifnonnull=boo goto_w=boooo jsr_w=boooo ";
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1745
    private static final String[] INSTRUCTION_NAMES;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1746
    private static final String[] INSTRUCTION_POPS;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1747
    private static final int[] INSTRUCTION_INFO;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1748
    static {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1749
        String[] insns = INSTRUCTION_FORMATS.split(" ");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1750
        assert(insns[opc_lookupswitch].startsWith("lookupswitch"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1751
        assert(insns[opc_tableswitch].startsWith("tableswitch"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1752
        assert(insns[opc_wide].startsWith("wide"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1753
        assert(insns[opc_invokedynamic].startsWith("invokedynamic"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1754
        int[] info = new int[256];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1755
        String[] names = new String[256];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1756
        String[] pops = new String[256];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1757
        for (int i = 0; i < insns.length; i++) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1758
            String insn = insns[i];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1759
            int dl = insn.indexOf('$');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1760
            if (dl > 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1761
                String p = insn.substring(dl+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1762
                if (p.indexOf('$') < 0)  p = "$" + p;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1763
                pops[i] = p;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1764
                insn = insn.substring(0, dl);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1765
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1766
            int eq = insn.indexOf('=');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1767
            if (eq < 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1768
                info[i] = 1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1769
                names[i] = insn;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1770
                continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1771
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1772
            names[i] = insn.substring(0, eq);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1773
            String fmt = insn.substring(eq+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1774
            if (fmt.equals("*")) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1775
                info[i] = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1776
                continue;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1777
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1778
            int sl = fmt.indexOf('/');
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1779
            if (sl < 0) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1780
                info[i] = (char) fmt.length();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1781
            } else {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1782
                String wfmt = fmt.substring(sl+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1783
                fmt = fmt.substring(0, sl);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1784
                info[i] = (char)( fmt.length() + (wfmt.length() * 16) );
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1785
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1786
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1787
        INSTRUCTION_INFO = info;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1788
        INSTRUCTION_NAMES = names;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1789
        INSTRUCTION_POPS = pops;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1790
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1791
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1792
    public static class Instruction implements Cloneable {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1793
        byte[] codeBase;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1794
        int pc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1795
        int bc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1796
        int info;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1797
        int wide;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1798
        int len;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1799
        Instruction(byte[] codeBase, int pc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1800
            this.codeBase = codeBase;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1801
            init(pc);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1802
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1803
        public Instruction clone() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1804
            try {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1805
                return (Instruction) super.clone();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1806
            } catch (CloneNotSupportedException ex) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1807
                throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1808
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1809
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1810
        private Instruction init(int pc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1811
            this.pc = pc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1812
            this.bc = codeBase[pc] & 0xFF;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1813
            this.info = INSTRUCTION_INFO[bc];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1814
            this.wide = 0;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1815
            this.len = (info & 0x0F);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1816
            if (len == 0)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1817
                computeLength();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1818
            return this;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1819
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1820
        Instruction next() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1821
            if (len == 0 && bc != 0)  throw new InternalError();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1822
            int npc = pc + len;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1823
            if (npc == codeBase.length)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1824
                return null;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1825
            return init(npc);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1826
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1827
        void forceNext(int newLen) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1828
            bc = opc_nop;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1829
            len = newLen;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1830
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1831
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1832
        public String toString() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1833
            StringBuilder buf = new StringBuilder();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1834
            buf.append(pc).append(":").append(INSTRUCTION_NAMES[bc]);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1835
            switch (len) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1836
            case 3: buf.append(" ").append(u2At(1)); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1837
            case 5: buf.append(" ").append(u2At(1)).append(" ").append(u2At(3)); break;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1838
            default:  for (int i = 1; i < len; i++)  buf.append(" ").append(u1At(1));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1839
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1840
            return buf.toString();
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1841
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1842
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1843
        // these are the hard parts
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1844
        private void computeLength() {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1845
            int cases;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1846
            switch (bc) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1847
            case opc_wide:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1848
                bc = codeBase[pc + 1];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1849
                info = INSTRUCTION_INFO[bc];
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1850
                len = ((info >> 4) & 0x0F);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1851
                if (len == 0)  throw new RuntimeException("misplaced wide bytecode: "+bc);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1852
                return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1853
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1854
            case opc_tableswitch:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1855
                cases = (u4At(alignedIntOffset(2)) - u4At(alignedIntOffset(1)) + 1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1856
                len = alignedIntOffset(3 + cases*1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1857
                return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1858
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1859
            case opc_lookupswitch:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1860
                cases = u4At(alignedIntOffset(1));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1861
                len = alignedIntOffset(2 + cases*2);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1862
                return;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1863
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1864
            default:
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1865
                throw new RuntimeException("unknown bytecode: "+bc);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1866
            }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1867
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1868
        // switch code
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1869
        // clget the Nth int (where 0 is the first after the opcode itself)
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1870
        public int alignedIntOffset(int n) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1871
            int pos = pc + 1;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1872
            pos += ((-pos) & 0x03);  // align it
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1873
            pos += (n * 4);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1874
            return pos - pc;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1875
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1876
        public int u1At(int pos) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1877
            return (codeBase[pc+pos] & 0xFF);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1878
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1879
        public int u2At(int pos) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1880
            return (u1At(pos+0)<<8) + u1At(pos+1);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1881
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1882
        public int u4At(int pos) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1883
            return (u2At(pos+0)<<16) + u2At(pos+2);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1884
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1885
        public void u1AtPut(int pos, int x) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1886
            codeBase[pc+pos] = (byte)x;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1887
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1888
        public void u2AtPut(int pos, int x) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1889
            codeBase[pc+pos+0] = (byte)(x >> 8);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1890
            codeBase[pc+pos+1] = (byte)(x >> 0);
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1891
        }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1892
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1893
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1894
    static String simplifyType(String type) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1895
        String simpleType = OBJ_SIGNATURE.matcher(type).replaceAll("L");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1896
        assert(simpleType.matches("^\\([A-Z]*\\)[A-Z]$"));
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1897
        // change (DD)D to (D_D_)D_
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1898
        simpleType = WIDE_SIGNATURE.matcher(simpleType).replaceAll("\\0_");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1899
        return simpleType;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1900
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1901
    static int argsize(String type) {
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1902
        return simplifyType(type).length()-3;
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1903
    }
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1904
    private static final Pattern OBJ_SIGNATURE = Pattern.compile("\\[*L[^;]*;|\\[+[A-Z]");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1905
    private static final Pattern WIDE_SIGNATURE = Pattern.compile("[JD]");
e7a391a3bcfe 7001423: JSR 292 bytecode enhancements need unit tests
jrose
parents:
diff changeset
  1906
}