blob: 72ba3b456d4dffd3d004916129ac455f44c4f27d [file] [log] [blame]
/*
* 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);
}