1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2011 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  *    contributors may be used to endorse or promote products derived from
16  *    this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 package com.sleepycat.asm;
31 
32 /**
33  * A visitor to visit a Java method. The methods of this class must be
34  * called in the following order: [ <tt>visitAnnotationDefault</tt> ] (
35  * <tt>visitAnnotation</tt> | <tt>visitParameterAnnotation</tt> |
36  * <tt>visitAttribute</tt> )* [ <tt>visitCode</tt> ( <tt>visitFrame</tt> |
37  * <tt>visit</tt><i>X</i>Insn</tt> | <tt>visitLabel</tt> | <tt>visitTryCatchBlock</tt> |
38  * <tt>visitLocalVariable</tt> | <tt>visitLineNumber</tt> )* <tt>visitMaxs</tt> ]
39  * <tt>visitEnd</tt>. In addition, the <tt>visit</tt><i>X</i>Insn</tt>
40  * and <tt>visitLabel</tt> methods must be called in the sequential order of
41  * the bytecode instructions of the visited code, <tt>visitTryCatchBlock</tt>
42  * must be called <i>before</i> the labels passed as arguments have been
43  * visited, and the <tt>visitLocalVariable</tt> and <tt>visitLineNumber</tt>
44  * methods must be called <i>after</i> the labels passed as arguments have been
45  * visited.
46  *
47  * @author Eric Bruneton
48  */
49 public abstract class MethodVisitor {
50 
51     /**
52      * The ASM API version implemented by this visitor. The value of this field
53      * must be one of {@link Opcodes#ASM4}.
54      */
55     protected final int api;
56 
57     /**
58      * The method visitor to which this visitor must delegate method calls. May
59      * be null.
60      */
61     protected MethodVisitor mv;
62 
63     /**
64      * Constructs a new {@link MethodVisitor}.
65      *
66      * @param api the ASM API version implemented by this visitor. Must be one
67      *        of {@link Opcodes#ASM4}.
68      */
MethodVisitor(final int api)69     public MethodVisitor(final int api) {
70         this(api, null);
71     }
72 
73     /**
74      * Constructs a new {@link MethodVisitor}.
75      *
76      * @param api the ASM API version implemented by this visitor. Must be one
77      *        of {@link Opcodes#ASM4}.
78      * @param mv the method visitor to which this visitor must delegate method
79      *        calls. May be null.
80      */
MethodVisitor(final int api, final MethodVisitor mv)81     public MethodVisitor(final int api, final MethodVisitor mv) {
82         /*if (api != Opcodes.ASM4) {
83             throw new IllegalArgumentException();
84         }*/
85         this.api = api;
86         this.mv = mv;
87     }
88 
89     // -------------------------------------------------------------------------
90     // Annotations and non standard attributes
91     // -------------------------------------------------------------------------
92 
93     /**
94      * Visits the default value of this annotation interface method.
95      *
96      * @return a visitor to the visit the actual default value of this
97      *         annotation interface method, or <tt>null</tt> if this visitor
98      *         is not interested in visiting this default value. The 'name'
99      *         parameters passed to the methods of this annotation visitor are
100      *         ignored. Moreover, exacly one visit method must be called on this
101      *         annotation visitor, followed by visitEnd.
102      */
visitAnnotationDefault()103     public AnnotationVisitor visitAnnotationDefault() {
104         if (mv != null) {
105             return mv.visitAnnotationDefault();
106         }
107         return null;
108     }
109 
110     /**
111      * Visits an annotation of this method.
112      *
113      * @param desc the class descriptor of the annotation class.
114      * @param visible <tt>true</tt> if the annotation is visible at runtime.
115      * @return a visitor to visit the annotation values, or <tt>null</tt> if
116      *         this visitor is not interested in visiting this annotation.
117      */
visitAnnotation(String desc, boolean visible)118     public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
119         if (mv != null) {
120             return mv.visitAnnotation(desc, visible);
121         }
122         return null;
123     }
124 
125     /**
126      * Visits an annotation of a parameter this method.
127      *
128      * @param parameter the parameter index.
129      * @param desc the class descriptor of the annotation class.
130      * @param visible <tt>true</tt> if the annotation is visible at runtime.
131      * @return a visitor to visit the annotation values, or <tt>null</tt> if
132      *         this visitor is not interested in visiting this annotation.
133      */
visitParameterAnnotation( int parameter, String desc, boolean visible)134     public AnnotationVisitor visitParameterAnnotation(
135         int parameter,
136         String desc,
137         boolean visible)
138     {
139         if (mv != null) {
140             return mv.visitParameterAnnotation(parameter, desc, visible);
141         }
142         return null;
143     }
144 
145     /**
146      * Visits a non standard attribute of this method.
147      *
148      * @param attr an attribute.
149      */
visitAttribute(Attribute attr)150     public void visitAttribute(Attribute attr) {
151         if (mv != null) {
152             mv.visitAttribute(attr);
153         }
154     }
155 
156     /**
157      * Starts the visit of the method's code, if any (i.e. non abstract method).
158      */
visitCode()159     public void visitCode() {
160         if (mv != null) {
161             mv.visitCode();
162         }
163     }
164 
165     /**
166      * Visits the current state of the local variables and operand stack
167      * elements. This method must(*) be called <i>just before</i> any
168      * instruction <b>i</b> that follows an unconditional branch instruction
169      * such as GOTO or THROW, that is the target of a jump instruction, or that
170      * starts an exception handler block. The visited types must describe the
171      * values of the local variables and of the operand stack elements <i>just
172      * before</i> <b>i</b> is executed. <br> <br> (*) this is mandatory only
173      * for classes whose version is greater than or equal to
174      * {@link Opcodes#V1_6 V1_6}. <br> <br> Packed frames are basically
175      * "deltas" from the state of the previous frame (very first frame is
176      * implicitly defined by the method's parameters and access flags): <ul>
177      * <li>{@link Opcodes#F_SAME} representing frame with exactly the same
178      * locals as the previous frame and with the empty stack.</li> <li>{@link Opcodes#F_SAME1}
179      * representing frame with exactly the same locals as the previous frame and
180      * with single value on the stack (<code>nStack</code> is 1 and
181      * <code>stack[0]</code> contains value for the type of the stack item).</li>
182      * <li>{@link Opcodes#F_APPEND} representing frame with current locals are
183      * the same as the locals in the previous frame, except that additional
184      * locals are defined (<code>nLocal</code> is 1, 2 or 3 and
185      * <code>local</code> elements contains values representing added types).</li>
186      * <li>{@link Opcodes#F_CHOP} representing frame with current locals are
187      * the same as the locals in the previous frame, except that the last 1-3
188      * locals are absent and with the empty stack (<code>nLocals</code> is 1,
189      * 2 or 3). </li> <li>{@link Opcodes#F_FULL} representing complete frame
190      * data.</li> </li> </ul>
191      *
192      * @param type the type of this stack map frame. Must be
193      *        {@link Opcodes#F_NEW} for expanded frames, or
194      *        {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND},
195      *        {@link Opcodes#F_CHOP}, {@link Opcodes#F_SAME} or
196      *        {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed
197      *        frames.
198      * @param nLocal the number of local variables in the visited frame.
199      * @param local the local variable types in this frame. This array must not
200      *        be modified. Primitive types are represented by
201      *        {@link Opcodes#TOP}, {@link Opcodes#INTEGER},
202      *        {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
203      *        {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
204      *        {@link Opcodes#UNINITIALIZED_THIS} (long and double are
205      *        represented by a single element). Reference types are represented
206      *        by String objects (representing internal names), and uninitialized
207      *        types by Label objects (this label designates the NEW instruction
208      *        that created this uninitialized value).
209      * @param nStack the number of operand stack elements in the visited frame.
210      * @param stack the operand stack types in this frame. This array must not
211      *        be modified. Its content has the same format as the "local" array.
212      * @throws IllegalStateException if a frame is visited just after another
213      *        one, without any instruction between the two (unless this frame
214      *        is a Opcodes#F_SAME frame, in which case it is silently ignored).
215      */
visitFrame( int type, int nLocal, Object[] local, int nStack, Object[] stack)216     public void visitFrame(
217         int type,
218         int nLocal,
219         Object[] local,
220         int nStack,
221         Object[] stack)
222     {
223         if (mv != null) {
224             mv.visitFrame(type, nLocal, local, nStack, stack);
225         }
226     }
227 
228     // -------------------------------------------------------------------------
229     // Normal instructions
230     // -------------------------------------------------------------------------
231 
232     /**
233      * Visits a zero operand instruction.
234      *
235      * @param opcode the opcode of the instruction to be visited. This opcode is
236      *        either NOP, ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2,
237      *        ICONST_3, ICONST_4, ICONST_5, LCONST_0, LCONST_1, FCONST_0,
238      *        FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD, FALOAD,
239      *        DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE,
240      *        DASTORE, AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP,
241      *        DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, SWAP, IADD, LADD, FADD,
242      *        DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
243      *        FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL,
244      *        LSHL, ISHR, LSHR, IUSHR, LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR,
245      *        I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I, D2L, D2F, I2B,
246      *        I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN,
247      *        FRETURN, DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW,
248      *        MONITORENTER, or MONITOREXIT.
249      */
visitInsn(int opcode)250     public void visitInsn(int opcode) {
251         if (mv != null) {
252             mv.visitInsn(opcode);
253         }
254     }
255 
256     /**
257      * Visits an instruction with a single int operand.
258      *
259      * @param opcode the opcode of the instruction to be visited. This opcode is
260      *        either BIPUSH, SIPUSH or NEWARRAY.
261      * @param operand the operand of the instruction to be visited.<br> When
262      *        opcode is BIPUSH, operand value should be between Byte.MIN_VALUE
263      *        and Byte.MAX_VALUE.<br> When opcode is SIPUSH, operand value
264      *        should be between Short.MIN_VALUE and Short.MAX_VALUE.<br> When
265      *        opcode is NEWARRAY, operand value should be one of
266      *        {@link Opcodes#T_BOOLEAN}, {@link Opcodes#T_CHAR},
267      *        {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE},
268      *        {@link Opcodes#T_BYTE}, {@link Opcodes#T_SHORT},
269      *        {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
270      */
visitIntInsn(int opcode, int operand)271     public void visitIntInsn(int opcode, int operand) {
272         if (mv != null) {
273             mv.visitIntInsn(opcode, operand);
274         }
275     }
276 
277     /**
278      * Visits a local variable instruction. A local variable instruction is an
279      * instruction that loads or stores the value of a local variable.
280      *
281      * @param opcode the opcode of the local variable instruction to be visited.
282      *        This opcode is either ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE,
283      *        LSTORE, FSTORE, DSTORE, ASTORE or RET.
284      * @param var the operand of the instruction to be visited. This operand is
285      *        the index of a local variable.
286      */
visitVarInsn(int opcode, int var)287     public void visitVarInsn(int opcode, int var) {
288         if (mv != null) {
289             mv.visitVarInsn(opcode, var);
290         }
291     }
292 
293     /**
294      * Visits a type instruction. A type instruction is an instruction that
295      * takes the internal name of a class as parameter.
296      *
297      * @param opcode the opcode of the type instruction to be visited. This
298      *        opcode is either NEW, ANEWARRAY, CHECKCAST or INSTANCEOF.
299      * @param type the operand of the instruction to be visited. This operand
300      *        must be the internal name of an object or array class (see {@link
301      *        Type#getInternalName() getInternalName}).
302      */
visitTypeInsn(int opcode, String type)303     public void visitTypeInsn(int opcode, String type) {
304         if (mv != null) {
305             mv.visitTypeInsn(opcode, type);
306         }
307     }
308 
309     /**
310      * Visits a field instruction. A field instruction is an instruction that
311      * loads or stores the value of a field of an object.
312      *
313      * @param opcode the opcode of the type instruction to be visited. This
314      *        opcode is either GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
315      * @param owner the internal name of the field's owner class (see {@link
316      *        Type#getInternalName() getInternalName}).
317      * @param name the field's name.
318      * @param desc the field's descriptor (see {@link Type Type}).
319      */
visitFieldInsn(int opcode, String owner, String name, String desc)320     public void visitFieldInsn(int opcode, String owner, String name, String desc) {
321         if (mv != null) {
322             mv.visitFieldInsn(opcode, owner, name, desc);
323         }
324     }
325 
326     /**
327      * Visits a method instruction. A method instruction is an instruction that
328      * invokes a method.
329      *
330      * @param opcode the opcode of the type instruction to be visited. This
331      *        opcode is either INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC
332      *        or INVOKEINTERFACE.
333      * @param owner the internal name of the method's owner class (see {@link
334      *        Type#getInternalName() getInternalName}).
335      * @param name the method's name.
336      * @param desc the method's descriptor (see {@link Type Type}).
337      */
visitMethodInsn(int opcode, String owner, String name, String desc)338     public void visitMethodInsn(int opcode, String owner, String name, String desc) {
339         if (mv != null) {
340             mv.visitMethodInsn(opcode, owner, name, desc);
341         }
342     }
343 
344     /**
345      * Visits an invokedynamic instruction.
346      *
347      * @param name the method's name.
348      * @param desc the method's descriptor (see {@link Type Type}).
349      * @param bsm the bootstrap method.
350      * @param bsmArgs the bootstrap method constant arguments. Each argument
351      *        must be an {@link Integer}, {@link Float}, {@link Long},
352      *        {@link Double}, {@link String}, {@link Type} or {@link Handle}
353      *        value. This method is allowed to modify the content of the array
354      *        so a caller should expect that this array may change.
355      */
visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs)356     public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
357         if (mv != null) {
358             mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs);
359         }
360     }
361 
362     /**
363      * Visits a jump instruction. A jump instruction is an instruction that may
364      * jump to another instruction.
365      *
366      * @param opcode the opcode of the type instruction to be visited. This
367      *        opcode is either IFEQ, IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ,
368      *        IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT, IF_ICMPLE, IF_ACMPEQ,
369      *        IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
370      * @param label the operand of the instruction to be visited. This operand
371      *        is a label that designates the instruction to which the jump
372      *        instruction may jump.
373      */
visitJumpInsn(int opcode, Label label)374     public void visitJumpInsn(int opcode, Label label) {
375         if (mv != null) {
376             mv.visitJumpInsn(opcode, label);
377         }
378     }
379 
380     /**
381      * Visits a label. A label designates the instruction that will be visited
382      * just after it.
383      *
384      * @param label a {@link Label Label} object.
385      */
visitLabel(Label label)386     public void visitLabel(Label label) {
387         if (mv != null) {
388             mv.visitLabel(label);
389         }
390     }
391 
392     // -------------------------------------------------------------------------
393     // Special instructions
394     // -------------------------------------------------------------------------
395 
396     /**
397      * Visits a LDC instruction. Note that new constant types may be added in
398      * future versions of the Java Virtual Machine. To easily detect new
399      * constant types, implementations of this method should check for
400      * unexpected constant types, like this:
401      * <pre>
402      * if (cst instanceof Integer) {
403      *   // ...
404      * } else if (cst instanceof Float) {
405      *   // ...
406      * } else if (cst instanceof Long) {
407      *   // ...
408      * } else if (cst instanceof Double) {
409      *   // ...
410      * } else if (cst instanceof String) {
411      *   // ...
412      * } else if (cst instanceof Type) {
413      *   int sort = ((Type) cst).getSort();
414      *   if (sort == Type.OBJECT) {
415      *     // ...
416      *   } else if (sort == Type.ARRAY) {
417      *     // ...
418      *   } else if (sort == Type.METHOD) {
419      *     // ...
420      *   } else {
421      *     // throw an exception
422      *   }
423      * } else if (cst instanceof Handle) {
424      *   // ...
425      * } else {
426      *   // throw an exception
427      * }</pre>
428      *
429      * @param cst the constant to be loaded on the stack. This parameter must be
430      *        a non null {@link Integer}, a {@link Float}, a {@link Long}, a
431      *        {@link Double}, a {@link String}, a {@link Type} of OBJECT or ARRAY
432      *        sort for <tt>.class</tt> constants, for classes whose version is
433      *        49.0, a {@link Type} of METHOD sort or a {@link Handle} for
434      *        MethodType and MethodHandle constants, for classes whose version
435      *        is 51.0.
436      */
visitLdcInsn(Object cst)437     public void visitLdcInsn(Object cst) {
438         if (mv != null) {
439             mv.visitLdcInsn(cst);
440         }
441     }
442 
443     /**
444      * Visits an IINC instruction.
445      *
446      * @param var index of the local variable to be incremented.
447      * @param increment amount to increment the local variable by.
448      */
visitIincInsn(int var, int increment)449     public void visitIincInsn(int var, int increment) {
450         if (mv != null) {
451             mv.visitIincInsn(var, increment);
452         }
453     }
454 
455     /**
456      * Visits a TABLESWITCH instruction.
457      *
458      * @param min the minimum key value.
459      * @param max the maximum key value.
460      * @param dflt beginning of the default handler block.
461      * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
462      *        the beginning of the handler block for the <tt>min + i</tt> key.
463      */
visitTableSwitchInsn(int min, int max, Label dflt, Label... labels)464     public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
465         if (mv != null) {
466             mv.visitTableSwitchInsn(min, max, dflt, labels);
467         }
468     }
469 
470     /**
471      * Visits a LOOKUPSWITCH instruction.
472      *
473      * @param dflt beginning of the default handler block.
474      * @param keys the values of the keys.
475      * @param labels beginnings of the handler blocks. <tt>labels[i]</tt> is
476      *        the beginning of the handler block for the <tt>keys[i]</tt> key.
477      */
visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels)478     public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
479         if (mv != null) {
480             mv.visitLookupSwitchInsn(dflt, keys, labels);
481         }
482     }
483 
484     /**
485      * Visits a MULTIANEWARRAY instruction.
486      *
487      * @param desc an array type descriptor (see {@link Type Type}).
488      * @param dims number of dimensions of the array to allocate.
489      */
visitMultiANewArrayInsn(String desc, int dims)490     public void visitMultiANewArrayInsn(String desc, int dims) {
491         if (mv != null) {
492             mv.visitMultiANewArrayInsn(desc, dims);
493         }
494     }
495 
496     // -------------------------------------------------------------------------
497     // Exceptions table entries, debug information, max stack and max locals
498     // -------------------------------------------------------------------------
499 
500     /**
501      * Visits a try catch block.
502      *
503      * @param start beginning of the exception handler's scope (inclusive).
504      * @param end end of the exception handler's scope (exclusive).
505      * @param handler beginning of the exception handler's code.
506      * @param type internal name of the type of exceptions handled by the
507      *        handler, or <tt>null</tt> to catch any exceptions (for "finally"
508      *        blocks).
509      * @throws IllegalArgumentException if one of the labels has already been
510      *         visited by this visitor (by the {@link #visitLabel visitLabel}
511      *         method).
512      */
visitTryCatchBlock(Label start, Label end, Label handler, String type)513     public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
514         if (mv != null) {
515             mv.visitTryCatchBlock(start, end, handler, type);
516         }
517     }
518 
519     /**
520      * Visits a local variable declaration.
521      *
522      * @param name the name of a local variable.
523      * @param desc the type descriptor of this local variable.
524      * @param signature the type signature of this local variable. May be
525      *        <tt>null</tt> if the local variable type does not use generic
526      *        types.
527      * @param start the first instruction corresponding to the scope of this
528      *        local variable (inclusive).
529      * @param end the last instruction corresponding to the scope of this local
530      *        variable (exclusive).
531      * @param index the local variable's index.
532      * @throws IllegalArgumentException if one of the labels has not already
533      *         been visited by this visitor (by the
534      *         {@link #visitLabel visitLabel} method).
535      */
visitLocalVariable( String name, String desc, String signature, Label start, Label end, int index)536     public void visitLocalVariable(
537         String name,
538         String desc,
539         String signature,
540         Label start,
541         Label end,
542         int index)
543     {
544         if (mv != null) {
545             mv.visitLocalVariable(name, desc, signature, start, end, index);
546         }
547     }
548 
549     /**
550      * Visits a line number declaration.
551      *
552      * @param line a line number. This number refers to the source file from
553      *        which the class was compiled.
554      * @param start the first instruction corresponding to this line number.
555      * @throws IllegalArgumentException if <tt>start</tt> has not already been
556      *         visited by this visitor (by the {@link #visitLabel visitLabel}
557      *         method).
558      */
visitLineNumber(int line, Label start)559     public void visitLineNumber(int line, Label start) {
560         if (mv != null) {
561             mv.visitLineNumber(line, start);
562         }
563     }
564 
565     /**
566      * Visits the maximum stack size and the maximum number of local variables
567      * of the method.
568      *
569      * @param maxStack maximum stack size of the method.
570      * @param maxLocals maximum number of local variables for the method.
571      */
visitMaxs(int maxStack, int maxLocals)572     public void visitMaxs(int maxStack, int maxLocals) {
573         if (mv != null) {
574             mv.visitMaxs(maxStack, maxLocals);
575         }
576     }
577 
578     /**
579      * Visits the end of the method. This method, which is the last one to be
580      * called, is used to inform the visitor that all the annotations and
581      * attributes of the method have been visited.
582      */
visitEnd()583     public void visitEnd() {
584         if (mv != null) {
585             mv.visitEnd();
586         }
587     }
588 }
589