239 lines
7.8 KiB
Java
239 lines
7.8 KiB
Java
/*
|
|
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
package org.openjdk.asmtools.jdis;
|
|
|
|
import org.openjdk.asmtools.jasm.RuntimeConstants;
|
|
import static org.openjdk.asmtools.jasm.Tables.*;
|
|
import static org.openjdk.asmtools.jasm.OpcodeTables.*;
|
|
import org.openjdk.asmtools.jasm.Tables;
|
|
import java.io.IOException;
|
|
import java.io.PrintWriter;
|
|
import java.util.ArrayList;
|
|
|
|
/**
|
|
* instruction attributes
|
|
*/
|
|
class iAtt {
|
|
|
|
/*-------------------------------------------------------- */
|
|
/* iAtt Fields */
|
|
private Options options;
|
|
|
|
short lnum = 0;
|
|
boolean referred = false; // from some other instruction
|
|
ArrayList<CodeData.LocVarData> vars;
|
|
ArrayList<CodeData.LocVarData> endvars;
|
|
ArrayList<TrapData> handlers;
|
|
ArrayList<TrapData> traps;
|
|
ArrayList<TrapData> endtraps;
|
|
StackMapData stackMapEntry;
|
|
CodeData code;
|
|
ClassData cls;
|
|
PrintWriter out; // =cls.out;
|
|
/*-------------------------------------------------------- */
|
|
|
|
public iAtt(CodeData code) {
|
|
this.code = code;
|
|
this.cls = code.meth.cls;
|
|
out = cls.out;
|
|
options = cls.options;
|
|
}
|
|
|
|
void add_var(CodeData.LocVarData var) {
|
|
if (vars == null) {
|
|
vars = new ArrayList<>(4);
|
|
}
|
|
vars.add(var);
|
|
}
|
|
|
|
void add_endvar(CodeData.LocVarData endvar) {
|
|
if (endvars == null) {
|
|
endvars = new ArrayList<>(4);
|
|
}
|
|
endvars.add(endvar);
|
|
}
|
|
|
|
void add_trap(TrapData trap) {
|
|
if (traps == null) {
|
|
traps = new ArrayList<>(4);
|
|
}
|
|
traps.add(trap);
|
|
}
|
|
|
|
void add_endtrap(TrapData endtrap) {
|
|
if (endtraps == null) {
|
|
endtraps = new ArrayList<>(4);
|
|
}
|
|
endtraps.add(endtrap);
|
|
}
|
|
|
|
void add_handler(TrapData endtrap) {
|
|
if (handlers == null) {
|
|
handlers = new ArrayList<>(4);
|
|
}
|
|
handlers.add(endtrap);
|
|
}
|
|
|
|
public void printEnds() throws IOException {
|
|
// prints additional information for instruction:
|
|
// end of local variable and trap scopes;
|
|
int len;
|
|
if ((endvars != null) && (options.contains(Options.PR.VAR))) {
|
|
len = endvars.size() - 1;
|
|
out.print("\t\tendvar");
|
|
for (CodeData.LocVarData line : endvars) {
|
|
out.print(" " + line.slot);
|
|
if (len-- > 0) {
|
|
out.print(",");
|
|
}
|
|
}
|
|
out.println(";");
|
|
}
|
|
|
|
if (endtraps != null) {
|
|
len = endtraps.size() - 1;
|
|
out.print("\t\tendtry");
|
|
for (TrapData line : endtraps) {
|
|
out.print(" " + line.ident());
|
|
if (len-- > 0) {
|
|
out.print(",");
|
|
}
|
|
}
|
|
out.println(";");
|
|
}
|
|
}
|
|
|
|
public void printBegins()
|
|
throws IOException {
|
|
// prints additional information for instruction:
|
|
// source line number;
|
|
// start of exception handler;
|
|
// begin of locvar and trap scopes;
|
|
boolean eitherOpt = options.contains(Options.PR.LNT) || options.contains(Options.PR.SRC);
|
|
boolean bothOpt = options.contains(Options.PR.LNT) && options.contains(Options.PR.SRC);
|
|
int k;
|
|
|
|
if ((lnum != 0) && eitherOpt) {
|
|
if (bothOpt) {
|
|
out.println("// " + lnum + ": " + cls.getSrcLine(lnum));
|
|
} else if (options.contains(Options.PR.LNT)) {
|
|
out.print(lnum);
|
|
} else if (options.contains(Options.PR.SRC)) {
|
|
out.println("// " + cls.getSrcLine(lnum));
|
|
}
|
|
}
|
|
out.print("\t");
|
|
if (handlers != null) {
|
|
for (TrapData line : handlers) {
|
|
out.print("\tcatch " + line.ident());
|
|
out.print(" " + cls.pool.getClassName(line.catch_cpx) + ";\n\t");
|
|
}
|
|
}
|
|
if (traps != null) {
|
|
int len = traps.size() - 1;
|
|
out.print("\ttry");
|
|
for (TrapData line : traps) {
|
|
out.print(" " + line.ident());
|
|
if (len-- > 0) {
|
|
out.print(",");
|
|
}
|
|
}
|
|
out.print(";\n\t");
|
|
}
|
|
if ((vars != null) && options.contains(Options.PR.VAR)) {
|
|
for (CodeData.LocVarData line : vars) {
|
|
out.println("\tvar " + line.slot + "; // " + cls.pool.getName(line.name_cpx) + ":" + cls.pool.getName(line.sig_cpx));
|
|
out.print("\t");
|
|
}
|
|
}
|
|
}
|
|
|
|
public void printMapList(int[] map) throws IOException {
|
|
boolean pr_cpx = options.contains(Options.PR.CPX);
|
|
|
|
for (int k = 0; k < map.length; k++) {
|
|
int fullmaptype = map[k];
|
|
int mt_val = fullmaptype & 0xFF;
|
|
StackMapType maptype = stackMapType(mt_val, out);
|
|
int argument = fullmaptype >> 8;
|
|
switch (maptype) {
|
|
case ITEM_Object:
|
|
if (pr_cpx) {
|
|
out.print(" #" + argument);
|
|
} else {
|
|
out.print(" ");
|
|
cls.pool.PrintConstant(out, argument);
|
|
}
|
|
break;
|
|
case ITEM_NewObject:
|
|
if (pr_cpx) {
|
|
out.print(" " + mt_val);
|
|
} else {
|
|
out.print(" " + maptype.printval());
|
|
}
|
|
out.print(" " + code.meth.lP + argument);
|
|
break;
|
|
default:
|
|
if (pr_cpx) {
|
|
out.print(" " + mt_val);
|
|
} else {
|
|
out.print(" " + maptype.printval());
|
|
}
|
|
}
|
|
out.print((k == (map.length - 1) ? ';' : ','));
|
|
}
|
|
}
|
|
|
|
public void printStackMap() throws IOException {
|
|
if (stackMapEntry == null) {
|
|
return;
|
|
}
|
|
boolean printed = false;
|
|
if (stackMapEntry.stackFrameType != null) {
|
|
out.print(Opcode.opc_stack_frame_type.parsekey()); // opcNamesTab[opc_stackframetype]);
|
|
out.print(" " + stackMapEntry.stackFrameType.parsekey() + ';');
|
|
out.print("\n\t\t");
|
|
printed = true;
|
|
}
|
|
int[] map = stackMapEntry.lockMap;
|
|
if ((map != null) && (map.length > 0)) {
|
|
out.print(Opcode.opc_locals_map.parsekey());
|
|
printMapList(map);
|
|
out.print("\n\t\t");
|
|
printed = true;
|
|
}
|
|
map = stackMapEntry.stackMap;
|
|
if ((map != null) && (map.length > 0)) {
|
|
out.print(Opcode.opc_stack_map.parsekey());
|
|
printMapList(map);
|
|
out.print("\n\t\t");
|
|
printed = true;
|
|
}
|
|
if (!printed) {
|
|
// empty attribute should be printed anyway - it should not
|
|
// be eliminated after jdis/jasm cycle
|
|
out.print(Opcode.opc_locals_map.parsekey() + " ;\n\t\t");
|
|
}
|
|
}
|
|
}
|