blob: 517a10d6a10a5038b4a82adfc20cd86451d89afa [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</code> argument for instance methods.
*
* @return 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 non-null; frame to operate on
* @param count &gt;= 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</code> (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 non-null; frame to operate on
* @param prototype 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 non-null; frame to operate on
* @param type 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 non-null; frame to operate on
* @param type1 non-null; type of the first argument
* @param type2 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 non-null; frame to operate on
* @param type1 non-null; type of the first argument
* @param type2 non-null; type of the second argument
* @param type3 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 non-null; frame to operate on
* @param idx &gt;= 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</code> are collapsed to the <code>int</code>
* variant. (See {@link BytecodeArray#parseInstruction} for
* details.)
*
* @param type 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</code>, with the given value.
*
* <p><b>Note:</b> Perhaps unintuitively, the stack manipulation
* ops (e.g., <code>dup</code> and <code>swap</code>) 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</code> sets this to <code>0x12312</code>, and the
* other form of that op sets this to
* <code>0x121</code>.</p>
*
* <p><b>Also Note:</b> For <code>switch*</code> 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</code> and
* constant auxiliary arguments.</p>
*
* @param cst 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*</code> table.
*
* <p><b>Note:</b> This is generally used in conjunction with
* {@link #auxIntArg} (which holds the padding).</p>
*
* @param cases 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 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 &gt;= 0; the local variable index
* @param type non-null; the type of the local
* @param local 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 non-null; frame to operate on
* @param offset &gt;= 0; byte offset in the method to the opcode being
* run
* @param opcode &gt;= 0; the opcode to run
*/
public void run(Frame frame, int offset, int opcode);
}