1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.dx.cf.code;
18
19import com.android.dx.rop.cst.Constant;
20import com.android.dx.rop.cst.ConstantPool;
21import com.android.dx.rop.cst.CstDouble;
22import com.android.dx.rop.cst.CstFloat;
23import com.android.dx.rop.cst.CstInteger;
24import com.android.dx.rop.cst.CstInvokeDynamic;
25import com.android.dx.rop.cst.CstKnownNull;
26import com.android.dx.rop.cst.CstLiteralBits;
27import com.android.dx.rop.cst.CstLong;
28import com.android.dx.rop.cst.CstType;
29import com.android.dx.rop.type.Type;
30import com.android.dx.util.Bits;
31import com.android.dx.util.ByteArray;
32import com.android.dx.util.Hex;
33import java.util.ArrayList;
34
35/**
36 * Bytecode array, which is part of a standard {@code Code} attribute.
37 */
38public final class BytecodeArray {
39    /** convenient no-op implementation of {@link Visitor} */
40    public static final Visitor EMPTY_VISITOR = new BaseVisitor();
41
42    /** {@code non-null;} underlying bytes */
43    private final ByteArray bytes;
44
45    /**
46     * {@code non-null;} constant pool to use when resolving constant
47     * pool indices
48     */
49    private final ConstantPool pool;
50
51    /**
52     * Constructs an instance.
53     *
54     * @param bytes {@code non-null;} underlying bytes
55     * @param pool {@code non-null;} constant pool to use when
56     * resolving constant pool indices
57     */
58    public BytecodeArray(ByteArray bytes, ConstantPool pool) {
59        if (bytes == null) {
60            throw new NullPointerException("bytes == null");
61        }
62
63        if (pool == null) {
64            throw new NullPointerException("pool == null");
65        }
66
67        this.bytes = bytes;
68        this.pool = pool;
69    }
70
71    /**
72     * Gets the underlying byte array.
73     *
74     * @return {@code non-null;} the byte array
75     */
76    public ByteArray getBytes() {
77        return bytes;
78    }
79
80    /**
81     * Gets the size of the bytecode array, per se.
82     *
83     * @return {@code >= 0;} the length of the bytecode array
84     */
85    public int size() {
86        return bytes.size();
87    }
88
89    /**
90     * Gets the total length of this structure in bytes, when included in
91     * a {@code Code} attribute. The returned value includes the
92     * array size plus four bytes for {@code code_length}.
93     *
94     * @return {@code >= 4;} the total length, in bytes
95     */
96    public int byteLength() {
97        return 4 + bytes.size();
98    }
99
100    /**
101     * Parses each instruction in the array, in order.
102     *
103     * @param visitor {@code null-ok;} visitor to call back to for
104     * each instruction
105     */
106    public void forEach(Visitor visitor) {
107        int sz = bytes.size();
108        int at = 0;
109
110        while (at < sz) {
111            /*
112             * Don't record the previous offset here, so that we get to see the
113             * raw code that initializes the array
114             */
115            at += parseInstruction(at, visitor);
116        }
117    }
118
119    /**
120     * Finds the offset to each instruction in the bytecode array. The
121     * result is a bit set with the offset of each opcode-per-se flipped on.
122     *
123     * @see Bits
124     * @return {@code non-null;} appropriately constructed bit set
125     */
126    public int[] getInstructionOffsets() {
127        int sz = bytes.size();
128        int[] result = Bits.makeBitSet(sz);
129        int at = 0;
130
131        while (at < sz) {
132            Bits.set(result, at, true);
133            int length = parseInstruction(at, null);
134            at += length;
135        }
136
137        return result;
138    }
139
140    /**
141     * Processes the given "work set" by repeatedly finding the lowest bit
142     * in the set, clearing it, and parsing and visiting the instruction at
143     * the indicated offset (that is, the bit index), repeating until the
144     * work set is empty. It is expected that the visitor will regularly
145     * set new bits in the work set during the process.
146     *
147     * @param workSet {@code non-null;} the work set to process
148     * @param visitor {@code non-null;} visitor to call back to for
149     * each instruction
150     */
151    public void processWorkSet(int[] workSet, Visitor visitor) {
152        if (visitor == null) {
153            throw new NullPointerException("visitor == null");
154        }
155
156        for (;;) {
157            int offset = Bits.findFirst(workSet, 0);
158            if (offset < 0) {
159                break;
160            }
161            Bits.clear(workSet, offset);
162            parseInstruction(offset, visitor);
163            visitor.setPreviousOffset(offset);
164        }
165    }
166
167    /**
168     * Parses the instruction at the indicated offset. Indicate the
169     * result by calling the visitor if supplied and by returning the
170     * number of bytes consumed by the instruction.
171     *
172     * <p>In order to simplify further processing, the opcodes passed
173     * to the visitor are canonicalized, altering the opcode to a more
174     * universal one and making formerly implicit arguments
175     * explicit. In particular:</p>
176     *
177     * <ul>
178     * <li>The opcodes to push literal constants of primitive types all become
179     *   {@code ldc}.
180     *   E.g., {@code fconst_0}, {@code sipush}, and
181     *   {@code lconst_0} qualify for this treatment.</li>
182     * <li>{@code aconst_null} becomes {@code ldc} of a
183     *   "known null."</li>
184     * <li>Shorthand local variable accessors become the corresponding
185     *   longhand. E.g. {@code aload_2} becomes {@code aload}.</li>
186     * <li>{@code goto_w} and {@code jsr_w} become {@code goto}
187     *   and {@code jsr} (respectively).</li>
188     * <li>{@code ldc_w} becomes {@code ldc}.</li>
189     * <li>{@code tableswitch} becomes {@code lookupswitch}.
190     * <li>Arithmetic, array, and value-returning ops are collapsed
191     *   to the {@code int} variant opcode, with the {@code type}
192     *   argument set to indicate the actual type. E.g.,
193     *   {@code fadd} becomes {@code iadd}, but
194     *   {@code type} is passed as {@code Type.FLOAT} in that
195     *   case. Similarly, {@code areturn} becomes
196     *   {@code ireturn}. (However, {@code return} remains
197     *   unchanged.</li>
198     * <li>Local variable access ops are collapsed to the {@code int}
199     *   variant opcode, with the {@code type} argument set to indicate
200     *   the actual type. E.g., {@code aload} becomes {@code iload},
201     *   but {@code type} is passed as {@code Type.OBJECT} in
202     *   that case.</li>
203     * <li>Numeric conversion ops ({@code i2l}, etc.) are left alone
204     *   to avoid too much confustion, but their {@code type} is
205     *   the pushed type. E.g., {@code i2b} gets type
206     *   {@code Type.INT}, and {@code f2d} gets type
207     *   {@code Type.DOUBLE}. Other unaltered opcodes also get
208     *   their pushed type. E.g., {@code arraylength} gets type
209     *   {@code Type.INT}.</li>
210     * </ul>
211     *
212     * @param offset {@code >= 0, < bytes.size();} offset to the start of the
213     * instruction
214     * @param visitor {@code null-ok;} visitor to call back to
215     * @return the length of the instruction, in bytes
216     */
217    public int parseInstruction(int offset, Visitor visitor) {
218        if (visitor == null) {
219            visitor = EMPTY_VISITOR;
220        }
221
222        try {
223            int opcode = bytes.getUnsignedByte(offset);
224            int info = ByteOps.opInfo(opcode);
225            int fmt = info & ByteOps.FMT_MASK;
226
227            switch (opcode) {
228                case ByteOps.NOP: {
229                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
230                    return 1;
231                }
232                case ByteOps.ACONST_NULL: {
233                    visitor.visitConstant(ByteOps.LDC, offset, 1,
234                                          CstKnownNull.THE_ONE, 0);
235                    return 1;
236                }
237                case ByteOps.ICONST_M1: {
238                    visitor.visitConstant(ByteOps.LDC, offset, 1,
239                                          CstInteger.VALUE_M1, -1);
240                    return 1;
241                }
242                case ByteOps.ICONST_0: {
243                    visitor.visitConstant(ByteOps.LDC, offset, 1,
244                                          CstInteger.VALUE_0, 0);
245                    return 1;
246                }
247                case ByteOps.ICONST_1: {
248                    visitor.visitConstant(ByteOps.LDC, offset, 1,
249                                          CstInteger.VALUE_1, 1);
250                    return 1;
251                }
252                case ByteOps.ICONST_2: {
253                    visitor.visitConstant(ByteOps.LDC, offset, 1,
254                                          CstInteger.VALUE_2, 2);
255                    return 1;
256                }
257                case ByteOps.ICONST_3: {
258                    visitor.visitConstant(ByteOps.LDC, offset, 1,
259                                          CstInteger.VALUE_3, 3);
260                    return 1;
261                }
262                case ByteOps.ICONST_4: {
263                    visitor.visitConstant(ByteOps.LDC, offset, 1,
264                                          CstInteger.VALUE_4, 4);
265                    return 1;
266                }
267                case ByteOps.ICONST_5:  {
268                    visitor.visitConstant(ByteOps.LDC, offset, 1,
269                                          CstInteger.VALUE_5, 5);
270                    return 1;
271                }
272                case ByteOps.LCONST_0: {
273                    visitor.visitConstant(ByteOps.LDC, offset, 1,
274                                          CstLong.VALUE_0, 0);
275                    return 1;
276                }
277                case ByteOps.LCONST_1: {
278                    visitor.visitConstant(ByteOps.LDC, offset, 1,
279                                          CstLong.VALUE_1, 0);
280                    return 1;
281                }
282                case ByteOps.FCONST_0: {
283                    visitor.visitConstant(ByteOps.LDC, offset, 1,
284                                          CstFloat.VALUE_0, 0);
285                    return 1;
286                }
287                case ByteOps.FCONST_1: {
288                    visitor.visitConstant(ByteOps.LDC, offset, 1,
289                                          CstFloat.VALUE_1, 0);
290                    return 1;
291                }
292                case ByteOps.FCONST_2:  {
293                    visitor.visitConstant(ByteOps.LDC, offset, 1,
294                                          CstFloat.VALUE_2, 0);
295                    return 1;
296                }
297                case ByteOps.DCONST_0: {
298                    visitor.visitConstant(ByteOps.LDC, offset, 1,
299                                          CstDouble.VALUE_0, 0);
300                    return 1;
301                }
302                case ByteOps.DCONST_1: {
303                    visitor.visitConstant(ByteOps.LDC, offset, 1,
304                                          CstDouble.VALUE_1, 0);
305                    return 1;
306                }
307                case ByteOps.BIPUSH: {
308                    int value = bytes.getByte(offset + 1);
309                    visitor.visitConstant(ByteOps.LDC, offset, 2,
310                                          CstInteger.make(value), value);
311                    return 2;
312                }
313                case ByteOps.SIPUSH: {
314                    int value = bytes.getShort(offset + 1);
315                    visitor.visitConstant(ByteOps.LDC, offset, 3,
316                                          CstInteger.make(value), value);
317                    return 3;
318                }
319                case ByteOps.LDC: {
320                    int idx = bytes.getUnsignedByte(offset + 1);
321                    Constant cst = pool.get(idx);
322                    int value = (cst instanceof CstInteger) ?
323                        ((CstInteger) cst).getValue() : 0;
324                    visitor.visitConstant(ByteOps.LDC, offset, 2, cst, value);
325                    return 2;
326                }
327                case ByteOps.LDC_W: {
328                    int idx = bytes.getUnsignedShort(offset + 1);
329                    Constant cst = pool.get(idx);
330                    int value = (cst instanceof CstInteger) ?
331                        ((CstInteger) cst).getValue() : 0;
332                    visitor.visitConstant(ByteOps.LDC, offset, 3, cst, value);
333                    return 3;
334                }
335                case ByteOps.LDC2_W: {
336                    int idx = bytes.getUnsignedShort(offset + 1);
337                    Constant cst = pool.get(idx);
338                    visitor.visitConstant(ByteOps.LDC2_W, offset, 3, cst, 0);
339                    return 3;
340                }
341                case ByteOps.ILOAD: {
342                    int idx = bytes.getUnsignedByte(offset + 1);
343                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,
344                                       Type.INT, 0);
345                    return 2;
346                }
347                case ByteOps.LLOAD: {
348                    int idx = bytes.getUnsignedByte(offset + 1);
349                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,
350                                       Type.LONG, 0);
351                    return 2;
352                }
353                case ByteOps.FLOAD: {
354                    int idx = bytes.getUnsignedByte(offset + 1);
355                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,
356                                       Type.FLOAT, 0);
357                    return 2;
358                }
359                case ByteOps.DLOAD: {
360                    int idx = bytes.getUnsignedByte(offset + 1);
361                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,
362                                       Type.DOUBLE, 0);
363                    return 2;
364                }
365                case ByteOps.ALOAD: {
366                    int idx = bytes.getUnsignedByte(offset + 1);
367                    visitor.visitLocal(ByteOps.ILOAD, offset, 2, idx,
368                                       Type.OBJECT, 0);
369                    return 2;
370                }
371                case ByteOps.ILOAD_0:
372                case ByteOps.ILOAD_1:
373                case ByteOps.ILOAD_2:
374                case ByteOps.ILOAD_3: {
375                    int idx = opcode - ByteOps.ILOAD_0;
376                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,
377                                       Type.INT, 0);
378                    return 1;
379                }
380                case ByteOps.LLOAD_0:
381                case ByteOps.LLOAD_1:
382                case ByteOps.LLOAD_2:
383                case ByteOps.LLOAD_3: {
384                    int idx = opcode - ByteOps.LLOAD_0;
385                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,
386                                       Type.LONG, 0);
387                    return 1;
388                }
389                case ByteOps.FLOAD_0:
390                case ByteOps.FLOAD_1:
391                case ByteOps.FLOAD_2:
392                case ByteOps.FLOAD_3: {
393                    int idx = opcode - ByteOps.FLOAD_0;
394                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,
395                                       Type.FLOAT, 0);
396                    return 1;
397                }
398                case ByteOps.DLOAD_0:
399                case ByteOps.DLOAD_1:
400                case ByteOps.DLOAD_2:
401                case ByteOps.DLOAD_3: {
402                    int idx = opcode - ByteOps.DLOAD_0;
403                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,
404                                       Type.DOUBLE, 0);
405                    return 1;
406                }
407                case ByteOps.ALOAD_0:
408                case ByteOps.ALOAD_1:
409                case ByteOps.ALOAD_2:
410                case ByteOps.ALOAD_3: {
411                    int idx = opcode - ByteOps.ALOAD_0;
412                    visitor.visitLocal(ByteOps.ILOAD, offset, 1, idx,
413                                       Type.OBJECT, 0);
414                    return 1;
415                }
416                case ByteOps.IALOAD: {
417                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.INT);
418                    return 1;
419                }
420                case ByteOps.LALOAD: {
421                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.LONG);
422                    return 1;
423                }
424                case ByteOps.FALOAD: {
425                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,
426                                        Type.FLOAT);
427                    return 1;
428                }
429                case ByteOps.DALOAD: {
430                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,
431                                        Type.DOUBLE);
432                    return 1;
433                }
434                case ByteOps.AALOAD: {
435                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,
436                                        Type.OBJECT);
437                    return 1;
438                }
439                case ByteOps.BALOAD: {
440                    /*
441                     * Note: This is a load from either a byte[] or a
442                     * boolean[].
443                     */
444                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.BYTE);
445                    return 1;
446                }
447                case ByteOps.CALOAD: {
448                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1, Type.CHAR);
449                    return 1;
450                }
451                case ByteOps.SALOAD: {
452                    visitor.visitNoArgs(ByteOps.IALOAD, offset, 1,
453                                        Type.SHORT);
454                    return 1;
455                }
456                case ByteOps.ISTORE: {
457                    int idx = bytes.getUnsignedByte(offset + 1);
458                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,
459                                       Type.INT, 0);
460                    return 2;
461                }
462                case ByteOps.LSTORE: {
463                    int idx = bytes.getUnsignedByte(offset + 1);
464                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,
465                                       Type.LONG, 0);
466                    return 2;
467                }
468                case ByteOps.FSTORE: {
469                    int idx = bytes.getUnsignedByte(offset + 1);
470                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,
471                                       Type.FLOAT, 0);
472                    return 2;
473                }
474                case ByteOps.DSTORE: {
475                    int idx = bytes.getUnsignedByte(offset + 1);
476                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,
477                                       Type.DOUBLE, 0);
478                    return 2;
479                }
480                case ByteOps.ASTORE: {
481                    int idx = bytes.getUnsignedByte(offset + 1);
482                    visitor.visitLocal(ByteOps.ISTORE, offset, 2, idx,
483                                       Type.OBJECT, 0);
484                    return 2;
485                }
486                case ByteOps.ISTORE_0:
487                case ByteOps.ISTORE_1:
488                case ByteOps.ISTORE_2:
489                case ByteOps.ISTORE_3: {
490                    int idx = opcode - ByteOps.ISTORE_0;
491                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,
492                                       Type.INT, 0);
493                    return 1;
494                }
495                case ByteOps.LSTORE_0:
496                case ByteOps.LSTORE_1:
497                case ByteOps.LSTORE_2:
498                case ByteOps.LSTORE_3: {
499                    int idx = opcode - ByteOps.LSTORE_0;
500                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,
501                                       Type.LONG, 0);
502                    return 1;
503                }
504                case ByteOps.FSTORE_0:
505                case ByteOps.FSTORE_1:
506                case ByteOps.FSTORE_2:
507                case ByteOps.FSTORE_3: {
508                    int idx = opcode - ByteOps.FSTORE_0;
509                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,
510                                       Type.FLOAT, 0);
511                    return 1;
512                }
513                case ByteOps.DSTORE_0:
514                case ByteOps.DSTORE_1:
515                case ByteOps.DSTORE_2:
516                case ByteOps.DSTORE_3: {
517                    int idx = opcode - ByteOps.DSTORE_0;
518                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,
519                                       Type.DOUBLE, 0);
520                    return 1;
521                }
522                case ByteOps.ASTORE_0:
523                case ByteOps.ASTORE_1:
524                case ByteOps.ASTORE_2:
525                case ByteOps.ASTORE_3: {
526                    int idx = opcode - ByteOps.ASTORE_0;
527                    visitor.visitLocal(ByteOps.ISTORE, offset, 1, idx,
528                                       Type.OBJECT, 0);
529                    return 1;
530                }
531                case ByteOps.IASTORE: {
532                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1, Type.INT);
533                    return 1;
534                }
535                case ByteOps.LASTORE: {
536                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
537                                        Type.LONG);
538                    return 1;
539                }
540                case ByteOps.FASTORE: {
541                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
542                                        Type.FLOAT);
543                    return 1;
544                }
545                case ByteOps.DASTORE: {
546                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
547                                        Type.DOUBLE);
548                    return 1;
549                }
550                case ByteOps.AASTORE: {
551                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
552                                        Type.OBJECT);
553                    return 1;
554                }
555                case ByteOps.BASTORE: {
556                    /*
557                     * Note: This is a load from either a byte[] or a
558                     * boolean[].
559                     */
560                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
561                                        Type.BYTE);
562                    return 1;
563                }
564                case ByteOps.CASTORE: {
565                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
566                                        Type.CHAR);
567                    return 1;
568                }
569                case ByteOps.SASTORE: {
570                    visitor.visitNoArgs(ByteOps.IASTORE, offset, 1,
571                                        Type.SHORT);
572                    return 1;
573                }
574                case ByteOps.POP:
575                case ByteOps.POP2:
576                case ByteOps.DUP:
577                case ByteOps.DUP_X1:
578                case ByteOps.DUP_X2:
579                case ByteOps.DUP2:
580                case ByteOps.DUP2_X1:
581                case ByteOps.DUP2_X2:
582                case ByteOps.SWAP: {
583                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
584                    return 1;
585                }
586                case ByteOps.IADD:
587                case ByteOps.ISUB:
588                case ByteOps.IMUL:
589                case ByteOps.IDIV:
590                case ByteOps.IREM:
591                case ByteOps.INEG:
592                case ByteOps.ISHL:
593                case ByteOps.ISHR:
594                case ByteOps.IUSHR:
595                case ByteOps.IAND:
596                case ByteOps.IOR:
597                case ByteOps.IXOR: {
598                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);
599                    return 1;
600                }
601                case ByteOps.LADD:
602                case ByteOps.LSUB:
603                case ByteOps.LMUL:
604                case ByteOps.LDIV:
605                case ByteOps.LREM:
606                case ByteOps.LNEG:
607                case ByteOps.LSHL:
608                case ByteOps.LSHR:
609                case ByteOps.LUSHR:
610                case ByteOps.LAND:
611                case ByteOps.LOR:
612                case ByteOps.LXOR: {
613                    /*
614                     * It's "opcode - 1" because, conveniently enough, all
615                     * these long ops are one past the int variants.
616                     */
617                    visitor.visitNoArgs(opcode - 1, offset, 1, Type.LONG);
618                    return 1;
619                }
620                case ByteOps.FADD:
621                case ByteOps.FSUB:
622                case ByteOps.FMUL:
623                case ByteOps.FDIV:
624                case ByteOps.FREM:
625                case ByteOps.FNEG: {
626                    /*
627                     * It's "opcode - 2" because, conveniently enough, all
628                     * these float ops are two past the int variants.
629                     */
630                    visitor.visitNoArgs(opcode - 2, offset, 1, Type.FLOAT);
631                    return 1;
632                }
633                case ByteOps.DADD:
634                case ByteOps.DSUB:
635                case ByteOps.DMUL:
636                case ByteOps.DDIV:
637                case ByteOps.DREM:
638                case ByteOps.DNEG: {
639                    /*
640                     * It's "opcode - 3" because, conveniently enough, all
641                     * these double ops are three past the int variants.
642                     */
643                    visitor.visitNoArgs(opcode - 3, offset, 1, Type.DOUBLE);
644                    return 1;
645                }
646                case ByteOps.IINC: {
647                    int idx = bytes.getUnsignedByte(offset + 1);
648                    int value = bytes.getByte(offset + 2);
649                    visitor.visitLocal(opcode, offset, 3, idx,
650                                       Type.INT, value);
651                    return 3;
652                }
653                case ByteOps.I2L:
654                case ByteOps.F2L:
655                case ByteOps.D2L: {
656                    visitor.visitNoArgs(opcode, offset, 1, Type.LONG);
657                    return 1;
658                }
659                case ByteOps.I2F:
660                case ByteOps.L2F:
661                case ByteOps.D2F: {
662                    visitor.visitNoArgs(opcode, offset, 1, Type.FLOAT);
663                    return 1;
664                }
665                case ByteOps.I2D:
666                case ByteOps.L2D:
667                case ByteOps.F2D: {
668                    visitor.visitNoArgs(opcode, offset, 1, Type.DOUBLE);
669                    return 1;
670                }
671                case ByteOps.L2I:
672                case ByteOps.F2I:
673                case ByteOps.D2I:
674                case ByteOps.I2B:
675                case ByteOps.I2C:
676                case ByteOps.I2S:
677                case ByteOps.LCMP:
678                case ByteOps.FCMPL:
679                case ByteOps.FCMPG:
680                case ByteOps.DCMPL:
681                case ByteOps.DCMPG:
682                case ByteOps.ARRAYLENGTH: {
683                    visitor.visitNoArgs(opcode, offset, 1, Type.INT);
684                    return 1;
685                }
686                case ByteOps.IFEQ:
687                case ByteOps.IFNE:
688                case ByteOps.IFLT:
689                case ByteOps.IFGE:
690                case ByteOps.IFGT:
691                case ByteOps.IFLE:
692                case ByteOps.IF_ICMPEQ:
693                case ByteOps.IF_ICMPNE:
694                case ByteOps.IF_ICMPLT:
695                case ByteOps.IF_ICMPGE:
696                case ByteOps.IF_ICMPGT:
697                case ByteOps.IF_ICMPLE:
698                case ByteOps.IF_ACMPEQ:
699                case ByteOps.IF_ACMPNE:
700                case ByteOps.GOTO:
701                case ByteOps.JSR:
702                case ByteOps.IFNULL:
703                case ByteOps.IFNONNULL: {
704                    int target = offset + bytes.getShort(offset + 1);
705                    visitor.visitBranch(opcode, offset, 3, target);
706                    return 3;
707                }
708                case ByteOps.RET: {
709                    int idx = bytes.getUnsignedByte(offset + 1);
710                    visitor.visitLocal(opcode, offset, 2, idx,
711                                       Type.RETURN_ADDRESS, 0);
712                    return 2;
713                }
714                case ByteOps.TABLESWITCH: {
715                    return parseTableswitch(offset, visitor);
716                }
717                case ByteOps.LOOKUPSWITCH: {
718                    return parseLookupswitch(offset, visitor);
719                }
720                case ByteOps.IRETURN: {
721                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1, Type.INT);
722                    return 1;
723                }
724                case ByteOps.LRETURN: {
725                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,
726                                        Type.LONG);
727                    return 1;
728                }
729                case ByteOps.FRETURN: {
730                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,
731                                        Type.FLOAT);
732                    return 1;
733                }
734                case ByteOps.DRETURN: {
735                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,
736                                        Type.DOUBLE);
737                    return 1;
738                }
739                case ByteOps.ARETURN: {
740                    visitor.visitNoArgs(ByteOps.IRETURN, offset, 1,
741                                        Type.OBJECT);
742                    return 1;
743                }
744                case ByteOps.RETURN:
745                case ByteOps.ATHROW:
746                case ByteOps.MONITORENTER:
747                case ByteOps.MONITOREXIT: {
748                    visitor.visitNoArgs(opcode, offset, 1, Type.VOID);
749                    return 1;
750                }
751                case ByteOps.GETSTATIC:
752                case ByteOps.PUTSTATIC:
753                case ByteOps.GETFIELD:
754                case ByteOps.PUTFIELD:
755                case ByteOps.INVOKEVIRTUAL:
756                case ByteOps.INVOKESPECIAL:
757                case ByteOps.INVOKESTATIC:
758                case ByteOps.NEW:
759                case ByteOps.ANEWARRAY:
760                case ByteOps.CHECKCAST:
761                case ByteOps.INSTANCEOF: {
762                    int idx = bytes.getUnsignedShort(offset + 1);
763                    Constant cst = pool.get(idx);
764                    visitor.visitConstant(opcode, offset, 3, cst, 0);
765                    return 3;
766                }
767                case ByteOps.INVOKEINTERFACE: {
768                    int idx = bytes.getUnsignedShort(offset + 1);
769                    int count = bytes.getUnsignedByte(offset + 3);
770                    int expectZero = bytes.getUnsignedByte(offset + 4);
771                    Constant cst = pool.get(idx);
772                    visitor.visitConstant(opcode, offset, 5, cst,
773                                          count | (expectZero << 8));
774                    return 5;
775                }
776                case ByteOps.INVOKEDYNAMIC: {
777                    int idx = bytes.getUnsignedShort(offset + 1);
778                    // Skip to must-be-zero bytes at offsets 3 and 4
779                    CstInvokeDynamic cstInvokeDynamic = (CstInvokeDynamic) pool.get(idx);
780                    visitor.visitConstant(opcode, offset, 5, cstInvokeDynamic, 0);
781                    return 5;
782                }
783                case ByteOps.NEWARRAY: {
784                    return parseNewarray(offset, visitor);
785                }
786                case ByteOps.WIDE: {
787                    return parseWide(offset, visitor);
788                }
789                case ByteOps.MULTIANEWARRAY: {
790                    int idx = bytes.getUnsignedShort(offset + 1);
791                    int dimensions = bytes.getUnsignedByte(offset + 3);
792                    Constant cst = pool.get(idx);
793                    visitor.visitConstant(opcode, offset, 4, cst, dimensions);
794                    return 4;
795                }
796                case ByteOps.GOTO_W:
797                case ByteOps.JSR_W: {
798                    int target = offset + bytes.getInt(offset + 1);
799                    int newop =
800                        (opcode == ByteOps.GOTO_W) ? ByteOps.GOTO :
801                        ByteOps.JSR;
802                    visitor.visitBranch(newop, offset, 5, target);
803                    return 5;
804                }
805                default: {
806                    visitor.visitInvalid(opcode, offset, 1);
807                    return 1;
808                }
809            }
810        } catch (SimException ex) {
811            ex.addContext("...at bytecode offset " + Hex.u4(offset));
812            throw ex;
813        } catch (RuntimeException ex) {
814            SimException se = new SimException(ex);
815            se.addContext("...at bytecode offset " + Hex.u4(offset));
816            throw se;
817        }
818    }
819
820    /**
821     * Helper to deal with {@code tableswitch}.
822     *
823     * @param offset the offset to the {@code tableswitch} opcode itself
824     * @param visitor {@code non-null;} visitor to use
825     * @return instruction length, in bytes
826     */
827    private int parseTableswitch(int offset, Visitor visitor) {
828        int at = (offset + 4) & ~3; // "at" skips the padding.
829
830        // Collect the padding.
831        int padding = 0;
832        for (int i = offset + 1; i < at; i++) {
833            padding = (padding << 8) | bytes.getUnsignedByte(i);
834        }
835
836        int defaultTarget = offset + bytes.getInt(at);
837        int low = bytes.getInt(at + 4);
838        int high = bytes.getInt(at + 8);
839        int count = high - low + 1;
840        at += 12;
841
842        if (low > high) {
843            throw new SimException("low / high inversion");
844        }
845
846        SwitchList cases = new SwitchList(count);
847        for (int i = 0; i < count; i++) {
848            int target = offset + bytes.getInt(at);
849            at += 4;
850            cases.add(low + i, target);
851        }
852        cases.setDefaultTarget(defaultTarget);
853        cases.removeSuperfluousDefaults();
854        cases.setImmutable();
855
856        int length = at - offset;
857        visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases,
858                            padding);
859
860        return length;
861    }
862
863    /**
864     * Helper to deal with {@code lookupswitch}.
865     *
866     * @param offset the offset to the {@code lookupswitch} opcode itself
867     * @param visitor {@code non-null;} visitor to use
868     * @return instruction length, in bytes
869     */
870    private int parseLookupswitch(int offset, Visitor visitor) {
871        int at = (offset + 4) & ~3; // "at" skips the padding.
872
873        // Collect the padding.
874        int padding = 0;
875        for (int i = offset + 1; i < at; i++) {
876            padding = (padding << 8) | bytes.getUnsignedByte(i);
877        }
878
879        int defaultTarget = offset + bytes.getInt(at);
880        int npairs = bytes.getInt(at + 4);
881        at += 8;
882
883        SwitchList cases = new SwitchList(npairs);
884        for (int i = 0; i < npairs; i++) {
885            int match = bytes.getInt(at);
886            int target = offset + bytes.getInt(at + 4);
887            at += 8;
888            cases.add(match, target);
889        }
890        cases.setDefaultTarget(defaultTarget);
891        cases.removeSuperfluousDefaults();
892        cases.setImmutable();
893
894        int length = at - offset;
895        visitor.visitSwitch(ByteOps.LOOKUPSWITCH, offset, length, cases,
896                            padding);
897
898        return length;
899    }
900
901    /**
902     * Helper to deal with {@code newarray}.
903     *
904     * @param offset the offset to the {@code newarray} opcode itself
905     * @param visitor {@code non-null;} visitor to use
906     * @return instruction length, in bytes
907     */
908    private int parseNewarray(int offset, Visitor visitor) {
909        int value = bytes.getUnsignedByte(offset + 1);
910        CstType type;
911        switch (value) {
912            case ByteOps.NEWARRAY_BOOLEAN: {
913                type = CstType.BOOLEAN_ARRAY;
914                break;
915            }
916            case ByteOps.NEWARRAY_CHAR: {
917                type = CstType.CHAR_ARRAY;
918                break;
919            }
920            case ByteOps.NEWARRAY_DOUBLE: {
921                type = CstType.DOUBLE_ARRAY;
922                break;
923            }
924            case ByteOps.NEWARRAY_FLOAT: {
925                type = CstType.FLOAT_ARRAY;
926                break;
927            }
928            case ByteOps.NEWARRAY_BYTE: {
929                type = CstType.BYTE_ARRAY;
930                break;
931            }
932            case ByteOps.NEWARRAY_SHORT: {
933                type = CstType.SHORT_ARRAY;
934                break;
935            }
936            case ByteOps.NEWARRAY_INT: {
937                type = CstType.INT_ARRAY;
938                break;
939            }
940            case ByteOps.NEWARRAY_LONG: {
941                type = CstType.LONG_ARRAY;
942                break;
943            }
944            default: {
945                throw new SimException("bad newarray code " +
946                        Hex.u1(value));
947            }
948        }
949
950        // Revisit the previous bytecode to find out the length of the array
951        int previousOffset = visitor.getPreviousOffset();
952        ConstantParserVisitor constantVisitor = new ConstantParserVisitor();
953        int arrayLength = 0;
954
955        /*
956         * For visitors that don't record the previous offset, -1 will be
957         * seen here
958         */
959        if (previousOffset >= 0) {
960            parseInstruction(previousOffset, constantVisitor);
961            if (constantVisitor.cst instanceof CstInteger &&
962                    constantVisitor.length + previousOffset == offset) {
963                arrayLength = constantVisitor.value;
964
965            }
966        }
967
968        /*
969         * Try to match the array initialization idiom. For example, if the
970         * subsequent code is initializing an int array, we are expecting the
971         * following pattern repeatedly:
972         *  dup
973         *  push index
974         *  push value
975         *  *astore
976         *
977         * where the index value will be incrimented sequentially from 0 up.
978         */
979        int nInit = 0;
980        int curOffset = offset+2;
981        int lastOffset = curOffset;
982        ArrayList<Constant> initVals = new ArrayList<Constant>();
983
984        if (arrayLength != 0) {
985            while (true) {
986                boolean punt = false;
987
988                // First, check if the next bytecode is dup.
989                int nextByte = bytes.getUnsignedByte(curOffset++);
990                if (nextByte != ByteOps.DUP)
991                    break;
992
993                /*
994                 * Next, check if the expected array index is pushed to
995                 * the stack.
996                 */
997                parseInstruction(curOffset, constantVisitor);
998                if (constantVisitor.length == 0 ||
999                        !(constantVisitor.cst instanceof CstInteger) ||
1000                        constantVisitor.value != nInit)
1001                    break;
1002
1003                // Next, fetch the init value and record it.
1004                curOffset += constantVisitor.length;
1005
1006                /*
1007                 * Next, find out what kind of constant is pushed onto
1008                 * the stack.
1009                 */
1010                parseInstruction(curOffset, constantVisitor);
1011                if (constantVisitor.length == 0 ||
1012                        !(constantVisitor.cst instanceof CstLiteralBits))
1013                    break;
1014
1015                curOffset += constantVisitor.length;
1016                initVals.add(constantVisitor.cst);
1017
1018                nextByte = bytes.getUnsignedByte(curOffset++);
1019                // Now, check if the value is stored to the array properly.
1020                switch (value) {
1021                    case ByteOps.NEWARRAY_BYTE:
1022                    case ByteOps.NEWARRAY_BOOLEAN: {
1023                        if (nextByte != ByteOps.BASTORE) {
1024                            punt = true;
1025                        }
1026                        break;
1027                    }
1028                    case ByteOps.NEWARRAY_CHAR: {
1029                        if (nextByte != ByteOps.CASTORE) {
1030                            punt = true;
1031                        }
1032                        break;
1033                    }
1034                    case ByteOps.NEWARRAY_DOUBLE: {
1035                        if (nextByte != ByteOps.DASTORE) {
1036                            punt = true;
1037                        }
1038                        break;
1039                    }
1040                    case ByteOps.NEWARRAY_FLOAT: {
1041                        if (nextByte != ByteOps.FASTORE) {
1042                            punt = true;
1043                        }
1044                        break;
1045                    }
1046                    case ByteOps.NEWARRAY_SHORT: {
1047                        if (nextByte != ByteOps.SASTORE) {
1048                            punt = true;
1049                        }
1050                        break;
1051                    }
1052                    case ByteOps.NEWARRAY_INT: {
1053                        if (nextByte != ByteOps.IASTORE) {
1054                            punt = true;
1055                        }
1056                        break;
1057                    }
1058                    case ByteOps.NEWARRAY_LONG: {
1059                        if (nextByte != ByteOps.LASTORE) {
1060                            punt = true;
1061                        }
1062                        break;
1063                    }
1064                    default:
1065                        punt = true;
1066                        break;
1067                }
1068                if (punt) {
1069                    break;
1070                }
1071                lastOffset = curOffset;
1072                nInit++;
1073            }
1074        }
1075
1076        /*
1077         * For singleton arrays it is still more economical to
1078         * generate the aput.
1079         */
1080        if (nInit < 2 || nInit != arrayLength) {
1081            visitor.visitNewarray(offset, 2, type, null);
1082            return 2;
1083        } else {
1084            visitor.visitNewarray(offset, lastOffset - offset, type, initVals);
1085            return lastOffset - offset;
1086        }
1087     }
1088
1089
1090    /**
1091     * Helper to deal with {@code wide}.
1092     *
1093     * @param offset the offset to the {@code wide} opcode itself
1094     * @param visitor {@code non-null;} visitor to use
1095     * @return instruction length, in bytes
1096     */
1097    private int parseWide(int offset, Visitor visitor) {
1098        int opcode = bytes.getUnsignedByte(offset + 1);
1099        int idx = bytes.getUnsignedShort(offset + 2);
1100        switch (opcode) {
1101            case ByteOps.ILOAD: {
1102                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,
1103                                   Type.INT, 0);
1104                return 4;
1105            }
1106            case ByteOps.LLOAD: {
1107                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,
1108                                   Type.LONG, 0);
1109                return 4;
1110            }
1111            case ByteOps.FLOAD: {
1112                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,
1113                                   Type.FLOAT, 0);
1114                return 4;
1115            }
1116            case ByteOps.DLOAD: {
1117                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,
1118                                   Type.DOUBLE, 0);
1119                return 4;
1120            }
1121            case ByteOps.ALOAD: {
1122                visitor.visitLocal(ByteOps.ILOAD, offset, 4, idx,
1123                                   Type.OBJECT, 0);
1124                return 4;
1125            }
1126            case ByteOps.ISTORE: {
1127                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,
1128                                   Type.INT, 0);
1129                return 4;
1130            }
1131            case ByteOps.LSTORE: {
1132                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,
1133                                   Type.LONG, 0);
1134                return 4;
1135            }
1136            case ByteOps.FSTORE: {
1137                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,
1138                                   Type.FLOAT, 0);
1139                return 4;
1140            }
1141            case ByteOps.DSTORE: {
1142                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,
1143                                   Type.DOUBLE, 0);
1144                return 4;
1145            }
1146            case ByteOps.ASTORE: {
1147                visitor.visitLocal(ByteOps.ISTORE, offset, 4, idx,
1148                                   Type.OBJECT, 0);
1149                return 4;
1150            }
1151            case ByteOps.RET: {
1152                visitor.visitLocal(opcode, offset, 4, idx,
1153                                   Type.RETURN_ADDRESS, 0);
1154                return 4;
1155            }
1156            case ByteOps.IINC: {
1157                int value = bytes.getShort(offset + 4);
1158                visitor.visitLocal(opcode, offset, 6, idx,
1159                                   Type.INT, value);
1160                return 6;
1161            }
1162            default: {
1163                visitor.visitInvalid(ByteOps.WIDE, offset, 1);
1164                return 1;
1165            }
1166        }
1167    }
1168
1169    /**
1170     * Instruction visitor interface.
1171     */
1172    public interface Visitor {
1173        /**
1174         * Visits an invalid instruction.
1175         *
1176         * @param opcode the opcode
1177         * @param offset offset to the instruction
1178         * @param length length of the instruction, in bytes
1179         */
1180        public void visitInvalid(int opcode, int offset, int length);
1181
1182        /**
1183         * Visits an instruction which has no inline arguments
1184         * (implicit or explicit).
1185         *
1186         * @param opcode the opcode
1187         * @param offset offset to the instruction
1188         * @param length length of the instruction, in bytes
1189         * @param type {@code non-null;} type the instruction operates on
1190         */
1191        public void visitNoArgs(int opcode, int offset, int length,
1192                Type type);
1193
1194        /**
1195         * Visits an instruction which has a local variable index argument.
1196         *
1197         * @param opcode the opcode
1198         * @param offset offset to the instruction
1199         * @param length length of the instruction, in bytes
1200         * @param idx the local variable index
1201         * @param type {@code non-null;} the type of the accessed value
1202         * @param value additional literal integer argument, if salient (i.e.,
1203         * for {@code iinc})
1204         */
1205        public void visitLocal(int opcode, int offset, int length,
1206                int idx, Type type, int value);
1207
1208        /**
1209         * Visits an instruction which has a (possibly synthetic)
1210         * constant argument, and possibly also an
1211         * additional literal integer argument. In the case of
1212         * {@code multianewarray}, the argument is the count of
1213         * dimensions. In the case of {@code invokeinterface},
1214         * the argument is the parameter count or'ed with the
1215         * should-be-zero value left-shifted by 8. In the case of entries
1216         * of type {@code int}, the {@code value} field always
1217         * holds the raw value (for convenience of clients).
1218         *
1219         * <p><b>Note:</b> In order to avoid giving it a barely-useful
1220         * visitor all its own, {@code newarray} also uses this
1221         * form, passing {@code value} as the array type code and
1222         * {@code cst} as a {@link CstType} instance
1223         * corresponding to the array type.</p>
1224         *
1225         * @param opcode the opcode
1226         * @param offset offset to the instruction
1227         * @param length length of the instruction, in bytes
1228         * @param cst {@code non-null;} the constant
1229         * @param value additional literal integer argument, if salient
1230         * (ignore if not)
1231         */
1232        public void visitConstant(int opcode, int offset, int length,
1233                Constant cst, int value);
1234
1235        /**
1236         * Visits an instruction which has a branch target argument.
1237         *
1238         * @param opcode the opcode
1239         * @param offset offset to the instruction
1240         * @param length length of the instruction, in bytes
1241         * @param target the absolute (not relative) branch target
1242         */
1243        public void visitBranch(int opcode, int offset, int length,
1244                int target);
1245
1246        /**
1247         * Visits a switch instruction.
1248         *
1249         * @param opcode the opcode
1250         * @param offset offset to the instruction
1251         * @param length length of the instruction, in bytes
1252         * @param cases {@code non-null;} list of (value, target)
1253         * pairs, plus the default target
1254         * @param padding the bytes found in the padding area (if any),
1255         * packed
1256         */
1257        public void visitSwitch(int opcode, int offset, int length,
1258                SwitchList cases, int padding);
1259
1260        /**
1261         * Visits a newarray instruction.
1262         *
1263         * @param offset   offset to the instruction
1264         * @param length   length of the instruction, in bytes
1265         * @param type {@code non-null;} the type of the array
1266         * @param initVals {@code non-null;} list of bytecode offsets
1267         * for init values
1268         */
1269        public void visitNewarray(int offset, int length, CstType type,
1270                ArrayList<Constant> initVals);
1271
1272        /**
1273         * Set previous bytecode offset
1274         * @param offset    offset of the previous fully parsed bytecode
1275         */
1276        public void setPreviousOffset(int offset);
1277
1278        /**
1279         * Get previous bytecode offset
1280         * @return return the recored offset of the previous bytecode
1281         */
1282        public int getPreviousOffset();
1283    }
1284
1285    /**
1286     * Base implementation of {@link Visitor}, which has empty method
1287     * bodies for all methods.
1288     */
1289    public static class BaseVisitor implements Visitor {
1290
1291        /** offset of the previously parsed bytecode */
1292        private int previousOffset;
1293
1294        BaseVisitor() {
1295            previousOffset = -1;
1296        }
1297
1298        /** {@inheritDoc} */
1299        @Override
1300        public void visitInvalid(int opcode, int offset, int length) {
1301            // This space intentionally left blank.
1302        }
1303
1304        /** {@inheritDoc} */
1305        @Override
1306        public void visitNoArgs(int opcode, int offset, int length,
1307                Type type) {
1308            // This space intentionally left blank.
1309        }
1310
1311        /** {@inheritDoc} */
1312        @Override
1313        public void visitLocal(int opcode, int offset, int length,
1314                int idx, Type type, int value) {
1315            // This space intentionally left blank.
1316        }
1317
1318        /** {@inheritDoc} */
1319        @Override
1320        public void visitConstant(int opcode, int offset, int length,
1321                Constant cst, int value) {
1322            // This space intentionally left blank.
1323        }
1324
1325        /** {@inheritDoc} */
1326        @Override
1327        public void visitBranch(int opcode, int offset, int length,
1328                int target) {
1329            // This space intentionally left blank.
1330        }
1331
1332        /** {@inheritDoc} */
1333        @Override
1334        public void visitSwitch(int opcode, int offset, int length,
1335                SwitchList cases, int padding) {
1336            // This space intentionally left blank.
1337        }
1338
1339        /** {@inheritDoc} */
1340        @Override
1341        public void visitNewarray(int offset, int length, CstType type,
1342                ArrayList<Constant> initValues) {
1343            // This space intentionally left blank.
1344        }
1345
1346        /** {@inheritDoc} */
1347        @Override
1348        public void setPreviousOffset(int offset) {
1349            previousOffset = offset;
1350        }
1351
1352        /** {@inheritDoc} */
1353        @Override
1354        public int getPreviousOffset() {
1355            return previousOffset;
1356        }
1357    }
1358
1359    /**
1360     * Implementation of {@link Visitor}, which just pays attention
1361     * to constant values.
1362     */
1363    class ConstantParserVisitor extends BaseVisitor {
1364        Constant cst;
1365        int length;
1366        int value;
1367
1368        /** Empty constructor */
1369        ConstantParserVisitor() {
1370        }
1371
1372        private void clear() {
1373            length = 0;
1374        }
1375
1376        /** {@inheritDoc} */
1377        @Override
1378        public void visitInvalid(int opcode, int offset, int length) {
1379            clear();
1380        }
1381
1382        /** {@inheritDoc} */
1383        @Override
1384        public void visitNoArgs(int opcode, int offset, int length,
1385                Type type) {
1386            clear();
1387        }
1388
1389        /** {@inheritDoc} */
1390        @Override
1391        public void visitLocal(int opcode, int offset, int length,
1392                int idx, Type type, int value) {
1393            clear();
1394        }
1395
1396        /** {@inheritDoc} */
1397        @Override
1398        public void visitConstant(int opcode, int offset, int length,
1399                Constant cst, int value) {
1400            this.cst = cst;
1401            this.length = length;
1402            this.value = value;
1403        }
1404
1405        /** {@inheritDoc} */
1406        @Override
1407        public void visitBranch(int opcode, int offset, int length,
1408                int target) {
1409            clear();
1410        }
1411
1412        /** {@inheritDoc} */
1413        @Override
1414        public void visitSwitch(int opcode, int offset, int length,
1415                SwitchList cases, int padding) {
1416            clear();
1417        }
1418
1419        /** {@inheritDoc} */
1420        @Override
1421        public void visitNewarray(int offset, int length, CstType type,
1422                ArrayList<Constant> initVals) {
1423            clear();
1424        }
1425
1426        /** {@inheritDoc} */
1427        @Override
1428        public void setPreviousOffset(int offset) {
1429            // Intentionally left empty
1430        }
1431
1432        /** {@inheritDoc} */
1433        @Override
1434        public int getPreviousOffset() {
1435            // Intentionally left empty
1436            return -1;
1437        }
1438    }
1439}
1440