diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 18:28:14 -0800 |
commit | f72d5de56a522ac3be03873bdde26f23a5eeeb3c (patch) | |
tree | 4b825dc642cb6eb9a060e54bf8d69288fbee4904 /dx/src/com/android/dx/cf/code/BaseMachine.java | |
parent | 31e30105703263782efd450d356cd67ea01af3b7 (diff) | |
download | android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.gz android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.tar.bz2 android_dalvik-f72d5de56a522ac3be03873bdde26f23a5eeeb3c.zip |
auto import from //depot/cupcake/@135843
Diffstat (limited to 'dx/src/com/android/dx/cf/code/BaseMachine.java')
-rw-r--r-- | dx/src/com/android/dx/cf/code/BaseMachine.java | 545 |
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; - - /** >= 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; - - /** >= -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; - - /** - * >= -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 >= 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 >= 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 >= 0, < 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 >= -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 >= 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 >= 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 >= 0, < 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."); - } -} |