1 /*
2 * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 package com.sun.org.apache.bcel.internal.generic;
21
22 import com.sun.org.apache.bcel.internal.Const;
23 import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry;
24 import com.sun.org.apache.bcel.internal.classfile.Annotations;
25 import com.sun.org.apache.bcel.internal.classfile.Attribute;
26 import com.sun.org.apache.bcel.internal.classfile.Code;
27 import com.sun.org.apache.bcel.internal.classfile.CodeException;
28 import com.sun.org.apache.bcel.internal.classfile.ExceptionTable;
29 import com.sun.org.apache.bcel.internal.classfile.LineNumber;
30 import com.sun.org.apache.bcel.internal.classfile.LineNumberTable;
31 import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
32 import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable;
33 import com.sun.org.apache.bcel.internal.classfile.LocalVariableTypeTable;
34 import com.sun.org.apache.bcel.internal.classfile.Method;
35 import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotationEntry;
36 import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotations;
37 import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations;
38 import com.sun.org.apache.bcel.internal.classfile.Utility;
39 import com.sun.org.apache.bcel.internal.util.BCELComparator;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.Comparator;
43 import java.util.HashMap;
44 import java.util.List;
45 import java.util.Map;
46 import java.util.Stack;
47
48 /**
49 * Template class for building up a method. This is done by defining exception
50 * handlers, adding thrown exceptions, local variables and attributes, whereas
51 * the `LocalVariableTable' and `LineNumberTable' attributes will be set
52 * automatically for the code. Use stripAttributes() if you don't like this.
53 *
54 * While generating code it may be necessary to insert NOP operations. You can
55 * use the `removeNOPs' method to get rid off them.
56 * The resulting method object can be obtained via the `getMethod()' method.
57 *
58 * @version $Id$
59 * @see InstructionList
60 * @see Method
61 * @LastModified: Jun 2019
62 */
63 public class MethodGen extends FieldGenOrMethodGen {
64
65 private String class_name;
66 private Type[] arg_types;
67 private String[] arg_names;
68 private int max_locals;
69 private int max_stack;
70 private InstructionList il;
71 private boolean strip_attributes;
72 private LocalVariableTypeTable local_variable_type_table = null;
73 private final List<LocalVariableGen> variable_vec = new ArrayList<>();
74 private final List<LineNumberGen> line_number_vec = new ArrayList<>();
75 private final List<CodeExceptionGen> exception_vec = new ArrayList<>();
76 private final List<String> throws_vec = new ArrayList<>();
77 private final List<Attribute> code_attrs_vec = new ArrayList<>();
78
79 private List<AnnotationEntryGen>[] param_annotations; // Array of lists containing AnnotationGen objects
80 private boolean hasParameterAnnotations = false;
81 private boolean haveUnpackedParameterAnnotations = false;
82
83 private static BCELComparator bcelComparator = new BCELComparator() {
84
85 @Override
86 public boolean equals( final Object o1, final Object o2 ) {
87 final MethodGen THIS = (MethodGen) o1;
88 final MethodGen THAT = (MethodGen) o2;
89 return THIS.getName().equals(THAT.getName())
90 && THIS.getSignature().equals(THAT.getSignature());
91 }
92
93
94 @Override
95 public int hashCode( final Object o ) {
96 final MethodGen THIS = (MethodGen) o;
97 return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
98 }
99 };
100
101
102 /**
103 * Declare method. If the method is non-static the constructor
104 * automatically declares a local variable `$this' in slot 0. The
105 * actual code is contained in the `il' parameter, which may further
106 * manipulated by the user. But he must take care not to remove any
107 * instruction (handles) that are still referenced from this object.
108 *
109 * For example one may not add a local variable and later remove the
110 * instructions it refers to without causing havoc. It is safe
340
341 /*
342 * If the range of the variable has not been set yet, it will be set to be valid from
343 * the start to the end of the instruction list.
344 *
345 * @return array of declared local variables sorted by index
346 */
347 public LocalVariableGen[] getLocalVariables() {
348 final int size = variable_vec.size();
349 final LocalVariableGen[] lg = new LocalVariableGen[size];
350 variable_vec.toArray(lg);
351 for (int i = 0; i < size; i++) {
352 if ((lg[i].getStart() == null) && (il != null)) {
353 lg[i].setStart(il.getStart());
354 }
355 if ((lg[i].getEnd() == null) && (il != null)) {
356 lg[i].setEnd(il.getEnd());
357 }
358 }
359 if (size > 1) {
360 Arrays.sort(lg, new Comparator<LocalVariableGen>() {
361 @Override
362 public int compare(final LocalVariableGen o1, final LocalVariableGen o2) {
363 return o1.getIndex() - o2.getIndex();
364 }
365 });
366 }
367 return lg;
368 }
369
370
371 /**
372 * @return `LocalVariableTable' attribute of all the local variables of this method.
373 */
374 public LocalVariableTable getLocalVariableTable( final ConstantPoolGen cp ) {
375 final LocalVariableGen[] lg = getLocalVariables();
376 final int size = lg.length;
377 final LocalVariable[] lv = new LocalVariable[size];
378 for (int i = 0; i < size; i++) {
379 lv[i] = lg[i].getLocalVariable(cp);
380 }
381 return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp
382 .getConstantPool());
383 }
384
385 /**
|
1 /*
2 * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
3 */
4 /*
5 * Licensed to the Apache Software Foundation (ASF) under one or more
6 * contributor license agreements. See the NOTICE file distributed with
7 * this work for additional information regarding copyright ownership.
8 * The ASF licenses this file to You under the Apache License, Version 2.0
9 * (the "License"); you may not use this file except in compliance with
10 * the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 package com.sun.org.apache.bcel.internal.generic;
21
22 import com.sun.org.apache.bcel.internal.Const;
23 import com.sun.org.apache.bcel.internal.classfile.AnnotationEntry;
24 import com.sun.org.apache.bcel.internal.classfile.Annotations;
25 import com.sun.org.apache.bcel.internal.classfile.Attribute;
26 import com.sun.org.apache.bcel.internal.classfile.Code;
27 import com.sun.org.apache.bcel.internal.classfile.CodeException;
28 import com.sun.org.apache.bcel.internal.classfile.ExceptionTable;
29 import com.sun.org.apache.bcel.internal.classfile.LineNumber;
30 import com.sun.org.apache.bcel.internal.classfile.LineNumberTable;
31 import com.sun.org.apache.bcel.internal.classfile.LocalVariable;
32 import com.sun.org.apache.bcel.internal.classfile.LocalVariableTable;
33 import com.sun.org.apache.bcel.internal.classfile.LocalVariableTypeTable;
34 import com.sun.org.apache.bcel.internal.classfile.Method;
35 import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotationEntry;
36 import com.sun.org.apache.bcel.internal.classfile.ParameterAnnotations;
37 import com.sun.org.apache.bcel.internal.classfile.RuntimeVisibleParameterAnnotations;
38 import com.sun.org.apache.bcel.internal.classfile.Utility;
39 import com.sun.org.apache.bcel.internal.util.BCELComparator;
40 import java.util.ArrayList;
41 import java.util.Arrays;
42 import java.util.HashMap;
43 import java.util.List;
44 import java.util.Map;
45 import java.util.Objects;
46 import java.util.Stack;
47
48 /**
49 * Template class for building up a method. This is done by defining exception
50 * handlers, adding thrown exceptions, local variables and attributes, whereas
51 * the `LocalVariableTable' and `LineNumberTable' attributes will be set
52 * automatically for the code. Use stripAttributes() if you don't like this.
53 *
54 * While generating code it may be necessary to insert NOP operations. You can
55 * use the `removeNOPs' method to get rid off them.
56 * The resulting method object can be obtained via the `getMethod()' method.
57 *
58 * @see InstructionList
59 * @see Method
60 * @LastModified: Jan 2020
61 */
62 public class MethodGen extends FieldGenOrMethodGen {
63
64 private String class_name;
65 private Type[] arg_types;
66 private String[] arg_names;
67 private int max_locals;
68 private int max_stack;
69 private InstructionList il;
70 private boolean strip_attributes;
71 private LocalVariableTypeTable local_variable_type_table = null;
72 private final List<LocalVariableGen> variable_vec = new ArrayList<>();
73 private final List<LineNumberGen> line_number_vec = new ArrayList<>();
74 private final List<CodeExceptionGen> exception_vec = new ArrayList<>();
75 private final List<String> throws_vec = new ArrayList<>();
76 private final List<Attribute> code_attrs_vec = new ArrayList<>();
77
78 private List<AnnotationEntryGen>[] param_annotations; // Array of lists containing AnnotationGen objects
79 private boolean hasParameterAnnotations = false;
80 private boolean haveUnpackedParameterAnnotations = false;
81
82 private static BCELComparator bcelComparator = new BCELComparator() {
83
84 @Override
85 public boolean equals( final Object o1, final Object o2 ) {
86 final MethodGen THIS = (MethodGen) o1;
87 final MethodGen THAT = (MethodGen) o2;
88 return Objects.equals(THIS.getName(), THAT.getName())
89 && Objects.equals(THIS.getSignature(), THAT.getSignature());
90 }
91
92
93 @Override
94 public int hashCode( final Object o ) {
95 final MethodGen THIS = (MethodGen) o;
96 return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
97 }
98 };
99
100
101 /**
102 * Declare method. If the method is non-static the constructor
103 * automatically declares a local variable `$this' in slot 0. The
104 * actual code is contained in the `il' parameter, which may further
105 * manipulated by the user. But he must take care not to remove any
106 * instruction (handles) that are still referenced from this object.
107 *
108 * For example one may not add a local variable and later remove the
109 * instructions it refers to without causing havoc. It is safe
339
340 /*
341 * If the range of the variable has not been set yet, it will be set to be valid from
342 * the start to the end of the instruction list.
343 *
344 * @return array of declared local variables sorted by index
345 */
346 public LocalVariableGen[] getLocalVariables() {
347 final int size = variable_vec.size();
348 final LocalVariableGen[] lg = new LocalVariableGen[size];
349 variable_vec.toArray(lg);
350 for (int i = 0; i < size; i++) {
351 if ((lg[i].getStart() == null) && (il != null)) {
352 lg[i].setStart(il.getStart());
353 }
354 if ((lg[i].getEnd() == null) && (il != null)) {
355 lg[i].setEnd(il.getEnd());
356 }
357 }
358 if (size > 1) {
359 Arrays.sort(lg, (o1, o2) -> o1.getIndex() - o2.getIndex());
360 }
361 return lg;
362 }
363
364
365 /**
366 * @return `LocalVariableTable' attribute of all the local variables of this method.
367 */
368 public LocalVariableTable getLocalVariableTable( final ConstantPoolGen cp ) {
369 final LocalVariableGen[] lg = getLocalVariables();
370 final int size = lg.length;
371 final LocalVariable[] lv = new LocalVariable[size];
372 for (int i = 0; i < size; i++) {
373 lv[i] = lg[i].getLocalVariable(cp);
374 }
375 return new LocalVariableTable(cp.addUtf8("LocalVariableTable"), 2 + lv.length * 10, lv, cp
376 .getConstantPool());
377 }
378
379 /**
|