1 /* 2 * Copyright (c) 1996, 2014, 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.jasm; 24 25 import java.io.IOException; 26 27 import static org.openjdk.asmtools.jasm.OpcodeTables.*; 28 29 /** 30 * 31 */ 32 class Instr { 33 34 Instr next = null; 35 int pc; 36 int pos; 37 Opcode opc; 38 Argument arg; 39 Object arg2; // second or unusual argument 40 41 public Instr(int pc, int pos, Opcode opc, Argument arg, Object arg2) { 42 this.pc = pc; 43 this.pos = pos; 44 this.opc = opc; 45 this.arg = arg; 46 this.arg2 = arg2; 47 } 48 49 public Instr() { 50 } 51 52 public void write(CheckedDataOutputStream out, Environment env) throws IOException { 53 OpcodeType type = opc.type(); 54 switch (type) { 55 case NORMAL: { 56 if (opc == Opcode.opc_bytecode) { 57 out.writeByte(arg.arg); 58 return; 59 } 60 out.writeByte(opc.value()); 61 int opcLen = opc.length(); 62 if (opcLen == 1) { 63 return; 64 } 65 66 switch (opc) { 67 case opc_tableswitch: 68 ((SwitchTable) arg2).writeTableSwitch(out); 69 return; 70 case opc_lookupswitch: 71 ((SwitchTable) arg2).writeLookupSwitch(out); 72 return; 73 } 74 75 int iarg; 76 try { 77 iarg = arg.arg; 78 } catch (NullPointerException e) { 79 throw new Parser.CompilerError(env.errorStr("comperr.instr.nullarg", opc.parsekey())); 80 } 81 //env.traceln("instr:"+opcNamesTab[opc]+" len="+opcLen+" arg:"+iarg); 82 switch (opc) { 83 case opc_jsr: 84 case opc_goto: 85 case opc_ifeq: 86 case opc_ifge: 87 case opc_ifgt: 88 case opc_ifle: 89 case opc_iflt: 90 case opc_ifne: 91 case opc_if_icmpeq: 92 case opc_if_icmpne: 93 case opc_if_icmpge: 94 case opc_if_icmpgt: 95 case opc_if_icmple: 96 case opc_if_icmplt: 97 case opc_if_acmpeq: 98 case opc_if_acmpne: 99 case opc_ifnull: 100 case opc_ifnonnull: 101 case opc_jsr_w: 102 case opc_goto_w: 103 iarg = iarg - pc; 104 break; 105 case opc_iinc: 106 iarg = (iarg << 8) | (((Argument) arg2).arg & 0xFF); 107 break; 108 case opc_invokeinterface: 109 iarg = ((iarg << 8) | (((Argument) arg2).arg & 0xFF)) << 8; 110 break; 111 case opc_invokedynamic: // JSR-292 112 iarg = (iarg << 16); 113 break; 114 case opc_ldc: 115 if ((iarg & 0xFFFFFF00) != 0) { 116 throw new Parser.CompilerError( 117 env.errorStr("comperr.instr.arglong", opc.parsekey(), iarg)); 118 } 119 break; 120 } 121 switch (opcLen) { 122 case 1: 123 return; 124 case 2: 125 out.writeByte(iarg); 126 return; 127 case 3: 128 out.writeShort(iarg); 129 return; 130 case 4: // opc_multianewarray only 131 out.writeShort(iarg); 132 iarg = ((Argument) arg2).arg; 133 out.writeByte(iarg); 134 return; 135 case 5: 136 out.writeInt(iarg); 137 return; 138 default: 139 throw new Parser.CompilerError( 140 env.errorStr("comperr.instr.opclen", opc.parsekey())); 141 } 142 } 143 case WIDE: 144 out.writeByte(Opcode.opc_wide.value()); 145 out.writeByte(opc.value() & 0xFF); 146 out.writeShort(arg.arg); 147 if (opc == Opcode.opc_iinc_w) { 148 out.writeShort(((Argument) arg2).arg); 149 } 150 return; 151 case PRIVELEGED: 152 case NONPRIVELEGED: 153 out.writeByte(opc.value() >> 8); 154 out.writeByte(opc.value() & 0xFF); 155 return; 156 default: 157 throw new Parser.CompilerError( 158 env.errorStr("comperr.instr.opclen", opc.parsekey())); 159 } // end writeSpecCode 160 161 } 162 } // end Instr 163