--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/instrument/ilib/ClassReaderWriter.java Sat Dec 01 00:00:00 2007 +0000
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2005 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package ilib;
+
+class ClassReaderWriter implements RuntimeConstants {
+
+ int codeAttributeIndex;
+ int lineNumberAttributeIndex;
+ int localVarAttributeIndex;
+
+ private final byte[] orig;
+ private final byte[] gen;
+ private final int sectionLength;
+
+ private static final int GROWTH_FACTOR = 2;
+ private static final int SECTIONS = 2;
+ private static final String codeAttributeName = "Code";
+ private static final String lineNumberAttributeName = "LineNumberTable";
+ private static final String localVarAttributeName = "LocalVariableTable";
+
+ private int[] genSectionPos = new int[SECTIONS];
+
+ private int inputPos = 0;
+ private int genPos = 0;
+ private int markPos = 0;
+ private int currentSection = 0;
+
+ private String[] constantPool;
+
+ ClassReaderWriter(byte[] orig) {
+ this.orig = orig;
+ sectionLength = orig.length * GROWTH_FACTOR;
+ gen = new byte[sectionLength * SECTIONS];
+ for (int section = 0; section < SECTIONS; ++section) {
+ genSectionPos[section] = section * sectionLength;
+ }
+ }
+
+ int setSection(int section) {
+ int prevSection = currentSection;
+ genSectionPos[prevSection] = genPos;
+ genPos = genSectionPos[section];
+ currentSection = section;
+ return prevSection;
+ }
+
+ byte[] result() {
+ int section;
+ int totalLength = 0;
+
+ setSection(0); // save current section
+
+ for (section = 0; section < SECTIONS; ++section) {
+ int sectionStart = section * sectionLength;
+ int sectionGenLength = genSectionPos[section] - sectionStart;
+ totalLength += sectionGenLength;
+ }
+
+ byte[] newcf = new byte[totalLength];
+ int written = 0;
+ for (section = 0; section < SECTIONS; ++section) {
+ int sectionStart = section * sectionLength;
+ int sectionGenLength = genSectionPos[section] - sectionStart;
+ System.arraycopy(gen, sectionStart, newcf, written, sectionGenLength);
+ written += sectionGenLength;
+ }
+
+ return newcf;
+ }
+
+ int readU1() {
+ return ((int)orig[inputPos++]) & 0xFF;
+ }
+
+ int readU2() {
+ int res = readU1();
+ return (res << 8) + readU1();
+ }
+
+ short readS2() {
+ int res = readU1();
+ return (short)((res << 8) + readU1());
+ }
+
+ int readU4() {
+ int res = readU2();
+ return (res << 16) + readU2();
+ }
+
+ void writeU1(int val) {
+ gen[genPos++] = (byte)val;
+ }
+
+ void writeU2(int val) {
+ writeU1(val >> 8);
+ writeU1(val & 0xFF);
+ }
+
+ void writeU4(int val) {
+ writeU2(val >> 16);
+ writeU2(val & 0xFFFF);
+ }
+
+ int copyU1() {
+ int value = readU1();
+ writeU1(value);
+ return value;
+ }
+
+ int copyU2() {
+ int value = readU2();
+ writeU2(value);
+ return value;
+ }
+
+ int copyU4() {
+ int value = readU4();
+ writeU4(value);
+ return value;
+ }
+
+ void copy(int count) {
+ for (int i = 0; i < count; ++i) {
+ gen[genPos++] = orig[inputPos++];
+ }
+ }
+
+ void skip(int count) {
+ inputPos += count;
+ }
+
+ byte[] readBytes(int count) {
+ byte[] bytes = new byte[count];
+ for (int i = 0; i < count; ++i) {
+ bytes[i] = orig[inputPos++];
+ }
+ return bytes;
+ }
+
+ void writeBytes(byte[] bytes) {
+ for (int i = 0; i < bytes.length; ++i) {
+ gen[genPos++] = bytes[i];
+ }
+ }
+
+ byte[] inputBytes() {
+ return orig;
+ }
+
+ int inputPosition() {
+ return inputPos;
+ }
+
+ void setInputPosition(int pos) {
+ inputPos = pos;
+ }
+
+ void markLocalPositionStart() {
+ markPos = inputPos;
+ }
+
+ int localPosition() {
+ return inputPos - markPos;
+ }
+
+ void rewind() {
+ setInputPosition(markPos);
+ }
+
+ int generatedPosition() {
+ return genPos;
+ }
+
+ void randomAccessWriteU2(int pos, int val) {
+ int savePos = genPos;
+ genPos = pos;
+ writeU2(val);
+ genPos = savePos;
+ }
+
+ void randomAccessWriteU4(int pos, int val) {
+ int savePos = genPos;
+ genPos = pos;
+ writeU4(val);
+ genPos = savePos;
+ }
+
+ String constantPoolString(int index) {
+ return constantPool[index];
+ }
+
+ void copyConstantPool(int constantPoolCount){
+ // copy const pool
+ constantPool = new String[constantPoolCount];
+ // index zero not in class file
+ for (int i = 1; i < constantPoolCount; ++i) {
+ int tag = readU1();
+ writeU1(tag);
+ switch (tag) {
+ case CONSTANT_CLASS:
+ case CONSTANT_STRING:
+ copy(2);
+ break;
+ case CONSTANT_FIELD:
+ case CONSTANT_METHOD:
+ case CONSTANT_INTERFACEMETHOD:
+ case CONSTANT_INTEGER:
+ case CONSTANT_FLOAT:
+ case CONSTANT_NAMEANDTYPE:
+ copy(4);
+ break;
+ case CONSTANT_LONG:
+ case CONSTANT_DOUBLE:
+ copy(8);
+ ++i; // these take two CP entries - duh!
+ break;
+ case CONSTANT_UTF8:
+ int len = copyU2();
+ byte[] utf8 = readBytes(len);
+ String str = null; // null to shut the compiler up
+ try {
+ str = new String(utf8, "UTF-8");
+ } catch (Exception exc) {
+ throw new Error("CP exception: " + exc);
+ }
+ constantPool[i] = str;
+ if (str.equals(codeAttributeName)) {
+ codeAttributeIndex = i;
+ } else if (str.equals(lineNumberAttributeName)) {
+ lineNumberAttributeIndex = i;
+ } else if (str.equals(localVarAttributeName)) {
+ localVarAttributeIndex = i;
+ }
+ writeBytes(utf8);
+ break;
+ default:
+ throw new Error(i + " unexpected CP tag: " + tag);
+ }
+ }
+ }
+
+}