com.android.dx.dex.code.RopToDop Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of builder Show documentation
Show all versions of builder Show documentation
Library to build Android applications.
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.dx.dex.code;
import com.android.dx.rop.code.Insn;
import com.android.dx.rop.code.RegOps;
import com.android.dx.rop.code.RegisterSpec;
import com.android.dx.rop.code.Rop;
import com.android.dx.rop.code.Rops;
import com.android.dx.rop.code.ThrowingCstInsn;
import com.android.dx.rop.cst.Constant;
import com.android.dx.rop.cst.CstFieldRef;
import com.android.dx.rop.cst.CstString;
import com.android.dx.rop.cst.CstType;
import com.android.dx.rop.type.Type;
import java.util.HashMap;
/**
* Translator from rop-level {@link Insn} instances to corresponding
* {@link Dop} instances.
*/
public final class RopToDop {
/** {@code non-null;} map from all the common rops to dalvik opcodes */
private static final HashMap MAP;
/**
* This class is uninstantiable.
*/
private RopToDop() {
// This space intentionally left blank.
}
/*
* The following comment lists each opcode that should be considered
* the "head" of an opcode chain, in terms of the process of fitting
* an instruction's arguments to an actual opcode. This list is
* automatically generated and may be of use in double-checking the
* manually-generated static initialization code for this class.
*
* TODO: Make opcode-gen produce useful code in this case instead
* of just a comment.
*/
// BEGIN(first-opcodes); GENERATED AUTOMATICALLY BY opcode-gen
// Opcodes.NOP
// Opcodes.MOVE
// Opcodes.MOVE_WIDE
// Opcodes.MOVE_OBJECT
// Opcodes.MOVE_RESULT
// Opcodes.MOVE_RESULT_WIDE
// Opcodes.MOVE_RESULT_OBJECT
// Opcodes.MOVE_EXCEPTION
// Opcodes.RETURN_VOID
// Opcodes.RETURN
// Opcodes.RETURN_WIDE
// Opcodes.RETURN_OBJECT
// Opcodes.CONST_4
// Opcodes.CONST_WIDE_16
// Opcodes.CONST_STRING
// Opcodes.CONST_CLASS
// Opcodes.MONITOR_ENTER
// Opcodes.MONITOR_EXIT
// Opcodes.CHECK_CAST
// Opcodes.INSTANCE_OF
// Opcodes.ARRAY_LENGTH
// Opcodes.NEW_INSTANCE
// Opcodes.NEW_ARRAY
// Opcodes.FILLED_NEW_ARRAY
// Opcodes.FILL_ARRAY_DATA
// Opcodes.THROW
// Opcodes.GOTO
// Opcodes.PACKED_SWITCH
// Opcodes.SPARSE_SWITCH
// Opcodes.CMPL_FLOAT
// Opcodes.CMPG_FLOAT
// Opcodes.CMPL_DOUBLE
// Opcodes.CMPG_DOUBLE
// Opcodes.CMP_LONG
// Opcodes.IF_EQ
// Opcodes.IF_NE
// Opcodes.IF_LT
// Opcodes.IF_GE
// Opcodes.IF_GT
// Opcodes.IF_LE
// Opcodes.IF_EQZ
// Opcodes.IF_NEZ
// Opcodes.IF_LTZ
// Opcodes.IF_GEZ
// Opcodes.IF_GTZ
// Opcodes.IF_LEZ
// Opcodes.AGET
// Opcodes.AGET_WIDE
// Opcodes.AGET_OBJECT
// Opcodes.AGET_BOOLEAN
// Opcodes.AGET_BYTE
// Opcodes.AGET_CHAR
// Opcodes.AGET_SHORT
// Opcodes.APUT
// Opcodes.APUT_WIDE
// Opcodes.APUT_OBJECT
// Opcodes.APUT_BOOLEAN
// Opcodes.APUT_BYTE
// Opcodes.APUT_CHAR
// Opcodes.APUT_SHORT
// Opcodes.IGET
// Opcodes.IGET_WIDE
// Opcodes.IGET_OBJECT
// Opcodes.IGET_BOOLEAN
// Opcodes.IGET_BYTE
// Opcodes.IGET_CHAR
// Opcodes.IGET_SHORT
// Opcodes.IPUT
// Opcodes.IPUT_WIDE
// Opcodes.IPUT_OBJECT
// Opcodes.IPUT_BOOLEAN
// Opcodes.IPUT_BYTE
// Opcodes.IPUT_CHAR
// Opcodes.IPUT_SHORT
// Opcodes.SGET
// Opcodes.SGET_WIDE
// Opcodes.SGET_OBJECT
// Opcodes.SGET_BOOLEAN
// Opcodes.SGET_BYTE
// Opcodes.SGET_CHAR
// Opcodes.SGET_SHORT
// Opcodes.SPUT
// Opcodes.SPUT_WIDE
// Opcodes.SPUT_OBJECT
// Opcodes.SPUT_BOOLEAN
// Opcodes.SPUT_BYTE
// Opcodes.SPUT_CHAR
// Opcodes.SPUT_SHORT
// Opcodes.INVOKE_VIRTUAL
// Opcodes.INVOKE_SUPER
// Opcodes.INVOKE_DIRECT
// Opcodes.INVOKE_STATIC
// Opcodes.INVOKE_INTERFACE
// Opcodes.NEG_INT
// Opcodes.NOT_INT
// Opcodes.NEG_LONG
// Opcodes.NOT_LONG
// Opcodes.NEG_FLOAT
// Opcodes.NEG_DOUBLE
// Opcodes.INT_TO_LONG
// Opcodes.INT_TO_FLOAT
// Opcodes.INT_TO_DOUBLE
// Opcodes.LONG_TO_INT
// Opcodes.LONG_TO_FLOAT
// Opcodes.LONG_TO_DOUBLE
// Opcodes.FLOAT_TO_INT
// Opcodes.FLOAT_TO_LONG
// Opcodes.FLOAT_TO_DOUBLE
// Opcodes.DOUBLE_TO_INT
// Opcodes.DOUBLE_TO_LONG
// Opcodes.DOUBLE_TO_FLOAT
// Opcodes.INT_TO_BYTE
// Opcodes.INT_TO_CHAR
// Opcodes.INT_TO_SHORT
// Opcodes.ADD_INT_2ADDR
// Opcodes.SUB_INT_2ADDR
// Opcodes.MUL_INT_2ADDR
// Opcodes.DIV_INT_2ADDR
// Opcodes.REM_INT_2ADDR
// Opcodes.AND_INT_2ADDR
// Opcodes.OR_INT_2ADDR
// Opcodes.XOR_INT_2ADDR
// Opcodes.SHL_INT_2ADDR
// Opcodes.SHR_INT_2ADDR
// Opcodes.USHR_INT_2ADDR
// Opcodes.ADD_LONG_2ADDR
// Opcodes.SUB_LONG_2ADDR
// Opcodes.MUL_LONG_2ADDR
// Opcodes.DIV_LONG_2ADDR
// Opcodes.REM_LONG_2ADDR
// Opcodes.AND_LONG_2ADDR
// Opcodes.OR_LONG_2ADDR
// Opcodes.XOR_LONG_2ADDR
// Opcodes.SHL_LONG_2ADDR
// Opcodes.SHR_LONG_2ADDR
// Opcodes.USHR_LONG_2ADDR
// Opcodes.ADD_FLOAT_2ADDR
// Opcodes.SUB_FLOAT_2ADDR
// Opcodes.MUL_FLOAT_2ADDR
// Opcodes.DIV_FLOAT_2ADDR
// Opcodes.REM_FLOAT_2ADDR
// Opcodes.ADD_DOUBLE_2ADDR
// Opcodes.SUB_DOUBLE_2ADDR
// Opcodes.MUL_DOUBLE_2ADDR
// Opcodes.DIV_DOUBLE_2ADDR
// Opcodes.REM_DOUBLE_2ADDR
// Opcodes.ADD_INT_LIT8
// Opcodes.RSUB_INT_LIT8
// Opcodes.MUL_INT_LIT8
// Opcodes.DIV_INT_LIT8
// Opcodes.REM_INT_LIT8
// Opcodes.AND_INT_LIT8
// Opcodes.OR_INT_LIT8
// Opcodes.XOR_INT_LIT8
// Opcodes.SHL_INT_LIT8
// Opcodes.SHR_INT_LIT8
// Opcodes.USHR_INT_LIT8
// END(first-opcodes)
static {
/*
* Note: The choices made here are to pick the optimistically
* smallest Dalvik opcode, and leave it to later processing to
* pessimize. See the automatically-generated comment above
* for reference.
*/
MAP = new HashMap(400);
MAP.put(Rops.NOP, Dops.NOP);
MAP.put(Rops.MOVE_INT, Dops.MOVE);
MAP.put(Rops.MOVE_LONG, Dops.MOVE_WIDE);
MAP.put(Rops.MOVE_FLOAT, Dops.MOVE);
MAP.put(Rops.MOVE_DOUBLE, Dops.MOVE_WIDE);
MAP.put(Rops.MOVE_OBJECT, Dops.MOVE_OBJECT);
MAP.put(Rops.MOVE_PARAM_INT, Dops.MOVE);
MAP.put(Rops.MOVE_PARAM_LONG, Dops.MOVE_WIDE);
MAP.put(Rops.MOVE_PARAM_FLOAT, Dops.MOVE);
MAP.put(Rops.MOVE_PARAM_DOUBLE, Dops.MOVE_WIDE);
MAP.put(Rops.MOVE_PARAM_OBJECT, Dops.MOVE_OBJECT);
/*
* Note: No entry for MOVE_EXCEPTION, since it varies by
* exception type. (That is, there is no unique instance to
* add to the map.)
*/
MAP.put(Rops.CONST_INT, Dops.CONST_4);
MAP.put(Rops.CONST_LONG, Dops.CONST_WIDE_16);
MAP.put(Rops.CONST_FLOAT, Dops.CONST_4);
MAP.put(Rops.CONST_DOUBLE, Dops.CONST_WIDE_16);
/*
* Note: No entry for CONST_OBJECT, since it needs to turn
* into either CONST_STRING or CONST_CLASS.
*/
/*
* TODO: I think the only case of this is for null, and
* const/4 should cover that.
*/
MAP.put(Rops.CONST_OBJECT_NOTHROW, Dops.CONST_4);
MAP.put(Rops.GOTO, Dops.GOTO);
MAP.put(Rops.IF_EQZ_INT, Dops.IF_EQZ);
MAP.put(Rops.IF_NEZ_INT, Dops.IF_NEZ);
MAP.put(Rops.IF_LTZ_INT, Dops.IF_LTZ);
MAP.put(Rops.IF_GEZ_INT, Dops.IF_GEZ);
MAP.put(Rops.IF_LEZ_INT, Dops.IF_LEZ);
MAP.put(Rops.IF_GTZ_INT, Dops.IF_GTZ);
MAP.put(Rops.IF_EQZ_OBJECT, Dops.IF_EQZ);
MAP.put(Rops.IF_NEZ_OBJECT, Dops.IF_NEZ);
MAP.put(Rops.IF_EQ_INT, Dops.IF_EQ);
MAP.put(Rops.IF_NE_INT, Dops.IF_NE);
MAP.put(Rops.IF_LT_INT, Dops.IF_LT);
MAP.put(Rops.IF_GE_INT, Dops.IF_GE);
MAP.put(Rops.IF_LE_INT, Dops.IF_LE);
MAP.put(Rops.IF_GT_INT, Dops.IF_GT);
MAP.put(Rops.IF_EQ_OBJECT, Dops.IF_EQ);
MAP.put(Rops.IF_NE_OBJECT, Dops.IF_NE);
MAP.put(Rops.SWITCH, Dops.SPARSE_SWITCH);
MAP.put(Rops.ADD_INT, Dops.ADD_INT_2ADDR);
MAP.put(Rops.ADD_LONG, Dops.ADD_LONG_2ADDR);
MAP.put(Rops.ADD_FLOAT, Dops.ADD_FLOAT_2ADDR);
MAP.put(Rops.ADD_DOUBLE, Dops.ADD_DOUBLE_2ADDR);
MAP.put(Rops.SUB_INT, Dops.SUB_INT_2ADDR);
MAP.put(Rops.SUB_LONG, Dops.SUB_LONG_2ADDR);
MAP.put(Rops.SUB_FLOAT, Dops.SUB_FLOAT_2ADDR);
MAP.put(Rops.SUB_DOUBLE, Dops.SUB_DOUBLE_2ADDR);
MAP.put(Rops.MUL_INT, Dops.MUL_INT_2ADDR);
MAP.put(Rops.MUL_LONG, Dops.MUL_LONG_2ADDR);
MAP.put(Rops.MUL_FLOAT, Dops.MUL_FLOAT_2ADDR);
MAP.put(Rops.MUL_DOUBLE, Dops.MUL_DOUBLE_2ADDR);
MAP.put(Rops.DIV_INT, Dops.DIV_INT_2ADDR);
MAP.put(Rops.DIV_LONG, Dops.DIV_LONG_2ADDR);
MAP.put(Rops.DIV_FLOAT, Dops.DIV_FLOAT_2ADDR);
MAP.put(Rops.DIV_DOUBLE, Dops.DIV_DOUBLE_2ADDR);
MAP.put(Rops.REM_INT, Dops.REM_INT_2ADDR);
MAP.put(Rops.REM_LONG, Dops.REM_LONG_2ADDR);
MAP.put(Rops.REM_FLOAT, Dops.REM_FLOAT_2ADDR);
MAP.put(Rops.REM_DOUBLE, Dops.REM_DOUBLE_2ADDR);
MAP.put(Rops.NEG_INT, Dops.NEG_INT);
MAP.put(Rops.NEG_LONG, Dops.NEG_LONG);
MAP.put(Rops.NEG_FLOAT, Dops.NEG_FLOAT);
MAP.put(Rops.NEG_DOUBLE, Dops.NEG_DOUBLE);
MAP.put(Rops.AND_INT, Dops.AND_INT_2ADDR);
MAP.put(Rops.AND_LONG, Dops.AND_LONG_2ADDR);
MAP.put(Rops.OR_INT, Dops.OR_INT_2ADDR);
MAP.put(Rops.OR_LONG, Dops.OR_LONG_2ADDR);
MAP.put(Rops.XOR_INT, Dops.XOR_INT_2ADDR);
MAP.put(Rops.XOR_LONG, Dops.XOR_LONG_2ADDR);
MAP.put(Rops.SHL_INT, Dops.SHL_INT_2ADDR);
MAP.put(Rops.SHL_LONG, Dops.SHL_LONG_2ADDR);
MAP.put(Rops.SHR_INT, Dops.SHR_INT_2ADDR);
MAP.put(Rops.SHR_LONG, Dops.SHR_LONG_2ADDR);
MAP.put(Rops.USHR_INT, Dops.USHR_INT_2ADDR);
MAP.put(Rops.USHR_LONG, Dops.USHR_LONG_2ADDR);
MAP.put(Rops.NOT_INT, Dops.NOT_INT);
MAP.put(Rops.NOT_LONG, Dops.NOT_LONG);
MAP.put(Rops.ADD_CONST_INT, Dops.ADD_INT_LIT8);
// Note: No dalvik ops for other types of add_const.
MAP.put(Rops.SUB_CONST_INT, Dops.RSUB_INT_LIT8);
/*
* Note: No dalvik ops for any type of sub_const; instead
* there's a *reverse* sub (constant - reg) for ints only.
*/
MAP.put(Rops.MUL_CONST_INT, Dops.MUL_INT_LIT8);
// Note: No dalvik ops for other types of mul_const.
MAP.put(Rops.DIV_CONST_INT, Dops.DIV_INT_LIT8);
// Note: No dalvik ops for other types of div_const.
MAP.put(Rops.REM_CONST_INT, Dops.REM_INT_LIT8);
// Note: No dalvik ops for other types of rem_const.
MAP.put(Rops.AND_CONST_INT, Dops.AND_INT_LIT8);
// Note: No dalvik op for and_const_long.
MAP.put(Rops.OR_CONST_INT, Dops.OR_INT_LIT8);
// Note: No dalvik op for or_const_long.
MAP.put(Rops.XOR_CONST_INT, Dops.XOR_INT_LIT8);
// Note: No dalvik op for xor_const_long.
MAP.put(Rops.SHL_CONST_INT, Dops.SHL_INT_LIT8);
// Note: No dalvik op for shl_const_long.
MAP.put(Rops.SHR_CONST_INT, Dops.SHR_INT_LIT8);
// Note: No dalvik op for shr_const_long.
MAP.put(Rops.USHR_CONST_INT, Dops.USHR_INT_LIT8);
// Note: No dalvik op for shr_const_long.
MAP.put(Rops.CMPL_LONG, Dops.CMP_LONG);
MAP.put(Rops.CMPL_FLOAT, Dops.CMPL_FLOAT);
MAP.put(Rops.CMPL_DOUBLE, Dops.CMPL_DOUBLE);
MAP.put(Rops.CMPG_FLOAT, Dops.CMPG_FLOAT);
MAP.put(Rops.CMPG_DOUBLE, Dops.CMPG_DOUBLE);
MAP.put(Rops.CONV_L2I, Dops.LONG_TO_INT);
MAP.put(Rops.CONV_F2I, Dops.FLOAT_TO_INT);
MAP.put(Rops.CONV_D2I, Dops.DOUBLE_TO_INT);
MAP.put(Rops.CONV_I2L, Dops.INT_TO_LONG);
MAP.put(Rops.CONV_F2L, Dops.FLOAT_TO_LONG);
MAP.put(Rops.CONV_D2L, Dops.DOUBLE_TO_LONG);
MAP.put(Rops.CONV_I2F, Dops.INT_TO_FLOAT);
MAP.put(Rops.CONV_L2F, Dops.LONG_TO_FLOAT);
MAP.put(Rops.CONV_D2F, Dops.DOUBLE_TO_FLOAT);
MAP.put(Rops.CONV_I2D, Dops.INT_TO_DOUBLE);
MAP.put(Rops.CONV_L2D, Dops.LONG_TO_DOUBLE);
MAP.put(Rops.CONV_F2D, Dops.FLOAT_TO_DOUBLE);
MAP.put(Rops.TO_BYTE, Dops.INT_TO_BYTE);
MAP.put(Rops.TO_CHAR, Dops.INT_TO_CHAR);
MAP.put(Rops.TO_SHORT, Dops.INT_TO_SHORT);
MAP.put(Rops.RETURN_VOID, Dops.RETURN_VOID);
MAP.put(Rops.RETURN_INT, Dops.RETURN);
MAP.put(Rops.RETURN_LONG, Dops.RETURN_WIDE);
MAP.put(Rops.RETURN_FLOAT, Dops.RETURN);
MAP.put(Rops.RETURN_DOUBLE, Dops.RETURN_WIDE);
MAP.put(Rops.RETURN_OBJECT, Dops.RETURN_OBJECT);
MAP.put(Rops.ARRAY_LENGTH, Dops.ARRAY_LENGTH);
MAP.put(Rops.THROW, Dops.THROW);
MAP.put(Rops.MONITOR_ENTER, Dops.MONITOR_ENTER);
MAP.put(Rops.MONITOR_EXIT, Dops.MONITOR_EXIT);
MAP.put(Rops.AGET_INT, Dops.AGET);
MAP.put(Rops.AGET_LONG, Dops.AGET_WIDE);
MAP.put(Rops.AGET_FLOAT, Dops.AGET);
MAP.put(Rops.AGET_DOUBLE, Dops.AGET_WIDE);
MAP.put(Rops.AGET_OBJECT, Dops.AGET_OBJECT);
MAP.put(Rops.AGET_BOOLEAN, Dops.AGET_BOOLEAN);
MAP.put(Rops.AGET_BYTE, Dops.AGET_BYTE);
MAP.put(Rops.AGET_CHAR, Dops.AGET_CHAR);
MAP.put(Rops.AGET_SHORT, Dops.AGET_SHORT);
MAP.put(Rops.APUT_INT, Dops.APUT);
MAP.put(Rops.APUT_LONG, Dops.APUT_WIDE);
MAP.put(Rops.APUT_FLOAT, Dops.APUT);
MAP.put(Rops.APUT_DOUBLE, Dops.APUT_WIDE);
MAP.put(Rops.APUT_OBJECT, Dops.APUT_OBJECT);
MAP.put(Rops.APUT_BOOLEAN, Dops.APUT_BOOLEAN);
MAP.put(Rops.APUT_BYTE, Dops.APUT_BYTE);
MAP.put(Rops.APUT_CHAR, Dops.APUT_CHAR);
MAP.put(Rops.APUT_SHORT, Dops.APUT_SHORT);
MAP.put(Rops.NEW_INSTANCE, Dops.NEW_INSTANCE);
MAP.put(Rops.CHECK_CAST, Dops.CHECK_CAST);
MAP.put(Rops.INSTANCE_OF, Dops.INSTANCE_OF);
MAP.put(Rops.GET_FIELD_LONG, Dops.IGET_WIDE);
MAP.put(Rops.GET_FIELD_FLOAT, Dops.IGET);
MAP.put(Rops.GET_FIELD_DOUBLE, Dops.IGET_WIDE);
MAP.put(Rops.GET_FIELD_OBJECT, Dops.IGET_OBJECT);
/*
* Note: No map entries for get_field_* for non-long integral types,
* since they need to be handled specially (see dopFor() below).
*/
MAP.put(Rops.GET_STATIC_LONG, Dops.SGET_WIDE);
MAP.put(Rops.GET_STATIC_FLOAT, Dops.SGET);
MAP.put(Rops.GET_STATIC_DOUBLE, Dops.SGET_WIDE);
MAP.put(Rops.GET_STATIC_OBJECT, Dops.SGET_OBJECT);
/*
* Note: No map entries for get_static* for non-long integral types,
* since they need to be handled specially (see dopFor() below).
*/
MAP.put(Rops.PUT_FIELD_LONG, Dops.IPUT_WIDE);
MAP.put(Rops.PUT_FIELD_FLOAT, Dops.IPUT);
MAP.put(Rops.PUT_FIELD_DOUBLE, Dops.IPUT_WIDE);
MAP.put(Rops.PUT_FIELD_OBJECT, Dops.IPUT_OBJECT);
/*
* Note: No map entries for put_field_* for non-long integral types,
* since they need to be handled specially (see dopFor() below).
*/
MAP.put(Rops.PUT_STATIC_LONG, Dops.SPUT_WIDE);
MAP.put(Rops.PUT_STATIC_FLOAT, Dops.SPUT);
MAP.put(Rops.PUT_STATIC_DOUBLE, Dops.SPUT_WIDE);
MAP.put(Rops.PUT_STATIC_OBJECT, Dops.SPUT_OBJECT);
/*
* Note: No map entries for put_static* for non-long integral types,
* since they need to be handled specially (see dopFor() below).
*/
/*
* Note: No map entries for invoke*, new_array, and
* filled_new_array, since they need to be handled specially
* (see dopFor() below).
*/
}
/**
* Returns the dalvik opcode appropriate for the given register-based
* instruction.
*
* @param insn {@code non-null;} the original instruction
* @return the corresponding dalvik opcode; one of the constants in
* {@link Dops}
*/
public static Dop dopFor(Insn insn) {
Rop rop = insn.getOpcode();
/*
* First, just try looking up the rop in the MAP of easy
* cases.
*/
Dop result = MAP.get(rop);
if (result != null) {
return result;
}
/*
* There was no easy case for the rop, so look up the opcode, and
* do something special for each:
*
* The move_exception, new_array, filled_new_array, and
* invoke* opcodes won't be found in MAP, since they'll each
* have different source and/or result register types / lists.
*
* The get* and put* opcodes for (non-long) integral types
* aren't in the map, since the type signatures aren't
* sufficient to distinguish between the types (the salient
* source or result will always be just "int").
*
* And const instruction need to distinguish between strings and
* classes.
*/
switch (rop.getOpcode()) {
case RegOps.MOVE_EXCEPTION: return Dops.MOVE_EXCEPTION;
case RegOps.INVOKE_STATIC: return Dops.INVOKE_STATIC;
case RegOps.INVOKE_VIRTUAL: return Dops.INVOKE_VIRTUAL;
case RegOps.INVOKE_SUPER: return Dops.INVOKE_SUPER;
case RegOps.INVOKE_DIRECT: return Dops.INVOKE_DIRECT;
case RegOps.INVOKE_INTERFACE: return Dops.INVOKE_INTERFACE;
case RegOps.NEW_ARRAY: return Dops.NEW_ARRAY;
case RegOps.FILLED_NEW_ARRAY: return Dops.FILLED_NEW_ARRAY;
case RegOps.FILL_ARRAY_DATA: return Dops.FILL_ARRAY_DATA;
case RegOps.MOVE_RESULT: {
RegisterSpec resultReg = insn.getResult();
if (resultReg == null) {
return Dops.NOP;
} else {
switch (resultReg.getBasicType()) {
case Type.BT_INT:
case Type.BT_FLOAT:
case Type.BT_BOOLEAN:
case Type.BT_BYTE:
case Type.BT_CHAR:
case Type.BT_SHORT:
return Dops.MOVE_RESULT;
case Type.BT_LONG:
case Type.BT_DOUBLE:
return Dops.MOVE_RESULT_WIDE;
case Type.BT_OBJECT:
return Dops.MOVE_RESULT_OBJECT;
default: {
throw new RuntimeException("Unexpected basic type");
}
}
}
}
case RegOps.GET_FIELD: {
CstFieldRef ref =
(CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch (basicType) {
case Type.BT_BOOLEAN: return Dops.IGET_BOOLEAN;
case Type.BT_BYTE: return Dops.IGET_BYTE;
case Type.BT_CHAR: return Dops.IGET_CHAR;
case Type.BT_SHORT: return Dops.IGET_SHORT;
case Type.BT_INT: return Dops.IGET;
}
break;
}
case RegOps.PUT_FIELD: {
CstFieldRef ref =
(CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch (basicType) {
case Type.BT_BOOLEAN: return Dops.IPUT_BOOLEAN;
case Type.BT_BYTE: return Dops.IPUT_BYTE;
case Type.BT_CHAR: return Dops.IPUT_CHAR;
case Type.BT_SHORT: return Dops.IPUT_SHORT;
case Type.BT_INT: return Dops.IPUT;
}
break;
}
case RegOps.GET_STATIC: {
CstFieldRef ref =
(CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch (basicType) {
case Type.BT_BOOLEAN: return Dops.SGET_BOOLEAN;
case Type.BT_BYTE: return Dops.SGET_BYTE;
case Type.BT_CHAR: return Dops.SGET_CHAR;
case Type.BT_SHORT: return Dops.SGET_SHORT;
case Type.BT_INT: return Dops.SGET;
}
break;
}
case RegOps.PUT_STATIC: {
CstFieldRef ref =
(CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
int basicType = ref.getBasicType();
switch (basicType) {
case Type.BT_BOOLEAN: return Dops.SPUT_BOOLEAN;
case Type.BT_BYTE: return Dops.SPUT_BYTE;
case Type.BT_CHAR: return Dops.SPUT_CHAR;
case Type.BT_SHORT: return Dops.SPUT_SHORT;
case Type.BT_INT: return Dops.SPUT;
}
break;
}
case RegOps.CONST: {
Constant cst = ((ThrowingCstInsn) insn).getConstant();
if (cst instanceof CstType) {
return Dops.CONST_CLASS;
} else if (cst instanceof CstString) {
return Dops.CONST_STRING;
}
break;
}
}
throw new RuntimeException("unknown rop: " + rop);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy