163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
--------------------------------------------------------------------------------
/documentation/api/package-list:
--------------------------------------------------------------------------------
1 | bytecodeparser
2 | bytecodeparser.analysis
3 | bytecodeparser.analysis.decoders
4 | bytecodeparser.analysis.opcodes
5 | bytecodeparser.analysis.stack
6 | bytecodeparser.utils
7 |
--------------------------------------------------------------------------------
/documentation/api/resources/inherit.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgodbillon/BytecodeParser/b24c5c54fe3fa457d79c065de33b05b2ac7797df/documentation/api/resources/inherit.gif
--------------------------------------------------------------------------------
/documentation/api/stylesheet.css:
--------------------------------------------------------------------------------
1 | /* Javadoc style sheet */
2 |
3 | /* Define colors, fonts and other style attributes here to override the defaults */
4 |
5 | /* Page background color */
6 | body { background-color: #FFFFFF; color:#000000 }
7 |
8 | /* Headings */
9 | h1 { font-size: 145% }
10 |
11 | /* Table colors */
12 | .TableHeadingColor { background: #CCCCFF; color:#000000 } /* Dark mauve */
13 | .TableSubHeadingColor { background: #EEEEFF; color:#000000 } /* Light mauve */
14 | .TableRowColor { background: #FFFFFF; color:#000000 } /* White */
15 |
16 | /* Font used in left-hand frame lists */
17 | .FrameTitleFont { font-size: 100%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
18 | .FrameHeadingFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
19 | .FrameItemFont { font-size: 90%; font-family: Helvetica, Arial, sans-serif; color:#000000 }
20 |
21 | /* Navigation bar fonts and colors */
22 | .NavBarCell1 { background-color:#EEEEFF; color:#000000} /* Light mauve */
23 | .NavBarCell1Rev { background-color:#00008B; color:#FFFFFF} /* Dark Blue */
24 | .NavBarFont1 { font-family: Arial, Helvetica, sans-serif; color:#000000;color:#000000;}
25 | .NavBarFont1Rev { font-family: Arial, Helvetica, sans-serif; color:#FFFFFF;color:#FFFFFF;}
26 |
27 | .NavBarCell2 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
28 | .NavBarCell3 { font-family: Arial, Helvetica, sans-serif; background-color:#FFFFFF; color:#000000}
29 |
30 |
--------------------------------------------------------------------------------
/lgpl-3.0.txt:
--------------------------------------------------------------------------------
1 | GNU LESSER GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 |
9 | This version of the GNU Lesser General Public License incorporates
10 | the terms and conditions of version 3 of the GNU General Public
11 | License, supplemented by the additional permissions listed below.
12 |
13 | 0. Additional Definitions.
14 |
15 | As used herein, "this License" refers to version 3 of the GNU Lesser
16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU
17 | General Public License.
18 |
19 | "The Library" refers to a covered work governed by this License,
20 | other than an Application or a Combined Work as defined below.
21 |
22 | An "Application" is any work that makes use of an interface provided
23 | by the Library, but which is not otherwise based on the Library.
24 | Defining a subclass of a class defined by the Library is deemed a mode
25 | of using an interface provided by the Library.
26 |
27 | A "Combined Work" is a work produced by combining or linking an
28 | Application with the Library. The particular version of the Library
29 | with which the Combined Work was made is also called the "Linked
30 | Version".
31 |
32 | The "Minimal Corresponding Source" for a Combined Work means the
33 | Corresponding Source for the Combined Work, excluding any source code
34 | for portions of the Combined Work that, considered in isolation, are
35 | based on the Application, and not on the Linked Version.
36 |
37 | The "Corresponding Application Code" for a Combined Work means the
38 | object code and/or source code for the Application, including any data
39 | and utility programs needed for reproducing the Combined Work from the
40 | Application, but excluding the System Libraries of the Combined Work.
41 |
42 | 1. Exception to Section 3 of the GNU GPL.
43 |
44 | You may convey a covered work under sections 3 and 4 of this License
45 | without being bound by section 3 of the GNU GPL.
46 |
47 | 2. Conveying Modified Versions.
48 |
49 | If you modify a copy of the Library, and, in your modifications, a
50 | facility refers to a function or data to be supplied by an Application
51 | that uses the facility (other than as an argument passed when the
52 | facility is invoked), then you may convey a copy of the modified
53 | version:
54 |
55 | a) under this License, provided that you make a good faith effort to
56 | ensure that, in the event an Application does not supply the
57 | function or data, the facility still operates, and performs
58 | whatever part of its purpose remains meaningful, or
59 |
60 | b) under the GNU GPL, with none of the additional permissions of
61 | this License applicable to that copy.
62 |
63 | 3. Object Code Incorporating Material from Library Header Files.
64 |
65 | The object code form of an Application may incorporate material from
66 | a header file that is part of the Library. You may convey such object
67 | code under terms of your choice, provided that, if the incorporated
68 | material is not limited to numerical parameters, data structure
69 | layouts and accessors, or small macros, inline functions and templates
70 | (ten or fewer lines in length), you do both of the following:
71 |
72 | a) Give prominent notice with each copy of the object code that the
73 | Library is used in it and that the Library and its use are
74 | covered by this License.
75 |
76 | b) Accompany the object code with a copy of the GNU GPL and this license
77 | document.
78 |
79 | 4. Combined Works.
80 |
81 | You may convey a Combined Work under terms of your choice that,
82 | taken together, effectively do not restrict modification of the
83 | portions of the Library contained in the Combined Work and reverse
84 | engineering for debugging such modifications, if you also do each of
85 | the following:
86 |
87 | a) Give prominent notice with each copy of the Combined Work that
88 | the Library is used in it and that the Library and its use are
89 | covered by this License.
90 |
91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license
92 | document.
93 |
94 | c) For a Combined Work that displays copyright notices during
95 | execution, include the copyright notice for the Library among
96 | these notices, as well as a reference directing the user to the
97 | copies of the GNU GPL and this license document.
98 |
99 | d) Do one of the following:
100 |
101 | 0) Convey the Minimal Corresponding Source under the terms of this
102 | License, and the Corresponding Application Code in a form
103 | suitable for, and under terms that permit, the user to
104 | recombine or relink the Application with a modified version of
105 | the Linked Version to produce a modified Combined Work, in the
106 | manner specified by section 6 of the GNU GPL for conveying
107 | Corresponding Source.
108 |
109 | 1) Use a suitable shared library mechanism for linking with the
110 | Library. A suitable mechanism is one that (a) uses at run time
111 | a copy of the Library already present on the user's computer
112 | system, and (b) will operate properly with a modified version
113 | of the Library that is interface-compatible with the Linked
114 | Version.
115 |
116 | e) Provide Installation Information, but only if you would otherwise
117 | be required to provide such information under section 6 of the
118 | GNU GPL, and only to the extent that such information is
119 | necessary to install and execute a modified version of the
120 | Combined Work produced by recombining or relinking the
121 | Application with a modified version of the Linked Version. (If
122 | you use option 4d0, the Installation Information must accompany
123 | the Minimal Corresponding Source and Corresponding Application
124 | Code. If you use option 4d1, you must provide the Installation
125 | Information in the manner specified by section 6 of the GNU GPL
126 | for conveying Corresponding Source.)
127 |
128 | 5. Combined Libraries.
129 |
130 | You may place library facilities that are a work based on the
131 | Library side by side in a single library together with other library
132 | facilities that are not Applications and are not covered by this
133 | License, and convey such a combined library under terms of your
134 | choice, if you do both of the following:
135 |
136 | a) Accompany the combined library with a copy of the same work based
137 | on the Library, uncombined with any other library facilities,
138 | conveyed under the terms of this License.
139 |
140 | b) Give prominent notice with the combined library that part of it
141 | is a work based on the Library, and explaining where to find the
142 | accompanying uncombined form of the same work.
143 |
144 | 6. Revised Versions of the GNU Lesser General Public License.
145 |
146 | The Free Software Foundation may publish revised and/or new versions
147 | of the GNU Lesser General Public License from time to time. Such new
148 | versions will be similar in spirit to the present version, but may
149 | differ in detail to address new problems or concerns.
150 |
151 | Each version is given a distinguishing version number. If the
152 | Library as you received it specifies that a certain numbered version
153 | of the GNU Lesser General Public License "or any later version"
154 | applies to it, you have the option of following the terms and
155 | conditions either of that published version or of any later version
156 | published by the Free Software Foundation. If the Library as you
157 | received it does not specify a version number of the GNU Lesser
158 | General Public License, you may choose any version of the GNU Lesser
159 | General Public License ever published by the Free Software Foundation.
160 |
161 | If the Library as you received it specifies that a proxy can decide
162 | whether future versions of the GNU Lesser General Public License shall
163 | apply, that proxy's public statement of acceptance of any version is
164 | permanent authorization for you to choose that version for the
165 | Library.
166 |
--------------------------------------------------------------------------------
/lib/javassist.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgodbillon/BytecodeParser/b24c5c54fe3fa457d79c065de33b05b2ac7797df/lib/javassist.jar
--------------------------------------------------------------------------------
/lib/junit-4.8.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgodbillon/BytecodeParser/b24c5c54fe3fa457d79c065de33b05b2ac7797df/lib/junit-4.8.2.jar
--------------------------------------------------------------------------------
/lib/log4j-1.2.16.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgodbillon/BytecodeParser/b24c5c54fe3fa457d79c065de33b05b2ac7797df/lib/log4j-1.2.16.jar
--------------------------------------------------------------------------------
/log4j.properties.test.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sgodbillon/BytecodeParser/b24c5c54fe3fa457d79c065de33b05b2ac7797df/log4j.properties.test.jar
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
3 | 4.0.0
4 |
5 | org.sgodbillon
6 | bytecode-parser
7 | 1.0-SNAPSHOT
8 | jar
9 |
10 | bytecode-parser
11 | http://maven.apache.org
12 |
13 |
14 | UTF-8
15 |
16 |
17 |
18 |
19 | javassist
20 | javassist
21 | 3.12.1.GA
22 |
23 |
24 | log4j
25 | log4j
26 | 1.2.17
27 |
28 |
29 | junit
30 | junit
31 | 4.8.2
32 | test
33 |
34 |
35 |
36 |
37 | src
38 | src/test
39 |
40 |
41 |
42 | maven-compiler-plugin
43 | 2.3.2
44 |
45 | 1.6
46 | 1.6
47 |
48 | bytecodeparser/**
49 |
50 |
51 |
52 |
53 |
54 |
55 |
--------------------------------------------------------------------------------
/src/bytecodeparser/CodeParser.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import javassist.CtBehavior;
23 | import javassist.bytecode.BadBytecode;
24 | import bytecodeparser.analysis.Opcodes;
25 | import bytecodeparser.analysis.opcodes.Op;
26 |
27 | /**
28 | * A basic bytecode parser.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class CodeParser {
33 | /**
34 | * The matching context.
35 | */
36 | public final Context context;
37 | private boolean stop = false;
38 |
39 | public CodeParser(CtBehavior behavior) {
40 | this.context = new Context(behavior);
41 | }
42 | /**
43 | * Parses the bytecode with the given OpHandler.
44 | * @param opHandler
45 | * @throws BadBytecode
46 | * @see {@link OpHandler}
47 | */
48 | public void parse(OpHandler opHandler) throws BadBytecode {
49 | while(context.iterator.hasNext()) {
50 | if(stop)
51 | break;
52 | int index = context.iterator.next();
53 | Op op = Opcodes.OPCODES.get(context.iterator.byteAt(index)).init(context, index);
54 | opHandler.handle(op, index);
55 | }
56 | }
57 |
58 | /**
59 | * Moves the code iterator to the given index.
60 | * @param index
61 | */
62 | public void move(int index) {
63 | stop = false;
64 | context.iterator.move(index);
65 | }
66 |
67 | /**
68 | * Looks the next frame's index.
69 | * @return
70 | */
71 | public int nextIndex() {
72 | return context.iterator.lookAhead();
73 | }
74 |
75 | /**
76 | * Resets the code iterator at the beginning of the bytecode.
77 | */
78 | public void begin() {
79 | stop = false;
80 | context.iterator.begin();
81 | }
82 |
83 | /**
84 | * Stops the parsing.
85 | */
86 | public void stop() {
87 | stop = true;
88 | }
89 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/Context.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import java.util.Map;
23 |
24 | import javassist.CtBehavior;
25 | import javassist.NotFoundException;
26 | import javassist.bytecode.ExceptionTable;
27 | import bytecodeparser.analysis.LocalVariable;
28 |
29 | /**
30 | * A context for parsing bytecode.
31 | * @author Stephane Godbillon
32 | *
33 | */
34 | public class Context {
35 | /**
36 | * The behavior which bytecode is being parsed.
37 | */
38 | public final CtBehavior behavior;
39 | /**
40 | * The bytecode iterator used for parsing.
41 | */
42 | public final MultiMarkerCodeIterator iterator;
43 | /**
44 | * The local variables of the behavior.
45 | */
46 | public final Map localVariables;
47 | /**
48 | * The exception handlers, from the ExceptionTable attribute.
49 | */
50 | public final int[] exceptionHandlers;
51 |
52 | public Context(CtBehavior behavior, MultiMarkerCodeIterator iterator, Map localVariables) {
53 | this.behavior = behavior;
54 | this.iterator = iterator;
55 | this.localVariables = localVariables;
56 | ExceptionTable exceptionTable = this.behavior.getMethodInfo().getCodeAttribute().getExceptionTable();
57 |
58 | if(exceptionTable != null) {
59 | this.exceptionHandlers = new int[exceptionTable.size()];
60 | for(int i = 0; i < exceptionTable.size(); i++) {
61 | exceptionHandlers[i] = exceptionTable.handlerPc(i);
62 | }
63 | } else {
64 | this.exceptionHandlers = new int[0];
65 | }
66 | }
67 |
68 | public Context(CtBehavior behavior, MultiMarkerCodeIterator iterator) {
69 | this(behavior, iterator, findLocalVariables(behavior));
70 | }
71 |
72 | public Context(CtBehavior behavior) {
73 | this(behavior, new MultiMarkerCodeIterator(behavior.getMethodInfo().getCodeAttribute()), findLocalVariables(behavior));
74 | }
75 |
76 | /**
77 | * States if the given index is a start of an exception handler.
78 | * @param index
79 | */
80 | public boolean isStartOfExceptionHandler(int index) {
81 | for(int i = 0; i < exceptionHandlers.length; i++)
82 | if(exceptionHandlers[i] == index)
83 | return true;
84 | return false;
85 | }
86 |
87 | private static Map findLocalVariables(CtBehavior behavior) {
88 | try {
89 | return LocalVariable.findVariables(behavior);
90 | } catch (NotFoundException e) {
91 | throw new RuntimeException("Error while retrieving the behavior's local variables!", e);
92 | }
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/src/bytecodeparser/MultiMarkerCodeIterator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import java.util.ArrayList;
23 |
24 | import javassist.bytecode.CodeAttribute;
25 | import javassist.bytecode.CodeIterator;
26 |
27 | /**
28 | * A code iterator that tracks more than one mark in the bytecode.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class MultiMarkerCodeIterator extends CodeIterator {
33 | public ArrayList marks = new ArrayList();
34 |
35 | protected MultiMarkerCodeIterator(CodeAttribute ca) {
36 | super(ca);
37 | }
38 |
39 | @Override
40 | protected void updateCursors(int pos, int length) {
41 | super.updateCursors(pos, length);
42 | for(int i = 0; i < marks.size(); i++) {
43 | int mark = marks.get(i);
44 | if(mark > pos)
45 | marks.set(i, mark + length);
46 | }
47 | }
48 |
49 | /**
50 | * Puts a mark on the given index in the bytecode.
51 | * @param index
52 | * @return the id of this mark, in order to get it later.
53 | */
54 | public int putMark(int index) {
55 | marks.add(index);
56 | return marks.size() - 1;
57 | }
58 |
59 | /**
60 | * Gets the index in the bytecode tracked by the mark matching the given mark id.
61 | * @param mark the mark id.
62 | * @return the index of this mark.
63 | */
64 | public int getMark(int mark) {
65 | return marks.get(mark);
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/bytecodeparser/OpHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser;
21 |
22 | import bytecodeparser.analysis.opcodes.Op;
23 |
24 | /**
25 | * A handler for opcodes, used when parsing bytecode with the CodeParser.
26 | * @author Stephane Godbillon
27 | * @see CodeParser#parse(OpHandler)
28 | */
29 | public interface OpHandler {
30 | /**
31 | * Handle the given op at the given index.
32 | * @param op
33 | * @param index
34 | */
35 | void handle(Op op, int index);
36 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/LocalVariable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis;
21 |
22 | import java.util.HashMap;
23 | import java.util.Map;
24 | import java.util.TreeMap;
25 |
26 | import org.apache.log4j.Logger;
27 |
28 | import javassist.CtBehavior;
29 | import javassist.Modifier;
30 | import javassist.NotFoundException;
31 | import javassist.bytecode.CodeAttribute;
32 | import javassist.bytecode.LocalVariableAttribute;
33 | import bytecodeparser.utils.Utils;
34 |
35 | /**
36 | * A local variable.
37 | * @author Stephane Godbillon
38 | *
39 | */
40 | public class LocalVariable {
41 | private static final Logger LOGGER = Logger.getLogger(LocalVariable.class);
42 |
43 | /**
44 | * The declaring behavior of this variable.
45 | */
46 | public final CtBehavior behavior;
47 | /**
48 | * The name of this variable.
49 | */
50 | public final String name;
51 | /**
52 | * The index of this local variable in the LocalVariableTable attribute.
53 | */
54 | public final int index;
55 | /**
56 | * The type of this variable.
57 | */
58 | public final LocalVariableType type;
59 | /**
60 | * Is this local variable a parameter of this behavior?
61 | */
62 | public final boolean isParameter;
63 |
64 | /**
65 | * Gives the range the local variable is valid within.
66 | */
67 | public int[] getValidityRange() {
68 | int[] result = new int[2];
69 | LocalVariableAttribute localVariableAttribute = Utils.getLocalVariableAttribute(behavior);
70 | result[0] = localVariableAttribute.startPc(index);
71 | result[1] = result[0] + localVariableAttribute.codeLength(index);
72 | return result;
73 | }
74 | /**
75 | * The slot the local variable is put into.
76 | * @return
77 | */
78 | public int getSlot() {
79 | return Utils.getLocalVariableAttribute(behavior).index(index);
80 | }
81 |
82 | public LocalVariable(int index, String name, LocalVariableType type, boolean isParameter, CtBehavior behavior) {
83 | this.index = index;
84 | this.name = name;
85 | this.type = type;
86 | this.behavior = behavior;
87 | this.isParameter = isParameter;
88 | }
89 | @Override
90 | public String toString() {
91 | return name + " (" + type.typeName + ") " + "[" + index + " -> " + getSlot() + "] between [" + getValidityRange()[0] + "," + getValidityRange()[1] + "]";
92 | }
93 |
94 | /**
95 | * Gets all the local variables of the given behavior, indexed by their index in the LocalVariableTable attribute.
96 | * @param behavior
97 | * @return the local variables of the given behavior, indexed by their index in the LocalVariableTable attribute.
98 | * @throws NotFoundException
99 | */
100 | public static Map findVariables(CtBehavior behavior) throws NotFoundException {
101 | int nbParameters = behavior.getParameterTypes().length;
102 | boolean isStatic = Modifier.isStatic(behavior.getModifiers());
103 | Map variables = new HashMap();
104 | CodeAttribute codeAttribute = behavior.getMethodInfo().getCodeAttribute();
105 | LocalVariableAttribute localVariableAttribute = (LocalVariableAttribute) codeAttribute.getAttribute("LocalVariableTable");
106 | LOGGER.debug("search vars : " + localVariableAttribute + " > " + (localVariableAttribute != null ? localVariableAttribute.tableLength() : 0));
107 | if(localVariableAttribute != null) {
108 | for(int i = 0; i < localVariableAttribute.tableLength(); i++) {
109 | boolean isParameter = isStatic ? i < nbParameters : (i > 0 && i <= nbParameters);
110 | LocalVariable localVariable = new LocalVariable(i, localVariableAttribute.variableName(i), LocalVariableType.parse(localVariableAttribute.signature(i)), isParameter, behavior);
111 | variables.put(i, localVariable);
112 | LOGGER.debug(String.format("findLocalVariables: foud var %s is '%s' (slot %s)", i, localVariable.name, localVariable.getSlot()));
113 | }
114 | } else LOGGER.debug("no local vars found");
115 | return variables;
116 | }
117 |
118 | /**
119 | * Get the local variable in the given slot at the given index in the given map of local variables.
120 | * @param slot
121 | * @param index
122 | * @param variables
123 | * @return the local variable in the given slot at the given index.
124 | */
125 | public static LocalVariable getLocalVariable(int slot, int index, Map variables) {
126 | TreeMap variablesByDistance = new TreeMap();
127 | for(LocalVariable lv : variables.values()) {
128 | if(lv.getSlot() == slot) {
129 | int[] validityRange = lv.getValidityRange();
130 | if(validityRange[1] >= index) {
131 | if(validityRange[0] <= index) {
132 | LOGGER.debug("getLocalVariable in slot " + slot + " at index " + index + ": found " + lv);
133 | return lv;
134 | } else
135 | variablesByDistance.put(validityRange[0] - index, lv);
136 | }
137 | }
138 | }
139 | if(variablesByDistance.size() > 0) {
140 | LOGGER.debug("getLocalVariable in slot " + slot + " at index " + index + ": found by shorter distance " + variablesByDistance.firstEntry().getValue());
141 | return variablesByDistance.firstEntry().getValue();
142 | }
143 | LOGGER.debug("getLocalVariable in slot " + slot + " at index " + index + ": NOT FOUND");
144 | return null;
145 | }
146 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/LocalVariableType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis;
21 |
22 | import java.util.HashMap;
23 | import java.util.Map;
24 |
25 | import javassist.CtClass;
26 | import javassist.bytecode.Descriptor;
27 | import javassist.bytecode.SignatureAttribute;
28 | import javassist.bytecode.SignatureAttribute.ArrayType;
29 | import javassist.bytecode.SignatureAttribute.ClassType;
30 |
31 | /**
32 | * Information about a localVariable type.
33 | * @author Stephane Godbillon
34 | *
35 | */
36 | public class LocalVariableType {
37 | /**
38 | * Is it a primitive type (int, long, etc.)
39 | */
40 | public final boolean isPrimitive;
41 | /**
42 | * The signature of this type.
43 | */
44 | public final String signature;
45 | /**
46 | * The name of this type, including array info.
47 | * Examples: int, long[], String
48 | */
49 | public final String typeName;
50 | /**
51 | * The name of this type, without any array info.
52 | * Examples: int, long, String
53 | */
54 | public final String shortTypeName;
55 | /**
56 | * The dimensions of the array, if any.
57 | * Examples: int => 0, int[][] => 2
58 | */
59 | public final int dimensions;
60 |
61 | private LocalVariableType(String signature, String typeName, String shortTypeName, boolean isPrimitive, int dimensions) {
62 | this.signature = signature;
63 | this.typeName = typeName;
64 | this.shortTypeName = shortTypeName;
65 | this.isPrimitive = isPrimitive;
66 | this.dimensions = dimensions;
67 | }
68 |
69 | /**
70 | * States if this type is an array.
71 | */
72 | public boolean isArray() {
73 | return dimensions > 0;
74 | }
75 |
76 | /**
77 | * Makes a localVariableType from a given signature.
78 | * @return LocalVariableType
79 | * @throws RuntimeException if the signature could not be parsed.
80 | */
81 | public static LocalVariableType parse(String signature) {
82 | int dimensions = 0;
83 | for(int i = 0; i < signature.length(); i++) {
84 | if(signature.charAt(i) == '[')
85 | dimensions++;
86 | else break;
87 | }
88 | try {
89 | javassist.bytecode.SignatureAttribute.Type objectType = SignatureAttribute.toFieldSignature(signature);
90 | if(objectType instanceof ArrayType)
91 | objectType = ((ArrayType) objectType).getComponentType();
92 | if(objectType instanceof ClassType) {
93 | String typeName = ((ClassType) objectType).getName();
94 | return new LocalVariableType(signature, addArrayTypeInfo(typeName, dimensions), typeName, false, dimensions);
95 | }
96 | throw new RuntimeException("not a class ?");
97 | } catch(Exception e) {
98 | // not a class
99 | String typeName = primitiveSymbols.get("" + signature.charAt(dimensions));
100 | if(typeName == null)
101 | throw new RuntimeException("unknown signature: " + signature, e);
102 | return new LocalVariableType(signature, addArrayTypeInfo(typeName, dimensions), typeName, true, dimensions);
103 | }
104 | }
105 |
106 | /**
107 | * Makes a localVariableType from a given CtClass.
108 | * @return LocalVariableType
109 | */
110 | public static LocalVariableType from(CtClass clazz) {
111 | return parse(Descriptor.of(clazz));
112 | }
113 |
114 | private static String addArrayTypeInfo(String typeName, int dimensions) {
115 | String result = typeName;
116 | for(int i = 0; i < dimensions; i++)
117 | result += "[]";
118 | return result;
119 | }
120 |
121 | private static Map primitiveSymbols = new HashMap();
122 | static {
123 | primitiveSymbols.put("V", "void");
124 | primitiveSymbols.put("Z", "boolean");
125 | primitiveSymbols.put("B", "byte");
126 | primitiveSymbols.put("C", "char");
127 | primitiveSymbols.put("S", "short");
128 | primitiveSymbols.put("I", "int");
129 | primitiveSymbols.put("J", "long");
130 | primitiveSymbols.put("F", "float");
131 | primitiveSymbols.put("D", "double");
132 | }
133 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedArrayCreationOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import javassist.bytecode.Opcode;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.opcodes.ArrayCreationOpcode;
25 | import bytecodeparser.analysis.stack.Array;
26 | import bytecodeparser.analysis.stack.Constant.IntegerConstant;
27 | import bytecodeparser.analysis.stack.Stack;
28 | import bytecodeparser.analysis.stack.StackElement;
29 | import bytecodeparser.analysis.stack.TrackableArray;
30 | import bytecodeparser.utils.Utils;
31 |
32 | /**
33 | * A decoded array creation op.
34 | * @author Stephane Godbillon
35 | *
36 | */
37 | public class DecodedArrayCreationOp extends DecodedBasicOp {
38 | /**
39 | * The number of dimensions of the created array.
40 | */
41 | public final int dimensions;
42 | /**
43 | * The signature of the created array.
44 | */
45 | public final String signature;
46 |
47 | public DecodedArrayCreationOp(ArrayCreationOpcode op, Context context, int index) {
48 | super(op, context, index);
49 | if(op.getCode() == Opcode.MULTIANEWARRAY)
50 | dimensions = parameterValues[1];
51 | else dimensions = 1;
52 | if(op.getCode() == Opcode.NEWARRAY)
53 | signature = getSignatureForSingleDimensionArrayOfPrimitive(parameterValues[0]);
54 | else signature = Utils.getConstPool(context.behavior).getClassInfo(parameterValues[0]);
55 | }
56 |
57 | @Override
58 | public void simulate(Stack stack) {
59 | int size = -1;
60 | if(dimensions == 1) {
61 | StackElement se = stack.pop();
62 | if(se instanceof IntegerConstant) {
63 | IntegerConstant ic = (IntegerConstant) se;
64 | size = ic.getValue();
65 | }
66 | } else {
67 | for(int i = 0; i < dimensions; i++)
68 | stack.pop();
69 | }
70 | if(size > -1)
71 | stack.push(new TrackableArray(signature, size));
72 | else stack.push(new Array(signature));
73 | }
74 |
75 | private static String getSignatureForSingleDimensionArrayOfPrimitive(int type) {
76 | switch(type) {
77 | case 4: return "[Z";
78 | case 5: return "[C";
79 | case 6: return "[F";
80 | case 7: return "[D";
81 | case 8: return "[B";
82 | case 9: return "[S";
83 | case 10: return "[I";
84 | case 11: return "[J";
85 | default: throw new RuntimeException("unexpected primitive array type! '" + type + "'");
86 | }
87 | }
88 |
89 | @Override
90 | public String toString() {
91 | return "DecodedArrayCreationOp dimensions=" + dimensions + " signature=" + signature;
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedArrayOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import java.util.Arrays;
23 |
24 | import bytecodeparser.Context;
25 | import bytecodeparser.analysis.opcodes.ArrayOpcode;
26 | import bytecodeparser.analysis.stack.Constant.IntegerConstant;
27 | import bytecodeparser.analysis.stack.Stack;
28 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
29 | import bytecodeparser.analysis.stack.StackElement;
30 | import bytecodeparser.analysis.stack.TrackableArray;
31 |
32 | /**
33 | * A decoded array operation op.
34 | * @author Stephane Godbillon
35 | *
36 | */
37 | public class DecodedArrayOp extends DecodedBasicOp {
38 | public DecodedArrayOp(ArrayOpcode op, Context context, int index) {
39 | super(op, context, index);
40 | }
41 | @Override
42 | public void simulate(Stack stack) {
43 | if(!this.op.as(ArrayOpcode.class).isLoad) {
44 | StackElementLength[] pops = Arrays.copyOf(getPops(), getPops().length - 1);
45 | StackElement subject = stack.getFromTop(StackElementLength.add(pops));
46 | if(subject instanceof TrackableArray) {
47 | TrackableArray array = (TrackableArray) subject;
48 | StackElement i = stack.getFromTop(StackElementLength.add(array.componentLength));
49 | if(i instanceof IntegerConstant) {
50 | StackElement value = stack.peek(array.componentLength);
51 | array.set(((IntegerConstant) i).getValue(), value);
52 | } else {
53 | array.isDirty = true;
54 | }
55 | }
56 | }
57 | super.simulate(stack);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedBasicOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.opcodes.BasicOpcode;
24 | import bytecodeparser.analysis.stack.Stack;
25 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
26 |
27 | /**
28 | * A decoded basic op.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class DecodedBasicOp extends DecodedOp {
33 | /**
34 | * Pops needed by this decoded op.
35 | */
36 | public final StackElementLength[] pops;
37 | /**
38 | * Pushes needed by this decoded op.
39 | */
40 | public final StackElementLength[] pushes;
41 |
42 | public DecodedBasicOp(BasicOpcode op, Context context, int index) {
43 | super(op, context, index);
44 |
45 | this.pops = op.getPops();
46 | this.pushes = op.getPushes();
47 | }
48 |
49 | @Override
50 | public void simulate(Stack stack) {
51 | Stack.processBasicAlteration(stack, getPops(), getPushes());
52 | }
53 |
54 | /**
55 | * Pops needed by this decoded op.
56 | */
57 | public StackElementLength[] getPops() {
58 | return pops;
59 | }
60 |
61 | /**
62 | * Pushes needed by this decoded op.
63 | */
64 | public StackElementLength[] getPushes() {
65 | return pushes;
66 | }
67 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedBranchOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.opcodes.BasicOpcode;
24 |
25 | /**
26 | * A decoded branch op.
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class DecodedBranchOp extends DecodedBasicOp {
31 | private final int jump;
32 |
33 | public DecodedBranchOp(BasicOpcode op, Context context, int index) {
34 | super(op, context, index);
35 | jump = parameterValues[0];
36 | }
37 |
38 | /**
39 | * @return the index this decoded op will jump to.
40 | */
41 | public int getJump() {
42 | return jump + index;
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedConstantPushOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import java.lang.reflect.Method;
23 |
24 | import javassist.bytecode.ConstPool;
25 | import javassist.bytecode.Opcode;
26 | import bytecodeparser.Context;
27 | import bytecodeparser.analysis.Opcodes.OpParameterType;
28 | import bytecodeparser.analysis.opcodes.ConstantPushOpcode;
29 | import bytecodeparser.analysis.stack.Constant.DoubleConstant;
30 | import bytecodeparser.analysis.stack.Constant.FloatConstant;
31 | import bytecodeparser.analysis.stack.Constant.IntegerConstant;
32 | import bytecodeparser.analysis.stack.Constant.LongConstant;
33 | import bytecodeparser.analysis.stack.Constant.StringConstant;
34 | import bytecodeparser.analysis.stack.Constant.WhateverConstant;
35 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
36 | import bytecodeparser.analysis.stack.Stack;
37 |
38 | /**
39 | * A decoded constant push op.
40 | * @author Stephane Godbillon
41 | *
42 | */
43 | public class DecodedConstantPushOp extends DecodedBasicOp {
44 | public DecodedConstantPushOp(ConstantPushOpcode op, Context context, int index) {
45 | super(op, context, index);
46 | }
47 |
48 | @Override
49 | public void simulate(Stack stack) {
50 | ConstantPushOpcode cpop = this.op.as(ConstantPushOpcode.class);
51 | if(cpop.getParameterTypes().length == 0) {
52 | switch(cpop.baseCode) {
53 | case Opcode.ICONST_0:
54 | stack.push(new IntegerConstant(cpop.getCode() - cpop.baseCode));
55 | break;
56 | case Opcode.LCONST_0:
57 | stack.push2(new LongConstant(new Long(new Integer(cpop.getCode() - cpop.baseCode))));
58 | break;
59 | case Opcode.FCONST_0:
60 | stack.push(new FloatConstant(new Float(cpop.getCode() - cpop.baseCode)));
61 | break;
62 | case Opcode.DCONST_0:
63 | stack.push2(new DoubleConstant(new Double(cpop.getCode() - cpop.baseCode)));
64 | break;
65 | default:
66 | throw new RuntimeException("unsupported basecode=" + cpop.baseCode + "(" + cpop.getName() + ")");
67 | }
68 | } else {
69 | OpParameterType type = cpop.getParameterTypes()[0];
70 | int value = cpop.decode(context, index).parameterValues[0];
71 | if(type == OpParameterType.S1 || type == OpParameterType.S2) {
72 | for(int i = 0; i < getPops().length; i++) {
73 | stack.pop(getPops()[i]);
74 | }
75 | stack.push(new IntegerConstant(cpop.decode(context, index).parameterValues[0]));
76 | } else if(type == OpParameterType.U1 || type == OpParameterType.U2) {
77 | Object o = context.behavior.getMethodInfo().getConstPool().getLdcValue(value);
78 | if(o == null) {
79 | ConstPool cp = context.behavior.getMethodInfo().getConstPool();
80 | for(Method m : ConstPool.class.getDeclaredMethods()) {
81 | if(m.getName().equals("getItem")) {
82 | m.setAccessible(true);
83 | try {
84 | Object _o = m.invoke(cp, new Integer(value));
85 | stack.push(new WhateverConstant(_o));
86 | } catch (Exception e) {
87 | throw new RuntimeException(e);
88 | }
89 | }
90 | }
91 | return;
92 | }
93 | if(pushes[0].equals(StackElementLength.DOUBLE) && !(o instanceof Long) && !(o instanceof Double))
94 | throw new RuntimeException("Constant push of type " + op.getName() + " should push a double-size element but is not! (o = " + o + ")");
95 | if(o instanceof Integer)
96 | stack.push(new IntegerConstant((Integer)o));
97 | else if(o instanceof Long)
98 | stack.push2(new LongConstant((Long)o));
99 | else if(o instanceof Float)
100 | stack.push(new FloatConstant((Float)o));
101 | else if(o instanceof Double)
102 | stack.push2(new DoubleConstant((Double)o));
103 | else if(o instanceof String)
104 | stack.push(new StringConstant((String)o));
105 | else throw new RuntimeException("unsupported type ??? =" + o.getClass() + "(" + cpop.code + " : " + cpop.getName() + ")");
106 | } else {
107 | throw new RuntimeException("unsupported code=" + cpop.code + "(" + cpop.getName() + ")");
108 | }
109 | }
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedFieldOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import static bytecodeparser.analysis.stack.Stack.StackElementLength.DOUBLE;
23 | import static bytecodeparser.analysis.stack.Stack.StackElementLength.ONE;
24 | import javassist.bytecode.Descriptor;
25 | import javassist.bytecode.Opcode;
26 | import bytecodeparser.Context;
27 | import bytecodeparser.analysis.opcodes.FieldOpcode;
28 | import bytecodeparser.analysis.stack.Stack;
29 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
30 |
31 | /**
32 | * A decoded field operation op.
33 | * @author Stephane Godbillon
34 | *
35 | */
36 | public class DecodedFieldOp extends DecodedOp {
37 | protected String descriptor;
38 | protected boolean load;
39 | protected boolean isStatic;
40 | protected StackElementLength stackElementLength;
41 |
42 | public DecodedFieldOp(FieldOpcode fo, Context context, int index) {
43 | super(fo, context, index);
44 | String descriptor = context.behavior.getMethodInfo().getConstPool().getFieldrefType(getMethodRefIndex());
45 | StackElementLength sel = ONE;
46 | if(Descriptor.dataSize(descriptor) == 2)
47 | sel = DOUBLE;
48 | this.stackElementLength = sel;
49 | this.descriptor = descriptor;
50 | this.load = fo.getCode() == Opcode.GETFIELD || fo.getCode() == Opcode.GETSTATIC;
51 | this.isStatic = fo.getCode() == Opcode.GETSTATIC ||fo.getCode() == Opcode.PUTSTATIC;
52 | }
53 |
54 | @Override
55 | public void simulate(Stack stack) {
56 | Stack.processBasicAlteration(stack, getPops(), getPushes());
57 | }
58 |
59 | /**
60 | * @return the methodRef index of this op.
61 | */
62 | public int getMethodRefIndex() {
63 | return parameterValues[0];
64 | }
65 |
66 | /**
67 | * @return the descriptor of the field.
68 | */
69 | public String getDescriptor() {
70 | return descriptor;
71 | }
72 |
73 | /**
74 | * Pops needed by this decoded op.
75 | */
76 | public StackElementLength[] getPops() {
77 | if(isStatic && !load)
78 | return new StackElementLength[] { stackElementLength };
79 | else if(isStatic && load)
80 | return new StackElementLength[0];
81 | else if(!isStatic && !load)
82 | return new StackElementLength[] { stackElementLength, ONE };
83 | else return new StackElementLength[] { ONE };
84 | }
85 |
86 | /**
87 | * Pushes needed by this decoded op.
88 | */
89 | public StackElementLength[] getPushes() {
90 | if(load)
91 | return new StackElementLength[] { stackElementLength };
92 | return new StackElementLength[0];
93 | }
94 |
95 | /**
96 | * States if this op is a read or write operation.
97 | */
98 | public boolean isRead() {
99 | return load;
100 | }
101 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedLocalVariableOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import javassist.bytecode.Opcode;
23 |
24 | import org.apache.log4j.Logger;
25 |
26 | import bytecodeparser.Context;
27 | import bytecodeparser.analysis.Opcodes.OpParameterType;
28 | import static bytecodeparser.analysis.Opcodes.OpParameterType.*;
29 | import bytecodeparser.analysis.LocalVariable;
30 | import bytecodeparser.analysis.opcodes.LocalVariableOpcode;
31 | import bytecodeparser.analysis.stack.Stack;
32 | import bytecodeparser.analysis.stack.StackElement;
33 | import bytecodeparser.analysis.stack.ValueFromLocalVariable;
34 |
35 | /**
36 | * A decoded local variable operation op.
37 | * @author Stephane Godbillon
38 | *
39 | */
40 | public class DecodedLocalVariableOp extends DecodedOp {
41 | private static final Logger LOGGER = Logger.getLogger(DecodedLocalVariableOp.class);
42 | /**
43 | * The matching local variable.
44 | */
45 | public final LocalVariable localVariable;
46 | /**
47 | * States if this op is a read (load) or write (store).
48 | */
49 | public final boolean load;
50 | /**
51 | * States if the matching localVariable is one- or two-words long.
52 | */
53 | public final boolean doubleLength;
54 | /**
55 | * States if the op is wide (nb localvars > 256)
56 | */
57 | public final boolean isWide;
58 |
59 | public DecodedLocalVariableOp(LocalVariableOpcode lvo, Context context, int index, boolean isWide) {
60 | super(lvo, context, index, guessTypes(lvo, context, index, isWide), decodeValues(guessTypes(lvo, context, index, isWide), context.iterator, index + (isWide ? 1 : 0)));
61 | this.isWide = isWide;
62 | int slot;
63 | if(parameterTypes.length > 0)
64 | slot = parameterValues[0];
65 | else slot = lvo.getCode() - lvo.getBaseOpcode();
66 | localVariable = LocalVariable.getLocalVariable(slot, index, context.localVariables);
67 | int base = lvo.getBaseOpcode();
68 | this.load = lvo.isLoad();
69 | doubleLength = base == Opcode.DLOAD || base == Opcode.DLOAD_0 || base == Opcode.LLOAD || base == Opcode.LLOAD_0 || base == Opcode.DSTORE || base == Opcode.DSTORE_0 || base == Opcode.LSTORE || base == Opcode.LSTORE_0;
70 | }
71 |
72 | @Override
73 | public void simulate(Stack stack) {
74 | if(op.code != Opcode.IINC) {
75 | ValueFromLocalVariable toPush = new ValueFromLocalVariable(localVariable);
76 | if(!load) {
77 | StackElement poppedSe;
78 | if(doubleLength)
79 | poppedSe = stack.pop2();
80 | else poppedSe = stack.pop();
81 | /* when a name is null while LocalVariableTable is present, it is likely that this class has been
82 | * previously enhanced and this local variable is just a variable proxy, so grab the original local
83 | * variable and consider its name
84 | */
85 | if(poppedSe instanceof ValueFromLocalVariable && (localVariable == null || localVariable.name == null)) {
86 | LOGGER.debug("ATTENTION ************** variable proxy for lv = '" + ((ValueFromLocalVariable) poppedSe).localVariable + "'");
87 | toPush = new ValueFromLocalVariable(((ValueFromLocalVariable) poppedSe).localVariable);
88 | }
89 | } else {
90 | if(doubleLength)
91 | stack.push2(toPush);
92 | else stack.push(toPush);
93 | }
94 | }
95 | }
96 |
97 | private static OpParameterType[] guessTypes(LocalVariableOpcode lvo, Context context, int index, boolean isWide) {
98 | int code = lvo.code;
99 | if(code != Opcode.ALOAD &&
100 | code != Opcode.ASTORE &&
101 | code != Opcode.DLOAD &&
102 | code != Opcode.DSTORE &&
103 | code != Opcode.FLOAD &&
104 | code != Opcode.FSTORE &&
105 | code != Opcode.ILOAD &&
106 | code != Opcode.ISTORE &&
107 | code != Opcode.LLOAD &&
108 | code != Opcode.LSTORE &&
109 | code != Opcode.IINC)
110 | return new OpParameterType[0];
111 | boolean isIINC = lvo.code == Opcode.IINC;
112 | OpParameterType[] result = new OpParameterType[isIINC ? 2 : 1];
113 | result[0] = isWide ? U2 : U1;
114 | if(isIINC)
115 | result[1] = isWide ? S2 : S1;
116 | return result;
117 | }
118 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import javassist.bytecode.CodeIterator;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.opcodes.Op;
26 | import bytecodeparser.analysis.stack.Stack;
27 |
28 | /**
29 | * A decoded Op.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public abstract class DecodedOp {
34 | /**
35 | * The context in which this op has been decoded.
36 | */
37 | public final Context context;
38 | /**
39 | * The index at which this op has been decoded.
40 | */
41 | public final int index;
42 | /**
43 | * The op that has been decoded.
44 | */
45 | public final Op op;
46 |
47 | public final OpParameterType[] parameterTypes;
48 | public final int[] parameterValues;
49 |
50 | public DecodedOp(Op op, Context context, int index) {
51 | this(op, context, index, op.getParameterTypes());
52 | }
53 |
54 | public DecodedOp(Op op, Context context, int index, OpParameterType[] parameterTypes) {
55 | this(op, context, index, parameterTypes, decodeValues(parameterTypes, context.iterator, index));
56 | }
57 |
58 | public DecodedOp(Op op, Context context, int index, OpParameterType[] parameterTypes, int[] parameterValues) {
59 | this.context = context;
60 | this.index = index;
61 | this.op = op;
62 | this.parameterTypes = parameterTypes;
63 | this.parameterValues = parameterValues;
64 | }
65 |
66 | public static int[] decodeValues(OpParameterType[] parameterTypes, CodeIterator iterator, int index) {
67 | int[] result = new int[parameterTypes.length];
68 | int nextValIndex = index + 1;
69 | for(int i = 0; i < parameterTypes.length; i++) {
70 | OpParameterType type = parameterTypes[i];
71 | result[i] = decodeValueAt(type, iterator, nextValIndex);
72 | nextValIndex += type.size;
73 | }
74 | return result;
75 | }
76 |
77 | public static int decodeValueAt(OpParameterType type, CodeIterator iterator, int index) {
78 | switch(type) {
79 | case S1:
80 | return iterator.byteAt(index);
81 | case S2:
82 | return iterator.s16bitAt(index);
83 | case S4:
84 | return iterator.s32bitAt(index);
85 | case U1:
86 | return iterator.byteAt(index);
87 | case U2:
88 | return iterator.u16bitAt(index);
89 | case U4:
90 | default:
91 | throw new RuntimeException("unsupported");
92 |
93 | }
94 | }
95 |
96 | /**
97 | * Simulate this op onto the given stack.
98 | * @param stack
99 | */
100 | public abstract void simulate(Stack stack);
101 | }
102 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedSwitchOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import static bytecodeparser.analysis.Opcodes.OpParameterType.S4;
23 |
24 | import java.util.Arrays;
25 |
26 | import javassist.bytecode.Opcode;
27 | import bytecodeparser.Context;
28 | import bytecodeparser.analysis.opcodes.SwitchOpcode;
29 | import bytecodeparser.analysis.stack.Stack;
30 |
31 | /**
32 | * A decoded switch (lookup/tableswitch) op.
33 | * @author Stephane Godbillon
34 | *
35 | */
36 | public class DecodedSwitchOpcode extends DecodedOp {
37 | /**
38 | * The default offset of the switch.
39 | */
40 | public final int defaultOffset;
41 | /**
42 | * The number of padding bytes, if any.
43 | */
44 | public final int padding;
45 | /**
46 | * The low index of entries (tableswitch). -1 if lookupswitch.
47 | */
48 | public final int low;
49 | /**
50 | * The high index of entries (tableswitch). -1 if lookupswitch.
51 | */
52 | public final int high;
53 | /**
54 | * The number of entries of the switch.
55 | */
56 | public final int nbEntries;
57 | /**
58 | * The offsets of the entries.
59 | */
60 | public final int[] offsets;
61 |
62 | public DecodedSwitchOpcode(SwitchOpcode op, Context context, int index) {
63 | super(op, context, index);
64 | int _padding = (index + 1) % 4;
65 | padding = _padding == 0 ? 0 : 4 - _padding;
66 | int nextIndex = index + padding + 1;
67 | defaultOffset = decodeValueAt(S4, context.iterator, nextIndex) + index;
68 | nextIndex += S4.size;
69 | if(op.code == Opcode.TABLESWITCH) {
70 | low = decodeValueAt(S4, context.iterator, nextIndex);
71 | nextIndex += S4.size;
72 | high = decodeValueAt(S4, context.iterator, nextIndex);
73 | nextIndex += S4.size;
74 | nbEntries = high - low + 1;
75 | offsets = new int[nbEntries];
76 | for(int i = 0; i < offsets.length; i++) {
77 | offsets[i] = decodeValueAt(S4, context.iterator, nextIndex) + index;
78 | nextIndex += S4.size;
79 | }
80 | } else { // LOOKUPSWITCH
81 | low = high = -1;
82 | nbEntries = decodeValueAt(S4, context.iterator, nextIndex);
83 | nextIndex += S4.size;
84 | offsets = new int[nbEntries];
85 | for(int i = 0; i < offsets.length; i++) {
86 | nextIndex += S4.size;
87 | offsets[i] = decodeValueAt(S4, context.iterator, nextIndex) + index;
88 | nextIndex += S4.size;
89 | }
90 | }
91 | }
92 |
93 | @Override
94 | public void simulate(Stack stack) {
95 | stack.pop();
96 | }
97 |
98 | @Override
99 | public String toString() {
100 | return "DecodedSwitchOpcode [" + op.getName() + "] : redirects -> " + Arrays.toString(offsets) + ", default " + defaultOffset + "(high=" + high + ", low=" + low + ")";
101 | }
102 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/decoders/DecodedWideOp.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.decoders;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes;
24 | import bytecodeparser.analysis.opcodes.LocalVariableOpcode;
25 | import bytecodeparser.analysis.opcodes.WideOpcode;
26 | import bytecodeparser.analysis.stack.Stack;
27 |
28 | /**
29 | * A decoded wide local variable operation op.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public class DecodedWideOp extends DecodedOp {
34 | /**
35 | * The wrapped decoded local variable opcode.
36 | */
37 | public final DecodedLocalVariableOp wrappedDecodedLocalVariableOp;
38 |
39 | public DecodedWideOp(WideOpcode wide, Context context, int index) {
40 | super(wide, context, index);
41 | wrappedDecodedLocalVariableOp = Opcodes.OPCODES.get(context.iterator.byteAt(index + 1)).as(LocalVariableOpcode.class).decodeWide(context, index);
42 | }
43 |
44 | @Override
45 | public void simulate(Stack stack) {
46 | wrappedDecodedLocalVariableOp.simulate(stack);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ArrayCreationOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedArrayCreationOp;
25 |
26 | /**
27 | * An array creation opcode.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ArrayCreationOpcode extends BasicOpcode {
32 | public ArrayCreationOpcode(int code, OpParameterType... opParameterTypes) {
33 | super(code, opParameterTypes);
34 | }
35 | @Override
36 | public DecodedArrayCreationOp decode(Context context, int index) {
37 | return new DecodedArrayCreationOp(this, context, index);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ArrayOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedArrayOp;
25 |
26 | /**
27 | * An opcode that is an operation on an array.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ArrayOpcode extends BasicOpcode {
32 | /**
33 | * States if the operation is a read (load -> true) or a write (store -> false).
34 | */
35 | public final boolean isLoad;
36 |
37 | public ArrayOpcode(int code, boolean isLoad, OpParameterType... opParameterTypes) {
38 | super(code, opParameterTypes);
39 | this.isLoad = isLoad;
40 | }
41 |
42 | @Override
43 | public DecodedArrayOp decode(Context context, int index) {
44 | return new DecodedArrayOp(this, context, index);
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/BasicOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedBasicOp;
25 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
26 |
27 | /**
28 | * A basic op that performs classic push/pops on the stack.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class BasicOpcode extends Op {
33 | protected StackElementLength[] pops, pushes;
34 | public BasicOpcode(int code, OpParameterType... opParameterTypes) {
35 | this(code, new StackElementLength[0], new StackElementLength[0], opParameterTypes);
36 | }
37 | public BasicOpcode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
38 | super(code, opParameterTypes);
39 | this.pops = pops;
40 | this.pushes = pushes;
41 | }
42 | /**
43 | * @return the pops of this opcode.
44 | */
45 | public StackElementLength[] getPops() {
46 | return pops;
47 | }
48 | /**
49 | * @return the pushes of this opcode.
50 | */
51 | public StackElementLength[] getPushes() {
52 | return pushes;
53 | }
54 | @Override
55 | public DecodedBasicOp decode(Context context, int index) {
56 | return new DecodedBasicOp(this, context, index);
57 | }
58 | @Override
59 | public String toString() {
60 | return "BasicOp: " + getName();
61 | }
62 | /**
63 | * Internal use only.
64 | */
65 | public BasicOpcode setPops(StackElementLength... pops) {
66 | if(pops != null)
67 | this.pops = pops;
68 | return this;
69 | }
70 | /**
71 | * Internal use only.
72 | */
73 | public BasicOpcode setPushes(StackElementLength... pushes) {
74 | if(pushes != null)
75 | this.pushes = pushes;
76 | return this;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/BranchOpCode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import javassist.bytecode.Opcode;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.decoders.DecodedBranchOp;
26 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
27 |
28 | /**
29 | * An opcode that stands for a fork in the bytecode.
30 | * @author Stephane Godbillon
31 | *
32 | */
33 | public class BranchOpCode extends BasicOpcode {
34 | public BranchOpCode(int code, OpParameterType... opParameterTypes) {
35 | super(code, opParameterTypes);
36 | }
37 | public BranchOpCode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
38 | super(code, pops, pushes, opParameterTypes);
39 | }
40 |
41 | @Override
42 | public DecodedBranchOp decode(Context context, int index) {
43 | return new DecodedBranchOp(this, context, index);
44 | }
45 |
46 | /**
47 | * States if this opcode is conditional fork or not.
48 | */
49 | public boolean isConditional() {
50 | return code >= Opcode.IFEQ && code <= Opcode.IF_ACMPNE || code == Opcode.IFNULL || code == Opcode.IFNONNULL;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ConstantPushOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes.OpParameterType;
24 | import bytecodeparser.analysis.decoders.DecodedConstantPushOp;
25 |
26 | /**
27 | * An opcode that stands for a push of a constant onto the stack.
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class ConstantPushOpcode extends BasicOpcode {
32 | public final int baseCode;
33 |
34 | public ConstantPushOpcode(int code, OpParameterType... opParameterTypes) {
35 | this(code, code, opParameterTypes);
36 | }
37 |
38 | public ConstantPushOpcode(int code, int baseCode, OpParameterType... opParameterTypes) {
39 | super(code, opParameterTypes);
40 | this.baseCode = baseCode;
41 | }
42 |
43 | @Override
44 | public DecodedConstantPushOp decode(Context context, int index) {
45 | return new DecodedConstantPushOp(this, context, index);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/ExitOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.analysis.Opcodes.OpParameterType;
23 | import bytecodeparser.analysis.stack.Stack.StackElementLength;
24 |
25 | /**
26 | * An opcode that stands for an exit of the behavior (like a return).
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class ExitOpcode extends BasicOpcode {
31 | public ExitOpcode(int code, OpParameterType... opParameterTypes) {
32 | super(code, opParameterTypes);
33 | }
34 | public ExitOpcode(int code, StackElementLength[] pops, StackElementLength[] pushes, OpParameterType... opParameterTypes) {
35 | super(code, pops, pushes, opParameterTypes);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/FieldOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import static bytecodeparser.analysis.Opcodes.OpParameterType.U2;
23 | import bytecodeparser.Context;
24 | import bytecodeparser.analysis.decoders.DecodedFieldOp;
25 |
26 | /**
27 | * An opcode concerning a field (read, write).
28 | * @author Stephane Godbillon
29 | *
30 | */
31 | public class FieldOpcode extends Op {
32 | private final DecodedFieldOp decodedOp;
33 |
34 | public FieldOpcode(int code) {
35 | this(code, null);
36 | }
37 | private FieldOpcode(int code, DecodedFieldOp decodedOp) {
38 | super(code, U2);
39 | this.decodedOp = decodedOp;
40 | }
41 | @Override
42 | public FieldOpcode init(Context context, int index) {
43 | return new FieldOpcode(code, decode(context, index));
44 | }
45 | @Override
46 | public DecodedFieldOp decode(Context context, int index) {
47 | if(decodedOp != null)
48 | return decodedOp;
49 | try {
50 | DecodedFieldOp decodedOp = new DecodedFieldOp(this, context, index);
51 | return decodedOp;
52 | } catch (Exception e) {
53 | throw new RuntimeException(e);
54 | }
55 | }
56 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/LocalVariableOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedLocalVariableOp;
24 |
25 | /**
26 | * An opcode concerning a local variable (read, write).
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class LocalVariableOpcode extends Op {
31 | private final int base;
32 | private final boolean load;
33 |
34 | public LocalVariableOpcode(int code, boolean load) {
35 | this(code, code, load);
36 | }
37 | public LocalVariableOpcode(int code, int base, boolean load) {
38 | super(code);
39 | this.base = base;
40 | this.load = load;
41 | }
42 |
43 | @Override
44 | public DecodedLocalVariableOp decode(Context context, int index) {
45 | return new DecodedLocalVariableOp(this, context, index, false);
46 | }
47 |
48 | public DecodedLocalVariableOp decodeWide(Context context, int index) {
49 | return new DecodedLocalVariableOp(this, context, index, true);
50 | }
51 |
52 | public int getBaseOpcode() {
53 | return base;
54 | }
55 |
56 | /**
57 | * States if this opcode is a read (load -> true) or a write (store -> false).
58 | * @return
59 | */
60 | public boolean isLoad() {
61 | return load;
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return "LocalVariableOp: " + getName();
67 | }
68 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/MethodInvocationOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import static bytecodeparser.analysis.Opcodes.OpParameterType.U2;
23 | import javassist.bytecode.Opcode;
24 | import bytecodeparser.Context;
25 | import bytecodeparser.analysis.decoders.DecodedMethodInvocationOp;
26 |
27 | /**
28 | * An opcode that stands for a method invocation.
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class MethodInvocationOpcode extends Op {
33 | public MethodInvocationOpcode(int code) {
34 | super(code, U2);
35 | }
36 | /**
37 | * States if the invoked method is static or not.
38 | */
39 | public boolean isInstanceMethod() {
40 | return code != Opcode.INVOKESTATIC;
41 | }
42 | @Override
43 | public DecodedMethodInvocationOp decode(Context context, int index) {
44 | try {
45 | return new DecodedMethodInvocationOp(this, context, index);
46 | } catch (Exception e) {
47 | throw new RuntimeException(e);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/Op.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.Opcodes;
24 | import bytecodeparser.analysis.Opcodes.OpParameterType;
25 | import bytecodeparser.analysis.decoders.DecodedOp;
26 |
27 | public abstract class Op {
28 | /**
29 | * The opcode int.
30 | */
31 | public final int code;
32 | protected final OpParameterType[] parameterTypes;
33 | private String name;
34 | public Op(int code, OpParameterType... opParameterTypes) {
35 | this.code = code;
36 | this.parameterTypes = opParameterTypes;
37 | }
38 |
39 | /**
40 | * Decodes this op with a given context.
41 | * @param context
42 | * @param index
43 | * @return the matching decodedOp.
44 | */
45 | public abstract DecodedOp decode(Context context, int index);
46 |
47 | /**
48 | * Should be called before using this object.
49 | * @return this object's copy with some contextual information, if needed.
50 | */
51 | public Op init(Context context, int index) {
52 | return this;
53 | }
54 |
55 | /**
56 | * @return the opcode int.
57 | */
58 | public int getCode() {
59 | return code;
60 | }
61 |
62 | /**
63 | * @return the paramaters types of this op, if any.
64 | */
65 | public OpParameterType[] getParameterTypes() {
66 | return parameterTypes;
67 | }
68 |
69 | /**
70 | * @return the name of this opcode.
71 | */
72 | public String getName() {
73 | if(name == null)
74 | name = Opcodes.findOpName(code);
75 | return name;
76 | }
77 |
78 | /**
79 | * Shortcut for chaining and casting.
80 | * @param specificOpClass
81 | * @return the casted op.
82 | */
83 | @SuppressWarnings(value="unchecked")
84 | public T as(Class specificOpClass) {
85 | return (T) this;
86 | }
87 |
88 | @Override
89 | public String toString() {
90 | return "op: " + getName() + "";
91 | }
92 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/SwitchOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedSwitchOpcode;
24 |
25 | /**
26 | * LookupSwitch or TableSwitch opcode.
27 | * @author Stephane Godbillon
28 | *
29 | */
30 | public class SwitchOpcode extends Op {
31 |
32 | public SwitchOpcode(int code) {
33 | super(code);
34 | }
35 |
36 | @Override
37 | public DecodedSwitchOpcode decode(Context context, int index) {
38 | return new DecodedSwitchOpcode(this, context, index);
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/opcodes/WideOpcode.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.opcodes;
21 |
22 | import bytecodeparser.Context;
23 | import bytecodeparser.analysis.decoders.DecodedLocalVariableOp;
24 | import bytecodeparser.analysis.decoders.DecodedWideOp;
25 | import javassist.bytecode.Opcode;
26 |
27 | /**
28 | * Wide opcode for localvariables (if there is more than 256 local vars in the method's body).
29 | * @author Stephane Godbillon
30 | *
31 | */
32 | public class WideOpcode extends Op {
33 | private final DecodedWideOp decodedWideOp;
34 |
35 | public WideOpcode() {
36 | this(null);
37 | }
38 |
39 | private WideOpcode(DecodedWideOp decodedWideOp) {
40 | super(Opcode.WIDE);
41 | this.decodedWideOp = decodedWideOp;
42 | }
43 |
44 | @Override
45 | public Op init(Context context, int index) {
46 | return new WideOpcode(new DecodedWideOp(this, context, index));
47 | }
48 |
49 | @Override
50 | public DecodedWideOp decode(Context context, int index) {
51 | if(decodedWideOp != null)
52 | return decodedWideOp;
53 | throw new RuntimeException("must be initialized before !");
54 | }
55 |
56 | /**
57 | * Gets the wrapped localVariable opcode.
58 | * This op MUST be decoded before invoking this method.
59 | * @return the wrapped localVariable op.
60 | * @throws RuntimeException if this op has not been initialized with init(context, index) before.
61 | */
62 | public LocalVariableOpcode getWrappedLocalVariableOpcode() {
63 | if(decodedWideOp != null)
64 | return decodedWideOp.op.as(LocalVariableOpcode.class);
65 | throw new RuntimeException("must be initialized before !");
66 | }
67 |
68 | /**
69 | * Gets the wrapped decoded localVariable opcode.
70 | * This op MUST be decoded before invoking this method.
71 | * @return the wrapped decoded localVariable op.
72 | * @throws RuntimeException if this op has not been initialized with init(context, index) before.
73 | */
74 | public DecodedLocalVariableOp getWrappedDecodedLocalVariableOp() {
75 | if(decodedWideOp != null)
76 | return decodedWideOp.wrappedDecodedLocalVariableOp;
77 | throw new RuntimeException("must be initialized before !");
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/Array.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A StackElement that stands for an array.
24 | * @author Stephane Godbillon
25 | *
26 | */
27 | public class Array extends StackElement {
28 | /**
29 | * The signature of this array.
30 | */
31 | public final String signature;
32 | public Array(String signature) {
33 | this.signature = signature;
34 | }
35 | @Override
36 | public Array copy() {
37 | return new Array(signature);
38 | }
39 | @Override
40 | public String toString() {
41 | return "simple array of '" + signature + "'";
42 | }
43 | }
--------------------------------------------------------------------------------
/src/bytecodeparser/analysis/stack/Constant.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2011 Stephane Godbillon
3 | *
4 | * This file is part of BytecodeParser. See the README file in the root
5 | * directory of this project.
6 | *
7 | * BytecodeParser is free software: you can redistribute it and/or modify
8 | * it under the terms of the GNU Lesser General Public License as published by
9 | * the Free Software Foundation, either version 3 of the License, or
10 | * (at your option) any later version.
11 |
12 | * BytecodeParser is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 | * GNU Lesser General Public License for more details.
16 |
17 | * You should have received a copy of the GNU Lesser General Public License
18 | * along with BytecodeParser. If not, see .
19 | */
20 | package bytecodeparser.analysis.stack;
21 |
22 | /**
23 | * A StackElement that is a constant.
24 | *
25 | * @author Stephane Godbillon
26 | *
27 | * @param T can be one of : String, Integer, Float, Long, Double, or Object. See the subclasses for more information.
28 | */
29 | public abstract class Constant extends StackElement {
30 | protected final T value;
31 |
32 | public Constant(T value) {
33 | this.value = value;
34 | }
35 |
36 | /**
37 | * @return The wrapped value.
38 | */
39 | public T getValue() {
40 | return value;
41 | }
42 |
43 | @Override
44 | public String toString() {
45 | return this.getClass().getSimpleName() + ": " + value;
46 | }
47 |
48 | /**
49 | * A StackElement that stands for a String Constant.
50 | * @author Stephane Godbillon
51 | *
52 | */
53 | public static class StringConstant extends Constant {
54 | public StringConstant(String value) {
55 | super(value);
56 | }
57 | @Override
58 | public StackElement copy() {
59 | return new StringConstant(value);
60 | }
61 | }
62 |
63 | /**
64 | * A StackElement that stands for an Integer Constant.
65 | * @author Stephane Godbillon
66 | *
67 | */
68 | public static class IntegerConstant extends Constant {
69 | public IntegerConstant(Integer value) {
70 | super(value);
71 | }
72 | @Override
73 | public StackElement copy() {
74 | return new IntegerConstant(value);
75 | }
76 | }
77 |
78 | /**
79 | * A StackElement that stands for a Float Constant.
80 | * @author Stephane Godbillon
81 | *
82 | */
83 | public static class FloatConstant extends Constant {
84 | public FloatConstant(Float value) {
85 | super(value);
86 | }
87 | @Override
88 | public StackElement copy() {
89 | return new FloatConstant(value);
90 | }
91 | }
92 |
93 | /**
94 | * A StackElement that stands for a Long Constant.
95 | * @author Stephane Godbillon
96 | *
97 | */
98 | public static class LongConstant extends Constant {
99 | public LongConstant(Long value) {
100 | super(value);
101 | }
102 | @Override
103 | public StackElement copy() {
104 | return new LongConstant(value);
105 | }
106 | }
107 |
108 | /**
109 | * A StackElement that stands for a Double Constant.
110 | * @author Stephane Godbillon
111 | *
112 | */
113 | public static class DoubleConstant extends Constant {
114 | public DoubleConstant(Double value) {
115 | super(value);
116 | }
117 | @Override
118 | public StackElement copy() {
119 | return new DoubleConstant(value);
120 | }
121 | }
122 |
123 | /**
124 | * A StackElement that stands for an Object Constant (so, whatever constant...).
125 | * @author Stephane Godbillon
126 | *
127 | */
128 | public static class WhateverConstant extends Constant