/*
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
* Copyright (c) 2002-2019 Guardsquare NV
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package proguard.optimize.peephole;
import proguard.classfile.*;
import proguard.classfile.constant.*;
import proguard.classfile.editor.*;
import proguard.classfile.instruction.Instruction;
import proguard.classfile.visitor.ClassPrinter;
/**
* This class contains a set of instruction sequences with their suggested
* more compact or more efficient replacements.
*
* @see InstructionSequencesReplacer
* @see InstructionSequenceReplacer
* @author Eric Lafortune
*/
public class InstructionSequenceConstants
{
// The arrays with constants and instructions used to be static,
// but now they are initialized with references to classes and
// class members, inside an instance of this class. As an added
// benefit, they can be garbage collected after they have been used.
public final Instruction[][][] VARIABLE_SEQUENCES;
public final Instruction[][][] ARITHMETIC_SEQUENCES;
public final Instruction[][][] FIELD_SEQUENCES;
public final Instruction[][][] CAST_SEQUENCES;
public final Instruction[][][] BRANCH_SEQUENCES;
public final Instruction[][][] STRING_SEQUENCES;
public final Instruction[][][] OBJECT_SEQUENCES;
public final Instruction[][][] MATH_SEQUENCES;
public final Instruction[][][] MATH_ANDROID_SEQUENCES;
public final Constant[] CONSTANTS;
// Internal short-hand constants.
private static final String BOOLEAN = ClassConstants.NAME_JAVA_LANG_BOOLEAN;
private static final String BYTE = ClassConstants.NAME_JAVA_LANG_BYTE;
private static final String CHARACTER = ClassConstants.NAME_JAVA_LANG_CHARACTER;
private static final String SHORT = ClassConstants.NAME_JAVA_LANG_SHORT;
private static final String INTEGER = ClassConstants.NAME_JAVA_LANG_INTEGER;
private static final String LONG = ClassConstants.NAME_JAVA_LANG_LONG;
private static final String FLOAT = ClassConstants.NAME_JAVA_LANG_FLOAT;
private static final String DOUBLE = ClassConstants.NAME_JAVA_LANG_DOUBLE;
private static final String STRING = ClassConstants.NAME_JAVA_LANG_STRING;
private static final String STRING_BUFFER = ClassConstants.NAME_JAVA_LANG_STRING_BUFFER;
private static final String STRING_BUILDER = ClassConstants.NAME_JAVA_LANG_STRING_BUILDER;
private static final String MATH = ClassConstants.NAME_JAVA_LANG_MATH;
private static final String FLOAT_MATH = ClassConstants.NAME_ANDROID_UTIL_FLOAT_MATH;
private static final int X = InstructionSequenceReplacer.X;
private static final int Y = InstructionSequenceReplacer.Y;
private static final int Z = InstructionSequenceReplacer.Z;
private static final int A = InstructionSequenceReplacer.A;
private static final int B = InstructionSequenceReplacer.B;
private static final int C = InstructionSequenceReplacer.C;
private static final int D = InstructionSequenceReplacer.D;
// Replacement constants that are derived from matched variables.
private static final int STRING_A_LENGTH = InstructionSequenceReplacer.STRING_A_LENGTH;
private static final int BOOLEAN_A_STRING = InstructionSequenceReplacer.BOOLEAN_A_STRING;
private static final int CHAR_A_STRING = InstructionSequenceReplacer.CHAR_A_STRING;
private static final int INT_A_STRING = InstructionSequenceReplacer.INT_A_STRING;
private static final int LONG_A_STRING = InstructionSequenceReplacer.LONG_A_STRING;
private static final int FLOAT_A_STRING = InstructionSequenceReplacer.FLOAT_A_STRING;
private static final int DOUBLE_A_STRING = InstructionSequenceReplacer.DOUBLE_A_STRING;
private static final int STRING_A_STRING = InstructionSequenceReplacer.STRING_A_STRING;
private static final int BOOLEAN_B_STRING = InstructionSequenceReplacer.BOOLEAN_B_STRING;
private static final int CHAR_B_STRING = InstructionSequenceReplacer.CHAR_B_STRING;
private static final int INT_B_STRING = InstructionSequenceReplacer.INT_B_STRING;
private static final int LONG_B_STRING = InstructionSequenceReplacer.LONG_B_STRING;
private static final int FLOAT_B_STRING = InstructionSequenceReplacer.FLOAT_B_STRING;
private static final int DOUBLE_B_STRING = InstructionSequenceReplacer.DOUBLE_B_STRING;
private static final int STRING_B_STRING = InstructionSequenceReplacer.STRING_B_STRING;
/**
* Creates a new instance of InstructionSequenceConstants, with constants
* that reference classes from the given class pools.
*/
public InstructionSequenceConstants(ClassPool programClassPool,
ClassPool libraryClassPool)
{
InstructionSequenceBuilder ____ =
new InstructionSequenceBuilder(programClassPool,
libraryClassPool);
// Create fieldref constants with wildcards, for fields in class X,
// with name Y, and the given primitive types.
ConstantPoolEditor constantPoolEditor = ____.getConstantPoolEditor();
final int FIELD_Z = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("Z"))), null, null));
final int FIELD_B = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("B"))), null, null));
final int FIELD_C = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("C"))), null, null));
final int FIELD_S = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("S"))), null, null));
final int FIELD_I = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("I"))), null, null));
final int FIELD_F = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("F"))), null, null));
final int FIELD_J = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("J"))), null, null));
final int FIELD_D = constantPoolEditor.addConstant(new FieldrefConstant(X, constantPoolEditor.addConstant(new NameAndTypeConstant(Y, constantPoolEditor.addUtf8Constant("D"))), null, null));
// Create methodref constants with wildcards, for methods in class X,
// with the given names and descriptors.
final int EQUALS = constantPoolEditor.addConstant(new MethodrefConstant(X, constantPoolEditor.addNameAndTypeConstant(ClassConstants.METHOD_NAME_EQUALS, ClassConstants.METHOD_TYPE_EQUALS), null, null));
final int TO_STRING = constantPoolEditor.addConstant(new MethodrefConstant(X, constantPoolEditor.addNameAnd