Machine.java revision de75089fb7216d19e9c22cce4dc62a49513477d3
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
17package com.android.dx.cf.code;
18
19import com.android.dx.rop.cst.Constant;
20import com.android.dx.rop.type.Prototype;
21import com.android.dx.rop.type.Type;
22import com.android.dx.rop.code.LocalItem;
23import 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 */
31public 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     * Indicates that the salient type of this operation is as
117     * given. This differentiates between, for example, the various
118     * arithmetic opcodes, which, by the time they hit a
119     * {@code Machine} are collapsed to the {@code int}
120     * variant. (See {@link BytecodeArray#parseInstruction} for
121     * details.)
122     *
123     * @param type {@code non-null;} the salient type of the upcoming operation
124     */
125    public void auxType(Type type);
126
127    /**
128     * Indicates that there is an auxiliary (inline, not stack)
129     * argument of type {@code int}, with the given value.
130     *
131     * <p><b>Note:</b> Perhaps unintuitively, the stack manipulation
132     * ops (e.g., {@code dup} and {@code swap}) use this to
133     * indicate the result stack pattern with a straightforward hex
134     * encoding of the push order starting with least-significant
135     * nibbles getting pushed first). For example, an all-category-1
136     * {@code dup2_x1} sets this to {@code 0x12312}, and the
137     * other form of that op sets this to
138     * {@code 0x121}.</p>
139     *
140     * <p><b>Also Note:</b> For {@code switch*} instructions, this is
141     * used to indicate the padding value (which is only useful for
142     * verification).</p>
143     *
144     * @param value the argument value
145     */
146    public void auxIntArg(int value);
147
148    /**
149     * Indicates that there is an auxiliary (inline, not stack) object
150     * argument, with the value based on the given constant.
151     *
152     * <p><b>Note:</b> Some opcodes use both {@code int} and
153     * constant auxiliary arguments.</p>
154     *
155     * @param cst {@code non-null;} the constant containing / referencing
156     * the value
157     */
158    public void auxCstArg(Constant cst);
159
160    /**
161     * Indicates that there is an auxiliary (inline, not stack) argument
162     * indicating a branch target.
163     *
164     * @param target the argument value
165     */
166    public void auxTargetArg(int target);
167
168    /**
169     * Indicates that there is an auxiliary (inline, not stack) argument
170     * consisting of a {@code switch*} table.
171     *
172     * <p><b>Note:</b> This is generally used in conjunction with
173     * {@link #auxIntArg} (which holds the padding).</p>
174     *
175     * @param cases {@code non-null;} the list of key-target pairs, plus the default
176     * target
177     */
178    public void auxSwitchArg(SwitchList cases);
179
180    /**
181     * Indicates that there is an auxiliary (inline, not stack) argument
182     * consisting of a list of initial values for a newly created array.
183     *
184     * @param initValues {@code non-null;} the list of constant values to initialize
185     * the array
186     */
187    public void auxInitValues(ArrayList<Constant> initValues);
188
189    /**
190     * Indicates that the target of this operation is the given local.
191     *
192     * @param idx {@code >= 0;} the local variable index
193     * @param type {@code non-null;} the type of the local
194     * @param local {@code null-ok;} the name and signature of the local, if known
195     */
196    public void localTarget(int idx, Type type, LocalItem local);
197
198    /**
199     * "Runs" the indicated opcode in an appropriate way, using the arguments
200     * area as appropriate, and modifying the given frame in response.
201     *
202     * @param frame {@code non-null;} frame to operate on
203     * @param offset {@code >= 0;} byte offset in the method to the opcode being
204     * run
205     * @param opcode {@code >= 0;} the opcode to run
206     */
207    public void run(Frame frame, int offset, int opcode);
208}
209