1 /* 2 * Copyright (c) 1996, 2017, 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 package org.openjdk.asmtools.jdis; 24 25 import org.openjdk.asmtools.jasm.RuntimeConstants; 26 import static org.openjdk.asmtools.jasm.Tables.*; 27 import static org.openjdk.asmtools.jasm.OpcodeTables.*; 28 import org.openjdk.asmtools.jasm.Tables; 29 import java.io.IOException; 30 import java.io.PrintWriter; 31 import java.util.ArrayList; 32 33 /** 34 * instruction attributes 35 */ 36 class iAtt { 37 38 /*-------------------------------------------------------- */ 39 /* iAtt Fields */ 40 private Options options; 41 42 short lnum = 0; 43 boolean referred = false; // from some other instruction 44 ArrayList<CodeData.LocVarData> vars; 45 ArrayList<CodeData.LocVarData> endvars; 46 ArrayList<TrapData> handlers; 47 ArrayList<TrapData> traps; 48 ArrayList<TrapData> endtraps; 49 StackMapData stackMapEntry; 50 CodeData code; 51 ClassData cls; 52 PrintWriter out; // =cls.out; 53 /*-------------------------------------------------------- */ 54 55 public iAtt(CodeData code) { 56 this.code = code; 57 this.cls = code.meth.cls; 58 out = cls.out; 59 options = cls.options; 60 } 61 62 void add_var(CodeData.LocVarData var) { 63 if (vars == null) { 64 vars = new ArrayList<>(4); 65 } 66 vars.add(var); 67 } 68 69 void add_endvar(CodeData.LocVarData endvar) { 70 if (endvars == null) { 71 endvars = new ArrayList<>(4); 72 } 73 endvars.add(endvar); 74 } 75 76 void add_trap(TrapData trap) { 77 if (traps == null) { 78 traps = new ArrayList<>(4); 79 } 80 traps.add(trap); 81 } 82 83 void add_endtrap(TrapData endtrap) { 84 if (endtraps == null) { 85 endtraps = new ArrayList<>(4); 86 } 87 endtraps.add(endtrap); 88 } 89 90 void add_handler(TrapData endtrap) { 91 if (handlers == null) { 92 handlers = new ArrayList<>(4); 93 } 94 handlers.add(endtrap); 95 } 96 97 public void printEnds() throws IOException { 98 // prints additional information for instruction: 99 // end of local variable and trap scopes; 100 int len; 101 if ((endvars != null) && (options.contains(Options.PR.VAR))) { 102 len = endvars.size() - 1; 103 out.print("\t\tendvar"); 104 for (CodeData.LocVarData line : endvars) { 105 out.print(" " + line.slot); 106 if (len-- > 0) { 107 out.print(","); 108 } 109 } 110 out.println(";"); 111 } 112 113 if (endtraps != null) { 114 len = endtraps.size() - 1; 115 out.print("\t\tendtry"); 116 for (TrapData line : endtraps) { 117 out.print(" " + line.ident()); 118 if (len-- > 0) { 119 out.print(","); 120 } 121 } 122 out.println(";"); 123 } 124 } 125 126 public void printBegins() 127 throws IOException { 128 // prints additional information for instruction: 129 // source line number; 130 // start of exception handler; 131 // begin of locvar and trap scopes; 132 boolean eitherOpt = options.contains(Options.PR.LNT) || options.contains(Options.PR.SRC); 133 boolean bothOpt = options.contains(Options.PR.LNT) && options.contains(Options.PR.SRC); 134 int k; 135 136 if ((lnum != 0) && eitherOpt) { 137 if (bothOpt) { 138 out.println("// " + lnum + ": " + cls.getSrcLine(lnum)); 139 } else if (options.contains(Options.PR.LNT)) { 140 out.print(lnum); 141 } else if (options.contains(Options.PR.SRC)) { 142 out.println("// " + cls.getSrcLine(lnum)); 143 } 144 } 145 out.print("\t"); 146 if (handlers != null) { 147 for (TrapData line : handlers) { 148 out.print("\tcatch " + line.ident()); 149 out.print(" " + cls.pool.getClassName(line.catch_cpx) + ";\n\t"); 150 } 151 } 152 if (traps != null) { 153 int len = traps.size() - 1; 154 out.print("\ttry"); 155 for (TrapData line : traps) { 156 out.print(" " + line.ident()); 157 if (len-- > 0) { 158 out.print(","); 159 } 160 } 161 out.print(";\n\t"); 162 } 163 if ((vars != null) && options.contains(Options.PR.VAR)) { 164 for (CodeData.LocVarData line : vars) { 165 out.println("\tvar " + line.slot + "; // " + cls.pool.getName(line.name_cpx) + ":" + cls.pool.getName(line.sig_cpx)); 166 out.print("\t"); 167 } 168 } 169 } 170 171 public void printMapList(int[] map) throws IOException { 172 boolean pr_cpx = options.contains(Options.PR.CPX); 173 174 for (int k = 0; k < map.length; k++) { 175 int fullmaptype = map[k]; 176 int mt_val = fullmaptype & 0xFF; 177 StackMapType maptype = stackMapType(mt_val, out); 178 int argument = fullmaptype >> 8; 179 switch (maptype) { 180 case ITEM_Object: 181 if (pr_cpx) { 182 out.print(" #" + argument); 183 } else { 184 out.print(" "); 185 cls.pool.PrintConstant(out, argument); 186 } 187 break; 188 case ITEM_NewObject: 189 if (pr_cpx) { 190 out.print(" " + mt_val); 191 } else { 192 out.print(" " + maptype.printval()); 193 } 194 out.print(" " + code.meth.lP + argument); 195 break; 196 default: 197 if (pr_cpx) { 198 out.print(" " + mt_val); 199 } else { 200 out.print(" " + maptype.printval()); 201 } 202 } 203 out.print((k == (map.length - 1) ? ';' : ',')); 204 } 205 } 206 207 public void printStackMap() throws IOException { 208 if (stackMapEntry == null) { 209 return; 210 } 211 boolean printed = false; 212 if (stackMapEntry.stackFrameType != null) { 213 out.print(Opcode.opc_stack_frame_type.parsekey()); // opcNamesTab[opc_stackframetype]); 214 out.print(" " + stackMapEntry.stackFrameType.parsekey() + ';'); 215 out.print("\n\t\t"); 216 printed = true; 217 } 218 int[] map = stackMapEntry.lockMap; 219 if ((map != null) && (map.length > 0)) { 220 out.print(Opcode.opc_locals_map.parsekey()); 221 printMapList(map); 222 out.print("\n\t\t"); 223 printed = true; 224 } 225 map = stackMapEntry.stackMap; 226 if ((map != null) && (map.length > 0)) { 227 out.print(Opcode.opc_stack_map.parsekey()); 228 printMapList(map); 229 out.print("\n\t\t"); 230 printed = true; 231 } 232 if (!printed) { 233 // empty attribute should be printed anyway - it should not 234 // be eliminated after jdis/jasm cycle 235 out.print(Opcode.opc_locals_map.parsekey() + " ;\n\t\t"); 236 } 237 } 238 }