summaryrefslogtreecommitdiffstats
path: root/dx/src/com/android/dx/cf/code/BaseMachine.java
diff options
context:
space:
mode:
Diffstat (limited to 'dx/src/com/android/dx/cf/code/BaseMachine.java')
-rw-r--r--dx/src/com/android/dx/cf/code/BaseMachine.java545
1 files changed, 0 insertions, 545 deletions
diff --git a/dx/src/com/android/dx/cf/code/BaseMachine.java b/dx/src/com/android/dx/cf/code/BaseMachine.java
deleted file mode 100644
index 430e48be7..000000000
--- a/dx/src/com/android/dx/cf/code/BaseMachine.java
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * 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.code.RegisterSpec;
-import com.android.dx.rop.code.LocalItem;
-import com.android.dx.rop.cst.Constant;
-import com.android.dx.rop.type.Prototype;
-import com.android.dx.rop.type.StdTypeList;
-import com.android.dx.rop.type.Type;
-import com.android.dx.rop.type.TypeBearer;
-import java.util.ArrayList;
-
-/**
- * Base implementation of {@link Machine}.
- *
- * <p><b>Note:</b> For the most part, the documentation for this class
- * ignores the distinction between {@link Type} and {@link
- * TypeBearer}.</p>
- */
-public abstract class BaseMachine implements Machine {
- /* non-null; the prototype for the associated method */
- private final Prototype prototype;
-
- /** non-null; primary arguments */
- private TypeBearer[] args;
-
- /** &gt;= 0; number of primary arguments */
- private int argCount;
-
- /** null-ok; type of the operation, if salient */
- private Type auxType;
-
- /** auxiliary <code>int</code> argument */
- private int auxInt;
-
- /** null-ok; auxiliary constant argument */
- private Constant auxCst;
-
- /** auxiliary branch target argument */
- private int auxTarget;
-
- /** null-ok; auxiliary switch cases argument */
- private SwitchList auxCases;
-
- /** null-ok; auxiliary initial value list for newarray */
- private ArrayList<Constant> auxInitValues;
-
- /** &gt;= -1; last local accessed */
- private int localIndex;
-
- /** null-ok; local target spec, if salient and calculated */
- private RegisterSpec localTarget;
-
- /** non-null; results */
- private TypeBearer[] results;
-
- /**
- * &gt;= -1; count of the results, or <code>-1</code> if no results
- * have been set
- */
- private int resultCount;
-
- /**
- * Constructs an instance.
- *
- * @param prototype non-null; the prototype for the associated method
- */
- public BaseMachine(Prototype prototype) {
- if (prototype == null) {
- throw new NullPointerException("prototype == null");
- }
-
- this.prototype = prototype;
- args = new TypeBearer[10];
- results = new TypeBearer[6];
- clearArgs();
- }
-
- /** {@inheritDoc} */
- public Prototype getPrototype() {
- return prototype;
- }
-
- /** {@inheritDoc} */
- public final void clearArgs() {
- argCount = 0;
- auxType = null;
- auxInt = 0;
- auxCst = null;
- auxTarget = 0;
- auxCases = null;
- auxInitValues = null;
- localIndex = -1;
- localTarget = null;
- resultCount = -1;
- }
-
- /** {@inheritDoc} */
- public final void popArgs(Frame frame, int count) {
- ExecutionStack stack = frame.getStack();
-
- clearArgs();
-
- if (count > args.length) {
- // Grow args, and add a little extra room to grow even more.
- args = new TypeBearer[count + 10];
- }
-
- for (int i = count - 1; i >= 0; i--) {
- args[i] = stack.pop();
- }
-
- argCount = count;
- }
-
- /** {@inheritDoc} */
- public void popArgs(Frame frame, Prototype prototype) {
- StdTypeList types = prototype.getParameterTypes();
- int size = types.size();
-
- // Use the above method to do the actual popping...
- popArgs(frame, size);
-
- // ...and then verify the popped types.
-
- for (int i = 0; i < size; i++) {
- if (! Merger.isPossiblyAssignableFrom(types.getType(i), args[i])) {
- throw new SimException("at stack depth " + (size - 1 - i) +
- ", expected type " + types.getType(i).toHuman() +
- " but found " + args[i].getType().toHuman());
- }
- }
- }
-
- public final void popArgs(Frame frame, Type type) {
- // Use the above method to do the actual popping...
- popArgs(frame, 1);
-
- // ...and then verify the popped type.
- if (! Merger.isPossiblyAssignableFrom(type, args[0])) {
- throw new SimException("expected type " + type.toHuman() +
- " but found " + args[0].getType().toHuman());
- }
- }
-
- /** {@inheritDoc} */
- public final void popArgs(Frame frame, Type type1, Type type2) {
- // Use the above method to do the actual popping...
- popArgs(frame, 2);
-
- // ...and then verify the popped types.
-
- if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
- throw new SimException("expected type " + type1.toHuman() +
- " but found " + args[0].getType().toHuman());
- }
-
- if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
- throw new SimException("expected type " + type2.toHuman() +
- " but found " + args[1].getType().toHuman());
- }
- }
-
- /** {@inheritDoc} */
- public final void popArgs(Frame frame, Type type1, Type type2,
- Type type3) {
- // Use the above method to do the actual popping...
- popArgs(frame, 3);
-
- // ...and then verify the popped types.
-
- if (! Merger.isPossiblyAssignableFrom(type1, args[0])) {
- throw new SimException("expected type " + type1.toHuman() +
- " but found " + args[0].getType().toHuman());
- }
-
- if (! Merger.isPossiblyAssignableFrom(type2, args[1])) {
- throw new SimException("expected type " + type2.toHuman() +
- " but found " + args[1].getType().toHuman());
- }
-
- if (! Merger.isPossiblyAssignableFrom(type3, args[2])) {
- throw new SimException("expected type " + type2.toHuman() +
- " but found " + args[2].getType().toHuman());
- }
- }
-
- /** {@inheritDoc} */
- public final void localArg(Frame frame, int idx) {
- clearArgs();
- args[0] = frame.getLocals().get(idx);
- argCount = 1;
- localIndex = idx;
- }
-
- /** {@inheritDoc} */
- public final void auxType(Type type) {
- auxType = type;
- }
-
- /** {@inheritDoc} */
- public final void auxIntArg(int value) {
- auxInt = value;
- }
-
- /** {@inheritDoc} */
- public final void auxCstArg(Constant cst) {
- if (cst == null) {
- throw new NullPointerException("cst == null");
- }
-
- auxCst = cst;
- }
-
- /** {@inheritDoc} */
- public final void auxTargetArg(int target) {
- auxTarget = target;
- }
-
- /** {@inheritDoc} */
- public final void auxSwitchArg(SwitchList cases) {
- if (cases == null) {
- throw new NullPointerException("cases == null");
- }
-
- auxCases = cases;
- }
-
- /** {@inheritDoc} */
- public final void auxInitValues(ArrayList<Constant> initValues) {
- auxInitValues = initValues;
- }
-
- /** {@inheritDoc} */
- public final void localTarget(int idx, Type type, LocalItem local) {
- localTarget = RegisterSpec.makeLocalOptional(idx, type, local);
- }
-
- /**
- * Gets the number of primary arguments.
- *
- * @return &gt;= 0; the number of primary arguments
- */
- protected final int argCount() {
- return argCount;
- }
-
- /**
- * Gets the width of the arguments (where a category-2 value counts as
- * two).
- *
- * @return &gt;= 0; the argument width
- */
- protected final int argWidth() {
- int result = 0;
-
- for (int i = 0; i < argCount; i++) {
- result += args[i].getType().getCategory();
- }
-
- return result;
- }
-
- /**
- * Gets the <code>n</code>th primary argument.
- *
- * @param n &gt;= 0, &lt; argCount(); which argument
- * @return non-null; the indicated argument
- */
- protected final TypeBearer arg(int n) {
- if (n >= argCount) {
- throw new IllegalArgumentException("n >= argCount");
- }
-
- try {
- return args[n];
- } catch (ArrayIndexOutOfBoundsException ex) {
- // Translate the exception.
- throw new IllegalArgumentException("n < 0");
- }
- }
-
- /**
- * Gets the type auxiliary argument.
- *
- * @return null-ok; the salient type
- */
- protected final Type getAuxType() {
- return auxType;
- }
-
- /**
- * Gets the <code>int</code> auxiliary argument.
- *
- * @return the argument value
- */
- protected final int getAuxInt() {
- return auxInt;
- }
-
- /**
- * Gets the constant auxiliary argument.
- *
- * @return null-ok; the argument value
- */
- protected final Constant getAuxCst() {
- return auxCst;
- }
-
- /**
- * Gets the branch target auxiliary argument.
- *
- * @return the argument value
- */
- protected final int getAuxTarget() {
- return auxTarget;
- }
-
- /**
- * Gets the switch cases auxiliary argument.
- *
- * @return null-ok; the argument value
- */
- protected final SwitchList getAuxCases() {
- return auxCases;
- }
-
- /**
- * Gets the init values auxiliary argument.
- *
- * @return null-ok; the argument value
- */
- protected final ArrayList<Constant> getInitValues() {
- return auxInitValues;
- }
- /**
- * Gets the last local index accessed.
- *
- * @return &gt;= -1; the salient local index or <code>-1</code> if none
- * was set since the last time {@link #clearArgs} was called
- */
- protected final int getLocalIndex() {
- return localIndex;
- }
-
- /**
- * Gets the target local register spec of the current operation, if any.
- * The local target spec is the combination of the values indicated
- * by a previous call to {@link #localTarget} with the type of what
- * should be the sole result set by a call to {@link #setResult} (or
- * the combination {@link #clearResult} then {@link #addResult}.
- *
- * @return null-ok; the salient register spec or <code>null</code> if no
- * local target was set since the last time {@link #clearArgs} was
- * called
- */
- protected final RegisterSpec getLocalTarget() {
- if (localTarget == null) {
- return null;
- }
-
- if (resultCount != 1) {
- throw new SimException("local target with " +
- ((resultCount == 0) ? "no" : "multiple") + " results");
- }
-
- TypeBearer result = results[0];
- Type resultType = result.getType();
- Type localType = localTarget.getType();
-
- if (resultType == localType) {
- return localTarget;
- }
-
- if (! Merger.isPossiblyAssignableFrom(localType, resultType)) {
- // The result and local types are inconsistent. Complain!
- throwLocalMismatch(resultType, localType);
- return null;
- }
-
- if (localType == Type.OBJECT) {
- /*
- * The result type is more specific than the local type,
- * so use that instead.
- */
- localTarget = localTarget.withType(result);
- }
-
- return localTarget;
- }
-
- /**
- * Clears the results.
- */
- protected final void clearResult() {
- resultCount = 0;
- }
-
- /**
- * Sets the results list to be the given single value.
- *
- * <p><b>Note:</b> If there is more than one result value, the
- * others may be added by using {@link #addResult}.</p>
- *
- * @param result non-null; result value
- */
- protected final void setResult(TypeBearer result) {
- if (result == null) {
- throw new NullPointerException("result == null");
- }
-
- results[0] = result;
- resultCount = 1;
- }
-
- /**
- * Adds an additional element to the list of results.
- *
- * @see #setResult
- *
- * @param result non-null; result value
- */
- protected final void addResult(TypeBearer result) {
- if (result == null) {
- throw new NullPointerException("result == null");
- }
-
- results[resultCount] = result;
- resultCount++;
- }
-
- /**
- * Gets the count of results. This throws an exception if results were
- * never set. (Explicitly clearing the results counts as setting them.)
- *
- * @return &gt;= 0; the count
- */
- protected final int resultCount() {
- if (resultCount < 0) {
- throw new SimException("results never set");
- }
-
- return resultCount;
- }
-
- /**
- * Gets the width of the results (where a category-2 value counts as
- * two).
- *
- * @return &gt;= 0; the result width
- */
- protected final int resultWidth() {
- int width = 0;
-
- for (int i = 0; i < resultCount; i++) {
- width += results[i].getType().getCategory();
- }
-
- return width;
- }
-
- /**
- * Gets the <code>n</code>th result value.
- *
- * @param n &gt;= 0, &lt; resultCount(); which result
- * @return non-null; the indicated result value
- */
- protected final TypeBearer result(int n) {
- if (n >= resultCount) {
- throw new IllegalArgumentException("n >= resultCount");
- }
-
- try {
- return results[n];
- } catch (ArrayIndexOutOfBoundsException ex) {
- // Translate the exception.
- throw new IllegalArgumentException("n < 0");
- }
- }
-
- /**
- * Stores the results of the latest operation into the given frame. If
- * there is a local target (see {@link #localTarget}), then the sole
- * result is stored to that target; otherwise any results are pushed
- * onto the stack.
- *
- * @param frame non-null; frame to operate on
- */
- protected final void storeResults(Frame frame) {
- if (resultCount < 0) {
- throw new SimException("results never set");
- }
-
- if (resultCount == 0) {
- // Nothing to do.
- return;
- }
-
- if (localTarget != null) {
- /*
- * Note: getLocalTarget() doesn't necessarily return
- * localTarget directly.
- */
- frame.getLocals().set(getLocalTarget());
- } else {
- ExecutionStack stack = frame.getStack();
- for (int i = 0; i < resultCount; i++) {
- stack.push(results[i]);
- }
- }
- }
-
- /**
- * Throws an exception that indicates a mismatch in local variable
- * types.
- *
- * @param found non-null; the encountered type
- * @param local non-null; the local variable's claimed type
- */
- public static void throwLocalMismatch(TypeBearer found,
- TypeBearer local) {
- throw new SimException("local variable type mismatch: " +
- "attempt to set or access a value of type " +
- found.toHuman() +
- " using a local variable of type " +
- local.toHuman() +
- ". This is symptomatic of .class transformation tools " +
- "that ignore local variable information.");
- }
-}