jdk/test/java/lang/instrument/ilib/ClassReaderWriter.java
changeset 26233 d391c2eadc8c
parent 26232 ca9aa0749e5d
parent 26229 b1d885c12096
child 26255 af28748e6b2d
equal deleted inserted replaced
26232:ca9aa0749e5d 26233:d391c2eadc8c
     1 /*
       
     2  * Copyright (c) 2005, 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.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 package ilib;
       
    25 
       
    26 class ClassReaderWriter implements RuntimeConstants {
       
    27 
       
    28     int codeAttributeIndex;
       
    29     int lineNumberAttributeIndex;
       
    30     int localVarAttributeIndex;
       
    31 
       
    32     private final byte[] orig;
       
    33     private final byte[] gen;
       
    34     private final int sectionLength;
       
    35 
       
    36     private static final int GROWTH_FACTOR = 2;
       
    37     private static final int SECTIONS = 2;
       
    38     private static final String codeAttributeName = "Code";
       
    39     private static final String lineNumberAttributeName = "LineNumberTable";
       
    40     private static final String localVarAttributeName = "LocalVariableTable";
       
    41 
       
    42     private int[] genSectionPos = new int[SECTIONS];
       
    43 
       
    44     private int inputPos = 0;
       
    45     private int genPos = 0;
       
    46     private int markPos = 0;
       
    47     private int currentSection = 0;
       
    48 
       
    49     private String[] constantPool;
       
    50 
       
    51     ClassReaderWriter(byte[] orig) {
       
    52         this.orig = orig;
       
    53         sectionLength = orig.length * GROWTH_FACTOR;
       
    54         gen = new byte[sectionLength * SECTIONS];
       
    55         for (int section = 0; section < SECTIONS; ++section) {
       
    56             genSectionPos[section] = section * sectionLength;
       
    57         }
       
    58     }
       
    59 
       
    60     int setSection(int section) {
       
    61         int prevSection = currentSection;
       
    62         genSectionPos[prevSection] = genPos;
       
    63         genPos = genSectionPos[section];
       
    64         currentSection = section;
       
    65         return prevSection;
       
    66     }
       
    67 
       
    68     byte[] result() {
       
    69         int section;
       
    70         int totalLength = 0;
       
    71 
       
    72         setSection(0); // save current section
       
    73 
       
    74         for (section = 0; section < SECTIONS; ++section) {
       
    75             int sectionStart = section * sectionLength;
       
    76             int sectionGenLength = genSectionPos[section] - sectionStart;
       
    77             totalLength += sectionGenLength;
       
    78         }
       
    79 
       
    80         byte[] newcf = new byte[totalLength];
       
    81         int written = 0;
       
    82         for (section = 0; section < SECTIONS; ++section) {
       
    83             int sectionStart = section * sectionLength;
       
    84             int sectionGenLength = genSectionPos[section] - sectionStart;
       
    85             System.arraycopy(gen, sectionStart, newcf, written, sectionGenLength);
       
    86             written += sectionGenLength;
       
    87         }
       
    88 
       
    89         return newcf;
       
    90     }
       
    91 
       
    92     int readU1() {
       
    93         return ((int)orig[inputPos++]) & 0xFF;
       
    94     }
       
    95 
       
    96     int readU2() {
       
    97         int res = readU1();
       
    98         return (res << 8) + readU1();
       
    99     }
       
   100 
       
   101     short readS2() {
       
   102         int res = readU1();
       
   103         return (short)((res << 8) + readU1());
       
   104     }
       
   105 
       
   106     int readU4() {
       
   107         int res = readU2();
       
   108         return (res << 16) + readU2();
       
   109     }
       
   110 
       
   111     void writeU1(int val) {
       
   112         gen[genPos++] = (byte)val;
       
   113     }
       
   114 
       
   115     void writeU2(int val) {
       
   116         writeU1(val >> 8);
       
   117         writeU1(val & 0xFF);
       
   118     }
       
   119 
       
   120     void writeU4(int val) {
       
   121         writeU2(val >> 16);
       
   122         writeU2(val & 0xFFFF);
       
   123     }
       
   124 
       
   125     int copyU1() {
       
   126         int value = readU1();
       
   127         writeU1(value);
       
   128         return value;
       
   129     }
       
   130 
       
   131     int copyU2() {
       
   132         int value = readU2();
       
   133         writeU2(value);
       
   134         return value;
       
   135     }
       
   136 
       
   137     int copyU4() {
       
   138         int value = readU4();
       
   139         writeU4(value);
       
   140         return value;
       
   141     }
       
   142 
       
   143     void copy(int count) {
       
   144         for (int i = 0; i < count; ++i) {
       
   145             gen[genPos++] = orig[inputPos++];
       
   146         }
       
   147     }
       
   148 
       
   149     void skip(int count) {
       
   150         inputPos += count;
       
   151     }
       
   152 
       
   153     byte[] readBytes(int count) {
       
   154         byte[] bytes = new byte[count];
       
   155         for (int i = 0; i < count; ++i) {
       
   156             bytes[i] = orig[inputPos++];
       
   157         }
       
   158         return bytes;
       
   159     }
       
   160 
       
   161     void writeBytes(byte[] bytes) {
       
   162         for (int i = 0; i < bytes.length; ++i) {
       
   163             gen[genPos++] = bytes[i];
       
   164         }
       
   165     }
       
   166 
       
   167     byte[] inputBytes() {
       
   168         return orig;
       
   169     }
       
   170 
       
   171     int inputPosition() {
       
   172         return inputPos;
       
   173     }
       
   174 
       
   175     void setInputPosition(int pos) {
       
   176         inputPos = pos;
       
   177     }
       
   178 
       
   179     void markLocalPositionStart() {
       
   180         markPos = inputPos;
       
   181     }
       
   182 
       
   183     int localPosition() {
       
   184         return inputPos - markPos;
       
   185     }
       
   186 
       
   187     void rewind() {
       
   188         setInputPosition(markPos);
       
   189     }
       
   190 
       
   191     int generatedPosition() {
       
   192         return genPos;
       
   193     }
       
   194 
       
   195     void randomAccessWriteU2(int pos, int val) {
       
   196         int savePos = genPos;
       
   197         genPos = pos;
       
   198         writeU2(val);
       
   199         genPos = savePos;
       
   200     }
       
   201 
       
   202     void randomAccessWriteU4(int pos, int val) {
       
   203         int savePos = genPos;
       
   204         genPos = pos;
       
   205         writeU4(val);
       
   206         genPos = savePos;
       
   207     }
       
   208 
       
   209     String constantPoolString(int index) {
       
   210         return constantPool[index];
       
   211     }
       
   212 
       
   213     void copyConstantPool(int constantPoolCount){
       
   214         // copy const pool
       
   215         constantPool = new String[constantPoolCount];
       
   216         // index zero not in class file
       
   217         for (int i = 1; i < constantPoolCount; ++i) {
       
   218             int tag = readU1();
       
   219             writeU1(tag);
       
   220             switch (tag) {
       
   221                 case CONSTANT_CLASS:
       
   222                 case CONSTANT_STRING:
       
   223                     copy(2);
       
   224                     break;
       
   225                 case CONSTANT_FIELD:
       
   226                 case CONSTANT_METHOD:
       
   227                 case CONSTANT_INTERFACEMETHOD:
       
   228                 case CONSTANT_INTEGER:
       
   229                 case CONSTANT_FLOAT:
       
   230                 case CONSTANT_NAMEANDTYPE:
       
   231                     copy(4);
       
   232                     break;
       
   233                 case CONSTANT_LONG:
       
   234                 case CONSTANT_DOUBLE:
       
   235                     copy(8);
       
   236                     ++i;  // these take two CP entries - duh!
       
   237                     break;
       
   238                 case CONSTANT_UTF8:
       
   239                     int len = copyU2();
       
   240                     byte[] utf8 = readBytes(len);
       
   241                     String str = null; // null to shut the compiler up
       
   242                     try {
       
   243                         str = new String(utf8, "UTF-8");
       
   244                     } catch (Exception exc) {
       
   245                         throw new Error("CP exception: " + exc);
       
   246                     }
       
   247                     constantPool[i] = str;
       
   248                     if (str.equals(codeAttributeName)) {
       
   249                         codeAttributeIndex = i;
       
   250                     } else if (str.equals(lineNumberAttributeName)) {
       
   251                         lineNumberAttributeIndex = i;
       
   252                     } else if (str.equals(localVarAttributeName)) {
       
   253                         localVarAttributeIndex = i;
       
   254                     }
       
   255                     writeBytes(utf8);
       
   256                     break;
       
   257                 default:
       
   258                     throw new Error(i + " unexpected CP tag: " + tag);
       
   259             }
       
   260         }
       
   261     }
       
   262 
       
   263 }