summaryrefslogtreecommitdiff
path: root/dx/src/com/android/dx/cf/code/ValueAwareMachine.java
diff options
context:
space:
mode:
Diffstat (limited to 'dx/src/com/android/dx/cf/code/ValueAwareMachine.java')
-rw-r--r--dx/src/com/android/dx/cf/code/ValueAwareMachine.java199
1 files changed, 199 insertions, 0 deletions
diff --git a/dx/src/com/android/dx/cf/code/ValueAwareMachine.java b/dx/src/com/android/dx/cf/code/ValueAwareMachine.java
new file mode 100644
index 0000000..de75db5
--- /dev/null
+++ b/dx/src/com/android/dx/cf/code/ValueAwareMachine.java
@@ -0,0 +1,199 @@
+/*
+ * 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.CstType;
+import com.android.dx.rop.type.Prototype;
+import com.android.dx.rop.type.Type;
+import com.android.dx.rop.type.TypeBearer;
+import com.android.dx.util.Hex;
+
+/**
+ * {@link Machine} which keeps track of known values but does not do
+ * smart/realistic reference type calculations.
+ */
+public class ValueAwareMachine extends BaseMachine {
+ /**
+ * Constructs an instance.
+ *
+ * @param prototype {@code non-null;} the prototype for the associated
+ * method
+ */
+ public ValueAwareMachine(Prototype prototype) {
+ super(prototype);
+ }
+
+ /** {@inheritDoc} */
+ public void run(Frame frame, int offset, int opcode) {
+ switch (opcode) {
+ case ByteOps.NOP:
+ case ByteOps.IASTORE:
+ case ByteOps.POP:
+ case ByteOps.POP2:
+ case ByteOps.IFEQ:
+ case ByteOps.IFNE:
+ case ByteOps.IFLT:
+ case ByteOps.IFGE:
+ case ByteOps.IFGT:
+ case ByteOps.IFLE:
+ case ByteOps.IF_ICMPEQ:
+ case ByteOps.IF_ICMPNE:
+ case ByteOps.IF_ICMPLT:
+ case ByteOps.IF_ICMPGE:
+ case ByteOps.IF_ICMPGT:
+ case ByteOps.IF_ICMPLE:
+ case ByteOps.IF_ACMPEQ:
+ case ByteOps.IF_ACMPNE:
+ case ByteOps.GOTO:
+ case ByteOps.RET:
+ case ByteOps.LOOKUPSWITCH:
+ case ByteOps.IRETURN:
+ case ByteOps.RETURN:
+ case ByteOps.PUTSTATIC:
+ case ByteOps.PUTFIELD:
+ case ByteOps.ATHROW:
+ case ByteOps.MONITORENTER:
+ case ByteOps.MONITOREXIT:
+ case ByteOps.IFNULL:
+ case ByteOps.IFNONNULL: {
+ // Nothing to do for these ops in this class.
+ clearResult();
+ break;
+ }
+ case ByteOps.LDC:
+ case ByteOps.LDC2_W: {
+ setResult((TypeBearer) getAuxCst());
+ break;
+ }
+ case ByteOps.ILOAD:
+ case ByteOps.ISTORE: {
+ setResult(arg(0));
+ break;
+ }
+ case ByteOps.IALOAD:
+ case ByteOps.IADD:
+ case ByteOps.ISUB:
+ case ByteOps.IMUL:
+ case ByteOps.IDIV:
+ case ByteOps.IREM:
+ case ByteOps.INEG:
+ case ByteOps.ISHL:
+ case ByteOps.ISHR:
+ case ByteOps.IUSHR:
+ case ByteOps.IAND:
+ case ByteOps.IOR:
+ case ByteOps.IXOR:
+ case ByteOps.IINC:
+ case ByteOps.I2L:
+ case ByteOps.I2F:
+ case ByteOps.I2D:
+ case ByteOps.L2I:
+ case ByteOps.L2F:
+ case ByteOps.L2D:
+ case ByteOps.F2I:
+ case ByteOps.F2L:
+ case ByteOps.F2D:
+ case ByteOps.D2I:
+ case ByteOps.D2L:
+ case ByteOps.D2F:
+ case ByteOps.I2B:
+ case ByteOps.I2C:
+ case ByteOps.I2S:
+ case ByteOps.LCMP:
+ case ByteOps.FCMPL:
+ case ByteOps.FCMPG:
+ case ByteOps.DCMPL:
+ case ByteOps.DCMPG:
+ case ByteOps.ARRAYLENGTH: {
+ setResult(getAuxType());
+ break;
+ }
+ case ByteOps.DUP:
+ case ByteOps.DUP_X1:
+ case ByteOps.DUP_X2:
+ case ByteOps.DUP2:
+ case ByteOps.DUP2_X1:
+ case ByteOps.DUP2_X2:
+ case ByteOps.SWAP: {
+ clearResult();
+ for (int pattern = getAuxInt(); pattern != 0; pattern >>= 4) {
+ int which = (pattern & 0x0f) - 1;
+ addResult(arg(which));
+ }
+ break;
+ }
+
+ case ByteOps.JSR: {
+ setResult(new ReturnAddress(getAuxTarget()));
+ break;
+ }
+ case ByteOps.GETSTATIC:
+ case ByteOps.GETFIELD:
+ case ByteOps.INVOKEVIRTUAL:
+ case ByteOps.INVOKESTATIC:
+ case ByteOps.INVOKEINTERFACE: {
+ Type type = ((TypeBearer) getAuxCst()).getType();
+ if (type == Type.VOID) {
+ clearResult();
+ } else {
+ setResult(type);
+ }
+ break;
+ }
+ case ByteOps.INVOKESPECIAL: {
+ Type thisType = arg(0).getType();
+ if (thisType.isUninitialized()) {
+ frame.makeInitialized(thisType);
+ }
+ Type type = ((TypeBearer) getAuxCst()).getType();
+ if (type == Type.VOID) {
+ clearResult();
+ } else {
+ setResult(type);
+ }
+ break;
+ }
+ case ByteOps.NEW: {
+ Type type = ((CstType) getAuxCst()).getClassType();
+ setResult(type.asUninitialized(offset));
+ break;
+ }
+ case ByteOps.NEWARRAY:
+ case ByteOps.CHECKCAST:
+ case ByteOps.MULTIANEWARRAY: {
+ Type type = ((CstType) getAuxCst()).getClassType();
+ setResult(type);
+ break;
+ }
+ case ByteOps.ANEWARRAY: {
+ Type type = ((CstType) getAuxCst()).getClassType();
+ setResult(type.getArrayType());
+ break;
+ }
+ case ByteOps.INSTANCEOF: {
+ setResult(Type.INT);
+ break;
+ }
+ default: {
+ throw new RuntimeException("shouldn't happen: " +
+ Hex.u1(opcode));
+ }
+ }
+
+ storeResults(frame);
+ }
+}