Home | History | Annotate | Download | only in code
      1 /*
      2  * Copyright (C) 2007 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.dx.cf.code;
     18 
     19 import com.android.dx.rop.cst.CstType;
     20 import com.android.dx.rop.type.Prototype;
     21 import com.android.dx.rop.type.Type;
     22 import com.android.dx.rop.type.TypeBearer;
     23 import com.android.dx.util.Hex;
     24 
     25 /**
     26  * {@link Machine} which keeps track of known values but does not do
     27  * smart/realistic reference type calculations.
     28  */
     29 public class ValueAwareMachine extends BaseMachine {
     30     /**
     31      * Constructs an instance.
     32      *
     33      * @param prototype {@code non-null;} the prototype for the associated
     34      * method
     35      */
     36     public ValueAwareMachine(Prototype prototype) {
     37         super(prototype);
     38     }
     39 
     40     /** {@inheritDoc} */
     41     public void run(Frame frame, int offset, int opcode) {
     42         switch (opcode) {
     43             case ByteOps.NOP:
     44             case ByteOps.IASTORE:
     45             case ByteOps.POP:
     46             case ByteOps.POP2:
     47             case ByteOps.IFEQ:
     48             case ByteOps.IFNE:
     49             case ByteOps.IFLT:
     50             case ByteOps.IFGE:
     51             case ByteOps.IFGT:
     52             case ByteOps.IFLE:
     53             case ByteOps.IF_ICMPEQ:
     54             case ByteOps.IF_ICMPNE:
     55             case ByteOps.IF_ICMPLT:
     56             case ByteOps.IF_ICMPGE:
     57             case ByteOps.IF_ICMPGT:
     58             case ByteOps.IF_ICMPLE:
     59             case ByteOps.IF_ACMPEQ:
     60             case ByteOps.IF_ACMPNE:
     61             case ByteOps.GOTO:
     62             case ByteOps.RET:
     63             case ByteOps.LOOKUPSWITCH:
     64             case ByteOps.IRETURN:
     65             case ByteOps.RETURN:
     66             case ByteOps.PUTSTATIC:
     67             case ByteOps.PUTFIELD:
     68             case ByteOps.ATHROW:
     69             case ByteOps.MONITORENTER:
     70             case ByteOps.MONITOREXIT:
     71             case ByteOps.IFNULL:
     72             case ByteOps.IFNONNULL: {
     73                 // Nothing to do for these ops in this class.
     74                 clearResult();
     75                 break;
     76             }
     77             case ByteOps.LDC:
     78             case ByteOps.LDC2_W: {
     79                 setResult((TypeBearer) getAuxCst());
     80                 break;
     81             }
     82             case ByteOps.ILOAD:
     83             case ByteOps.ISTORE: {
     84                 setResult(arg(0));
     85                 break;
     86             }
     87             case ByteOps.IALOAD:
     88             case ByteOps.IADD:
     89             case ByteOps.ISUB:
     90             case ByteOps.IMUL:
     91             case ByteOps.IDIV:
     92             case ByteOps.IREM:
     93             case ByteOps.INEG:
     94             case ByteOps.ISHL:
     95             case ByteOps.ISHR:
     96             case ByteOps.IUSHR:
     97             case ByteOps.IAND:
     98             case ByteOps.IOR:
     99             case ByteOps.IXOR:
    100             case ByteOps.IINC:
    101             case ByteOps.I2L:
    102             case ByteOps.I2F:
    103             case ByteOps.I2D:
    104             case ByteOps.L2I:
    105             case ByteOps.L2F:
    106             case ByteOps.L2D:
    107             case ByteOps.F2I:
    108             case ByteOps.F2L:
    109             case ByteOps.F2D:
    110             case ByteOps.D2I:
    111             case ByteOps.D2L:
    112             case ByteOps.D2F:
    113             case ByteOps.I2B:
    114             case ByteOps.I2C:
    115             case ByteOps.I2S:
    116             case ByteOps.LCMP:
    117             case ByteOps.FCMPL:
    118             case ByteOps.FCMPG:
    119             case ByteOps.DCMPL:
    120             case ByteOps.DCMPG:
    121             case ByteOps.ARRAYLENGTH: {
    122                 setResult(getAuxType());
    123                 break;
    124             }
    125             case ByteOps.DUP:
    126             case ByteOps.DUP_X1:
    127             case ByteOps.DUP_X2:
    128             case ByteOps.DUP2:
    129             case ByteOps.DUP2_X1:
    130             case ByteOps.DUP2_X2:
    131             case ByteOps.SWAP: {
    132                 clearResult();
    133                 for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {
    134                     int which = (pattern & 0x0f) - 1;
    135                     addResult(arg(which));
    136                 }
    137                 break;
    138             }
    139 
    140             case ByteOps.JSR: {
    141                 setResult(new ReturnAddress(getAuxTarget()));
    142                 break;
    143             }
    144             case ByteOps.GETSTATIC:
    145             case ByteOps.GETFIELD:
    146             case ByteOps.INVOKEVIRTUAL:
    147             case ByteOps.INVOKESTATIC:
    148             case ByteOps.INVOKEINTERFACE: {
    149                 Type type = ((TypeBearer) getAuxCst()).getType();
    150                 if (type == Type.VOID) {
    151                     clearResult();
    152                 } else {
    153                     setResult(type);
    154                 }
    155                 break;
    156             }
    157             case ByteOps.INVOKESPECIAL: {
    158                 Type thisType = arg(0).getType();
    159                 if (thisType.isUninitialized()) {
    160                     frame.makeInitialized(thisType);
    161                 }
    162                 Type type = ((TypeBearer) getAuxCst()).getType();
    163                 if (type == Type.VOID) {
    164                     clearResult();
    165                 } else {
    166                     setResult(type);
    167                 }
    168                 break;
    169             }
    170             case ByteOps.NEW: {
    171                 Type type = ((CstType) getAuxCst()).getClassType();
    172                 setResult(type.asUninitialized(offset));
    173                 break;
    174             }
    175             case ByteOps.NEWARRAY:
    176             case ByteOps.CHECKCAST:
    177             case ByteOps.MULTIANEWARRAY: {
    178                 Type type = ((CstType) getAuxCst()).getClassType();
    179                 setResult(type);
    180                 break;
    181             }
    182             case ByteOps.ANEWARRAY: {
    183                 Type type = ((CstType) getAuxCst()).getClassType();
    184                 setResult(type.getArrayType());
    185                 break;
    186             }
    187             case ByteOps.INSTANCEOF: {
    188                 setResult(Type.INT);
    189                 break;
    190             }
    191             default: {
    192                 throw new RuntimeException("shouldn't happen: " +
    193                                            Hex.u1(opcode));
    194             }
    195         }
    196 
    197         storeResults(frame);
    198     }
    199 }
    200