jdk/src/share/classes/sun/dyn/anon/ConstantPoolParser.java
author jrose
Tue, 05 May 2009 22:40:09 -0700
changeset 2707 5a17df307cbc
child 5506 202f599c92aa
permissions -rw-r--r--
6829144: JSR 292 JVM features need a provisional Java API Summary: JDK API and runtime (partial) for anonk, meth, indy Reviewed-by: mr
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2707
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     1
/*
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     2
 * Copyright 2008-2009 Sun Microsystems, Inc.  All Rights Reserved.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     4
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    10
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    15
 * accompanied this code).
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    16
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    20
 *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    23
 * have any questions.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    24
 */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    25
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    26
package sun.dyn.anon;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    27
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    28
import java.io.IOException;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    29
import java.io.OutputStream;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    30
import java.nio.BufferUnderflowException;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    31
import java.nio.ByteBuffer;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    32
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    33
import static sun.dyn.anon.ConstantPoolVisitor.*;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    34
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    35
/** A constant pool parser.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    36
 */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    37
public class ConstantPoolParser {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    38
    final byte[] classFile;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    39
    final byte[] tags;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    40
    final char[] firstHeader;  // maghi, maglo, minor, major, cplen
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    41
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    42
    // these are filled in on first parse:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    43
    int endOffset;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    44
    char[] secondHeader;       // flags, this_class, super_class, intlen
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    45
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    46
    // used to decode UTF8 array
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    47
    private char[] charArray = new char[80];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    48
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    49
    /** Creates a constant pool parser.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    50
     * @param classFile an array of bytes containing a class.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    51
     * @throws InvalidConstantPoolFormatException if the header of the class has errors.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    52
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    53
    public ConstantPoolParser(byte[] classFile) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    54
        this.classFile = classFile;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    55
        this.firstHeader = parseHeader(classFile);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    56
        this.tags = new byte[firstHeader[4]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    57
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    58
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    59
    /** Create a constant pool parser by loading the bytecodes of the
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    60
     *  class taken as argument.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    61
     *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    62
     * @param templateClass the class to parse.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    63
     *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    64
     * @throws IOException raised if an I/O occurs when loading
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    65
     *  the bytecode of the template class.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    66
     * @throws InvalidConstantPoolFormatException if the header of the class has errors.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    67
     *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    68
     * @see #ConstantPoolParser(byte[])
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    69
     * @see AnonymousClassLoader#readClassFile(Class)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    70
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    71
    public ConstantPoolParser(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    72
        this(AnonymousClassLoader.readClassFile(templateClass));
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    73
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    74
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    75
    /** Creates an empty patch to patch the class file
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    76
     *  used by the current parser.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    77
     * @return a new class patch.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    78
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    79
    public ConstantPoolPatch createPatch() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    80
        return new ConstantPoolPatch(this);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    81
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    82
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    83
    /** Report the tag of the indicated CP entry.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    84
     * @param index
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    85
     * @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    86
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    87
    public byte getTag(int index) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    88
        getEndOffset();  // trigger an exception if we haven't parsed yet
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    89
        return tags[index];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    90
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    91
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    92
    /** Report the length of the constant pool. */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    93
    public int getLength() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    94
        return firstHeader[4];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    95
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    96
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    97
    /** Report the offset, within the class file, of the start of the constant pool. */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    98
    public int getStartOffset() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
    99
        return firstHeader.length * 2;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   100
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   101
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   102
    /** Report the offset, within the class file, of the end of the constant pool. */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   103
    public int getEndOffset() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   104
        if (endOffset == 0)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   105
            throw new IllegalStateException("class file has not yet been parsed");
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   106
        return endOffset;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   107
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   108
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   109
    /** Report the CP index of this class's own name. */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   110
    public int getThisClassIndex() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   111
        getEndOffset();   // provoke exception if not yet parsed
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   112
        return secondHeader[1];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   113
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   114
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   115
    /** Report the total size of the class file. */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   116
    public int getTailLength() {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   117
        return classFile.length - getEndOffset();
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   118
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   119
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   120
    /** Write the head (header plus constant pool)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   121
     *  of the class file to the indicated stream.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   122
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   123
    public void writeHead(OutputStream out) throws IOException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   124
        out.write(classFile, 0, getEndOffset());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   125
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   126
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   127
    /** Write the head (header plus constant pool)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   128
     *  of the class file to the indicated stream,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   129
     *  incorporating the non-null entries of the given array
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   130
     *  as patches.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   131
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   132
    void writePatchedHead(OutputStream out, Object[] patchArray) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   133
        // this will be useful to partially emulate the class loader on old JVMs
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   134
        throw new UnsupportedOperationException("Not yet implemented");
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   135
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   136
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   137
    /** Write the tail (everything after the constant pool)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   138
     *  of the class file to the indicated stream.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   139
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   140
    public void writeTail(OutputStream out) throws IOException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   141
        out.write(classFile, getEndOffset(), getTailLength());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   142
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   143
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   144
    private static char[] parseHeader(byte[] classFile) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   145
        char[] result = new char[5];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   146
        ByteBuffer buffer = ByteBuffer.wrap(classFile);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   147
        for (int i = 0; i < result.length; i++)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   148
            result[i] = (char) getUnsignedShort(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   149
        int magic = result[0] << 16 | result[1] << 0;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   150
        if (magic != 0xCAFEBABE)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   151
            throw new InvalidConstantPoolFormatException("invalid magic number "+magic);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   152
        // skip major, minor version
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   153
        int len = result[4];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   154
        if (len < 1)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   155
            throw new InvalidConstantPoolFormatException("constant pool length < 1");
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   156
        return result;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   157
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   158
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   159
    /** Parse the constant pool of the class
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   160
     *  calling a method visit* each time a constant pool entry is parsed.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   161
     *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   162
     *  The order of the calls to visit* is not guaranteed to be the same
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   163
     *  than the order of the constant pool entry in the bytecode array.
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   164
     *
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   165
     * @param visitor
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   166
     * @throws InvalidConstantPoolFormatException
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   167
     */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   168
    public void parse(ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   169
        ByteBuffer buffer = ByteBuffer.wrap(classFile);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   170
        buffer.position(getStartOffset()); //skip header
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   171
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   172
        Object[] values = new Object[getLength()];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   173
        try {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   174
            parseConstantPool(buffer, values, visitor);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   175
        } catch(BufferUnderflowException e) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   176
            throw new InvalidConstantPoolFormatException(e);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   177
        }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   178
        if (endOffset == 0) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   179
            endOffset = buffer.position();
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   180
            secondHeader = new char[4];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   181
            for (int i = 0; i < secondHeader.length; i++) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   182
                secondHeader[i] = (char) getUnsignedShort(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   183
            }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   184
        }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   185
        resolveConstantPool(values, visitor);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   186
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   187
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   188
    private char[] getCharArray(int utfLength) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   189
        if (utfLength <= charArray.length)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   190
            return charArray;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   191
        return charArray = new char[utfLength];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   192
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   193
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   194
    private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   195
        for (int i = 1; i < tags.length; ) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   196
            byte tag = (byte) getUnsignedByte(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   197
            assert(tags[i] == 0 || tags[i] == tag);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   198
            tags[i] = tag;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   199
            switch (tag) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   200
                case CONSTANT_Utf8:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   201
                    int utfLen = getUnsignedShort(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   202
                    String value = getUTF8(buffer, utfLen, getCharArray(utfLen));
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   203
                    visitor.visitUTF8(i, CONSTANT_Utf8, value);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   204
                    tags[i] = tag;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   205
                    values[i++] = value;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   206
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   207
                case CONSTANT_Integer:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   208
                    visitor.visitConstantValue(i, tag, buffer.getInt());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   209
                    i++;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   210
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   211
                case CONSTANT_Float:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   212
                    visitor.visitConstantValue(i, tag, buffer.getFloat());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   213
                    i++;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   214
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   215
                case CONSTANT_Long:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   216
                    visitor.visitConstantValue(i, tag, buffer.getLong());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   217
                    i+=2;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   218
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   219
                case CONSTANT_Double:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   220
                    visitor.visitConstantValue(i, tag, buffer.getDouble());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   221
                    i+=2;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   222
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   223
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   224
                case CONSTANT_Class:    // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   225
                case CONSTANT_String:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   226
                    tags[i] = tag;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   227
                    values[i++] = new int[] { getUnsignedShort(buffer) };
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   228
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   229
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   230
                case CONSTANT_Fieldref:           // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   231
                case CONSTANT_Methodref:          // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   232
                case CONSTANT_InterfaceMethodref: // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   233
                case CONSTANT_NameAndType:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   234
                    tags[i] = tag;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   235
                    values[i++] = new int[] { getUnsignedShort(buffer), getUnsignedShort(buffer) };
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   236
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   237
                default:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   238
                    throw new AssertionError("invalid constant "+tag);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   239
            }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   240
        }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   241
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   242
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   243
    private void resolveConstantPool(Object[] values, ConstantPoolVisitor visitor) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   244
        // clean out the int[] values, which are temporary
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   245
        for (int beg = 1, end = values.length-1, beg2, end2;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   246
             beg <= end;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   247
             beg = beg2, end = end2) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   248
             beg2 = end; end2 = beg-1;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   249
             //System.out.println("CP resolve pass: "+beg+".."+end);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   250
             for (int i = beg; i <= end; i++) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   251
                  Object value = values[i];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   252
                  if (!(value instanceof int[]))
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   253
                      continue;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   254
                  int[] array = (int[]) value;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   255
                  byte tag = tags[i];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   256
                  switch (tag) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   257
                      case CONSTANT_String:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   258
                          String stringBody = (String) values[array[0]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   259
                          visitor.visitConstantString(i, tag, stringBody, array[0]);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   260
                          values[i] = null;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   261
                          break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   262
                      case CONSTANT_Class: {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   263
                          String className = (String) values[array[0]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   264
                          // use the external form favored by Class.forName:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   265
                          className = className.replace('/', '.');
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   266
                          visitor.visitConstantString(i, tag, className, array[0]);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   267
                          values[i] = className;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   268
                          break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   269
                      }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   270
                      case CONSTANT_NameAndType: {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   271
                          String memberName = (String) values[array[0]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   272
                          String signature  = (String) values[array[1]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   273
                          visitor.visitDescriptor(i, tag, memberName, signature,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   274
                                                  array[0], array[1]);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   275
                          values[i] = new String[] {memberName, signature};
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   276
                          break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   277
                      }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   278
                      case CONSTANT_Fieldref:           // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   279
                      case CONSTANT_Methodref:          // fall through:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   280
                      case CONSTANT_InterfaceMethodref: {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   281
                              Object className   = values[array[0]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   282
                              Object nameAndType = values[array[1]];
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   283
                              if (!(className instanceof String) ||
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   284
                                  !(nameAndType instanceof String[])) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   285
                                   // one more pass is needed
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   286
                                   if (beg2 > i)  beg2 = i;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   287
                                   if (end2 < i)  end2 = i;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   288
                                   continue;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   289
                              }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   290
                              String[] nameAndTypeArray = (String[]) nameAndType;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   291
                              visitor.visitMemberRef(i, tag,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   292
                                  (String)className,
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   293
                                  nameAndTypeArray[0],
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   294
                                  nameAndTypeArray[1],
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   295
                                  array[0], array[1]);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   296
                              values[i] = null;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   297
                          }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   298
                          break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   299
                      default:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   300
                          continue;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   301
                }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   302
            }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   303
        }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   304
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   305
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   306
    private static int getUnsignedByte(ByteBuffer buffer) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   307
        return buffer.get() & 0xFF;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   308
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   309
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   310
    private static int getUnsignedShort(ByteBuffer buffer) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   311
        int b1 = getUnsignedByte(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   312
        int b2 = getUnsignedByte(buffer);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   313
        return (b1 << 8) + (b2 << 0);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   314
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   315
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   316
    private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   317
      int utfLimit = buffer.position() + utfLen;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   318
      int index = 0;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   319
      while (buffer.position() < utfLimit) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   320
          int c = buffer.get() & 0xff;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   321
          if (c > 127) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   322
              buffer.position(buffer.position() - 1);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   323
              return getUTF8Extended(buffer, utfLimit, charArray, index);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   324
          }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   325
          charArray[index++] = (char)c;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   326
      }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   327
      return new String(charArray, 0, index);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   328
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   329
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   330
    private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   331
        int c, c2, c3;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   332
        while (buffer.position() < utfLimit) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   333
            c = buffer.get() & 0xff;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   334
            switch (c >> 4) {
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   335
                case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   336
                    /* 0xxxxxxx*/
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   337
                    charArray[index++] = (char)c;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   338
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   339
                case 12: case 13:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   340
                    /* 110x xxxx   10xx xxxx*/
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   341
                    c2 = buffer.get();
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   342
                    if ((c2 & 0xC0) != 0x80)
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   343
                        throw new InvalidConstantPoolFormatException(
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   344
                            "malformed input around byte " + buffer.position());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   345
                     charArray[index++] = (char)(((c  & 0x1F) << 6) |
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   346
                                                  (c2 & 0x3F));
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   347
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   348
                case 14:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   349
                    /* 1110 xxxx  10xx xxxx  10xx xxxx */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   350
                    c2 = buffer.get();
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   351
                    c3 = buffer.get();
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   352
                    if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   353
                       throw new InvalidConstantPoolFormatException(
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   354
                          "malformed input around byte " + (buffer.position()));
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   355
                    charArray[index++] = (char)(((c  & 0x0F) << 12) |
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   356
                                                ((c2 & 0x3F) << 6)  |
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   357
                                                ((c3 & 0x3F) << 0));
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   358
                    break;
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   359
                default:
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   360
                    /* 10xx xxxx,  1111 xxxx */
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   361
                    throw new InvalidConstantPoolFormatException(
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   362
                        "malformed input around byte " + buffer.position());
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   363
            }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   364
        }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   365
        // The number of chars produced may be less than utflen
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   366
        return new String(charArray, 0, index);
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   367
    }
5a17df307cbc 6829144: JSR 292 JVM features need a provisional Java API
jrose
parents:
diff changeset
   368
}