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.Constant;
     20 import com.android.dx.rop.type.Prototype;
     21 import com.android.dx.rop.type.Type;
     22 import com.android.dx.rop.code.LocalItem;
     23 import java.util.ArrayList;
     24 
     25 /**
     26  * Interface for machines capable of executing bytecode by acting
     27  * upon a {@link Frame}. A machine conceptually contains four arbitrary-value
     28  * argument slots, slots for several literal-value arguments, and slots for
     29  * branch target information.
     30  */
     31 public interface Machine {
     32     /**
     33      * Gets the effective prototype of the method that this instance is
     34      * being used for. The <i>effective</i> prototype includes an initial
     35      * {@code this} argument for instance methods.
     36      *
     37      * @return {@code non-null;} the method prototype
     38      */
     39     public Prototype getPrototype();
     40 
     41     /**
     42      * Clears the regular and auxiliary arguments area.
     43      */
     44     public void clearArgs();
     45 
     46     /**
     47      * Pops the given number of values from the stack (of either category),
     48      * and store them in the arguments area, indicating that there are now
     49      * that many arguments. Also, clear the auxiliary arguments.
     50      *
     51      * @param frame {@code non-null;} frame to operate on
     52      * @param count {@code >= 0;} number of values to pop
     53      */
     54     public void popArgs(Frame frame, int count);
     55 
     56     /**
     57      * Pops values from the stack of the types indicated by the given
     58      * {@code Prototype} (popped in reverse of the argument
     59      * order, so the first prototype argument type is for the deepest
     60      * element of the stack), and store them in the arguments area,
     61      * indicating that there are now that many arguments. Also, clear
     62      * the auxiliary arguments.
     63      *
     64      * @param frame {@code non-null;} frame to operate on
     65      * @param prototype {@code non-null;} prototype indicating arguments to pop
     66      */
     67     public void popArgs(Frame frame, Prototype prototype);
     68 
     69     /**
     70      * Pops a value from the stack of the indicated type, and store it
     71      * in the arguments area, indicating that there are now that many
     72      * arguments. Also, clear the auxiliary arguments.
     73      *
     74      * @param frame {@code non-null;} frame to operate on
     75      * @param type {@code non-null;} type of the argument
     76      */
     77     public void popArgs(Frame frame, Type type);
     78 
     79     /**
     80      * Pops values from the stack of the indicated types (popped in
     81      * reverse argument order, so the first indicated type is for the
     82      * deepest element of the stack), and store them in the arguments
     83      * area, indicating that there are now that many arguments. Also,
     84      * clear the auxiliary arguments.
     85      *
     86      * @param frame {@code non-null;} frame to operate on
     87      * @param type1 {@code non-null;} type of the first argument
     88      * @param type2 {@code non-null;} type of the second argument
     89      */
     90     public void popArgs(Frame frame, Type type1, Type type2);
     91 
     92     /**
     93      * Pops values from the stack of the indicated types (popped in
     94      * reverse argument order, so the first indicated type is for the
     95      * deepest element of the stack), and store them in the arguments
     96      * area, indicating that there are now that many arguments. Also,
     97      * clear the auxiliary arguments.
     98      *
     99      * @param frame {@code non-null;} frame to operate on
    100      * @param type1 {@code non-null;} type of the first argument
    101      * @param type2 {@code non-null;} type of the second argument
    102      * @param type3 {@code non-null;} type of the third argument
    103      */
    104     public void popArgs(Frame frame, Type type1, Type type2, Type type3);
    105 
    106     /**
    107      * Loads the local variable with the given index as the sole argument in
    108      * the arguments area. Also, clear the auxiliary arguments.
    109      *
    110      * @param frame {@code non-null;} frame to operate on
    111      * @param idx {@code >= 0;} the local variable index
    112      */
    113     public void localArg(Frame frame, int idx);
    114 
    115     /**
    116      * Used to specify if a loaded local variable has info in the local
    117      * variable table.
    118      *
    119      * @param local {@code true} if local arg has info in local variable table
    120      */
    121     public void localInfo(boolean local);
    122 
    123     /**
    124      * Indicates that the salient type of this operation is as
    125      * given. This differentiates between, for example, the various
    126      * arithmetic opcodes, which, by the time they hit a
    127      * {@code Machine} are collapsed to the {@code int}
    128      * variant. (See {@link BytecodeArray#parseInstruction} for
    129      * details.)
    130      *
    131      * @param type {@code non-null;} the salient type of the upcoming operation
    132      */
    133     public void auxType(Type type);
    134 
    135     /**
    136      * Indicates that there is an auxiliary (inline, not stack)
    137      * argument of type {@code int}, with the given value.
    138      *
    139      * <p><b>Note:</b> Perhaps unintuitively, the stack manipulation
    140      * ops (e.g., {@code dup} and {@code swap}) use this to
    141      * indicate the result stack pattern with a straightforward hex
    142      * encoding of the push order starting with least-significant
    143      * nibbles getting pushed first). For example, an all-category-1
    144      * {@code dup2_x1} sets this to {@code 0x12312}, and the
    145      * other form of that op sets this to
    146      * {@code 0x121}.</p>
    147      *
    148      * <p><b>Also Note:</b> For {@code switch*} instructions, this is
    149      * used to indicate the padding value (which is only useful for
    150      * verification).</p>
    151      *
    152      * @param value the argument value
    153      */
    154     public void auxIntArg(int value);
    155 
    156     /**
    157      * Indicates that there is an auxiliary (inline, not stack) object
    158      * argument, with the value based on the given constant.
    159      *
    160      * <p><b>Note:</b> Some opcodes use both {@code int} and
    161      * constant auxiliary arguments.</p>
    162      *
    163      * @param cst {@code non-null;} the constant containing / referencing
    164      * the value
    165      */
    166     public void auxCstArg(Constant cst);
    167 
    168     /**
    169      * Indicates that there is an auxiliary (inline, not stack) argument
    170      * indicating a branch target.
    171      *
    172      * @param target the argument value
    173      */
    174     public void auxTargetArg(int target);
    175 
    176     /**
    177      * Indicates that there is an auxiliary (inline, not stack) argument
    178      * consisting of a {@code switch*} table.
    179      *
    180      * <p><b>Note:</b> This is generally used in conjunction with
    181      * {@link #auxIntArg} (which holds the padding).</p>
    182      *
    183      * @param cases {@code non-null;} the list of key-target pairs, plus the default
    184      * target
    185      */
    186     public void auxSwitchArg(SwitchList cases);
    187 
    188     /**
    189      * Indicates that there is an auxiliary (inline, not stack) argument
    190      * consisting of a list of initial values for a newly created array.
    191      *
    192      * @param initValues {@code non-null;} the list of constant values to initialize
    193      * the array
    194      */
    195     public void auxInitValues(ArrayList<Constant> initValues);
    196 
    197     /**
    198      * Indicates that the target of this operation is the given local.
    199      *
    200      * @param idx {@code >= 0;} the local variable index
    201      * @param type {@code non-null;} the type of the local
    202      * @param local {@code null-ok;} the name and signature of the local, if known
    203      */
    204     public void localTarget(int idx, Type type, LocalItem local);
    205 
    206     /**
    207      * "Runs" the indicated opcode in an appropriate way, using the arguments
    208      * area as appropriate, and modifying the given frame in response.
    209      *
    210      * @param frame {@code non-null;} frame to operate on
    211      * @param offset {@code >= 0;} byte offset in the method to the opcode being
    212      * run
    213      * @param opcode {@code >= 0;} the opcode to run
    214      */
    215     public void run(Frame frame, int offset, int opcode);
    216 }
    217