test/tools/javac/lambdaShapes/org/openjdk/tests/separate/ClassFile.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1448
7d34e91f66bb
parent 0
959103a6100f
permissions
-rw-r--r--

merge

     1 /*
     2  * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     8  * particular file as subject to the "Classpath" exception as provided
     9  * by Oracle in the LICENSE file that accompanied this code.
    10  *
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    14  * version 2 for more details (a copy is included in the LICENSE file that
    15  * accompanied this code).
    16  *
    17  * You should have received a copy of the GNU General Public License version
    18  * 2 along with this work; if not, write to the Free Software Foundation,
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    20  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    22  * or visit www.oracle.com if you need additional information or have any
    23  * questions.
    24  */
    26 package org.openjdk.tests.separate;
    28 import java.io.*;
    29 import java.util.*;
    31 class CfInputStream extends ByteArrayInputStream {
    32     private int ct;
    33     public CfInputStream(byte[] input) {
    34         super(input);
    35     }
    37     byte u1() { return (byte)read(); }
    38     short u2() {
    39         int b0 = read() << 8;
    40         int b1 = read();
    41         return (short)(b0 | b1);
    42     }
    43     int u4() {
    44         int b0 = read() << 24;
    45         int b1 = read() << 16;
    46         int b2 = read() << 8;
    47         int b3 = read();
    48         return b0 | b1 | b2 | b3;
    49     }
    50     byte[] array(int count) {
    51         byte[] ret = new byte[count];
    52         read(ret, 0, count);
    53         return ret;
    54     }
    55 };
    57 class CfOutputStream extends ByteArrayOutputStream {
    58     void u1(byte b) { write((int)b); }
    59     void u2(short s) {
    60         write((s >> 8) & 0xff);
    61         write(s & 0xff);
    62     }
    63     void u4(int i) {
    64         write((i >> 24) & 0xff);
    65         write((i >> 16) & 0xff);
    66         write((i >> 8) & 0xff);
    67         write(i & 0xff);
    68     }
    69     void array(byte[] a) {
    70         write(a, 0, a.length);
    71     }
    73     public byte[] toByteArray() { return super.toByteArray(); }
    74 };
    76 // A quick and dirty class file parser and representation
    77 public class ClassFile {
    79     int magic;
    80     short minor_version;
    81     short major_version;
    82     ArrayList<CpEntry> constant_pool;
    83     short access_flags;
    84     short this_class;
    85     short super_class;
    86     ArrayList<Interface> interfaces;
    87     ArrayList<Field> fields;
    88     ArrayList<Method> methods;
    89     ArrayList<Attribute> attributes;
    91     ClassFile(byte[] cf) {
    92         CfInputStream in = new CfInputStream(cf);
    94         magic = in.u4();
    95         minor_version = in.u2();
    96         major_version = in.u2();
    98         short cpCount = in.u2();
    99         constant_pool = new ArrayList<>();
   100         constant_pool.add(new CpNull());
   101         for (int i = 1; i < cpCount; ++i) {
   102             constant_pool.add(CpEntry.newCpEntry(in));
   103         }
   105         access_flags = in.u2();
   106         this_class = in.u2();
   107         super_class = in.u2();
   109         short ifaceCount = in.u2();
   110         interfaces = new ArrayList<>();
   111         for (int i = 0; i < ifaceCount; ++i) {
   112             interfaces.add(new Interface(in));
   113         }
   115         short fieldCount = in.u2();
   116         fields = new ArrayList<>();
   117         for (int i = 0; i < fieldCount; ++i) {
   118             fields.add(new Field(in));
   119         }
   121         short methodCount = in.u2();
   122         methods = new ArrayList<>();
   123         for (int i = 0; i < methodCount; ++i) {
   124             methods.add(new Method(in));
   125         }
   127         short attributeCount = in.u2();
   128         attributes = new ArrayList<>();
   129         for (int i = 0; i < attributeCount; ++i) {
   130             attributes.add(new Attribute(in));
   131         }
   132     }
   134     byte[] toByteArray() {
   135         CfOutputStream out = new CfOutputStream();
   137         out.u4(magic);
   138         out.u2(minor_version);
   139         out.u2(major_version);
   141         out.u2((short)(constant_pool.size()));
   142         for (CpEntry cp : constant_pool) {
   143             cp.write(out);
   144         }
   146         out.u2(access_flags);
   147         out.u2(this_class);
   148         out.u2(super_class);
   150         out.u2((short)interfaces.size());
   151         for (Interface iface : interfaces) {
   152             iface.write(out);
   153         }
   155         out.u2((short)fields.size());
   156         for (Field field : fields) {
   157             field.write(out);
   158         }
   160         out.u2((short)methods.size());
   161         for (Method method : methods) {
   162             method.write(out);
   163         }
   165         out.u2((short)attributes.size());
   166         for (Attribute attribute : attributes) {
   167             attribute.write(out);
   168         }
   170         return out.toByteArray();
   171     }
   173     static abstract class CpEntry {
   174         byte tag;
   176         CpEntry(byte t) { tag = t; }
   177         void write(CfOutputStream out) {
   178             out.u1(tag);
   179         }
   181         static CpEntry newCpEntry(CfInputStream in) {
   182             byte tag = in.u1();
   183             switch (tag) {
   184                 case CpUtf8.TAG: return new CpUtf8(in);
   185                 case CpInteger.TAG: return new CpInteger(in);
   186                 case CpFloat.TAG: return new CpFloat(in);
   187                 case CpLong.TAG: return new CpLong(in);
   188                 case CpDouble.TAG: return new CpDouble(in);
   189                 case CpClass.TAG: return new CpClass(in);
   190                 case CpString.TAG: return new CpString(in);
   191                 case CpFieldRef.TAG: return new CpFieldRef(in);
   192                 case CpMethodRef.TAG: return new CpMethodRef(in);
   193                 case CpInterfaceMethodRef.TAG:
   194                     return new CpInterfaceMethodRef(in);
   195                 case CpNameAndType.TAG: return new CpNameAndType(in);
   196                 case CpMethodHandle.TAG: return new CpMethodHandle(in);
   197                 case CpMethodType.TAG: return new CpMethodType(in);
   198                 case CpInvokeDynamic.TAG: return new CpInvokeDynamic(in);
   199                 default: throw new RuntimeException("Bad cp entry tag: " + tag);
   200             }
   201         }
   202     }
   204     static class CpNull extends CpEntry {
   205         CpNull() { super((byte)0); }
   206         CpNull(CfInputStream in) { super((byte)0); }
   207         void write(CfOutputStream out) {}
   208     }
   210     static class CpUtf8 extends CpEntry {
   211         static final byte TAG = 1;
   212         byte[] bytes;
   214         CpUtf8() { super(TAG); }
   215         CpUtf8(CfInputStream in) {
   216             this();
   217             short length = in.u2();
   218             bytes = in.array(length);
   219         }
   220         void write(CfOutputStream out) {
   221             super.write(out);
   222             out.u2((short)bytes.length);
   223             out.array(bytes);
   224         }
   225     }
   227     static class CpU4Constant extends CpEntry {
   228         byte[] bytes;
   230         CpU4Constant(byte tag) { super(tag); }
   231         CpU4Constant(byte tag, CfInputStream in) {
   232             this(tag);
   233             bytes = in.array(4);
   234         }
   235         void write(CfOutputStream out) { super.write(out); out.array(bytes); }
   236     }
   237     static class CpInteger extends CpU4Constant {
   238         static final byte TAG = 3;
   239         CpInteger() { super(TAG); }
   240         CpInteger(CfInputStream in) { super(TAG, in); }
   241     }
   242     static class CpFloat extends CpU4Constant {
   243         static final byte TAG = 4;
   244         CpFloat() { super(TAG); }
   245         CpFloat(CfInputStream in) { super(TAG, in); }
   246     }
   248     static class CpU8Constant extends CpEntry {
   249         byte[] bytes;
   251         CpU8Constant(byte tag) { super(tag); }
   252         CpU8Constant(byte tag, CfInputStream in) {
   253             this(tag);
   254             bytes = in.array(8);
   255         }
   256         void write(CfOutputStream out) { super.write(out); out.array(bytes); }
   257     }
   258     static class CpLong extends CpU8Constant {
   259         static final byte TAG = 5;
   260         CpLong() { super(TAG); }
   261         CpLong(CfInputStream in) { super(TAG, in); }
   262     }
   263     static class CpDouble extends CpU8Constant {
   264         static final byte TAG = 6;
   265         CpDouble() { super(TAG); }
   266         CpDouble(CfInputStream in) { super(TAG, in); }
   267     }
   269     static class CpClass extends CpEntry {
   270         static final byte TAG = 7;
   271         short name_index;
   273         CpClass() { super(TAG); }
   274         CpClass(CfInputStream in) { super(TAG); name_index = in.u2(); }
   275         void write(CfOutputStream out) {
   276             super.write(out);
   277             out.u2(name_index);
   278         }
   279     }
   281     static class CpString extends CpEntry {
   282         static final byte TAG = 8;
   283         short string_index;
   285         CpString() { super(TAG); }
   286         CpString(CfInputStream in) { super(TAG); string_index = in.u2(); }
   287         void write(CfOutputStream out) {
   288             super.write(out);
   289             out.u2(string_index);
   290         }
   291     }
   293     static class CpRef extends CpEntry {
   294         short class_index;
   295         short name_and_type_index;
   297         CpRef(byte tag) { super(tag); }
   298         CpRef(byte tag, CfInputStream in) {
   299             this(tag);
   300             class_index = in.u2();
   301             name_and_type_index = in.u2();
   302         }
   303         void write(CfOutputStream out) {
   304             super.write(out);
   305             out.u2(class_index);
   306             out.u2(name_and_type_index);
   307         }
   308     }
   309     static class CpFieldRef extends CpRef {
   310         static final byte TAG = 9;
   311         CpFieldRef() { super(TAG); }
   312         CpFieldRef(CfInputStream in) { super(TAG, in); }
   313     }
   314     static class CpMethodRef extends CpRef {
   315         static final byte TAG = 10;
   316         CpMethodRef() { super(TAG); }
   317         CpMethodRef(CfInputStream in) { super(TAG, in); }
   318     }
   319     static class CpInterfaceMethodRef extends CpRef {
   320         static final byte TAG = 11;
   321         CpInterfaceMethodRef() { super(TAG); }
   322         CpInterfaceMethodRef(CfInputStream in) { super(TAG, in); }
   323     }
   325     static class CpNameAndType extends CpEntry {
   326         static final byte TAG = 12;
   327         short name_index;
   328         short descriptor_index;
   330         CpNameAndType() { super(TAG); }
   331         CpNameAndType(CfInputStream in) {
   332             this();
   333             name_index = in.u2();
   334             descriptor_index = in.u2();
   335         }
   336         void write(CfOutputStream out) {
   337             super.write(out);
   338             out.u2(name_index);
   339             out.u2(descriptor_index);
   340         }
   341     }
   343     static class CpMethodHandle extends CpEntry {
   344         static final byte TAG = 15;
   345         byte reference_kind;
   346         short reference_index;
   348         CpMethodHandle() { super(TAG); }
   349         CpMethodHandle(CfInputStream in) {
   350             this();
   351             reference_kind = in.u1();
   352             reference_index = in.u2();
   353         }
   354         void write(CfOutputStream out) {
   355             super.write(out);
   356             out.u1(reference_kind);
   357             out.u2(reference_index);
   358         }
   359     }
   361     static class CpMethodType extends CpEntry {
   362         static final byte TAG = 16;
   363         short descriptor_index;
   365         CpMethodType() { super(TAG); }
   366         CpMethodType(CfInputStream in) {
   367             this();
   368             descriptor_index = in.u2();
   369         }
   370         void write(CfOutputStream out) {
   371             super.write(out);
   372             out.u2(descriptor_index);
   373         }
   374     }
   376     static class CpInvokeDynamic extends CpEntry {
   377         static final byte TAG = 18;
   378         short bootstrap_index;
   379         short name_and_type_index;
   381         CpInvokeDynamic() { super(TAG); }
   382         CpInvokeDynamic(CfInputStream in) {
   383             this();
   384             bootstrap_index = in.u2();
   385             name_and_type_index = in.u2();
   386         }
   387         void write(CfOutputStream out) {
   388             super.write(out);
   389             out.u2(bootstrap_index);
   390             out.u2(name_and_type_index);
   391         }
   392     }
   394     static class Interface {
   395         short index;
   397         Interface() {}
   398         Interface(CfInputStream in) { index = in.u2(); }
   399         void write(CfOutputStream out) { out.u2(index); }
   400     }
   402     static class FieldOrMethod {
   403         short access_flags;
   404         short name_index;
   405         short descriptor_index;
   406         ArrayList<Attribute> attributes;
   408         FieldOrMethod() { attributes = new ArrayList<>(); }
   409         FieldOrMethod(CfInputStream in) {
   410             access_flags = in.u2();
   411             name_index = in.u2();
   412             descriptor_index = in.u2();
   414             short attrCount = in.u2();
   415             attributes = new ArrayList<>();
   416             for (int i = 0; i < attrCount; ++i) {
   417                 attributes.add(new Attribute(in));
   418             }
   419         }
   420         void write(CfOutputStream out) {
   421             out.u2(access_flags);
   422             out.u2(name_index);
   423             out.u2(descriptor_index);
   424             out.u2((short)attributes.size());
   425             for (Attribute attribute : attributes) { attribute.write(out); }
   426         }
   427     }
   429     static class Field extends FieldOrMethod {
   430         Field() {}
   431         Field(CfInputStream in) { super(in); }
   432     }
   433     static class Method extends FieldOrMethod {
   434         Method() {}
   435         Method(CfInputStream in) { super(in); }
   436     }
   438     static class Attribute {
   439         short attribute_name_index;
   440         byte[] info;
   442         Attribute() { info = new byte[0]; }
   443         Attribute(CfInputStream in) {
   444             attribute_name_index = in.u2();
   445             int length = in.u4();
   446             info = in.array(length);
   447         }
   448         void write(CfOutputStream out) {
   449             out.u2(attribute_name_index);
   450             out.u4(info.length);
   451             out.array(info);
   452         }
   453     }
   454 }

mercurial