summaryrefslogtreecommitdiff
path: root/src/proguard/evaluation
diff options
context:
space:
mode:
Diffstat (limited to 'src/proguard/evaluation')
-rw-r--r--src/proguard/evaluation/BasicBranchUnit.java2
-rw-r--r--src/proguard/evaluation/BasicInvocationUnit.java13
-rw-r--r--src/proguard/evaluation/BranchUnit.java2
-rw-r--r--src/proguard/evaluation/ClassConstantValueFactory.java10
-rw-r--r--src/proguard/evaluation/ConstantValueFactory.java8
-rw-r--r--src/proguard/evaluation/InvocationUnit.java2
-rw-r--r--src/proguard/evaluation/Processor.java103
-rw-r--r--src/proguard/evaluation/Stack.java2
-rw-r--r--src/proguard/evaluation/TracedStack.java158
-rw-r--r--src/proguard/evaluation/TracedVariables.java2
-rw-r--r--src/proguard/evaluation/Variables.java2
-rw-r--r--src/proguard/evaluation/value/ArrayReferenceValue.java165
-rw-r--r--src/proguard/evaluation/value/Category1Value.java2
-rw-r--r--src/proguard/evaluation/value/Category2Value.java2
-rw-r--r--src/proguard/evaluation/value/ComparisonValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/CompositeLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedByteValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedCharacterValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ConvertedShortValue.java2
-rw-r--r--src/proguard/evaluation/value/DetailedArrayReferenceValue.java301
-rw-r--r--src/proguard/evaluation/value/DetailedValueFactory.java48
-rw-r--r--src/proguard/evaluation/value/DoubleValue.java4
-rw-r--r--src/proguard/evaluation/value/FloatValue.java4
-rw-r--r--src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java159
-rw-r--r--src/proguard/evaluation/value/IdentifiedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/IdentifiedReferenceValue.java81
-rw-r--r--src/proguard/evaluation/value/IdentifiedValueFactory.java37
-rw-r--r--src/proguard/evaluation/value/InitialValueFactory.java79
-rw-r--r--src/proguard/evaluation/value/InstructionOffsetValue.java65
-rw-r--r--src/proguard/evaluation/value/IntegerValue.java4
-rw-r--r--src/proguard/evaluation/value/LongValue.java4
-rw-r--r--src/proguard/evaluation/value/NegatedDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/NegatedLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ParticularDoubleValue.java8
-rw-r--r--src/proguard/evaluation/value/ParticularFloatValue.java8
-rw-r--r--src/proguard/evaluation/value/ParticularIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/ParticularLongValue.java2
-rw-r--r--src/proguard/evaluation/value/ParticularValueFactory.java (renamed from src/proguard/evaluation/value/SpecificValueFactory.java)26
-rw-r--r--src/proguard/evaluation/value/ReferenceValue.java553
-rw-r--r--src/proguard/evaluation/value/SpecificDoubleValue.java4
-rw-r--r--src/proguard/evaluation/value/SpecificFloatValue.java4
-rw-r--r--src/proguard/evaluation/value/SpecificIntegerValue.java8
-rw-r--r--src/proguard/evaluation/value/SpecificLongValue.java8
-rw-r--r--src/proguard/evaluation/value/TopValue.java2
-rw-r--r--src/proguard/evaluation/value/TypedReferenceValue.java613
-rw-r--r--src/proguard/evaluation/value/UnknownDoubleValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownFloatValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownIntegerValue.java2
-rw-r--r--src/proguard/evaluation/value/UnknownLongValue.java2
-rw-r--r--src/proguard/evaluation/value/Value.java36
-rw-r--r--src/proguard/evaluation/value/ValueFactory.java63
63 files changed, 1951 insertions, 693 deletions
diff --git a/src/proguard/evaluation/BasicBranchUnit.java b/src/proguard/evaluation/BasicBranchUnit.java
index 127e922..f10e4be 100644
--- a/src/proguard/evaluation/BasicBranchUnit.java
+++ b/src/proguard/evaluation/BasicBranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/BasicInvocationUnit.java b/src/proguard/evaluation/BasicInvocationUnit.java
index 474556c..f7cc902 100644
--- a/src/proguard/evaluation/BasicInvocationUnit.java
+++ b/src/proguard/evaluation/BasicInvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -68,7 +68,7 @@ implements InvocationUnit,
// Initialize the parameters.
boolean isStatic =
- (method.getAccessFlags() & ClassConstants.INTERNAL_ACC_STATIC) != 0;
+ (method.getAccessFlags() & ClassConstants.ACC_STATIC) != 0;
// Count the number of parameters, taking into account their categories.
int parameterSize = ClassUtil.internalMethodParameterSize(descriptor, isStatic);
@@ -225,7 +225,7 @@ implements InvocationUnit,
// Push the return value, if applicable.
String returnType = ClassUtil.internalMethodReturnType(type);
- if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
+ if (returnType.charAt(0) != ClassConstants.TYPE_VOID)
{
stack.push(getMethodReturnValue(clazz, methodrefConstant, returnType));
}
@@ -250,7 +250,7 @@ implements InvocationUnit,
// Push the return value, if applicable.
String returnType = ClassUtil.internalMethodReturnType(type);
- if (returnType.charAt(0) != ClassConstants.INTERNAL_TYPE_VOID)
+ if (returnType.charAt(0) != ClassConstants.TYPE_VOID)
{
stack.push(getMethodReturnValue(clazz, invokeDynamicConstant, returnType));
}
@@ -417,9 +417,4 @@ implements InvocationUnit,
returnTypeClass = referencedClasses[referencedClasses.length - 1];
}
}
-
-
-// public void visitLibraryMember(LibraryClass libraryClass, LibraryMember libraryMember)
-// {
-// }
}
diff --git a/src/proguard/evaluation/BranchUnit.java b/src/proguard/evaluation/BranchUnit.java
index a381da7..e81b61d 100644
--- a/src/proguard/evaluation/BranchUnit.java
+++ b/src/proguard/evaluation/BranchUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/ClassConstantValueFactory.java b/src/proguard/evaluation/ClassConstantValueFactory.java
index 1c418c2..62cc42c 100644
--- a/src/proguard/evaluation/ClassConstantValueFactory.java
+++ b/src/proguard/evaluation/ClassConstantValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,10 +21,8 @@
package proguard.evaluation;
import proguard.classfile.*;
-import proguard.classfile.constant.*;
-import proguard.classfile.constant.visitor.ConstantVisitor;
-import proguard.classfile.util.SimplifiedVisitor;
-import proguard.evaluation.value.*;
+import proguard.classfile.constant.ClassConstant;
+import proguard.evaluation.value.ValueFactory;
/**
* This class creates java.lang.Class ReferenceValue instances that correspond
@@ -46,7 +44,7 @@ extends ConstantValueFactory
public void visitClassConstant(Clazz clazz, ClassConstant classConstant)
{
// Create a Class reference instead of a reference to the class.
- value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_CLASS,
+ value = valueFactory.createReferenceValue(ClassConstants.NAME_JAVA_LANG_CLASS,
classConstant.javaLangClassClass,
false);
}
diff --git a/src/proguard/evaluation/ConstantValueFactory.java b/src/proguard/evaluation/ConstantValueFactory.java
index 0afb20c..6875bde 100644
--- a/src/proguard/evaluation/ConstantValueFactory.java
+++ b/src/proguard/evaluation/ConstantValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -85,14 +85,14 @@ implements ConstantVisitor
public void visitStringConstant(Clazz clazz, StringConstant stringConstant)
{
- value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_STRING,
+ value = valueFactory.createReferenceValue(ClassConstants.NAME_JAVA_LANG_STRING,
stringConstant.javaLangStringClass,
false);
}
public void visitMethodHandleConstant(Clazz clazz, MethodHandleConstant methodHandleConstant)
{
- value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_HANDLE,
+ value = valueFactory.createReferenceValue(ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_HANDLE,
methodHandleConstant.javaLangInvokeMethodHandleClass,
false);
}
@@ -106,7 +106,7 @@ implements ConstantVisitor
public void visitMethodTypeConstant(Clazz clazz, MethodTypeConstant methodTypeConstant)
{
- value = valueFactory.createReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_INVOKE_METHOD_TYPE,
+ value = valueFactory.createReferenceValue(ClassConstants.NAME_JAVA_LANG_INVOKE_METHOD_TYPE,
methodTypeConstant.javaLangInvokeMethodTypeClass,
false);
}
diff --git a/src/proguard/evaluation/InvocationUnit.java b/src/proguard/evaluation/InvocationUnit.java
index e526b35..0750894 100644
--- a/src/proguard/evaluation/InvocationUnit.java
+++ b/src/proguard/evaluation/InvocationUnit.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/Processor.java b/src/proguard/evaluation/Processor.java
index 3bfc5f3..d03b853 100644
--- a/src/proguard/evaluation/Processor.java
+++ b/src/proguard/evaluation/Processor.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -40,6 +40,7 @@ implements InstructionVisitor
private final ValueFactory valueFactory;
private final BranchUnit branchUnit;
private final InvocationUnit invocationUnit;
+ private final boolean alwaysCast;
private final ConstantValueFactory constantValueFactory;
private final ClassConstantValueFactory classConstantValueFactory;
@@ -51,18 +52,22 @@ implements InstructionVisitor
* @param stack the local stack.
* @param branchUnit the class that can affect the program counter.
* @param invocationUnit the class that can access other program members.
+ * @param alwaysCast a flag that specifies whether downcasts or casts
+ * of null values should always be performed.
*/
public Processor(Variables variables,
Stack stack,
ValueFactory valueFactory,
BranchUnit branchUnit,
- InvocationUnit invocationUnit)
+ InvocationUnit invocationUnit,
+ boolean alwaysCast)
{
this.variables = variables;
this.stack = stack;
this.valueFactory = valueFactory;
this.branchUnit = branchUnit;
this.invocationUnit = invocationUnit;
+ this.alwaysCast = alwaysCast;
constantValueFactory = new ConstantValueFactory(valueFactory);
classConstantValueFactory = new ClassConstantValueFactory(valueFactory);
@@ -114,70 +119,83 @@ implements InstructionVisitor
case InstructionConstants.OP_BALOAD:
case InstructionConstants.OP_CALOAD:
case InstructionConstants.OP_SALOAD:
- stack.ipop();
- stack.apop();
- stack.push(valueFactory.createIntegerValue());
+ {
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ stack.push(arrayReference.integerArrayLoad(arrayIndex, valueFactory));
break;
-
+ }
case InstructionConstants.OP_LALOAD:
- stack.ipop();
- stack.apop();
- stack.push(valueFactory.createLongValue());
+ {
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ stack.push(arrayReference.longArrayLoad(arrayIndex, valueFactory));
break;
-
+ }
case InstructionConstants.OP_FALOAD:
- stack.ipop();
- stack.apop();
- stack.push(valueFactory.createFloatValue());
+ {
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ stack.push(arrayReference.floatArrayLoad(arrayIndex, valueFactory));
break;
-
+ }
case InstructionConstants.OP_DALOAD:
- stack.ipop();
- stack.apop();
- stack.push(valueFactory.createDoubleValue());
+ {
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ stack.push(arrayReference.doubleArrayLoad(arrayIndex, valueFactory));
break;
-
+ }
case InstructionConstants.OP_AALOAD:
{
IntegerValue arrayIndex = stack.ipop();
ReferenceValue arrayReference = stack.apop();
- stack.push(arrayReference.arrayLoad(arrayIndex, valueFactory));
+ stack.push(arrayReference.referenceArrayLoad(arrayIndex, valueFactory));
break;
}
-
case InstructionConstants.OP_IASTORE:
case InstructionConstants.OP_BASTORE:
case InstructionConstants.OP_CASTORE:
case InstructionConstants.OP_SASTORE:
- stack.ipop();
- stack.ipop();
- stack.apop();
+ {
+ Value value = stack.ipop();
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ arrayReference.arrayStore(arrayIndex, value);
break;
-
+ }
case InstructionConstants.OP_LASTORE:
- stack.lpop();
- stack.ipop();
- stack.apop();
+ {
+ Value value = stack.lpop();
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ arrayReference.arrayStore(arrayIndex, value);
break;
-
+ }
case InstructionConstants.OP_FASTORE:
- stack.fpop();
- stack.ipop();
- stack.apop();
+ {
+ Value value = stack.fpop();
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ arrayReference.arrayStore(arrayIndex, value);
break;
-
+ }
case InstructionConstants.OP_DASTORE:
- stack.dpop();
- stack.ipop();
- stack.apop();
+ {
+ Value value = stack.dpop();
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ arrayReference.arrayStore(arrayIndex, value);
break;
-
+ }
case InstructionConstants.OP_AASTORE:
- stack.apop();
- stack.ipop();
- stack.apop();
+ {
+ Value value = stack.apop();
+ IntegerValue arrayIndex = stack.ipop();
+ ReferenceValue arrayReference = stack.apop();
+ arrayReference.arrayStore(arrayIndex, value);
break;
-
+ }
case InstructionConstants.OP_POP:
stack.pop1();
break;
@@ -527,8 +545,8 @@ implements InstructionVisitor
break;
case InstructionConstants.OP_ARRAYLENGTH:
- stack.apop();
- stack.push(valueFactory.createIntegerValue());
+ ReferenceValue referenceValue = stack.apop();
+ stack.push(referenceValue.arrayLength(valueFactory));
break;
case InstructionConstants.OP_ATHROW:
@@ -591,6 +609,7 @@ implements InstructionVisitor
// TODO: Check cast.
ReferenceValue castValue = stack.apop();
ReferenceValue castResultValue =
+ !alwaysCast &&
castValue.isNull() == Value.ALWAYS ? castValue :
castValue.isNull() == Value.NEVER ? constantValueFactory.constantValue(clazz, constantIndex).referenceValue() :
constantValueFactory.constantValue(clazz, constantIndex).referenceValue().generalize(valueFactory.createReferenceValueNull());
diff --git a/src/proguard/evaluation/Stack.java b/src/proguard/evaluation/Stack.java
index c449e86..9294853 100644
--- a/src/proguard/evaluation/Stack.java
+++ b/src/proguard/evaluation/Stack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/TracedStack.java b/src/proguard/evaluation/TracedStack.java
index 08778a1..08e30e9 100644
--- a/src/proguard/evaluation/TracedStack.java
+++ b/src/proguard/evaluation/TracedStack.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -24,12 +24,13 @@ import proguard.evaluation.value.Value;
/**
* This Stack saves additional information with stack elements, to keep track
- * of their origins and destinations.
+ * of their origins.
* <p>
* The stack stores a given producer Value along with each Value it stores.
* It then generalizes a given collected Value with the producer Value
* of each Value it loads. The producer Value and the initial collected Value
- * can be set; the generalized collected Value can be retrieved.
+ * can be set. The generalized collected Value can be retrieved, either taking
+ * into account dup/swap instructions as proper instructions or ignoring them.
*
* @author Eric Lafortune
*/
@@ -37,6 +38,7 @@ public class TracedStack extends Stack
{
private Value producerValue;
private Stack producerStack;
+ private Stack actualProducerStack;
/**
@@ -46,7 +48,8 @@ public class TracedStack extends Stack
{
super(maxSize);
- producerStack = new Stack(maxSize);
+ producerStack = new Stack(maxSize);
+ actualProducerStack = new Stack(maxSize);
}
@@ -57,7 +60,8 @@ public class TracedStack extends Stack
{
super(tracedStack);
- producerStack = new Stack(tracedStack.producerStack);
+ producerStack = new Stack(tracedStack.producerStack);
+ actualProducerStack = new Stack(tracedStack.actualProducerStack);
}
@@ -84,14 +88,15 @@ public class TracedStack extends Stack
/**
- * Sets the specified producer Value on the stack, without disturbing it.
+ * Gets the specified actual producer Value from the stack, ignoring
+ * dup/swap instructions, without disturbing it.
* @param index the index of the stack element, counting from the bottom
* of the stack.
- * @param value the producer value to set.
+ * @return the producer value at the specified position.
*/
- public void setBottomProducerValue(int index, Value value)
+ public Value getBottomActualProducerValue(int index)
{
- producerStack.setBottom(index, value);
+ return actualProducerStack.getBottom(index);
}
@@ -108,14 +113,15 @@ public class TracedStack extends Stack
/**
- * Sets the specified producer Value on the stack, without disturbing it.
+ * Gets the specified actual producer Value from the stack, ignoring
+ * dup/swap instructions, without disturbing it.
* @param index the index of the stack element, counting from the top
* of the stack.
- * @param value the producer value to set.
+ * @return the producer value at the specified position.
*/
- public void setTopProducerValue(int index, Value value)
+ public Value getTopActualProducerValue(int index)
{
- producerStack.setTop(index, value);
+ return actualProducerStack.getTop(index);
}
@@ -126,6 +132,7 @@ public class TracedStack extends Stack
super.reset(size);
producerStack.reset(size);
+ actualProducerStack.reset(size);
}
public void copy(TracedStack other)
@@ -133,13 +140,15 @@ public class TracedStack extends Stack
super.copy(other);
producerStack.copy(other.producerStack);
+ actualProducerStack.copy(other.actualProducerStack);
}
public boolean generalize(TracedStack other)
{
return
super.generalize(other) |
- producerStack.generalize(other.producerStack);
+ producerStack.generalize(other.producerStack) |
+ actualProducerStack.generalize(other.actualProducerStack);
}
public void clear()
@@ -147,6 +156,7 @@ public class TracedStack extends Stack
super.clear();
producerStack.clear();
+ actualProducerStack.clear();
}
public void removeTop(int index)
@@ -154,6 +164,7 @@ public class TracedStack extends Stack
super.removeTop(index);
producerStack.removeTop(index);
+ actualProducerStack.removeTop(index);
}
public void push(Value value)
@@ -203,85 +214,99 @@ public class TracedStack extends Stack
{
super.dup();
- producerPop();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup();
}
public void dup_x1()
{
super.dup_x1();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup_x1();
}
public void dup_x2()
{
super.dup_x2();
- producerPop();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup_x2();
}
public void dup2()
{
super.dup2();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup2();
}
public void dup2_x1()
{
super.dup2_x1();
- producerPop();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup2_x1();
}
public void dup2_x2()
{
super.dup2_x2();
- producerPop();
- producerPop();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.dup2_x2();
}
public void swap()
{
super.swap();
- producerPop();
- producerPop();
- producerPush();
- producerPush();
+ producerStack.pop();
+ producerStack.pop();
+ producerStack.push(producerValue);
+ producerStack.push(producerValue);
+
+ actualProducerStack.swap();
}
@@ -298,14 +323,16 @@ public class TracedStack extends Stack
TracedStack other = (TracedStack)object;
return super.equals(object) &&
- this.producerStack.equals(other.producerStack);
+ this.producerStack.equals(other.producerStack) &&
+ this.actualProducerStack.equals(other.actualProducerStack);
}
public int hashCode()
{
- return super.hashCode() ^
- producerStack.hashCode();
+ return super.hashCode() ^
+ producerStack.hashCode() ^
+ actualProducerStack.hashCode();
}
@@ -315,10 +342,13 @@ public class TracedStack extends Stack
for (int index = 0; index < this.size(); index++)
{
- Value value = this.values[index];
- Value producerValue = producerStack.getBottom(index);
+ Value value = this.values[index];
+ Value producerValue = producerStack.getBottom(index);
+ Value actualProducerValue = actualProducerStack.getBottom(index);
buffer = buffer.append('[')
- .append(producerValue == null ? "empty:" : producerValue.toString())
+ .append(producerValue == null ? "empty:" :
+ producerValue.equals(actualProducerValue) ? producerValue.toString() :
+ producerValue.toString() + actualProducerValue.toString())
.append(value == null ? "empty" : value.toString())
.append(']');
}
@@ -332,11 +362,13 @@ public class TracedStack extends Stack
private void producerPush()
{
producerStack.push(producerValue);
+ actualProducerStack.push(producerValue);
}
private void producerPop()
{
producerStack.pop();
+ actualProducerStack.pop();
}
}
diff --git a/src/proguard/evaluation/TracedVariables.java b/src/proguard/evaluation/TracedVariables.java
index fef54e1..23e3041 100644
--- a/src/proguard/evaluation/TracedVariables.java
+++ b/src/proguard/evaluation/TracedVariables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/Variables.java b/src/proguard/evaluation/Variables.java
index 16b39e7..4b3a2a4 100644
--- a/src/proguard/evaluation/Variables.java
+++ b/src/proguard/evaluation/Variables.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ArrayReferenceValue.java b/src/proguard/evaluation/value/ArrayReferenceValue.java
new file mode 100644
index 0000000..56f18ad
--- /dev/null
+++ b/src/proguard/evaluation/value/ArrayReferenceValue.java
@@ -0,0 +1,165 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.Clazz;
+
+/**
+ * This ReferenceValue represents a partially evaluated array. It has an array
+ * length and possibly array values (up to a fixed maximum number). It is not
+ * immutable.
+ *
+ * @author Eric Lafortune
+ */
+class ArrayReferenceValue extends TypedReferenceValue
+{
+ protected final IntegerValue arrayLength;
+
+
+ /**
+ * Creates a new ArrayReferenceValue.
+ */
+ public ArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength)
+ {
+ super(type, referencedClass, false);
+
+ this.arrayLength = arrayLength;
+ }
+
+
+ // Implementations for ReferenceValue.
+
+ public IntegerValue arrayLength(ValueFactory valueFactory)
+ {
+ return arrayLength;
+ }
+
+
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ return other.generalize(this);
+ }
+
+
+ public int equal(ReferenceValue other)
+ {
+ return other.equal(this);
+ }
+
+
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+
+
+ // Implementations of binary ReferenceValue methods with
+ // ArrayReferenceValue arguments.
+
+ public ReferenceValue generalize(ArrayReferenceValue other)
+ {
+ return
+ this.equals(other) ? this :
+ this.type != null &&
+ this.type.equals(other.type) &&
+ this.referencedClass == other.referencedClass ? new ArrayReferenceValue(this.type,
+ this.referencedClass,
+ this.arrayLength.generalize(other.arrayLength)) :
+ generalize((TypedReferenceValue)other);
+ }
+
+
+ public int equal(ArrayReferenceValue other)
+ {
+ if (this.arrayLength.equal(other.arrayLength) == NEVER)
+ {
+ return NEVER;
+ }
+
+ return equal((TypedReferenceValue)other);
+ }
+
+
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
+// {
+// return generalize((ArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedArrayReferenceValue other)
+// {
+// return equal((ArrayReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // DetailedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(DetailedArrayReferenceValue other)
+// {
+// return generalize((IdentifiedArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(DetailedArrayReferenceValue other)
+// {
+// return equal((IdentifiedArrayReferenceValue)other);
+// }
+
+
+ // Implementations for Object.
+
+ public boolean equals(Object object)
+ {
+ return this == object ||
+ super.equals(object) &&
+ this.arrayLength.equals(((ArrayReferenceValue)object).arrayLength);
+ }
+
+
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ arrayLength.hashCode();
+ }
+
+
+ public String toString()
+ {
+ return super.toString() + '['+arrayLength+']';
+ }
+}
diff --git a/src/proguard/evaluation/value/Category1Value.java b/src/proguard/evaluation/value/Category1Value.java
index a5ebf86..777e3e3 100644
--- a/src/proguard/evaluation/value/Category1Value.java
+++ b/src/proguard/evaluation/value/Category1Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/Category2Value.java b/src/proguard/evaluation/value/Category2Value.java
index 2be6e71..80c2183 100644
--- a/src/proguard/evaluation/value/Category2Value.java
+++ b/src/proguard/evaluation/value/Category2Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ComparisonValue.java b/src/proguard/evaluation/value/ComparisonValue.java
index abbf31c..e2cd94e 100644
--- a/src/proguard/evaluation/value/ComparisonValue.java
+++ b/src/proguard/evaluation/value/ComparisonValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeDoubleValue.java b/src/proguard/evaluation/value/CompositeDoubleValue.java
index be739ed..85b606a 100644
--- a/src/proguard/evaluation/value/CompositeDoubleValue.java
+++ b/src/proguard/evaluation/value/CompositeDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeFloatValue.java b/src/proguard/evaluation/value/CompositeFloatValue.java
index 0961068..35f160f 100644
--- a/src/proguard/evaluation/value/CompositeFloatValue.java
+++ b/src/proguard/evaluation/value/CompositeFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeIntegerValue.java b/src/proguard/evaluation/value/CompositeIntegerValue.java
index 97caa2f..de56452 100644
--- a/src/proguard/evaluation/value/CompositeIntegerValue.java
+++ b/src/proguard/evaluation/value/CompositeIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/CompositeLongValue.java b/src/proguard/evaluation/value/CompositeLongValue.java
index 3b8a97f..70351c8 100644
--- a/src/proguard/evaluation/value/CompositeLongValue.java
+++ b/src/proguard/evaluation/value/CompositeLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedByteValue.java b/src/proguard/evaluation/value/ConvertedByteValue.java
index eb1a350..6fd96e4 100644
--- a/src/proguard/evaluation/value/ConvertedByteValue.java
+++ b/src/proguard/evaluation/value/ConvertedByteValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedCharacterValue.java b/src/proguard/evaluation/value/ConvertedCharacterValue.java
index a491bed..81f0500 100644
--- a/src/proguard/evaluation/value/ConvertedCharacterValue.java
+++ b/src/proguard/evaluation/value/ConvertedCharacterValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedDoubleValue.java b/src/proguard/evaluation/value/ConvertedDoubleValue.java
index 65fab84..bd20542 100644
--- a/src/proguard/evaluation/value/ConvertedDoubleValue.java
+++ b/src/proguard/evaluation/value/ConvertedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedFloatValue.java b/src/proguard/evaluation/value/ConvertedFloatValue.java
index e74ec8d..83e1eb1 100644
--- a/src/proguard/evaluation/value/ConvertedFloatValue.java
+++ b/src/proguard/evaluation/value/ConvertedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedIntegerValue.java b/src/proguard/evaluation/value/ConvertedIntegerValue.java
index 273b5a1..c5d83b5 100644
--- a/src/proguard/evaluation/value/ConvertedIntegerValue.java
+++ b/src/proguard/evaluation/value/ConvertedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedLongValue.java b/src/proguard/evaluation/value/ConvertedLongValue.java
index 5cb9104..944e8b6 100644
--- a/src/proguard/evaluation/value/ConvertedLongValue.java
+++ b/src/proguard/evaluation/value/ConvertedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ConvertedShortValue.java b/src/proguard/evaluation/value/ConvertedShortValue.java
index cef2a20..7e0472f 100644
--- a/src/proguard/evaluation/value/ConvertedShortValue.java
+++ b/src/proguard/evaluation/value/ConvertedShortValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/DetailedArrayReferenceValue.java b/src/proguard/evaluation/value/DetailedArrayReferenceValue.java
new file mode 100644
index 0000000..73ca067
--- /dev/null
+++ b/src/proguard/evaluation/value/DetailedArrayReferenceValue.java
@@ -0,0 +1,301 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.Clazz;
+import proguard.classfile.util.ClassUtil;
+import proguard.util.ArrayUtil;
+
+/**
+ * This IdentifiedArrayReferenceValue represents an identified array reference
+ * value with its elements.
+ *
+ * @author Eric Lafortune
+ */
+class DetailedArrayReferenceValue extends IdentifiedArrayReferenceValue
+{
+ private static final int MAXIMUM_STORED_ARRAY_LENGTH = 32;
+
+
+ private final Value[] values;
+
+
+ /**
+ * Creates a new array reference value with the given ID.
+ */
+ public DetailedArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength,
+ ValueFactory valuefactory,
+ int id)
+ {
+ super(type, referencedClass, arrayLength, valuefactory, id);
+
+ // Is the array short enough to analyze?
+ if (arrayLength.isParticular() &&
+ arrayLength.value() <= MAXIMUM_STORED_ARRAY_LENGTH)
+ {
+ // Initialize the values of the array.
+ InitialValueFactory initialValueFactory =
+ new InitialValueFactory(valuefactory);
+
+ String elementType = ClassUtil.isInternalArrayType(type) ?
+ type.substring(1) :
+ type;
+
+ this.values = new Value[arrayLength.value()];
+
+ for (int index = 0; index < values.length; index++)
+ {
+ values[index] = initialValueFactory.createValue(elementType);
+ }
+ }
+ else
+ {
+ // Just ignore the values of the array.
+ this.values = null;
+ }
+ }
+
+
+ // Implementations for ReferenceValue.
+
+ public IntegerValue integerArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ Value value = arrayLoad(indexValue, valueFactory);
+ return value != null ?
+ value.integerValue() :
+ super.integerArrayLoad(indexValue, valueFactory);
+ }
+
+
+ public LongValue longArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ Value value = arrayLoad(indexValue, valueFactory);
+ return value != null ?
+ value.longValue() :
+ super.longArrayLoad(indexValue, valueFactory);
+ }
+
+
+ public FloatValue floatArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ Value value = arrayLoad(indexValue, valueFactory);
+ return value != null ?
+ value.floatValue() :
+ super.floatArrayLoad(indexValue, valueFactory);
+ }
+
+
+ public DoubleValue doubleArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ Value value = arrayLoad(indexValue, valueFactory);
+ return value != null ?
+ value.doubleValue() :
+ super.doubleArrayLoad(indexValue, valueFactory);
+ }
+
+
+ public ReferenceValue referenceArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ Value value = arrayLoad(indexValue, valueFactory);
+ return value != null ?
+ value.referenceValue() :
+ super.referenceArrayLoad(indexValue, valueFactory);
+ }
+
+
+ /**
+ * Returns the specified untyped value from the given array, or null if it
+ * is unknown.
+ */
+ private Value arrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ if (values != null &&
+ indexValue.isParticular())
+ {
+ int index = indexValue.value();
+ if (index >=0 &&
+ index < values.length)
+ {
+ return values[index];
+ }
+ }
+
+ return null;
+ }
+
+
+ public void arrayStore(IntegerValue indexValue, Value value)
+ {
+ if (values != null)
+ {
+ if (indexValue.isParticular())
+ {
+ int index = indexValue.value();
+ if (index >=0 &&
+ index < values.length)
+ {
+ values[index] = value;
+ }
+ }
+ else
+ {
+ for (int index = 0; index < values.length; index++)
+ {
+ values[index].generalize(value);
+ }
+ }
+ }
+ }
+
+
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ return other.generalize(this);
+ }
+
+
+ public int equal(ReferenceValue other)
+ {
+ return other.equal(this);
+ }
+
+
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // ArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(ArrayReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(ArrayReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
+// {
+// return generalize((ArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedArrayReferenceValue other)
+// {
+// return equal((ArrayReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // DetailedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(DetailedArrayReferenceValue other)
+// {
+// return generalize((IdentifiedArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(DetailedArrayReferenceValue other)
+// {
+// return equal((IdentifiedArrayReferenceValue)other);
+// }
+
+
+ // Implementations for Value.
+
+ public boolean isParticular()
+ {
+ if (values == null)
+ {
+ return false;
+ }
+
+ for (int index = 0; index < values.length; index++)
+ {
+ if (!values[index].isParticular())
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+
+ // Implementations for Object.
+
+ public boolean equals(Object object)
+ {
+ return this == object ||
+ super.equals(object) &&
+ ArrayUtil.equalOrNull(this.values, ((DetailedArrayReferenceValue)object).values);
+ }
+
+
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ ArrayUtil.hashCodeOrNull(values);
+ }
+
+
+ public String toString()
+ {
+ if (values == null)
+ {
+ return super.toString();
+ }
+
+ StringBuffer buffer = new StringBuffer(super.toString());
+
+ buffer.append('{');
+ for (int index = 0; index < values.length; index++)
+ {
+ buffer.append(values[index]);
+ buffer.append(index < values.length-1 ? ',' : '}');
+ }
+
+ return buffer.toString();
+ }
+} \ No newline at end of file
diff --git a/src/proguard/evaluation/value/DetailedValueFactory.java b/src/proguard/evaluation/value/DetailedValueFactory.java
new file mode 100644
index 0000000..d28b8ab
--- /dev/null
+++ b/src/proguard/evaluation/value/DetailedValueFactory.java
@@ -0,0 +1,48 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.*;
+
+/**
+ * This identified value factory creates array reference values that also
+ * represent their elements, in as far as possible.
+ *
+ * @author Eric Lafortune
+ */
+public class DetailedValueFactory
+extends IdentifiedValueFactory
+{
+ // Implementations for ReferenceValue.
+
+ public ReferenceValue createArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength)
+ {
+ return type == null ?
+ REFERENCE_VALUE_NULL :
+ new DetailedArrayReferenceValue(ClassConstants.TYPE_ARRAY + type,
+ referencedClass,
+ arrayLength,
+ this,
+ referenceID++);
+ }
+} \ No newline at end of file
diff --git a/src/proguard/evaluation/value/DoubleValue.java b/src/proguard/evaluation/value/DoubleValue.java
index 6630b2f..7587ed3 100644
--- a/src/proguard/evaluation/value/DoubleValue.java
+++ b/src/proguard/evaluation/value/DoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -354,6 +354,6 @@ public abstract class DoubleValue extends Category2Value
public final String internalType()
{
- return String.valueOf(ClassConstants.INTERNAL_TYPE_DOUBLE);
+ return String.valueOf(ClassConstants.TYPE_DOUBLE);
}
}
diff --git a/src/proguard/evaluation/value/FloatValue.java b/src/proguard/evaluation/value/FloatValue.java
index 6dc8bee..ce7806e 100644
--- a/src/proguard/evaluation/value/FloatValue.java
+++ b/src/proguard/evaluation/value/FloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -354,6 +354,6 @@ public abstract class FloatValue extends Category1Value
public final String internalType()
{
- return String.valueOf(ClassConstants.INTERNAL_TYPE_FLOAT);
+ return String.valueOf(ClassConstants.TYPE_FLOAT);
}
}
diff --git a/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java b/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java
new file mode 100644
index 0000000..3b597a1
--- /dev/null
+++ b/src/proguard/evaluation/value/IdentifiedArrayReferenceValue.java
@@ -0,0 +1,159 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.Clazz;
+
+/**
+ * This ArrayReferenceValue represents an array reference value that is
+ * identified by a unique ID.
+ *
+ * @author Eric Lafortune
+ */
+class IdentifiedArrayReferenceValue extends ArrayReferenceValue
+{
+ private final ValueFactory valuefactory;
+ private final int id;
+
+
+ /**
+ * Creates a new array reference value with the given ID.
+ */
+ public IdentifiedArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength,
+ ValueFactory valuefactory,
+ int id)
+ {
+ super(type, referencedClass, arrayLength);
+
+ this.valuefactory = valuefactory;
+ this.id = id;
+ }
+
+
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ return other.generalize(this);
+ }
+
+
+ public int equal(ReferenceValue other)
+ {
+ return other.equal(this);
+ }
+
+
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // ArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(ArrayReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(ArrayReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+//
+//
+ // Implementations of binary ReferenceValue methods with
+ // IdentifiedArrayReferenceValue arguments.
+
+// public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
+// {
+// return generalize((ArrayReferenceValue)other);
+// }
+
+
+ public int equal(IdentifiedArrayReferenceValue other)
+ {
+ return this.equals(other) ? ALWAYS :
+ this.equal((TypedReferenceValue)other);
+ }
+
+
+// // Implementations of binary ReferenceValue methods with
+// // DetailedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(DetailedArrayReferenceValue other)
+// {
+// return generalize((IdentifiedArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(DetailedArrayReferenceValue other)
+// {
+// return equal((IdentifiedArrayReferenceValue)other);
+// }
+
+
+ // Implementations for Value.
+
+ public boolean isSpecific()
+ {
+ return true;
+ }
+
+
+ // Implementations for Object.
+
+ public boolean equals(Object object)
+ {
+ return this == object ||
+ super.equals(object) &&
+ this.valuefactory.equals(((IdentifiedArrayReferenceValue)object).valuefactory) &&
+ this.id == ((IdentifiedArrayReferenceValue)object).id;
+ }
+
+
+ public int hashCode()
+ {
+ return super.hashCode() ^
+ valuefactory.hashCode() ^
+ id;
+ }
+
+
+ public String toString()
+ {
+ return super.toString() + '#' + id;
+ }
+} \ No newline at end of file
diff --git a/src/proguard/evaluation/value/IdentifiedDoubleValue.java b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
index 4ff2466..6740a2c 100644
--- a/src/proguard/evaluation/value/IdentifiedDoubleValue.java
+++ b/src/proguard/evaluation/value/IdentifiedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedFloatValue.java b/src/proguard/evaluation/value/IdentifiedFloatValue.java
index c8349bc..62e4b2b 100644
--- a/src/proguard/evaluation/value/IdentifiedFloatValue.java
+++ b/src/proguard/evaluation/value/IdentifiedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedIntegerValue.java b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
index 6c3ee5d..ac1d033 100644
--- a/src/proguard/evaluation/value/IdentifiedIntegerValue.java
+++ b/src/proguard/evaluation/value/IdentifiedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedLongValue.java b/src/proguard/evaluation/value/IdentifiedLongValue.java
index e0b68f2..b670ae6 100644
--- a/src/proguard/evaluation/value/IdentifiedLongValue.java
+++ b/src/proguard/evaluation/value/IdentifiedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/IdentifiedReferenceValue.java b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
index 5cfbd60..7f0196b 100644
--- a/src/proguard/evaluation/value/IdentifiedReferenceValue.java
+++ b/src/proguard/evaluation/value/IdentifiedReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -23,18 +23,19 @@ package proguard.evaluation.value;
import proguard.classfile.Clazz;
/**
- * This LongValue represents a reference value that is identified by a unique ID.
+ * This TypedReferenceValue represents a reference value that is identified by a
+ * unique ID.
*
* @author Eric Lafortune
*/
-final class IdentifiedReferenceValue extends ReferenceValue
+class IdentifiedReferenceValue extends TypedReferenceValue
{
private final ValueFactory valuefactory;
private final int id;
/**
- * Creates a new long value with the given ID.
+ * Creates a new reference value with the given ID.
*/
public IdentifiedReferenceValue(String type,
Clazz referencedClass,
@@ -49,25 +50,81 @@ final class IdentifiedReferenceValue extends ReferenceValue
}
- // Implementations for ReferenceValue.
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ return other.generalize(this);
+ }
+
public int equal(ReferenceValue other)
{
- return this.equals(other) ? ALWAYS : MAYBE;
+ return other.equal(this);
}
- // Implementations of binary methods of ReferenceValue.
+ // Implementations of binary ReferenceValue methods with
+ // IdentifiedReferenceValue arguments.
- public ReferenceValue generalize(ReferenceValue other)
+// public ReferenceValue generalize(IdentifiedReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+
+
+ public int equal(IdentifiedReferenceValue other)
{
- // Remove the ID if both values don't share the same ID.
- return this.equals(other) ?
- this :
- new ReferenceValue(type, referencedClass, mayBeNull).generalize(other);
+ return this.equals(other) ? ALWAYS :
+ this.equal((TypedReferenceValue)other);
}
+// // Implementations of binary ReferenceValue methods with
+// // ArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(ArrayReferenceValue other)
+// {
+// return generalize((TypedReferenceValue)other);
+// }
+//
+//
+// public int equal(ArrayReferenceValue other)
+// {
+// return equal((TypedReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // IdentifiedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
+// {
+// return generalize((ArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(IdentifiedArrayReferenceValue other)
+// {
+// return equal((ArrayReferenceValue)other);
+// }
+//
+//
+// // Implementations of binary ReferenceValue methods with
+// // DetailedArrayReferenceValue arguments.
+//
+// public ReferenceValue generalize(DetailedArrayReferenceValue other)
+// {
+// return generalize((IdentifiedArrayReferenceValue)other);
+// }
+//
+//
+// public int equal(DetailedArrayReferenceValue other)
+// {
+// return equal((IdentifiedArrayReferenceValue)other);
+// }
+
+
// Implementations for Value.
public boolean isSpecific()
diff --git a/src/proguard/evaluation/value/IdentifiedValueFactory.java b/src/proguard/evaluation/value/IdentifiedValueFactory.java
index be5c885..6bd1d5d 100644
--- a/src/proguard/evaluation/value/IdentifiedValueFactory.java
+++ b/src/proguard/evaluation/value/IdentifiedValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -21,21 +21,20 @@
package proguard.evaluation.value;
import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
/**
- * This class provides methods to create and reuse IntegerValue objects.
+ * This particular value factory attaches a unique ID to any unknown values.
*
* @author Eric Lafortune
*/
public class IdentifiedValueFactory
-extends SpecificValueFactory
+extends ParticularValueFactory
{
- private int integerID;
- private int longID;
- private int floatID;
- private int doubleID;
- private int referenceID;
+ protected int integerID;
+ protected int longID;
+ protected int floatID;
+ protected int doubleID;
+ protected int referenceID;
// Implementations for ValueFactory.
@@ -70,6 +69,24 @@ extends SpecificValueFactory
{
return type == null ?
REFERENCE_VALUE_NULL :
- new IdentifiedReferenceValue(type, referencedClass, mayBeNull, this, referenceID++);
+ new IdentifiedReferenceValue(type,
+ referencedClass,
+ mayBeNull,
+ this,
+ referenceID++);
+ }
+
+
+ public ReferenceValue createArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength)
+ {
+ return type == null ?
+ REFERENCE_VALUE_NULL :
+ new IdentifiedArrayReferenceValue(ClassConstants.TYPE_ARRAY + type,
+ referencedClass,
+ arrayLength,
+ this,
+ referenceID++);
}
} \ No newline at end of file
diff --git a/src/proguard/evaluation/value/InitialValueFactory.java b/src/proguard/evaluation/value/InitialValueFactory.java
new file mode 100644
index 0000000..4b2cf29
--- /dev/null
+++ b/src/proguard/evaluation/value/InitialValueFactory.java
@@ -0,0 +1,79 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.ClassConstants;
+
+/**
+ * This value factory creates initial values for fields and array elements,
+ * with the help of a given value factory. Note that this class itself doesn't
+ * implement ValueFactory.
+ *
+ * @author Eric Lafortune
+ */
+public class InitialValueFactory
+{
+ private final ValueFactory valueFactory;
+
+
+ /**
+ * Creates a new InitialValueFactory.
+ * @param valueFactory the value factory that will actually create the
+ * values.
+ */
+ public InitialValueFactory(ValueFactory valueFactory)
+ {
+ this.valueFactory = valueFactory;
+ }
+
+
+ /**
+ * Creates an initial value (0, 0L, 0.0f, 0.0, null) of the given type.
+ */
+ public Value createValue(String type)
+ {
+ switch (type.charAt(0))
+ {
+ case ClassConstants.TYPE_BOOLEAN:
+ case ClassConstants.TYPE_BYTE:
+ case ClassConstants.TYPE_CHAR:
+ case ClassConstants.TYPE_SHORT:
+ case ClassConstants.TYPE_INT:
+ return valueFactory.createIntegerValue(0);
+
+ case ClassConstants.TYPE_LONG:
+ return valueFactory.createLongValue(0L);
+
+ case ClassConstants.TYPE_FLOAT:
+ return valueFactory.createFloatValue(0.0f);
+
+ case ClassConstants.TYPE_DOUBLE:
+ return valueFactory.createDoubleValue(0.0);
+
+ case ClassConstants.TYPE_CLASS_START:
+ case ClassConstants.TYPE_ARRAY:
+ return valueFactory.createReferenceValueNull();
+
+ default:
+ throw new IllegalArgumentException("Invalid type ["+type+"]");
+ }
+ }
+}
diff --git a/src/proguard/evaluation/value/InstructionOffsetValue.java b/src/proguard/evaluation/value/InstructionOffsetValue.java
index 07a44ee..7cb953e 100644
--- a/src/proguard/evaluation/value/InstructionOffsetValue.java
+++ b/src/proguard/evaluation/value/InstructionOffsetValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -143,60 +143,73 @@ public class InstructionOffsetValue extends Category1Value
*/
public final Value generalize(InstructionOffsetValue other)
{
- // If the values array of either is null, return the other one.
- if (this.values == null)
+ // If the values array of either is null, we can return the other one.
+ int[] thisValues = this.values;
+ if (thisValues == null)
{
return other;
}
- if (other.values == null)
+ int[] otherValues = other.values;
+ if (otherValues == null)
{
return this;
}
// Compute the length of the union of the arrays.
- int newLength = this.values.length;
- for (int index = 0; index < other.values.length; index++)
+ int newLength = thisValues.length;
+ for (int index = 0; index < otherValues.length; index++)
{
- if (!this.contains(other.values[index]))
+ if (!this.contains(otherValues[index]))
{
newLength++;
}
}
- // If the length of the union array is equal to the length of the values
- // array of either, return it.
- if (newLength == other.values.length)
+ // If the length of the union array is equal to the length of the other
+ // values array, we can return it.
+ if (newLength == otherValues.length)
{
return other;
}
- // The ordering of the this array may not be right, so we can't just
- // use it.
- //if (newLength == this.values.length)
- //{
- // return this;
- //}
+ // If the length of the union array is equal to the length of this
+ // values array, we can return it. We have to make sure that the other
+ // values are at the end. We'll just test one special case, with a
+ // single other value.
+ if (newLength == this.values.length &&
+ otherValues.length == 1 &&
+ thisValues[thisValues.length-1] == otherValues[0])
+ {
+ return this;
+ }
// Create the union array.
+ int newIndex = 0;
int[] newValues = new int[newLength];
- int newIndex = 0;
+ // Is the length of the union array is equal to the sum of the lengths?
+ if (newLength == thisValues.length + otherValues.length)
+ {
+ // We can just copy all values, because they are unique.
+ System.arraycopy(thisValues, 0, newValues, 0, thisValues.length);
- // Copy the values that are different from the other array.
- for (int index = 0; index < this.values.length; index++)
+ newIndex = thisValues.length;
+ }
+ else
{
- if (!other.contains(this.values[index]))
+ // Copy the values that are different from the other array.
+ for (int index = 0; index < thisValues.length; index++)
{
- newValues[newIndex++] = this.values[index];
+ if (!other.contains(thisValues[index]))
+ {
+ newValues[newIndex++] = thisValues[index];
+ }
}
}
// Copy the values from the other array.
- for (int index = 0; index < other.values.length; index++)
- {
- newValues[newIndex++] = other.values[index];
- }
+ System.arraycopy(otherValues, 0, newValues, newIndex, otherValues.length);
return new InstructionOffsetValue(newValues);
}
@@ -231,7 +244,7 @@ public class InstructionOffsetValue extends Category1Value
public final String internalType()
{
- return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
+ return String.valueOf(ClassConstants.TYPE_INT);
}
diff --git a/src/proguard/evaluation/value/IntegerValue.java b/src/proguard/evaluation/value/IntegerValue.java
index b1824c6..148c0ea 100644
--- a/src/proguard/evaluation/value/IntegerValue.java
+++ b/src/proguard/evaluation/value/IntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -997,6 +997,6 @@ public abstract class IntegerValue extends Category1Value
public final String internalType()
{
- return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
+ return String.valueOf(ClassConstants.TYPE_INT);
}
}
diff --git a/src/proguard/evaluation/value/LongValue.java b/src/proguard/evaluation/value/LongValue.java
index e23c13c..e8f9e12 100644
--- a/src/proguard/evaluation/value/LongValue.java
+++ b/src/proguard/evaluation/value/LongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -549,6 +549,6 @@ public abstract class LongValue extends Category2Value
public final String internalType()
{
- return String.valueOf(ClassConstants.INTERNAL_TYPE_INT);
+ return String.valueOf(ClassConstants.TYPE_INT);
}
}
diff --git a/src/proguard/evaluation/value/NegatedDoubleValue.java b/src/proguard/evaluation/value/NegatedDoubleValue.java
index 7619be7..25de608 100644
--- a/src/proguard/evaluation/value/NegatedDoubleValue.java
+++ b/src/proguard/evaluation/value/NegatedDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedFloatValue.java b/src/proguard/evaluation/value/NegatedFloatValue.java
index 51b5074..7a05579 100644
--- a/src/proguard/evaluation/value/NegatedFloatValue.java
+++ b/src/proguard/evaluation/value/NegatedFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedIntegerValue.java b/src/proguard/evaluation/value/NegatedIntegerValue.java
index 1729083..cbbabdd 100644
--- a/src/proguard/evaluation/value/NegatedIntegerValue.java
+++ b/src/proguard/evaluation/value/NegatedIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/NegatedLongValue.java b/src/proguard/evaluation/value/NegatedLongValue.java
index 7510524..bb9f729 100644
--- a/src/proguard/evaluation/value/NegatedLongValue.java
+++ b/src/proguard/evaluation/value/NegatedLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ParticularDoubleValue.java b/src/proguard/evaluation/value/ParticularDoubleValue.java
index e8c5aa7..d97eb5f 100644
--- a/src/proguard/evaluation/value/ParticularDoubleValue.java
+++ b/src/proguard/evaluation/value/ParticularDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -182,9 +182,9 @@ final class ParticularDoubleValue extends SpecificDoubleValue
public IntegerValue compare(ParticularDoubleValue other)
{
- return this.value < other.value ? SpecificValueFactory.INTEGER_VALUE_M1 :
- this.value == other.value ? SpecificValueFactory.INTEGER_VALUE_0 :
- SpecificValueFactory.INTEGER_VALUE_1;
+ return this.value < other.value ? ParticularValueFactory.INTEGER_VALUE_M1 :
+ this.value == other.value ? ParticularValueFactory.INTEGER_VALUE_0 :
+ ParticularValueFactory.INTEGER_VALUE_1;
}
diff --git a/src/proguard/evaluation/value/ParticularFloatValue.java b/src/proguard/evaluation/value/ParticularFloatValue.java
index cbdde31..9084b36 100644
--- a/src/proguard/evaluation/value/ParticularFloatValue.java
+++ b/src/proguard/evaluation/value/ParticularFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -182,9 +182,9 @@ final class ParticularFloatValue extends SpecificFloatValue
public IntegerValue compare(ParticularFloatValue other)
{
- return this.value < other.value ? SpecificValueFactory.INTEGER_VALUE_M1 :
- this.value == other.value ? SpecificValueFactory.INTEGER_VALUE_0 :
- SpecificValueFactory.INTEGER_VALUE_1;
+ return this.value < other.value ? ParticularValueFactory.INTEGER_VALUE_M1 :
+ this.value == other.value ? ParticularValueFactory.INTEGER_VALUE_0 :
+ ParticularValueFactory.INTEGER_VALUE_1;
}
diff --git a/src/proguard/evaluation/value/ParticularIntegerValue.java b/src/proguard/evaluation/value/ParticularIntegerValue.java
index 609e95f..86f8a22 100644
--- a/src/proguard/evaluation/value/ParticularIntegerValue.java
+++ b/src/proguard/evaluation/value/ParticularIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/ParticularLongValue.java b/src/proguard/evaluation/value/ParticularLongValue.java
index 1903235..7e7cc20 100644
--- a/src/proguard/evaluation/value/ParticularLongValue.java
+++ b/src/proguard/evaluation/value/ParticularLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/SpecificValueFactory.java b/src/proguard/evaluation/value/ParticularValueFactory.java
index f761938..f28c10e 100644
--- a/src/proguard/evaluation/value/SpecificValueFactory.java
+++ b/src/proguard/evaluation/value/ParticularValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -20,12 +20,14 @@
*/
package proguard.evaluation.value;
+import proguard.classfile.*;
+
/**
- * This class provides methods to create and reuse IntegerValue objects.
+ * This value factory creates particular values.
*
* @author Eric Lafortune
*/
-public class SpecificValueFactory
+public class ParticularValueFactory
extends ValueFactory
{
// Shared copies of Value objects, to avoid creating a lot of objects.
@@ -69,9 +71,9 @@ extends ValueFactory
public LongValue createLongValue(long value)
{
- return value == 0 ? LONG_VALUE_0 :
- value == 1 ? LONG_VALUE_1 :
- new ParticularLongValue(value);
+ return value == 0L ? LONG_VALUE_0 :
+ value == 1L ? LONG_VALUE_1 :
+ new ParticularLongValue(value);
}
@@ -94,4 +96,16 @@ extends ValueFactory
value == 1.0 ? DOUBLE_VALUE_1 :
new ParticularDoubleValue(value);
}
+
+
+ public ReferenceValue createArrayReferenceValue(String type,
+ Clazz referencedClass,
+ IntegerValue arrayLength)
+ {
+ return type == null ?
+ REFERENCE_VALUE_NULL :
+ new ArrayReferenceValue(ClassConstants.TYPE_ARRAY + type,
+ referencedClass,
+ arrayLength);
+ }
}
diff --git a/src/proguard/evaluation/value/ReferenceValue.java b/src/proguard/evaluation/value/ReferenceValue.java
index 4a52e82..1f87382 100644
--- a/src/proguard/evaluation/value/ReferenceValue.java
+++ b/src/proguard/evaluation/value/ReferenceValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -20,191 +20,110 @@
*/
package proguard.evaluation.value;
-import proguard.classfile.*;
-import proguard.classfile.util.ClassUtil;
-import proguard.classfile.visitor.ClassCollector;
-
-import java.util.*;
+import proguard.classfile.Clazz;
/**
- * This class represents a partially evaluated reference value. It has a type
- * and a flag that indicates whether the value could be <code>null</code>. If
- * the type is <code>null</code>, the value is <code>null</code>.
+ * This class represents a partially evaluated reference value.
*
* @author Eric Lafortune
*/
-public class ReferenceValue extends Category1Value
+public abstract class ReferenceValue extends Category1Value
{
- private static final boolean DEBUG = false;
+ /**
+ * Returns the type.
+ */
+ public abstract String getType();
+;
+ /**
+ * Returns the class that is referenced by the type.
+ */
+ public abstract Clazz getReferencedClass();
- protected final String type;
- protected final Clazz referencedClass;
- protected final boolean mayBeNull;
+ // Basic unary methods.
/**
- * Creates a new ReferenceValue.
+ * Returns whether the type is <code>null</code>.
*/
- public ReferenceValue(String type,
- Clazz referencedClass,
- boolean mayBeNull)
- {
- this.type = type;
- this.referencedClass = referencedClass;
- this.mayBeNull = mayBeNull;
- }
+ public abstract int isNull();
/**
- * Returns the type.
+ * Returns whether the type is an instance of the given type.
+ */
+ public abstract int instanceOf(String otherType, Clazz otherReferencedClass);
+
+
+ /**
+ * Returns a generalization of this ReferenceValue that may be null,
+ * depending on the flag.
+ */
+ public abstract ReferenceValue generalizeMayBeNull(boolean mayBeNull);
+
+
+ /**
+ * Returns the length of the array, assuming this type is an array.
*/
- public String getType()
+ public IntegerValue arrayLength(ValueFactory valueFactory)
{
- return type;
+ return valueFactory.createIntegerValue();
}
/**
- * Returns the class that is referenced by the type.
+ * Returns the value of the array at the given index, assuming this type
+ * is an integer array.
*/
- public Clazz getReferencedClass()
+ public IntegerValue integerArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
{
- return referencedClass;
+ return valueFactory.createIntegerValue();
}
- // Basic unary methods.
-
/**
- * Returns whether the type is <code>null</code>.
+ * Returns the value of the array at the given index, assuming this type
+ * is an long array.
*/
- public int isNull()
+ public LongValue longArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
{
- return type == null ? ALWAYS :
- mayBeNull ? MAYBE :
- NEVER;
+ return valueFactory.createLongValue();
}
/**
- * Returns whether the type is an instance of the given type.
+ * Returns the value of the array at the given index, assuming this type
+ * is an float array.
*/
- public int instanceOf(String otherType, Clazz otherReferencedClass)
+ public FloatValue floatArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
{
- String thisType = this.type;
-
- // If this type is null, it is never an instance of any class.
- if (thisType == null)
- {
- return NEVER;
- }
-
- // Start taking into account the type dimensions.
- int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
- int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
- int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
-
- // Strip any common array prefixes.
- thisType = thisType.substring(commonDimensionCount);
- otherType = otherType.substring(commonDimensionCount);
-
- // If either stripped type is a primitive type, we can tell right away.
- if (commonDimensionCount > 0 &&
- (ClassUtil.isInternalPrimitiveType(thisType.charAt(0)) ||
- ClassUtil.isInternalPrimitiveType(otherType.charAt(0))))
- {
- return !thisType.equals(otherType) ? NEVER :
- mayBeNull ? MAYBE :
- ALWAYS;
- }
-
- // Strip the class type prefix and suffix of this type, if any.
- if (thisDimensionCount == commonDimensionCount)
- {
- thisType = ClassUtil.internalClassNameFromClassType(thisType);
- }
-
- // Strip the class type prefix and suffix of the other type, if any.
- if (otherDimensionCount == commonDimensionCount)
- {
- otherType = ClassUtil.internalClassNameFromClassType(otherType);
- }
-
- // If this type is an array type, and the other type is not
- // java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
- // this type can never be an instance.
- if (thisDimensionCount > otherDimensionCount &&
- !ClassUtil.isInternalArrayInterfaceName(otherType))
- {
- return NEVER;
- }
-
- // If the other type is an array type, and this type is not
- // java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
- // this type can never be an instance.
- if (thisDimensionCount < otherDimensionCount &&
- !ClassUtil.isInternalArrayInterfaceName(thisType))
- {
- return NEVER;
- }
-
- // If this type may be null, it might not be an instance of any class.
- if (mayBeNull)
- {
- return MAYBE;
- }
-
- // If this type is equal to the other type, or if the other type is
- // java.lang.Object, this type is always an instance.
- if (thisType.equals(otherType) ||
- ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT.equals(otherType))
- {
- return ALWAYS;
- }
-
- // If this type is an array type, it's ok.
- if (thisDimensionCount > otherDimensionCount)
- {
- return ALWAYS;
- }
-
- // If the other type is an array type, it might be ok.
- if (thisDimensionCount < otherDimensionCount)
- {
- return MAYBE;
- }
-
- // If the value extends the type, we're sure.
- return referencedClass != null &&
- otherReferencedClass != null &&
- referencedClass.extendsOrImplements(otherReferencedClass) ?
- ALWAYS :
- MAYBE;
+ return valueFactory.createFloatValue();
}
/**
- * Returns the length of the array, assuming this type is an array.
+ * Returns the value of the array at the given index, assuming this type
+ * is an double array.
*/
- public IntegerValue arrayLength(ValueFactory valueFactory)
+ public DoubleValue doubleArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
{
- return valueFactory.createIntegerValue();
+ return valueFactory.createDoubleValue();
}
/**
* Returns the value of the array at the given index, assuming this type
- * is an array.
+ * is a reference array.
+ */
+ public abstract ReferenceValue referenceArrayLoad(IntegerValue indexValue, ValueFactory valueFactory);
+
+
+ /**
+ * Stores the given value at the given index in the given array, assuming
+ * this type is an array.
*/
- public Value arrayLoad(IntegerValue integerValue, ValueFactory valueFactory)
+ public void arrayStore(IntegerValue indexValue, Value value)
{
- return
- type == null ? ValueFactory.REFERENCE_VALUE_NULL :
- !ClassUtil.isInternalArrayType(type) ? ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
- valueFactory.createValue(type.substring(1),
- referencedClass,
- true);
}
@@ -214,327 +133,173 @@ public class ReferenceValue extends Category1Value
* Returns the generalization of this ReferenceValue and the given other
* ReferenceValue.
*/
- public ReferenceValue generalize(ReferenceValue other)
+ public abstract ReferenceValue generalize(ReferenceValue other);
+
+
+ /**
+ * Returns whether this ReferenceValue is equal to the given other
+ * ReferenceValue.
+ * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
+ */
+ public abstract int equal(ReferenceValue other);
+
+
+ // Derived unary methods.
+
+ /**
+ * Returns whether this ReferenceValue is not <code>null</code>.
+ * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
+ */
+ public final int isNotNull()
{
- // If both types are identical, the generalization is the same too.
- if (this.equals(other))
- {
- return this;
- }
-
- String thisType = this.type;
- String otherType = other.type;
-
- // If both types are nul, the generalization is null too.
- if (thisType == null && otherType == null)
- {
- return ValueFactory.REFERENCE_VALUE_NULL;
- }
-
- // If this type is null, the generalization is the other type, maybe null.
- if (thisType == null)
- {
- return other.generalizeMayBeNull(true);
- }
-
- // If the other type is null, the generalization is this type, maybe null.
- if (otherType == null)
- {
- return this.generalizeMayBeNull(true);
- }
-
- boolean mayBeNull = this.mayBeNull || other.mayBeNull;
-
- // If the two types are equal, the generalization remains the same, maybe null.
- if (thisType.equals(otherType))
- {
- return this.generalizeMayBeNull(mayBeNull);
- }
-
- // Start taking into account the type dimensions.
- int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
- int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
- int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
-
- if (thisDimensionCount == otherDimensionCount)
- {
- // See if we can take into account the referenced classes.
- Clazz thisReferencedClass = this.referencedClass;
- Clazz otherReferencedClass = other.referencedClass;
-
- if (thisReferencedClass != null &&
- otherReferencedClass != null)
- {
- if (thisReferencedClass.extendsOrImplements(otherReferencedClass))
- {
- return other.generalizeMayBeNull(mayBeNull);
- }
-
- if (otherReferencedClass.extendsOrImplements(thisReferencedClass))
- {
- return this.generalizeMayBeNull(mayBeNull);
- }
-
- // Collect the superclasses and interfaces of this class.
- Set thisSuperClasses = new HashSet();
- thisReferencedClass.hierarchyAccept(false, true, true, false,
- new ClassCollector(thisSuperClasses));
-
- int thisSuperClassesCount = thisSuperClasses.size();
- if (thisSuperClassesCount == 0 &&
- thisReferencedClass.getSuperName() != null)
- {
- throw new IllegalArgumentException("Can't find any super classes of ["+thisType+"] (not even immediate super class ["+thisReferencedClass.getSuperName()+"])");
- }
-
- // Collect the superclasses and interfaces of the other class.
- Set otherSuperClasses = new HashSet();
- otherReferencedClass.hierarchyAccept(false, true, true, false,
- new ClassCollector(otherSuperClasses));
-
- int otherSuperClassesCount = otherSuperClasses.size();
- if (otherSuperClassesCount == 0 &&
- otherReferencedClass.getSuperName() != null)
- {
- throw new IllegalArgumentException("Can't find any super classes of ["+otherType+"] (not even immediate super class ["+otherReferencedClass.getSuperName()+"])");
- }
-
- if (DEBUG)
- {
- System.out.println("ReferenceValue.generalize this ["+thisReferencedClass.getName()+"] with other ["+otherReferencedClass.getName()+"]");
- System.out.println(" This super classes: "+thisSuperClasses);
- System.out.println(" Other super classes: "+otherSuperClasses);
- }
-
- // Find the common superclasses.
- thisSuperClasses.retainAll(otherSuperClasses);
-
- if (DEBUG)
- {
- System.out.println(" Common super classes: "+thisSuperClasses);
- }
-
- // Find a class that is a subclass of all common superclasses,
- // or that at least has the maximum number of common superclasses.
- Clazz commonClass = null;
-
- int maximumSuperClassCount = -1;
-
- // Go over all common superclasses to find it. In case of
- // multiple subclasses, keep the lowest one alphabetically,
- // in order to ensure that the choice is deterministic.
- Iterator commonSuperClasses = thisSuperClasses.iterator();
- while (commonSuperClasses.hasNext())
- {
- Clazz commonSuperClass = (Clazz)commonSuperClasses.next();
-
- int superClassCount = superClassCount(commonSuperClass, thisSuperClasses);
- if (maximumSuperClassCount < superClassCount ||
- (maximumSuperClassCount == superClassCount &&
- commonClass != null &&
- commonClass.getName().compareTo(commonSuperClass.getName()) > 0))
- {
- commonClass = commonSuperClass;
- maximumSuperClassCount = superClassCount;
- }
- }
-
- if (commonClass == null)
- {
- throw new IllegalArgumentException("Can't find common super class of ["+
- thisType +"] (with "+thisSuperClassesCount +" known super classes) and ["+
- otherType+"] (with "+otherSuperClassesCount+" known super classes)");
- }
-
- if (DEBUG)
- {
- System.out.println(" Best common class: ["+commonClass.getName()+"]");
- }
-
- // TODO: Handle more difficult cases, with multiple global subclasses.
-
- return new ReferenceValue(commonDimensionCount == 0 ?
- commonClass.getName() :
- ClassUtil.internalArrayTypeFromClassName(commonClass.getName(),
- commonDimensionCount),
- commonClass,
- mayBeNull);
- }
- }
- else if (thisDimensionCount > otherDimensionCount)
- {
- // See if the other type is an interface type of arrays.
- if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(otherType)))
- {
- return other.generalizeMayBeNull(mayBeNull);
- }
- }
- else if (thisDimensionCount < otherDimensionCount)
- {
- // See if this type is an interface type of arrays.
- if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(thisType)))
- {
- return this.generalizeMayBeNull(mayBeNull);
- }
- }
-
- // Reduce the common dimension count if either type is an array of
- // primitives type of this dimension.
- if (commonDimensionCount > 0 &&
- (ClassUtil.isInternalPrimitiveType(otherType.charAt(commonDimensionCount))) ||
- ClassUtil.isInternalPrimitiveType(thisType.charAt(commonDimensionCount)))
- {
- commonDimensionCount--;
- }
-
- // Fall back on a basic Object or array of Objects type.
- return commonDimensionCount == 0 ?
- mayBeNull ?
- ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
- ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL :
- new ReferenceValue(ClassUtil.internalArrayTypeFromClassName(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT,
- commonDimensionCount),
- null,
- mayBeNull);
+ return -isNull();
}
+ // Derived binary methods.
+
/**
- * Returns if the number of superclasses of the given class in the given
- * set of classes.
+ * Returns whether this ReferenceValue and the given ReferenceValue are different.
+ * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
*/
- private int superClassCount(Clazz subClass, Set classes)
+ public final int notEqual(ReferenceValue other)
{
- int count = 0;
+ return -equal(other);
+ }
- Iterator iterator = classes.iterator();
- while (iterator.hasNext())
- {
- Clazz clazz = (Clazz)iterator.next();
- if (subClass.extendsOrImplements(clazz))
- {
- count++;
- }
- }
+ // Similar binary methods, but this time with typed reference arguments.
- return count;
+ /**
+ * Returns the generalization of this ReferenceValue and the given other
+ * TypedReferenceValue.
+ */
+ public ReferenceValue generalize(TypedReferenceValue other)
+ {
+ return generalize((ReferenceValue)other);
}
/**
* Returns whether this ReferenceValue is equal to the given other
- * ReferenceValue.
+ * TypedReferenceValue.
* @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
*/
- public int equal(ReferenceValue other)
+ public int equal(TypedReferenceValue other)
{
- return this.type == null && other.type == null ? ALWAYS : MAYBE;
+ return equal((ReferenceValue)other);
}
- // Derived unary methods.
+ // Similar binary methods, but this time with identified reference
+ // arguments.
/**
- * Returns whether this ReferenceValue is not <code>null</code>.
+ * Returns the generalization of this ReferenceValue and the given other
+ * IdentifiedReferenceValue.
+ */
+ public ReferenceValue generalize(IdentifiedReferenceValue other)
+ {
+ return generalize((TypedReferenceValue)other);
+ }
+
+
+ /**
+ * Returns whether this ReferenceValue is equal to the given other
+ * IdentifiedReferenceValue.
* @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
*/
- public final int isNotNull()
+ public int equal(IdentifiedReferenceValue other)
{
- return -isNull();
+ return equal((TypedReferenceValue)other);
}
+ // Similar binary methods, but this time with array reference arguments.
+
/**
* Returns the generalization of this ReferenceValue and the given other
- * ReferenceValue.
+ * ArrayReferenceValue.
*/
- private ReferenceValue generalizeMayBeNull(boolean mayBeNull)
+ public ReferenceValue generalize(ArrayReferenceValue other)
{
- return this.mayBeNull || !mayBeNull ?
- this :
- new ReferenceValue(this.type, this.referencedClass, true);
+ return generalize((TypedReferenceValue)other);
}
- // Derived binary methods.
-
/**
- * Returns whether this ReferenceValue and the given ReferenceValue are different.
+ * Returns whether this ReferenceValue is equal to the given other
+ * ArrayReferenceValue.
* @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
*/
- public final int notEqual(ReferenceValue other)
+ public int equal(ArrayReferenceValue other)
{
- return -equal(other);
+ return equal((TypedReferenceValue)other);
}
- // Implementations for Value.
+ // Similar binary methods, but this time with identified array reference
+ // arguments.
- public final ReferenceValue referenceValue()
+ /**
+ * Returns the generalization of this ReferenceValue and the given other
+ * IdentifiedArrayReferenceValue.
+ */
+ public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
{
- return this;
+ return generalize((ArrayReferenceValue)other);
}
- public final Value generalize(Value other)
- {
- return this.generalize(other.referenceValue());
- }
- public boolean isParticular()
+ /**
+ * Returns whether this ReferenceValue is equal to the given other
+ * IdentifiedArrayReferenceValue.
+ * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
+ */
+ public int equal(IdentifiedArrayReferenceValue other)
{
- return type == null;
+ return equal((ArrayReferenceValue)other);
}
- public final int computationalType()
+
+ // Similar binary methods, but this time with detailed array reference
+ // arguments.
+
+ /**
+ * Returns the generalization of this ReferenceValue and the given other
+ * DetailedArrayReferenceValue.
+ */
+ public ReferenceValue generalize(DetailedArrayReferenceValue other)
{
- return TYPE_REFERENCE;
+ return generalize((IdentifiedArrayReferenceValue)other);
}
- public final String internalType()
+
+ /**
+ * Returns whether this ReferenceValue is equal to the given other
+ * DetailedArrayReferenceValue.
+ * @return <code>NEVER</code>, <code>MAYBE</code>, or <code>ALWAYS</code>.
+ */
+ public int equal(DetailedArrayReferenceValue other)
{
- return
- type == null ? ClassConstants.INTERNAL_TYPE_JAVA_LANG_OBJECT :
- ClassUtil.isInternalArrayType(type) ? type :
- ClassConstants.INTERNAL_TYPE_CLASS_START +
- type +
- ClassConstants.INTERNAL_TYPE_CLASS_END;
+ return equal((IdentifiedArrayReferenceValue)other);
}
- // Implementations for Object.
+ // Implementations for Value.
- public boolean equals(Object object)
+ public final ReferenceValue referenceValue()
{
- if (this == object)
- {
- return true;
- }
-
- if (object == null ||
- this.getClass() != object.getClass())
- {
- return false;
- }
-
- ReferenceValue other = (ReferenceValue)object;
- return this.type == null ? other.type == null :
- (this.mayBeNull == other.mayBeNull &&
- this.type.equals(other.type));
+ return this;
}
-
- public int hashCode()
+ public final Value generalize(Value other)
{
- return this.getClass().hashCode() ^
- (type == null ? 0 : type.hashCode() ^ (mayBeNull ? 0 : 1));
+ return this.generalize(other.referenceValue());
}
-
- public String toString()
+ public final int computationalType()
{
- return type == null ?
- "null" :
- type + (referencedClass == null ? "?" : "") + (mayBeNull ? "" : "!");
+ return TYPE_REFERENCE;
}
}
diff --git a/src/proguard/evaluation/value/SpecificDoubleValue.java b/src/proguard/evaluation/value/SpecificDoubleValue.java
index 644f553..5ee2db2 100644
--- a/src/proguard/evaluation/value/SpecificDoubleValue.java
+++ b/src/proguard/evaluation/value/SpecificDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -157,7 +157,7 @@ abstract class SpecificDoubleValue extends DoubleValue
// Not handling NaN properly.
//return this.equals(other) ?
- // SpecificValueFactory.INTEGER_VALUE_0 :
+ // ParticularValueFactory.INTEGER_VALUE_0 :
// new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificFloatValue.java b/src/proguard/evaluation/value/SpecificFloatValue.java
index d88baa3..66e245a 100644
--- a/src/proguard/evaluation/value/SpecificFloatValue.java
+++ b/src/proguard/evaluation/value/SpecificFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -157,7 +157,7 @@ abstract class SpecificFloatValue extends FloatValue
// Not handling NaN properly.
//return this.equals(other) ?
- // SpecificValueFactory.INTEGER_VALUE_0 :
+ // ParticularValueFactory.INTEGER_VALUE_0 :
// new ComparisonValue(this, other);
}
diff --git a/src/proguard/evaluation/value/SpecificIntegerValue.java b/src/proguard/evaluation/value/SpecificIntegerValue.java
index 81f8646..352e385 100644
--- a/src/proguard/evaluation/value/SpecificIntegerValue.java
+++ b/src/proguard/evaluation/value/SpecificIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -208,14 +208,14 @@ abstract class SpecificIntegerValue extends IntegerValue
public IntegerValue subtract(SpecificIntegerValue other)
{
return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
+ ParticularValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(this, CompositeIntegerValue.SUBTRACT, other);
}
public IntegerValue subtractFrom(SpecificIntegerValue other)
{
return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
+ ParticularValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(other, CompositeIntegerValue.SUBTRACT, this);
}
@@ -310,7 +310,7 @@ abstract class SpecificIntegerValue extends IntegerValue
public IntegerValue xor(SpecificIntegerValue other)
{
return this.equals(other) ?
- SpecificValueFactory.INTEGER_VALUE_0 :
+ ParticularValueFactory.INTEGER_VALUE_0 :
new CompositeIntegerValue(other, CompositeIntegerValue.XOR, this);
}
diff --git a/src/proguard/evaluation/value/SpecificLongValue.java b/src/proguard/evaluation/value/SpecificLongValue.java
index 15138b4..162f9fe 100644
--- a/src/proguard/evaluation/value/SpecificLongValue.java
+++ b/src/proguard/evaluation/value/SpecificLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -153,14 +153,14 @@ abstract class SpecificLongValue extends LongValue
public LongValue subtract(SpecificLongValue other)
{
return this.equals(other) ?
- SpecificValueFactory.LONG_VALUE_0 :
+ ParticularValueFactory.LONG_VALUE_0 :
new CompositeLongValue(this, CompositeLongValue.SUBTRACT, other);
}
public LongValue subtractFrom(SpecificLongValue other)
{
return this.equals(other) ?
- SpecificValueFactory.LONG_VALUE_0 :
+ ParticularValueFactory.LONG_VALUE_0 :
new CompositeLongValue(other, CompositeLongValue.SUBTRACT, this);
}
@@ -225,7 +225,7 @@ abstract class SpecificLongValue extends LongValue
public LongValue xor(SpecificLongValue other)
{
return this.equals(other) ?
- SpecificValueFactory.LONG_VALUE_0 :
+ ParticularValueFactory.LONG_VALUE_0 :
new CompositeLongValue(other, CompositeLongValue.XOR, this);
}
diff --git a/src/proguard/evaluation/value/TopValue.java b/src/proguard/evaluation/value/TopValue.java
index c7320fa..4422f69 100644
--- a/src/proguard/evaluation/value/TopValue.java
+++ b/src/proguard/evaluation/value/TopValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/TypedReferenceValue.java b/src/proguard/evaluation/value/TypedReferenceValue.java
new file mode 100644
index 0000000..4f8629c
--- /dev/null
+++ b/src/proguard/evaluation/value/TypedReferenceValue.java
@@ -0,0 +1,613 @@
+/*
+ * ProGuard -- shrinking, optimization, obfuscation, and preverification
+ * of Java bytecode.
+ *
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+package proguard.evaluation.value;
+
+import proguard.classfile.*;
+import proguard.classfile.util.ClassUtil;
+import proguard.classfile.visitor.ClassCollector;
+
+import java.util.*;
+
+/**
+ * This ReferenceValue represents a partially evaluated reference value.
+ * It has a type and a flag that indicates whether the value could be
+ * <code>null</code>. If the type is <code>null</code>, the value is
+ * <code>null</code>.
+ *
+ * @author Eric Lafortune
+ */
+public class TypedReferenceValue extends ReferenceValue
+{
+ private static final boolean DEBUG = false;
+
+
+ protected final String type;
+ protected final Clazz referencedClass;
+ protected final boolean mayBeNull;
+
+
+ /**
+ * Creates a new TypedReferenceValue.
+ */
+ public TypedReferenceValue(String type,
+ Clazz referencedClass,
+ boolean mayBeNull)
+ {
+ this.type = type;
+ this.referencedClass = referencedClass;
+ this.mayBeNull = mayBeNull;
+ }
+
+
+ // Implementations for ReferenceValue.
+
+ public String getType()
+ {
+ return type;
+ }
+
+
+ public Clazz getReferencedClass()
+ {
+ return referencedClass;
+ }
+
+
+ // Implementations of unary methods of ReferenceValue.
+
+ public int isNull()
+ {
+ return type == null ? ALWAYS :
+ mayBeNull ? MAYBE :
+ NEVER;
+ }
+
+
+ public int instanceOf(String otherType, Clazz otherReferencedClass)
+ {
+ String thisType = this.type;
+
+ // If this type is null, it is never an instance of any class.
+ if (thisType == null)
+ {
+ return NEVER;
+ }
+
+ // Start taking into account the type dimensions.
+ int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
+ int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
+ int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
+
+ // Strip any common array prefixes.
+ thisType = thisType.substring(commonDimensionCount);
+ otherType = otherType.substring(commonDimensionCount);
+
+ // If either stripped type is a primitive type, we can tell right away.
+ if (commonDimensionCount > 0 &&
+ (ClassUtil.isInternalPrimitiveType(thisType.charAt(0)) ||
+ ClassUtil.isInternalPrimitiveType(otherType.charAt(0))))
+ {
+ return !thisType.equals(otherType) ? NEVER :
+ mayBeNull ? MAYBE :
+ ALWAYS;
+ }
+
+ // Strip the class type prefix and suffix of this type, if any.
+ if (thisDimensionCount == commonDimensionCount)
+ {
+ thisType = ClassUtil.internalClassNameFromClassType(thisType);
+ }
+
+ // Strip the class type prefix and suffix of the other type, if any.
+ if (otherDimensionCount == commonDimensionCount)
+ {
+ otherType = ClassUtil.internalClassNameFromClassType(otherType);
+ }
+
+ // If this type is an array type, and the other type is not
+ // java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
+ // this type can never be an instance.
+ if (thisDimensionCount > otherDimensionCount &&
+ !ClassUtil.isInternalArrayInterfaceName(otherType))
+ {
+ return NEVER;
+ }
+
+ // If the other type is an array type, and this type is not
+ // java.lang.Object, java.lang.Cloneable, or java.io.Serializable,
+ // this type can never be an instance.
+ if (thisDimensionCount < otherDimensionCount &&
+ !ClassUtil.isInternalArrayInterfaceName(thisType))
+ {
+ return NEVER;
+ }
+
+ // If this type may be null, it might not be an instance of any class.
+ if (mayBeNull)
+ {
+ return MAYBE;
+ }
+
+ // If this type is equal to the other type, or if the other type is
+ // java.lang.Object, this type is always an instance.
+ if (thisType.equals(otherType) ||
+ ClassConstants.NAME_JAVA_LANG_OBJECT.equals(otherType))
+ {
+ return ALWAYS;
+ }
+
+ // If this type is an array type, it's ok.
+ if (thisDimensionCount > otherDimensionCount)
+ {
+ return ALWAYS;
+ }
+
+ // If the other type is an array type, it might be ok.
+ if (thisDimensionCount < otherDimensionCount)
+ {
+ return MAYBE;
+ }
+
+ // If the value extends the type, we're sure.
+ return referencedClass != null &&
+ otherReferencedClass != null &&
+ referencedClass.extendsOrImplements(otherReferencedClass) ?
+ ALWAYS :
+ MAYBE;
+ }
+
+
+ public ReferenceValue generalizeMayBeNull(boolean mayBeNull)
+ {
+ return this.mayBeNull == mayBeNull ?
+ this :
+ new TypedReferenceValue(type, referencedClass, true);
+ }
+
+
+ public ReferenceValue referenceArrayLoad(IntegerValue indexValue, ValueFactory valueFactory)
+ {
+ return
+ type == null ? ValueFactory.REFERENCE_VALUE_NULL :
+ !ClassUtil.isInternalArrayType(type) ? ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
+ valueFactory.createValue(type.substring(1),
+ referencedClass,
+ true).referenceValue();
+ }
+
+
+ // Implementations of binary methods of ReferenceValue.
+
+ public ReferenceValue generalize(ReferenceValue other)
+ {
+ return other.generalize(this);
+ }
+
+
+ public int equal(ReferenceValue other)
+ {
+ return other.equal(this);
+ }
+
+
+ // Implementations of binary ReferenceValue methods with TypedReferenceValue
+ // arguments.
+
+ public ReferenceValue generalize(TypedReferenceValue other)
+ {
+ // If both types are identical, the generalization is the same too.
+ if (this.equals(other))
+ {
+ return this;
+ }
+
+ String thisType = this.type;
+ String otherType = other.type;
+
+ // If both types are nul, the generalization is null too.
+ if (thisType == null && otherType == null)
+ {
+ return ValueFactory.REFERENCE_VALUE_NULL;
+ }
+
+ // If this type is null, the generalization is the other type, maybe null.
+ if (thisType == null)
+ {
+ return other.generalizeMayBeNull(true);
+ }
+
+ // If the other type is null, the generalization is this type, maybe null.
+ if (otherType == null)
+ {
+ return this.generalizeMayBeNull(true);
+ }
+
+ boolean mayBeNull = this.mayBeNull || other.mayBeNull;
+
+ // If the two types are equal, the generalization remains the same, maybe null.
+ if (thisType.equals(otherType))
+ {
+ return typedReferenceValue(this, mayBeNull);
+ }
+
+ // Start taking into account the type dimensions.
+ int thisDimensionCount = ClassUtil.internalArrayTypeDimensionCount(thisType);
+ int otherDimensionCount = ClassUtil.internalArrayTypeDimensionCount(otherType);
+ int commonDimensionCount = Math.min(thisDimensionCount, otherDimensionCount);
+
+ if (thisDimensionCount == otherDimensionCount)
+ {
+ // See if we can take into account the referenced classes.
+ Clazz thisReferencedClass = this.referencedClass;
+ Clazz otherReferencedClass = other.referencedClass;
+
+ if (thisReferencedClass != null &&
+ otherReferencedClass != null)
+ {
+ // Is one class simply an extension of the other one?
+ if (thisReferencedClass.extendsOrImplements(otherReferencedClass))
+ {
+ return typedReferenceValue(other, mayBeNull);
+ }
+
+ if (otherReferencedClass.extendsOrImplements(thisReferencedClass))
+ {
+ return typedReferenceValue(this, mayBeNull);
+ }
+
+ // Do the classes have a non-trivial common superclass?
+ Clazz commonClass = findCommonClass(thisReferencedClass,
+ otherReferencedClass,
+ false);
+
+ if (commonClass.getName().equals(ClassConstants.NAME_JAVA_LANG_OBJECT))
+ {
+ // Otherwise, do the classes have a common interface?
+ Clazz commonInterface = findCommonClass(thisReferencedClass,
+ otherReferencedClass,
+ true);
+ if (commonInterface != null)
+ {
+ commonClass = commonInterface;
+ }
+ }
+
+ return new TypedReferenceValue(commonDimensionCount == 0 ?
+ commonClass.getName() :
+ ClassUtil.internalArrayTypeFromClassName(commonClass.getName(),
+ commonDimensionCount),
+ commonClass,
+ mayBeNull);
+ }
+ }
+ else if (thisDimensionCount > otherDimensionCount)
+ {
+ // See if the other type is an interface type of arrays.
+ if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(otherType)))
+ {
+ return typedReferenceValue(other, mayBeNull);
+ }
+ }
+ else if (thisDimensionCount < otherDimensionCount)
+ {
+ // See if this type is an interface type of arrays.
+ if (ClassUtil.isInternalArrayInterfaceName(ClassUtil.internalClassNameFromClassType(thisType)))
+ {
+ return typedReferenceValue(this, mayBeNull);
+ }
+ }
+
+ // Reduce the common dimension count if either type is an array of
+ // primitives type of this dimension.
+ if (commonDimensionCount > 0 &&
+ (ClassUtil.isInternalPrimitiveType(otherType.charAt(commonDimensionCount))) ||
+ ClassUtil.isInternalPrimitiveType(thisType.charAt(commonDimensionCount)))
+ {
+ commonDimensionCount--;
+ }
+
+ // Fall back on a basic Object or array of Objects type.
+ return
+ commonDimensionCount != 0 ?
+ new TypedReferenceValue(ClassUtil.internalArrayTypeFromClassName(ClassConstants.NAME_JAVA_LANG_OBJECT, commonDimensionCount),
+ null,
+ mayBeNull) :
+ mayBeNull ?
+ ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
+ ValueFactory.REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL;
+ }
+
+
+ /**
+ * Returns the most specific common superclass or interface of the given
+ * classes.
+ * @param class1 the first class.
+ * @param class2 the second class.
+ * @param interfaces specifies whether to look for a superclass or for an
+ * interface.
+ * @return the common class.
+ */
+ private Clazz findCommonClass(Clazz class1,
+ Clazz class2,
+ boolean interfaces)
+ {
+ // Collect the superclasses or the interfaces of this class.
+ Set superClasses1 = new HashSet();
+ class1.hierarchyAccept(!interfaces,
+ !interfaces,
+ interfaces,
+ false,
+ new ClassCollector(superClasses1));
+
+ int superClasses1Count = superClasses1.size();
+ if (superClasses1Count == 0)
+ {
+ if (interfaces)
+ {
+ return null;
+ }
+ else if (class1.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+class1.getName()+"] (not even immediate super class ["+class1.getSuperName()+"])");
+ }
+ }
+
+ // Collect the superclasses or the interfaces of the other class.
+ Set superClasses2 = new HashSet();
+ class2.hierarchyAccept(!interfaces,
+ !interfaces,
+ interfaces,
+ false,
+ new ClassCollector(superClasses2));
+
+ int superClasses2Count = superClasses2.size();
+ if (superClasses2Count == 0)
+ {
+ if (interfaces)
+ {
+ return null;
+ }
+ else if (class2.getSuperName() != null)
+ {
+ throw new IllegalArgumentException("Can't find any super classes of ["+class2.getName()+"] (not even immediate super class ["+class2.getSuperName()+"])");
+ }
+ }
+
+ if (DEBUG)
+ {
+ System.out.println("ReferenceValue.generalize this ["+class1.getName()+"] with other ["+class2.getName()+"] (interfaces = "+interfaces+")");
+ System.out.println(" This super classes: "+superClasses1);
+ System.out.println(" Other super classes: "+superClasses2);
+ }
+
+ // Find the common superclasses.
+ superClasses1.retainAll(superClasses2);
+
+ if (DEBUG)
+ {
+ System.out.println(" Common super classes: "+superClasses1);
+ }
+
+ if (interfaces && superClasses1.isEmpty())
+ {
+ return null;
+ }
+
+ // Find a class that is a subclass of all common superclasses,
+ // or that at least has the maximum number of common superclasses.
+ Clazz commonClass = null;
+
+ int maximumSuperClassCount = -1;
+
+ // Go over all common superclasses to find it. In case of
+ // multiple subclasses, keep the lowest one alphabetically,
+ // in order to ensure that the choice is deterministic.
+ Iterator commonSuperClasses = superClasses1.iterator();
+ while (commonSuperClasses.hasNext())
+ {
+ Clazz commonSuperClass = (Clazz)commonSuperClasses.next();
+
+ int superClassCount = superClassCount(commonSuperClass, superClasses1);
+ if (maximumSuperClassCount < superClassCount ||
+ (maximumSuperClassCount == superClassCount &&
+ commonClass != null &&
+ commonClass.getName().compareTo(commonSuperClass.getName()) > 0))
+ {
+ commonClass = commonSuperClass;
+ maximumSuperClassCount = superClassCount;
+ }
+ }
+
+ if (commonClass == null)
+ {
+ throw new IllegalArgumentException("Can't find common super class of ["+
+ class1.getName() +"] (with "+superClasses1Count +" known super classes) and ["+
+ class2.getName()+"] (with "+superClasses2Count+" known super classes)");
+ }
+
+ if (DEBUG)
+ {
+ System.out.println(" Best common class: ["+commonClass.getName()+"]");
+ }
+
+ return commonClass;
+ }
+
+
+ /**
+ * Returns the given reference value that may or may not be null, ensuring
+ * that it is a TypedReferenceValue, not a subclass.
+ */
+ private static ReferenceValue typedReferenceValue(TypedReferenceValue referenceValue,
+ boolean mayBeNull)
+ {
+ return referenceValue.getClass() == TypedReferenceValue.class ?
+ referenceValue.generalizeMayBeNull(mayBeNull) :
+ new TypedReferenceValue(referenceValue.type,
+ referenceValue.referencedClass,
+ mayBeNull);
+ }
+
+
+ /**
+ * Returns if the number of superclasses of the given class in the given
+ * set of classes.
+ */
+ private int superClassCount(Clazz subClass, Set classes)
+ {
+ int count = 0;
+
+ Iterator iterator = classes.iterator();
+
+ while (iterator.hasNext())
+ {
+ Clazz clazz = (Clazz)iterator.next();
+ if (subClass.extendsOrImplements(clazz))
+ {
+ count++;
+ }
+ }
+
+ return count;
+ }
+
+
+ public int equal(TypedReferenceValue other)
+ {
+ return this.type == null && other.type == null ? ALWAYS : MAYBE;
+ }
+
+
+ // Implementations of binary ReferenceValue methods with
+ // IdentifiedReferenceValue arguments.
+
+ public ReferenceValue generalize(IdentifiedReferenceValue other)
+ {
+ return generalize((TypedReferenceValue)other);
+ }
+
+
+ public int equal(IdentifiedReferenceValue other)
+ {
+ return equal((TypedReferenceValue)other);
+ }
+
+
+ // Implementations of binary ReferenceValue methods with
+ // ArrayReferenceValue arguments.
+
+ public ReferenceValue generalize(ArrayReferenceValue other)
+ {
+ return generalize((TypedReferenceValue)other);
+ }
+
+
+ public int equal(ArrayReferenceValue other)
+ {
+ return equal((TypedReferenceValue)other);
+ }
+
+
+ // Implementations of binary ReferenceValue methods with
+ // IdentifiedArrayReferenceValue arguments.
+
+ public ReferenceValue generalize(IdentifiedArrayReferenceValue other)
+ {
+ return generalize((ArrayReferenceValue)other);
+ }
+
+
+ public int equal(IdentifiedArrayReferenceValue other)
+ {
+ return equal((ArrayReferenceValue)other);
+ }
+
+
+ // Implementations of binary ReferenceValue methods with
+ // DetailedArrayReferenceValue arguments.
+
+ public ReferenceValue generalize(DetailedArrayReferenceValue other)
+ {
+ return generalize((IdentifiedArrayReferenceValue)other);
+ }
+
+
+ public int equal(DetailedArrayReferenceValue other)
+ {
+ return equal((IdentifiedArrayReferenceValue)other);
+ }
+
+
+ // Implementations for Value.
+
+ public boolean isParticular()
+ {
+ return type == null;
+ }
+
+
+ public final String internalType()
+ {
+ return
+ type == null ? ClassConstants.TYPE_JAVA_LANG_OBJECT :
+ ClassUtil.isInternalArrayType(type) ? type :
+ ClassConstants.TYPE_CLASS_START +
+ type +
+ ClassConstants.TYPE_CLASS_END;
+ }
+
+
+ // Implementations for Object.
+
+ public boolean equals(Object object)
+ {
+ if (this == object)
+ {
+ return true;
+ }
+
+ if (object == null ||
+ this.getClass() != object.getClass())
+ {
+ return false;
+ }
+
+ TypedReferenceValue other = (TypedReferenceValue)object;
+ return this.type == null ? other.type == null :
+ (this.mayBeNull == other.mayBeNull &&
+ this.type.equals(other.type));
+ }
+
+
+ public int hashCode()
+ {
+ return this.getClass().hashCode() ^
+ (type == null ? 0 : type.hashCode() ^ (mayBeNull ? 0 : 1));
+ }
+
+
+ public String toString()
+ {
+ return type == null ?
+ "null" :
+ type + (referencedClass == null ? "?" : "") + (mayBeNull ? "" : "!");
+ }
+}
diff --git a/src/proguard/evaluation/value/UnknownDoubleValue.java b/src/proguard/evaluation/value/UnknownDoubleValue.java
index f8bad9a..ad2f511 100644
--- a/src/proguard/evaluation/value/UnknownDoubleValue.java
+++ b/src/proguard/evaluation/value/UnknownDoubleValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownFloatValue.java b/src/proguard/evaluation/value/UnknownFloatValue.java
index 464ceed..f6f2047 100644
--- a/src/proguard/evaluation/value/UnknownFloatValue.java
+++ b/src/proguard/evaluation/value/UnknownFloatValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownIntegerValue.java b/src/proguard/evaluation/value/UnknownIntegerValue.java
index b273b12..5c05721 100644
--- a/src/proguard/evaluation/value/UnknownIntegerValue.java
+++ b/src/proguard/evaluation/value/UnknownIntegerValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/UnknownLongValue.java b/src/proguard/evaluation/value/UnknownLongValue.java
index ee315be..ced2d1f 100644
--- a/src/proguard/evaluation/value/UnknownLongValue.java
+++ b/src/proguard/evaluation/value/UnknownLongValue.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
diff --git a/src/proguard/evaluation/value/Value.java b/src/proguard/evaluation/value/Value.java
index f8d9327..5cfd02c 100644
--- a/src/proguard/evaluation/value/Value.java
+++ b/src/proguard/evaluation/value/Value.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -45,7 +45,7 @@ public abstract class Value
*/
public Category1Value category1Value()
{
- throw new IllegalArgumentException("Value is not a Category 1 value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a Category 1 value [" + this.getClass().getName() + "]");
}
/**
@@ -53,7 +53,7 @@ public abstract class Value
*/
public Category2Value category2Value()
{
- throw new IllegalArgumentException("Value is not a Category 2 value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a Category 2 value [" + this.getClass().getName() + "]");
}
@@ -62,7 +62,7 @@ public abstract class Value
*/
public IntegerValue integerValue()
{
- throw new IllegalArgumentException("Value is not an integer value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not an integer value [" + this.getClass().getName() + "]");
}
/**
@@ -70,7 +70,7 @@ public abstract class Value
*/
public LongValue longValue()
{
- throw new IllegalArgumentException("Value is not a long value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a long value [" + this.getClass().getName() + "]");
}
/**
@@ -78,7 +78,7 @@ public abstract class Value
*/
public FloatValue floatValue()
{
- throw new IllegalArgumentException("Value is not a float value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a float value [" + this.getClass().getName() + "]");
}
/**
@@ -86,7 +86,7 @@ public abstract class Value
*/
public DoubleValue doubleValue()
{
- throw new IllegalArgumentException("Value is not a double value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a double value [" + this.getClass().getName() + "]");
}
/**
@@ -94,7 +94,7 @@ public abstract class Value
*/
public ReferenceValue referenceValue()
{
- throw new IllegalArgumentException("Value is not a reference value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not a reference value [" + this.getClass().getName() + "]");
}
/**
@@ -102,7 +102,7 @@ public abstract class Value
*/
public InstructionOffsetValue instructionOffsetValue()
{
- throw new IllegalArgumentException("Value is not an instruction offset value [" + this.getClass().getName() + "]");
+ throw new IllegalArgumentException("Value \"" + this.toString() + "\" is not an instruction offset value [" + this.getClass().getName() + "]");
}
@@ -154,15 +154,15 @@ public abstract class Value
/**
* Returns the internal type of this Value.
- * @return <code>ClassConstants.INTERNAL_TYPE_BOOLEAN</code>,
- * <code>ClassConstants.INTERNAL_TYPE_BYTE</code>,
- * <code>ClassConstants.INTERNAL_TYPE_CHAR</code>,
- * <code>ClassConstants.INTERNAL_TYPE_SHORT</code>,
- * <code>ClassConstants.INTERNAL_TYPE_INT</code>,
- * <code>ClassConstants.INTERNAL_TYPE_LONG</code>,
- * <code>ClassConstants.INTERNAL_TYPE_FLOAT</code>,
- * <code>ClassConstants.INTERNAL_TYPE_DOUBLE</code>,
- * <code>ClassConstants.INTERNAL_TYPE_CLASS_START ... ClassConstants.INTERNAL_TYPE_CLASS_END</code>, or
+ * @return <code>ClassConstants.TYPE_BOOLEAN</code>,
+ * <code>ClassConstants.TYPE_BYTE</code>,
+ * <code>ClassConstants.TYPE_CHAR</code>,
+ * <code>ClassConstants.TYPE_SHORT</code>,
+ * <code>ClassConstants.TYPE_INT</code>,
+ * <code>ClassConstants.TYPE_LONG</code>,
+ * <code>ClassConstants.TYPE_FLOAT</code>,
+ * <code>ClassConstants.TYPE_DOUBLE</code>,
+ * <code>ClassConstants.TYPE_CLASS_START ... ClassConstants.TYPE_CLASS_END</code>, or
* an array type containing any of these types (always as String).
*/
public abstract String internalType();
diff --git a/src/proguard/evaluation/value/ValueFactory.java b/src/proguard/evaluation/value/ValueFactory.java
index c94ac65..cb9e657 100644
--- a/src/proguard/evaluation/value/ValueFactory.java
+++ b/src/proguard/evaluation/value/ValueFactory.java
@@ -2,7 +2,7 @@
* ProGuard -- shrinking, optimization, obfuscation, and preverification
* of Java bytecode.
*
- * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
+ * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
@@ -36,9 +36,9 @@ public class ValueFactory
static final FloatValue FLOAT_VALUE = new UnknownFloatValue();
static final DoubleValue DOUBLE_VALUE = new UnknownDoubleValue();
- static final ReferenceValue REFERENCE_VALUE_NULL = new ReferenceValue(null, null, true);
- static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL = new ReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT, null, true);
- static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL = new ReferenceValue(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT, null, false);
+ static final ReferenceValue REFERENCE_VALUE_NULL = new TypedReferenceValue(null, null, true);
+ static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL = new TypedReferenceValue(ClassConstants.NAME_JAVA_LANG_OBJECT, null, true);
+ static final ReferenceValue REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL = new TypedReferenceValue(ClassConstants.NAME_JAVA_LANG_OBJECT, null, false);
/**
@@ -50,20 +50,20 @@ public class ValueFactory
{
switch (type.charAt(0))
{
- case ClassConstants.INTERNAL_TYPE_VOID: return null;
- case ClassConstants.INTERNAL_TYPE_BOOLEAN:
- case ClassConstants.INTERNAL_TYPE_BYTE:
- case ClassConstants.INTERNAL_TYPE_CHAR:
- case ClassConstants.INTERNAL_TYPE_SHORT:
- case ClassConstants.INTERNAL_TYPE_INT: return createIntegerValue();
- case ClassConstants.INTERNAL_TYPE_LONG: return createLongValue();
- case ClassConstants.INTERNAL_TYPE_FLOAT: return createFloatValue();
- case ClassConstants.INTERNAL_TYPE_DOUBLE: return createDoubleValue();
- default: return createReferenceValue(ClassUtil.isInternalArrayType(type) ?
- type :
- ClassUtil.internalClassNameFromClassType(type),
- referencedClass,
- mayBeNull);
+ case ClassConstants.TYPE_VOID: return null;
+ case ClassConstants.TYPE_BOOLEAN:
+ case ClassConstants.TYPE_BYTE:
+ case ClassConstants.TYPE_CHAR:
+ case ClassConstants.TYPE_SHORT:
+ case ClassConstants.TYPE_INT: return createIntegerValue();
+ case ClassConstants.TYPE_LONG: return createLongValue();
+ case ClassConstants.TYPE_FLOAT: return createFloatValue();
+ case ClassConstants.TYPE_DOUBLE: return createDoubleValue();
+ default: return createReferenceValue(ClassUtil.isInternalArrayType(type) ?
+ type :
+ ClassUtil.internalClassNameFromClassType(type),
+ referencedClass,
+ mayBeNull);
}
}
@@ -153,10 +153,10 @@ public class ValueFactory
Clazz referencedClass,
boolean mayBeNull)
{
- return type == null ? REFERENCE_VALUE_NULL :
- !type.equals(ClassConstants.INTERNAL_NAME_JAVA_LANG_OBJECT) ? new ReferenceValue(type, referencedClass, mayBeNull) :
- mayBeNull ? REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
- REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL;
+ return type == null ? REFERENCE_VALUE_NULL :
+ !type.equals(ClassConstants.NAME_JAVA_LANG_OBJECT) ? new TypedReferenceValue(type, referencedClass, mayBeNull) :
+ mayBeNull ? REFERENCE_VALUE_JAVA_LANG_OBJECT_MAYBE_NULL :
+ REFERENCE_VALUE_JAVA_LANG_OBJECT_NOT_NULL;
}
@@ -169,24 +169,7 @@ public class ValueFactory
Clazz referencedClass,
IntegerValue arrayLength)
{
- return createArrayReferenceValue(type,
- referencedClass,
- arrayLength,
- createValue(type, referencedClass, false));
- }
-
-
- /**
- * Creates a new ReferenceValue for arrays of the given type and length,
- * containing the given element. The type must be a fully specified internal
- * type for primitives, classes, or arrays.
- */
- public ReferenceValue createArrayReferenceValue(String type,
- Clazz referencedClass,
- IntegerValue arrayLength,
- Value elementValue)
- {
- return createReferenceValue(ClassConstants.INTERNAL_TYPE_ARRAY + type,
+ return createReferenceValue(ClassConstants.TYPE_ARRAY + type,
referencedClass,
false);
}