Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/org/objectweb/asm/MethodVisitor.java
42362 views
1
/*
2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3
*
4
* This code is free software; you can redistribute it and/or modify it
5
* under the terms of the GNU General Public License version 2 only, as
6
* published by the Free Software Foundation. Oracle designates this
7
* particular file as subject to the "Classpath" exception as provided
8
* by Oracle in the LICENSE file that accompanied this code.
9
*
10
* This code is distributed in the hope that it will be useful, but WITHOUT
11
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13
* version 2 for more details (a copy is included in the LICENSE file that
14
* accompanied this code).
15
*
16
* You should have received a copy of the GNU General Public License version
17
* 2 along with this work; if not, write to the Free Software Foundation,
18
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19
*
20
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21
* or visit www.oracle.com if you need additional information or have any
22
* questions.
23
*/
24
25
/*
26
* This file is available under and governed by the GNU General Public
27
* License version 2 only, as published by the Free Software Foundation.
28
* However, the following notice accompanied the original version of this
29
* file:
30
*
31
* ASM: a very small and fast Java bytecode manipulation framework
32
* Copyright (c) 2000-2011 INRIA, France Telecom
33
* All rights reserved.
34
*
35
* Redistribution and use in source and binary forms, with or without
36
* modification, are permitted provided that the following conditions
37
* are met:
38
* 1. Redistributions of source code must retain the above copyright
39
* notice, this list of conditions and the following disclaimer.
40
* 2. Redistributions in binary form must reproduce the above copyright
41
* notice, this list of conditions and the following disclaimer in the
42
* documentation and/or other materials provided with the distribution.
43
* 3. Neither the name of the copyright holders nor the names of its
44
* contributors may be used to endorse or promote products derived from
45
* this software without specific prior written permission.
46
*
47
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
48
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
51
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
52
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
53
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
54
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
55
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
56
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
57
* THE POSSIBILITY OF SUCH DAMAGE.
58
*/
59
package jdk.internal.org.objectweb.asm;
60
61
/**
62
* A visitor to visit a Java method. The methods of this class must be called in the following
63
* order: ( {@code visitParameter} )* [ {@code visitAnnotationDefault} ] ( {@code visitAnnotation} |
64
* {@code visitAnnotableParameterCount} | {@code visitParameterAnnotation} {@code
65
* visitTypeAnnotation} | {@code visitAttribute} )* [ {@code visitCode} ( {@code visitFrame} |
66
* {@code visit<i>X</i>Insn} | {@code visitLabel} | {@code visitInsnAnnotation} | {@code
67
* visitTryCatchBlock} | {@code visitTryCatchAnnotation} | {@code visitLocalVariable} | {@code
68
* visitLocalVariableAnnotation} | {@code visitLineNumber} )* {@code visitMaxs} ] {@code visitEnd}.
69
* In addition, the {@code visit<i>X</i>Insn} and {@code visitLabel} methods must be called in the
70
* sequential order of the bytecode instructions of the visited code, {@code visitInsnAnnotation}
71
* must be called <i>after</i> the annotated instruction, {@code visitTryCatchBlock} must be called
72
* <i>before</i> the labels passed as arguments have been visited, {@code
73
* visitTryCatchBlockAnnotation} must be called <i>after</i> the corresponding try catch block has
74
* been visited, and the {@code visitLocalVariable}, {@code visitLocalVariableAnnotation} and {@code
75
* visitLineNumber} methods must be called <i>after</i> the labels passed as arguments have been
76
* visited.
77
*
78
* @author Eric Bruneton
79
*/
80
public abstract class MethodVisitor {
81
82
private static final String REQUIRES_ASM5 = "This feature requires ASM5";
83
84
/**
85
* The ASM API version implemented by this visitor. The value of this field must be one of {@link
86
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
87
*/
88
protected final int api;
89
90
/**
91
* The method visitor to which this visitor must delegate method calls. May be {@literal null}.
92
*/
93
protected MethodVisitor mv;
94
95
/**
96
* Constructs a new {@link MethodVisitor}.
97
*
98
* @param api the ASM API version implemented by this visitor. Must be one of {@link
99
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
100
*/
101
public MethodVisitor(final int api) {
102
this(api, null);
103
}
104
105
/**
106
* Constructs a new {@link MethodVisitor}.
107
*
108
* @param api the ASM API version implemented by this visitor. Must be one of {@link
109
* Opcodes#ASM4}, {@link Opcodes#ASM5}, {@link Opcodes#ASM6} or {@link Opcodes#ASM7}.
110
* @param methodVisitor the method visitor to which this visitor must delegate method calls. May
111
* be null.
112
*/
113
@SuppressWarnings("deprecation")
114
public MethodVisitor(final int api, final MethodVisitor methodVisitor) {
115
if (api != Opcodes.ASM8
116
&& api != Opcodes.ASM7
117
&& api != Opcodes.ASM6
118
&& api != Opcodes.ASM5
119
&& api != Opcodes.ASM4
120
&& api != Opcodes.ASM9_EXPERIMENTAL) {
121
throw new IllegalArgumentException("Unsupported api " + api);
122
}
123
if (api == Opcodes.ASM9_EXPERIMENTAL) {
124
Constants.checkAsmExperimental(this);
125
}
126
this.api = api;
127
this.mv = methodVisitor;
128
}
129
130
// -----------------------------------------------------------------------------------------------
131
// Parameters, annotations and non standard attributes
132
// -----------------------------------------------------------------------------------------------
133
134
/**
135
* Visits a parameter of this method.
136
*
137
* @param name parameter name or {@literal null} if none is provided.
138
* @param access the parameter's access flags, only {@code ACC_FINAL}, {@code ACC_SYNTHETIC}
139
* or/and {@code ACC_MANDATED} are allowed (see {@link Opcodes}).
140
*/
141
public void visitParameter(final String name, final int access) {
142
if (api < Opcodes.ASM5) {
143
throw new UnsupportedOperationException(REQUIRES_ASM5);
144
}
145
if (mv != null) {
146
mv.visitParameter(name, access);
147
}
148
}
149
150
/**
151
* Visits the default value of this annotation interface method.
152
*
153
* @return a visitor to the visit the actual default value of this annotation interface method, or
154
* {@literal null} if this visitor is not interested in visiting this default value. The
155
* 'name' parameters passed to the methods of this annotation visitor are ignored. Moreover,
156
* exacly one visit method must be called on this annotation visitor, followed by visitEnd.
157
*/
158
public AnnotationVisitor visitAnnotationDefault() {
159
if (mv != null) {
160
return mv.visitAnnotationDefault();
161
}
162
return null;
163
}
164
165
/**
166
* Visits an annotation of this method.
167
*
168
* @param descriptor the class descriptor of the annotation class.
169
* @param visible {@literal true} if the annotation is visible at runtime.
170
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
171
* interested in visiting this annotation.
172
*/
173
public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
174
if (mv != null) {
175
return mv.visitAnnotation(descriptor, visible);
176
}
177
return null;
178
}
179
180
/**
181
* Visits an annotation on a type in the method signature.
182
*
183
* @param typeRef a reference to the annotated type. The sort of this type reference must be
184
* {@link TypeReference#METHOD_TYPE_PARAMETER}, {@link
185
* TypeReference#METHOD_TYPE_PARAMETER_BOUND}, {@link TypeReference#METHOD_RETURN}, {@link
186
* TypeReference#METHOD_RECEIVER}, {@link TypeReference#METHOD_FORMAL_PARAMETER} or {@link
187
* TypeReference#THROWS}. See {@link TypeReference}.
188
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
189
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
190
* 'typeRef' as a whole.
191
* @param descriptor the class descriptor of the annotation class.
192
* @param visible {@literal true} if the annotation is visible at runtime.
193
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
194
* interested in visiting this annotation.
195
*/
196
public AnnotationVisitor visitTypeAnnotation(
197
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
198
if (api < Opcodes.ASM5) {
199
throw new UnsupportedOperationException(REQUIRES_ASM5);
200
}
201
if (mv != null) {
202
return mv.visitTypeAnnotation(typeRef, typePath, descriptor, visible);
203
}
204
return null;
205
}
206
207
/**
208
* Visits the number of method parameters that can have annotations. By default (i.e. when this
209
* method is not called), all the method parameters defined by the method descriptor can have
210
* annotations.
211
*
212
* @param parameterCount the number of method parameters than can have annotations. This number
213
* must be less or equal than the number of parameter types in the method descriptor. It can
214
* be strictly less when a method has synthetic parameters and when these parameters are
215
* ignored when computing parameter indices for the purpose of parameter annotations (see
216
* https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
217
* @param visible {@literal true} to define the number of method parameters that can have
218
* annotations visible at runtime, {@literal false} to define the number of method parameters
219
* that can have annotations invisible at runtime.
220
*/
221
public void visitAnnotableParameterCount(final int parameterCount, final boolean visible) {
222
if (mv != null) {
223
mv.visitAnnotableParameterCount(parameterCount, visible);
224
}
225
}
226
227
/**
228
* Visits an annotation of a parameter this method.
229
*
230
* @param parameter the parameter index. This index must be strictly smaller than the number of
231
* parameters in the method descriptor, and strictly smaller than the parameter count
232
* specified in {@link #visitAnnotableParameterCount}. Important note: <i>a parameter index i
233
* is not required to correspond to the i'th parameter descriptor in the method
234
* descriptor</i>, in particular in case of synthetic parameters (see
235
* https://docs.oracle.com/javase/specs/jvms/se9/html/jvms-4.html#jvms-4.7.18).
236
* @param descriptor the class descriptor of the annotation class.
237
* @param visible {@literal true} if the annotation is visible at runtime.
238
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
239
* interested in visiting this annotation.
240
*/
241
public AnnotationVisitor visitParameterAnnotation(
242
final int parameter, final String descriptor, final boolean visible) {
243
if (mv != null) {
244
return mv.visitParameterAnnotation(parameter, descriptor, visible);
245
}
246
return null;
247
}
248
249
/**
250
* Visits a non standard attribute of this method.
251
*
252
* @param attribute an attribute.
253
*/
254
public void visitAttribute(final Attribute attribute) {
255
if (mv != null) {
256
mv.visitAttribute(attribute);
257
}
258
}
259
260
/** Starts the visit of the method's code, if any (i.e. non abstract method). */
261
public void visitCode() {
262
if (mv != null) {
263
mv.visitCode();
264
}
265
}
266
267
/**
268
* Visits the current state of the local variables and operand stack elements. This method must(*)
269
* be called <i>just before</i> any instruction <b>i</b> that follows an unconditional branch
270
* instruction such as GOTO or THROW, that is the target of a jump instruction, or that starts an
271
* exception handler block. The visited types must describe the values of the local variables and
272
* of the operand stack elements <i>just before</i> <b>i</b> is executed.<br>
273
* <br>
274
* (*) this is mandatory only for classes whose version is greater than or equal to {@link
275
* Opcodes#V1_6}. <br>
276
* <br>
277
* The frames of a method must be given either in expanded form, or in compressed form (all frames
278
* must use the same format, i.e. you must not mix expanded and compressed frames within a single
279
* method):
280
*
281
* <ul>
282
* <li>In expanded form, all frames must have the F_NEW type.
283
* <li>In compressed form, frames are basically "deltas" from the state of the previous frame:
284
* <ul>
285
* <li>{@link Opcodes#F_SAME} representing frame with exactly the same locals as the
286
* previous frame and with the empty stack.
287
* <li>{@link Opcodes#F_SAME1} representing frame with exactly the same locals as the
288
* previous frame and with single value on the stack ( <code>numStack</code> is 1 and
289
* <code>stack[0]</code> contains value for the type of the stack item).
290
* <li>{@link Opcodes#F_APPEND} representing frame with current locals are the same as the
291
* locals in the previous frame, except that additional locals are defined (<code>
292
* numLocal</code> is 1, 2 or 3 and <code>local</code> elements contains values
293
* representing added types).
294
* <li>{@link Opcodes#F_CHOP} representing frame with current locals are the same as the
295
* locals in the previous frame, except that the last 1-3 locals are absent and with
296
* the empty stack (<code>numLocal</code> is 1, 2 or 3).
297
* <li>{@link Opcodes#F_FULL} representing complete frame data.
298
* </ul>
299
* </ul>
300
*
301
* <br>
302
* In both cases the first frame, corresponding to the method's parameters and access flags, is
303
* implicit and must not be visited. Also, it is illegal to visit two or more frames for the same
304
* code location (i.e., at least one instruction must be visited between two calls to visitFrame).
305
*
306
* @param type the type of this stack map frame. Must be {@link Opcodes#F_NEW} for expanded
307
* frames, or {@link Opcodes#F_FULL}, {@link Opcodes#F_APPEND}, {@link Opcodes#F_CHOP}, {@link
308
* Opcodes#F_SAME} or {@link Opcodes#F_APPEND}, {@link Opcodes#F_SAME1} for compressed frames.
309
* @param numLocal the number of local variables in the visited frame.
310
* @param local the local variable types in this frame. This array must not be modified. Primitive
311
* types are represented by {@link Opcodes#TOP}, {@link Opcodes#INTEGER}, {@link
312
* Opcodes#FLOAT}, {@link Opcodes#LONG}, {@link Opcodes#DOUBLE}, {@link Opcodes#NULL} or
313
* {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a single element).
314
* Reference types are represented by String objects (representing internal names), and
315
* uninitialized types by Label objects (this label designates the NEW instruction that
316
* created this uninitialized value).
317
* @param numStack the number of operand stack elements in the visited frame.
318
* @param stack the operand stack types in this frame. This array must not be modified. Its
319
* content has the same format as the "local" array.
320
* @throws IllegalStateException if a frame is visited just after another one, without any
321
* instruction between the two (unless this frame is a Opcodes#F_SAME frame, in which case it
322
* is silently ignored).
323
*/
324
public void visitFrame(
325
final int type,
326
final int numLocal,
327
final Object[] local,
328
final int numStack,
329
final Object[] stack) {
330
if (mv != null) {
331
mv.visitFrame(type, numLocal, local, numStack, stack);
332
}
333
}
334
335
// -----------------------------------------------------------------------------------------------
336
// Normal instructions
337
// -----------------------------------------------------------------------------------------------
338
339
/**
340
* Visits a zero operand instruction.
341
*
342
* @param opcode the opcode of the instruction to be visited. This opcode is either NOP,
343
* ACONST_NULL, ICONST_M1, ICONST_0, ICONST_1, ICONST_2, ICONST_3, ICONST_4, ICONST_5,
344
* LCONST_0, LCONST_1, FCONST_0, FCONST_1, FCONST_2, DCONST_0, DCONST_1, IALOAD, LALOAD,
345
* FALOAD, DALOAD, AALOAD, BALOAD, CALOAD, SALOAD, IASTORE, LASTORE, FASTORE, DASTORE,
346
* AASTORE, BASTORE, CASTORE, SASTORE, POP, POP2, DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2,
347
* SWAP, IADD, LADD, FADD, DADD, ISUB, LSUB, FSUB, DSUB, IMUL, LMUL, FMUL, DMUL, IDIV, LDIV,
348
* FDIV, DDIV, IREM, LREM, FREM, DREM, INEG, LNEG, FNEG, DNEG, ISHL, LSHL, ISHR, LSHR, IUSHR,
349
* LUSHR, IAND, LAND, IOR, LOR, IXOR, LXOR, I2L, I2F, I2D, L2I, L2F, L2D, F2I, F2L, F2D, D2I,
350
* D2L, D2F, I2B, I2C, I2S, LCMP, FCMPL, FCMPG, DCMPL, DCMPG, IRETURN, LRETURN, FRETURN,
351
* DRETURN, ARETURN, RETURN, ARRAYLENGTH, ATHROW, MONITORENTER, or MONITOREXIT.
352
*/
353
public void visitInsn(final int opcode) {
354
if (mv != null) {
355
mv.visitInsn(opcode);
356
}
357
}
358
359
/**
360
* Visits an instruction with a single int operand.
361
*
362
* @param opcode the opcode of the instruction to be visited. This opcode is either BIPUSH, SIPUSH
363
* or NEWARRAY.
364
* @param operand the operand of the instruction to be visited.<br>
365
* When opcode is BIPUSH, operand value should be between Byte.MIN_VALUE and Byte.MAX_VALUE.
366
* <br>
367
* When opcode is SIPUSH, operand value should be between Short.MIN_VALUE and Short.MAX_VALUE.
368
* <br>
369
* When opcode is NEWARRAY, operand value should be one of {@link Opcodes#T_BOOLEAN}, {@link
370
* Opcodes#T_CHAR}, {@link Opcodes#T_FLOAT}, {@link Opcodes#T_DOUBLE}, {@link Opcodes#T_BYTE},
371
* {@link Opcodes#T_SHORT}, {@link Opcodes#T_INT} or {@link Opcodes#T_LONG}.
372
*/
373
public void visitIntInsn(final int opcode, final int operand) {
374
if (mv != null) {
375
mv.visitIntInsn(opcode, operand);
376
}
377
}
378
379
/**
380
* Visits a local variable instruction. A local variable instruction is an instruction that loads
381
* or stores the value of a local variable.
382
*
383
* @param opcode the opcode of the local variable instruction to be visited. This opcode is either
384
* ILOAD, LLOAD, FLOAD, DLOAD, ALOAD, ISTORE, LSTORE, FSTORE, DSTORE, ASTORE or RET.
385
* @param var the operand of the instruction to be visited. This operand is the index of a local
386
* variable.
387
*/
388
public void visitVarInsn(final int opcode, final int var) {
389
if (mv != null) {
390
mv.visitVarInsn(opcode, var);
391
}
392
}
393
394
/**
395
* Visits a type instruction. A type instruction is an instruction that takes the internal name of
396
* a class as parameter.
397
*
398
* @param opcode the opcode of the type instruction to be visited. This opcode is either NEW,
399
* ANEWARRAY, CHECKCAST or INSTANCEOF.
400
* @param type the operand of the instruction to be visited. This operand must be the internal
401
* name of an object or array class (see {@link Type#getInternalName()}).
402
*/
403
public void visitTypeInsn(final int opcode, final String type) {
404
if (mv != null) {
405
mv.visitTypeInsn(opcode, type);
406
}
407
}
408
409
/**
410
* Visits a field instruction. A field instruction is an instruction that loads or stores the
411
* value of a field of an object.
412
*
413
* @param opcode the opcode of the type instruction to be visited. This opcode is either
414
* GETSTATIC, PUTSTATIC, GETFIELD or PUTFIELD.
415
* @param owner the internal name of the field's owner class (see {@link Type#getInternalName()}).
416
* @param name the field's name.
417
* @param descriptor the field's descriptor (see {@link Type}).
418
*/
419
public void visitFieldInsn(
420
final int opcode, final String owner, final String name, final String descriptor) {
421
if (mv != null) {
422
mv.visitFieldInsn(opcode, owner, name, descriptor);
423
}
424
}
425
426
/**
427
* Visits a method instruction. A method instruction is an instruction that invokes a method.
428
*
429
* @param opcode the opcode of the type instruction to be visited. This opcode is either
430
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
431
* @param owner the internal name of the method's owner class (see {@link
432
* Type#getInternalName()}).
433
* @param name the method's name.
434
* @param descriptor the method's descriptor (see {@link Type}).
435
* @deprecated use {@link #visitMethodInsn(int, String, String, String, boolean)} instead.
436
*/
437
@Deprecated
438
public void visitMethodInsn(
439
final int opcode, final String owner, final String name, final String descriptor) {
440
int opcodeAndSource = opcode | (api < Opcodes.ASM5 ? Opcodes.SOURCE_DEPRECATED : 0);
441
visitMethodInsn(opcodeAndSource, owner, name, descriptor, opcode == Opcodes.INVOKEINTERFACE);
442
}
443
444
/**
445
* Visits a method instruction. A method instruction is an instruction that invokes a method.
446
*
447
* @param opcode the opcode of the type instruction to be visited. This opcode is either
448
* INVOKEVIRTUAL, INVOKESPECIAL, INVOKESTATIC or INVOKEINTERFACE.
449
* @param owner the internal name of the method's owner class (see {@link
450
* Type#getInternalName()}).
451
* @param name the method's name.
452
* @param descriptor the method's descriptor (see {@link Type}).
453
* @param isInterface if the method's owner class is an interface.
454
*/
455
public void visitMethodInsn(
456
final int opcode,
457
final String owner,
458
final String name,
459
final String descriptor,
460
final boolean isInterface) {
461
if (api < Opcodes.ASM5 && (opcode & Opcodes.SOURCE_DEPRECATED) == 0) {
462
if (isInterface != (opcode == Opcodes.INVOKEINTERFACE)) {
463
throw new UnsupportedOperationException("INVOKESPECIAL/STATIC on interfaces requires ASM5");
464
}
465
visitMethodInsn(opcode, owner, name, descriptor);
466
return;
467
}
468
if (mv != null) {
469
mv.visitMethodInsn(opcode & ~Opcodes.SOURCE_MASK, owner, name, descriptor, isInterface);
470
}
471
}
472
473
/**
474
* Visits an invokedynamic instruction.
475
*
476
* @param name the method's name.
477
* @param descriptor the method's descriptor (see {@link Type}).
478
* @param bootstrapMethodHandle the bootstrap method.
479
* @param bootstrapMethodArguments the bootstrap method constant arguments. Each argument must be
480
* an {@link Integer}, {@link Float}, {@link Long}, {@link Double}, {@link String}, {@link
481
* Type}, {@link Handle} or {@link ConstantDynamic} value. This method is allowed to modify
482
* the content of the array so a caller should expect that this array may change.
483
*/
484
public void visitInvokeDynamicInsn(
485
final String name,
486
final String descriptor,
487
final Handle bootstrapMethodHandle,
488
final Object... bootstrapMethodArguments) {
489
if (api < Opcodes.ASM5) {
490
throw new UnsupportedOperationException(REQUIRES_ASM5);
491
}
492
if (mv != null) {
493
mv.visitInvokeDynamicInsn(name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
494
}
495
}
496
497
/**
498
* Visits a jump instruction. A jump instruction is an instruction that may jump to another
499
* instruction.
500
*
501
* @param opcode the opcode of the type instruction to be visited. This opcode is either IFEQ,
502
* IFNE, IFLT, IFGE, IFGT, IFLE, IF_ICMPEQ, IF_ICMPNE, IF_ICMPLT, IF_ICMPGE, IF_ICMPGT,
503
* IF_ICMPLE, IF_ACMPEQ, IF_ACMPNE, GOTO, JSR, IFNULL or IFNONNULL.
504
* @param label the operand of the instruction to be visited. This operand is a label that
505
* designates the instruction to which the jump instruction may jump.
506
*/
507
public void visitJumpInsn(final int opcode, final Label label) {
508
if (mv != null) {
509
mv.visitJumpInsn(opcode, label);
510
}
511
}
512
513
/**
514
* Visits a label. A label designates the instruction that will be visited just after it.
515
*
516
* @param label a {@link Label} object.
517
*/
518
public void visitLabel(final Label label) {
519
if (mv != null) {
520
mv.visitLabel(label);
521
}
522
}
523
524
// -----------------------------------------------------------------------------------------------
525
// Special instructions
526
// -----------------------------------------------------------------------------------------------
527
528
/**
529
* Visits a LDC instruction. Note that new constant types may be added in future versions of the
530
* Java Virtual Machine. To easily detect new constant types, implementations of this method
531
* should check for unexpected constant types, like this:
532
*
533
* <pre>
534
* if (cst instanceof Integer) {
535
* // ...
536
* } else if (cst instanceof Float) {
537
* // ...
538
* } else if (cst instanceof Long) {
539
* // ...
540
* } else if (cst instanceof Double) {
541
* // ...
542
* } else if (cst instanceof String) {
543
* // ...
544
* } else if (cst instanceof Type) {
545
* int sort = ((Type) cst).getSort();
546
* if (sort == Type.OBJECT) {
547
* // ...
548
* } else if (sort == Type.ARRAY) {
549
* // ...
550
* } else if (sort == Type.METHOD) {
551
* // ...
552
* } else {
553
* // throw an exception
554
* }
555
* } else if (cst instanceof Handle) {
556
* // ...
557
* } else if (cst instanceof ConstantDynamic) {
558
* // ...
559
* } else {
560
* // throw an exception
561
* }
562
* </pre>
563
*
564
* @param value the constant to be loaded on the stack. This parameter must be a non null {@link
565
* Integer}, a {@link Float}, a {@link Long}, a {@link Double}, a {@link String}, a {@link
566
* Type} of OBJECT or ARRAY sort for {@code .class} constants, for classes whose version is
567
* 49, a {@link Type} of METHOD sort for MethodType, a {@link Handle} for MethodHandle
568
* constants, for classes whose version is 51 or a {@link ConstantDynamic} for a constant
569
* dynamic for classes whose version is 55.
570
*/
571
public void visitLdcInsn(final Object value) {
572
if (api < Opcodes.ASM5
573
&& (value instanceof Handle
574
|| (value instanceof Type && ((Type) value).getSort() == Type.METHOD))) {
575
throw new UnsupportedOperationException(REQUIRES_ASM5);
576
}
577
if (api < Opcodes.ASM7 && value instanceof ConstantDynamic) {
578
throw new UnsupportedOperationException("This feature requires ASM7");
579
}
580
if (mv != null) {
581
mv.visitLdcInsn(value);
582
}
583
}
584
585
/**
586
* Visits an IINC instruction.
587
*
588
* @param var index of the local variable to be incremented.
589
* @param increment amount to increment the local variable by.
590
*/
591
public void visitIincInsn(final int var, final int increment) {
592
if (mv != null) {
593
mv.visitIincInsn(var, increment);
594
}
595
}
596
597
/**
598
* Visits a TABLESWITCH instruction.
599
*
600
* @param min the minimum key value.
601
* @param max the maximum key value.
602
* @param dflt beginning of the default handler block.
603
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
604
* handler block for the {@code min + i} key.
605
*/
606
public void visitTableSwitchInsn(
607
final int min, final int max, final Label dflt, final Label... labels) {
608
if (mv != null) {
609
mv.visitTableSwitchInsn(min, max, dflt, labels);
610
}
611
}
612
613
/**
614
* Visits a LOOKUPSWITCH instruction.
615
*
616
* @param dflt beginning of the default handler block.
617
* @param keys the values of the keys.
618
* @param labels beginnings of the handler blocks. {@code labels[i]} is the beginning of the
619
* handler block for the {@code keys[i]} key.
620
*/
621
public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) {
622
if (mv != null) {
623
mv.visitLookupSwitchInsn(dflt, keys, labels);
624
}
625
}
626
627
/**
628
* Visits a MULTIANEWARRAY instruction.
629
*
630
* @param descriptor an array type descriptor (see {@link Type}).
631
* @param numDimensions the number of dimensions of the array to allocate.
632
*/
633
public void visitMultiANewArrayInsn(final String descriptor, final int numDimensions) {
634
if (mv != null) {
635
mv.visitMultiANewArrayInsn(descriptor, numDimensions);
636
}
637
}
638
639
/**
640
* Visits an annotation on an instruction. This method must be called just <i>after</i> the
641
* annotated instruction. It can be called several times for the same instruction.
642
*
643
* @param typeRef a reference to the annotated type. The sort of this type reference must be
644
* {@link TypeReference#INSTANCEOF}, {@link TypeReference#NEW}, {@link
645
* TypeReference#CONSTRUCTOR_REFERENCE}, {@link TypeReference#METHOD_REFERENCE}, {@link
646
* TypeReference#CAST}, {@link TypeReference#CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT}, {@link
647
* TypeReference#METHOD_INVOCATION_TYPE_ARGUMENT}, {@link
648
* TypeReference#CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT}, or {@link
649
* TypeReference#METHOD_REFERENCE_TYPE_ARGUMENT}. See {@link TypeReference}.
650
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
651
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
652
* 'typeRef' as a whole.
653
* @param descriptor the class descriptor of the annotation class.
654
* @param visible {@literal true} if the annotation is visible at runtime.
655
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
656
* interested in visiting this annotation.
657
*/
658
public AnnotationVisitor visitInsnAnnotation(
659
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
660
if (api < Opcodes.ASM5) {
661
throw new UnsupportedOperationException(REQUIRES_ASM5);
662
}
663
if (mv != null) {
664
return mv.visitInsnAnnotation(typeRef, typePath, descriptor, visible);
665
}
666
return null;
667
}
668
669
// -----------------------------------------------------------------------------------------------
670
// Exceptions table entries, debug information, max stack and max locals
671
// -----------------------------------------------------------------------------------------------
672
673
/**
674
* Visits a try catch block.
675
*
676
* @param start the beginning of the exception handler's scope (inclusive).
677
* @param end the end of the exception handler's scope (exclusive).
678
* @param handler the beginning of the exception handler's code.
679
* @param type the internal name of the type of exceptions handled by the handler, or {@literal
680
* null} to catch any exceptions (for "finally" blocks).
681
* @throws IllegalArgumentException if one of the labels has already been visited by this visitor
682
* (by the {@link #visitLabel} method).
683
*/
684
public void visitTryCatchBlock(
685
final Label start, final Label end, final Label handler, final String type) {
686
if (mv != null) {
687
mv.visitTryCatchBlock(start, end, handler, type);
688
}
689
}
690
691
/**
692
* Visits an annotation on an exception handler type. This method must be called <i>after</i> the
693
* {@link #visitTryCatchBlock} for the annotated exception handler. It can be called several times
694
* for the same exception handler.
695
*
696
* @param typeRef a reference to the annotated type. The sort of this type reference must be
697
* {@link TypeReference#EXCEPTION_PARAMETER}. See {@link TypeReference}.
698
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
699
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
700
* 'typeRef' as a whole.
701
* @param descriptor the class descriptor of the annotation class.
702
* @param visible {@literal true} if the annotation is visible at runtime.
703
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
704
* interested in visiting this annotation.
705
*/
706
public AnnotationVisitor visitTryCatchAnnotation(
707
final int typeRef, final TypePath typePath, final String descriptor, final boolean visible) {
708
if (api < Opcodes.ASM5) {
709
throw new UnsupportedOperationException(REQUIRES_ASM5);
710
}
711
if (mv != null) {
712
return mv.visitTryCatchAnnotation(typeRef, typePath, descriptor, visible);
713
}
714
return null;
715
}
716
717
/**
718
* Visits a local variable declaration.
719
*
720
* @param name the name of a local variable.
721
* @param descriptor the type descriptor of this local variable.
722
* @param signature the type signature of this local variable. May be {@literal null} if the local
723
* variable type does not use generic types.
724
* @param start the first instruction corresponding to the scope of this local variable
725
* (inclusive).
726
* @param end the last instruction corresponding to the scope of this local variable (exclusive).
727
* @param index the local variable's index.
728
* @throws IllegalArgumentException if one of the labels has not already been visited by this
729
* visitor (by the {@link #visitLabel} method).
730
*/
731
public void visitLocalVariable(
732
final String name,
733
final String descriptor,
734
final String signature,
735
final Label start,
736
final Label end,
737
final int index) {
738
if (mv != null) {
739
mv.visitLocalVariable(name, descriptor, signature, start, end, index);
740
}
741
}
742
743
/**
744
* Visits an annotation on a local variable type.
745
*
746
* @param typeRef a reference to the annotated type. The sort of this type reference must be
747
* {@link TypeReference#LOCAL_VARIABLE} or {@link TypeReference#RESOURCE_VARIABLE}. See {@link
748
* TypeReference}.
749
* @param typePath the path to the annotated type argument, wildcard bound, array element type, or
750
* static inner type within 'typeRef'. May be {@literal null} if the annotation targets
751
* 'typeRef' as a whole.
752
* @param start the fist instructions corresponding to the continuous ranges that make the scope
753
* of this local variable (inclusive).
754
* @param end the last instructions corresponding to the continuous ranges that make the scope of
755
* this local variable (exclusive). This array must have the same size as the 'start' array.
756
* @param index the local variable's index in each range. This array must have the same size as
757
* the 'start' array.
758
* @param descriptor the class descriptor of the annotation class.
759
* @param visible {@literal true} if the annotation is visible at runtime.
760
* @return a visitor to visit the annotation values, or {@literal null} if this visitor is not
761
* interested in visiting this annotation.
762
*/
763
public AnnotationVisitor visitLocalVariableAnnotation(
764
final int typeRef,
765
final TypePath typePath,
766
final Label[] start,
767
final Label[] end,
768
final int[] index,
769
final String descriptor,
770
final boolean visible) {
771
if (api < Opcodes.ASM5) {
772
throw new UnsupportedOperationException(REQUIRES_ASM5);
773
}
774
if (mv != null) {
775
return mv.visitLocalVariableAnnotation(
776
typeRef, typePath, start, end, index, descriptor, visible);
777
}
778
return null;
779
}
780
781
/**
782
* Visits a line number declaration.
783
*
784
* @param line a line number. This number refers to the source file from which the class was
785
* compiled.
786
* @param start the first instruction corresponding to this line number.
787
* @throws IllegalArgumentException if {@code start} has not already been visited by this visitor
788
* (by the {@link #visitLabel} method).
789
*/
790
public void visitLineNumber(final int line, final Label start) {
791
if (mv != null) {
792
mv.visitLineNumber(line, start);
793
}
794
}
795
796
/**
797
* Visits the maximum stack size and the maximum number of local variables of the method.
798
*
799
* @param maxStack maximum stack size of the method.
800
* @param maxLocals maximum number of local variables for the method.
801
*/
802
public void visitMaxs(final int maxStack, final int maxLocals) {
803
if (mv != null) {
804
mv.visitMaxs(maxStack, maxLocals);
805
}
806
}
807
808
/**
809
* Visits the end of the method. This method, which is the last one to be called, is used to
810
* inform the visitor that all the annotations and attributes of the method have been visited.
811
*/
812
public void visitEnd() {
813
if (mv != null) {
814
mv.visitEnd();
815
}
816
}
817
}
818
819