diff options
Diffstat (limited to 'dx/src/com/android/dx/dex/code/CstInsn.java')
-rw-r--r-- | dx/src/com/android/dx/dex/code/CstInsn.java | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/dx/src/com/android/dx/dex/code/CstInsn.java b/dx/src/com/android/dx/dex/code/CstInsn.java new file mode 100644 index 0000000..3f848c0 --- /dev/null +++ b/dx/src/com/android/dx/dex/code/CstInsn.java @@ -0,0 +1,205 @@ +/* + * 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.dex.code; + +import com.android.dx.rop.code.RegisterSpecList; +import com.android.dx.rop.code.SourcePosition; +import com.android.dx.rop.cst.Constant; + +/** + * Instruction which has a single constant argument in addition + * to all the normal instruction information. + */ +public final class CstInsn extends FixedSizeInsn { + /** {@code non-null;} the constant argument for this instruction */ + private final Constant constant; + + /** + * {@code >= -1;} the constant pool index for {@link #constant}, or + * {@code -1} if not yet set + */ + private int index; + + /** + * {@code >= -1;} the constant pool index for the class reference in + * {@link #constant} if any, or {@code -1} if not yet set + */ + private int classIndex; + + /** + * Constructs an instance. The output address of this instance is + * initially unknown ({@code -1}) as is the constant pool index. + * + * @param opcode the opcode; one of the constants from {@link Dops} + * @param position {@code non-null;} source position + * @param registers {@code non-null;} register list, including a + * result register if appropriate (that is, registers may be either + * ins or outs) + * @param constant {@code non-null;} constant argument + */ + public CstInsn(Dop opcode, SourcePosition position, + RegisterSpecList registers, Constant constant) { + super(opcode, position, registers); + + if (constant == null) { + throw new NullPointerException("constant == null"); + } + + this.constant = constant; + this.index = -1; + this.classIndex = -1; + } + + /** {@inheritDoc} */ + @Override + public DalvInsn withOpcode(Dop opcode) { + CstInsn result = + new CstInsn(opcode, getPosition(), getRegisters(), constant); + + if (index >= 0) { + result.setIndex(index); + } + + if (classIndex >= 0) { + result.setClassIndex(classIndex); + } + + return result; + } + + /** {@inheritDoc} */ + @Override + public DalvInsn withRegisters(RegisterSpecList registers) { + CstInsn result = + new CstInsn(getOpcode(), getPosition(), registers, constant); + + if (index >= 0) { + result.setIndex(index); + } + + if (classIndex >= 0) { + result.setClassIndex(classIndex); + } + + return result; + } + + /** + * Gets the constant argument. + * + * @return {@code non-null;} the constant argument + */ + public Constant getConstant() { + return constant; + } + + /** + * Gets the constant's index. It is only valid to call this after + * {@link #setIndex} has been called. + * + * @return {@code >= 0;} the constant pool index + */ + public int getIndex() { + if (index < 0) { + throw new RuntimeException("index not yet set for " + constant); + } + + return index; + } + + /** + * Returns whether the constant's index has been set for this instance. + * + * @see #setIndex + * + * @return {@code true} iff the index has been set + */ + public boolean hasIndex() { + return (index >= 0); + } + + /** + * Sets the constant's index. It is only valid to call this method once + * per instance. + * + * @param index {@code >= 0;} the constant pool index + */ + public void setIndex(int index) { + if (index < 0) { + throw new IllegalArgumentException("index < 0"); + } + + if (this.index >= 0) { + throw new RuntimeException("index already set"); + } + + this.index = index; + } + + /** + * Gets the constant's class index. It is only valid to call this after + * {@link #setClassIndex} has been called. + * + * @return {@code >= 0;} the constant's class's constant pool index + */ + public int getClassIndex() { + if (classIndex < 0) { + throw new RuntimeException("class index not yet set"); + } + + return classIndex; + } + + /** + * Returns whether the constant's class index has been set for this + * instance. + * + * @see #setClassIndex + * + * @return {@code true} iff the index has been set + */ + public boolean hasClassIndex() { + return (classIndex >= 0); + } + + /** + * Sets the constant's class index. This is the constant pool index + * for the class referred to by this instance's constant. Only + * reference constants have a class, so it is only on instances + * with reference constants that this method should ever be + * called. It is only valid to call this method once per instance. + * + * @param index {@code >= 0;} the constant's class's constant pool index + */ + public void setClassIndex(int index) { + if (index < 0) { + throw new IllegalArgumentException("index < 0"); + } + + if (this.classIndex >= 0) { + throw new RuntimeException("class index already set"); + } + + this.classIndex = index; + } + + /** {@inheritDoc} */ + @Override + protected String argString() { + return constant.toHuman(); + } +} |