/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* An extension of BinaryCode that allows code to be printed.
* Includes printing of disassembled byte codes, exception info,
* local variable and line number info.
*
*/
package ilib;
private final ClassReaderWriter c;
private final int length;
private final int[] map;
private final byte[] widening;
private int pos;
private int newPos;
private class Span {
final int delta;
final int target;
final int newDelta;
final int newTarget;
}
}
/**
* Constructor
*/
this.c = c;
this.methodName = methodName;
for (int i = 0; i <= length; ++i) {
map[i] = i;
}
}
trace("external ");
}
}
}
}
traceln();
}
}
}
}
}
}
}
}
private void traceln() {
}
}
private void trace(int i) {
}
}
/**
* Print an integer so that it takes 'length' characters in
* the output. Temporary until formatting code is stable.
*/
trace(" ");
}
}
traceln();
traceln();
}
c.rewind();
while (c.localPosition() < length) {
}
trace("Searching for adjustments...");
c.rewind();
while (c.localPosition() < length) {
if (!adjustInstruction()) {
c.rewind();
traceln();
traceln("Restarting adjustments after change...");
}
}
// write the new bytecodes
traceln();
traceln();
trace("Writing new code...");
c.rewind();
while (c.localPosition() < length) {
}
throw new Error("not all snippets written");
}
}
/**
* Walk one instruction inserting instrumentation at specified instructions
*/
pos = c.localPosition();
// no support for instrumenting wide instructions
switch (wopcode) {
case opc_aload: case opc_astore:
case opc_fload: case opc_fstore:
case opc_iload: case opc_istore:
case opc_lload: case opc_lstore:
case opc_dload: case opc_dstore:
case opc_ret:
break;
case opc_iinc:
c.readS2();
break;
default:
}
} else {
}
switch (opcode) {
case opc_tableswitch:{
c.readU4();
break;
}
case opc_lookupswitch:{
c.readU4();
break;
}
default: {
}
}
pos = c.localPosition();
}
}
}
/**
* Walk one instruction adjusting for insertions
*/
pos = c.localPosition();
traceln();
trace(" ");
}
}
switch (wopcode) {
case opc_aload: case opc_astore:
case opc_fload: case opc_fstore:
case opc_iload: case opc_istore:
case opc_lload: case opc_lstore:
case opc_dload: case opc_dstore:
case opc_ret:
break;
case opc_iinc:
}
break;
default:
}
} else {
}
switch (opcode) {
case opc_tableswitch:{
traceln("");
trace('\t');
traceFixedWidthInt(i, 5);
}
} else {
}
if (widened != deltaPadding) {
return false; // cause restart
}
break;
}
case opc_lookupswitch:{
for (int i = 0; i< npairs; ++i) {
traceln("");
trace('\t');
}
} else {
}
if (widened != deltaPadding) {
return false; // cause restart
}
break;
}
case opc_if_acmpeq: case opc_if_acmpne:
case opc_ifnull: case opc_ifnonnull: {
switch (opcode) {
break;
default:
break;
}
return false; // cause restart
}
}
}
break;
}
case opc_jsr_w:
case opc_goto_w: {
}
break;
}
default: {
break;
}
}
}
return true; // successful return
}
/**
* Walk one instruction writing the transformed instruction.
*/
pos = c.localPosition();
traceln();
trace(" ... -- Inserting new code");
c.writeBytes(newCode);
}
traceln();
trace(" ");
}
}
switch (wopcode) {
case opc_aload: case opc_astore:
case opc_fload: case opc_fstore:
case opc_iload: case opc_istore:
case opc_lload: case opc_lstore:
case opc_dload: case opc_dstore:
case opc_ret:
break;
case opc_iinc:
}
break;
default:
}
} else {
}
switch (opcode) {
case opc_tableswitch:{
}
}
traceln("");
trace('\t');
traceFixedWidthInt(i, 5);
}
}
break;
}
case opc_lookupswitch:{
}
}
for (int i = 0; i< npairs; ++i) {
traceln("");
trace('\t');
}
}
break;
}
case opc_if_acmpeq: case opc_if_acmpne:
case opc_ifnull: case opc_ifnonnull: {
switch (opcode) {
case opc_jsr:
break;
case opc_goto:
break;
default:
throw new Error("unexpected opcode: " +
opcode);
}
switch (opcode) {
case opc_ifeq:
break;
case opc_ifge:
break;
case opc_ifgt:
break;
case opc_ifle:
break;
case opc_iflt:
break;
case opc_ifne:
break;
case opc_if_icmpeq:
break;
case opc_if_icmpne:
break;
case opc_if_icmpge:
break;
case opc_if_icmpgt:
break;
case opc_if_icmple:
break;
case opc_if_icmplt:
break;
case opc_if_acmpeq:
break;
case opc_if_acmpne:
break;
case opc_ifnull:
break;
case opc_ifnonnull:
break;
default:
throw new Error("unexpected opcode: " +
opcode);
}
} else {
throw new Error("unexpected widening");
}
}
break;
}
case opc_jsr_w:
case opc_goto_w: {
}
break;
}
default: {
}
}
}
}
/**
* Copy the exception table for this method code
*/
if (tableLength > 0) {
traceln();
traceln("Exception table:");
c.writeU2(newStartPC);
c.writeU2(newHandlerPC);
trace(" ");
if (catchType == 0)
traceln("any");
else {
}
}
}
}
}
/**
* Copy the line number table for this method code
*/
// name index already read
if (tableLength > 0) {
traceln();
}
c.writeU2(newStartPC);
int lineNumber = c.copyU2();
": [was] " + startPC +
" [now] " + newStartPC);
}
}
}
}
/**
* Copy the local variable table for this method code
*/
// name index already read
if (tableLength > 0) {
traceln();
}
c.writeU2(newStartPC);
int descriptorIndex = c.copyU2();
trace(" ");
trace(" ");
", slot=" + index);
}
}
}
}
}