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