| /* |
| * 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.cf.code; |
| |
| import com.android.dx.rop.cst.Constant; |
| import com.android.dx.rop.type.Prototype; |
| import com.android.dx.rop.type.Type; |
| import com.android.dx.rop.code.LocalItem; |
| import java.util.ArrayList; |
| |
| /** |
| * Interface for machines capable of executing bytecode by acting |
| * upon a {@link Frame}. A machine conceptually contains four arbitrary-value |
| * argument slots, slots for several literal-value arguments, and slots for |
| * branch target information. |
| */ |
| public interface Machine { |
| /** |
| * Gets the effective prototype of the method that this instance is |
| * being used for. The <i>effective</i> prototype includes an initial |
| * {@code this} argument for instance methods. |
| * |
| * @return {@code non-null;} the method prototype |
| */ |
| public Prototype getPrototype(); |
| |
| /** |
| * Clears the regular and auxiliary arguments area. |
| */ |
| public void clearArgs(); |
| |
| /** |
| * Pops the given number of values from the stack (of either category), |
| * and store them in the arguments area, indicating that there are now |
| * that many arguments. Also, clear the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param count {@code >= 0;} number of values to pop |
| */ |
| public void popArgs(Frame frame, int count); |
| |
| /** |
| * Pops values from the stack of the types indicated by the given |
| * {@code Prototype} (popped in reverse of the argument |
| * order, so the first prototype argument type is for the deepest |
| * element of the stack), and store them in the arguments area, |
| * indicating that there are now that many arguments. Also, clear |
| * the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param prototype {@code non-null;} prototype indicating arguments to pop |
| */ |
| public void popArgs(Frame frame, Prototype prototype); |
| |
| /** |
| * Pops a value from the stack of the indicated type, and store it |
| * in the arguments area, indicating that there are now that many |
| * arguments. Also, clear the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param type {@code non-null;} type of the argument |
| */ |
| public void popArgs(Frame frame, Type type); |
| |
| /** |
| * Pops values from the stack of the indicated types (popped in |
| * reverse argument order, so the first indicated type is for the |
| * deepest element of the stack), and store them in the arguments |
| * area, indicating that there are now that many arguments. Also, |
| * clear the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param type1 {@code non-null;} type of the first argument |
| * @param type2 {@code non-null;} type of the second argument |
| */ |
| public void popArgs(Frame frame, Type type1, Type type2); |
| |
| /** |
| * Pops values from the stack of the indicated types (popped in |
| * reverse argument order, so the first indicated type is for the |
| * deepest element of the stack), and store them in the arguments |
| * area, indicating that there are now that many arguments. Also, |
| * clear the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param type1 {@code non-null;} type of the first argument |
| * @param type2 {@code non-null;} type of the second argument |
| * @param type3 {@code non-null;} type of the third argument |
| */ |
| public void popArgs(Frame frame, Type type1, Type type2, Type type3); |
| |
| /** |
| * Loads the local variable with the given index as the sole argument in |
| * the arguments area. Also, clear the auxiliary arguments. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param idx {@code >= 0;} the local variable index |
| */ |
| public void localArg(Frame frame, int idx); |
| |
| /** |
| * Indicates that the salient type of this operation is as |
| * given. This differentiates between, for example, the various |
| * arithmetic opcodes, which, by the time they hit a |
| * {@code Machine} are collapsed to the {@code int} |
| * variant. (See {@link BytecodeArray#parseInstruction} for |
| * details.) |
| * |
| * @param type {@code non-null;} the salient type of the upcoming operation |
| */ |
| public void auxType(Type type); |
| |
| /** |
| * Indicates that there is an auxiliary (inline, not stack) |
| * argument of type {@code int}, with the given value. |
| * |
| * <p><b>Note:</b> Perhaps unintuitively, the stack manipulation |
| * ops (e.g., {@code dup} and {@code swap}) use this to |
| * indicate the result stack pattern with a straightforward hex |
| * encoding of the push order starting with least-significant |
| * nibbles getting pushed first). For example, an all-category-1 |
| * {@code dup2_x1} sets this to {@code 0x12312}, and the |
| * other form of that op sets this to |
| * {@code 0x121}.</p> |
| * |
| * <p><b>Also Note:</b> For {@code switch*} instructions, this is |
| * used to indicate the padding value (which is only useful for |
| * verification).</p> |
| * |
| * @param value the argument value |
| */ |
| public void auxIntArg(int value); |
| |
| /** |
| * Indicates that there is an auxiliary (inline, not stack) object |
| * argument, with the value based on the given constant. |
| * |
| * <p><b>Note:</b> Some opcodes use both {@code int} and |
| * constant auxiliary arguments.</p> |
| * |
| * @param cst {@code non-null;} the constant containing / referencing |
| * the value |
| */ |
| public void auxCstArg(Constant cst); |
| |
| /** |
| * Indicates that there is an auxiliary (inline, not stack) argument |
| * indicating a branch target. |
| * |
| * @param target the argument value |
| */ |
| public void auxTargetArg(int target); |
| |
| /** |
| * Indicates that there is an auxiliary (inline, not stack) argument |
| * consisting of a {@code switch*} table. |
| * |
| * <p><b>Note:</b> This is generally used in conjunction with |
| * {@link #auxIntArg} (which holds the padding).</p> |
| * |
| * @param cases {@code non-null;} the list of key-target pairs, plus the default |
| * target |
| */ |
| public void auxSwitchArg(SwitchList cases); |
| |
| /** |
| * Indicates that there is an auxiliary (inline, not stack) argument |
| * consisting of a list of initial values for a newly created array. |
| * |
| * @param initValues {@code non-null;} the list of constant values to initialize |
| * the array |
| */ |
| public void auxInitValues(ArrayList<Constant> initValues); |
| |
| /** |
| * Indicates that the target of this operation is the given local. |
| * |
| * @param idx {@code >= 0;} the local variable index |
| * @param type {@code non-null;} the type of the local |
| * @param local {@code null-ok;} the name and signature of the local, if known |
| */ |
| public void localTarget(int idx, Type type, LocalItem local); |
| |
| /** |
| * "Runs" the indicated opcode in an appropriate way, using the arguments |
| * area as appropriate, and modifying the given frame in response. |
| * |
| * @param frame {@code non-null;} frame to operate on |
| * @param offset {@code >= 0;} byte offset in the method to the opcode being |
| * run |
| * @param opcode {@code >= 0;} the opcode to run |
| */ |
| public void run(Frame frame, int offset, int opcode); |
| } |