All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.snapscript.dx.cf.code.Machine Maven / Gradle / Ivy

There is a newer version: 1.4.6
Show newest version
/*
 * 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 org.snapscript.dx.cf.code;

import java.util.ArrayList;

import org.snapscript.dx.rop.code.LocalItem;
import org.snapscript.dx.rop.cst.Constant;
import org.snapscript.dx.rop.type.Prototype;
import org.snapscript.dx.rop.type.Type;

/**
 * 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 effective 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);

    /**
     * Used to specify if a loaded local variable has info in the local
     * variable table.
     *
     * @param local {@code true} if local arg has info in local variable table
     */
    public void localInfo(boolean local);

    /**
     * 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.
     *
     * 

Note: 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}.

* *

Also Note: For {@code switch*} instructions, this is * used to indicate the padding value (which is only useful for * verification).

* * @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. * *

Note: Some opcodes use both {@code int} and * constant auxiliary arguments.

* * @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. * *

Note: This is generally used in conjunction with * {@link #auxIntArg} (which holds the padding).

* * @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 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); }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy