diff --git a/jode/ChangeLog b/jode/ChangeLog
index 1e1ed4a..8a2d1d4 100644
--- a/jode/ChangeLog
+++ b/jode/ChangeLog
@@ -1,3 +1,56 @@
+2001-08-14 Jochen Hoenicke
+
+ * build.xml: test is default.
+ (release-javadoc): New target.
+ (release-src): Get from dir test only source files.
+ (doc-javadoc): More parameters for nicer docu.
+
+2001-08-12 Jochen Hoenicke
+
+ * net/sf/jode/bytecode/TypeSignature.java:
+ (getArgumentSize): Renamed to ...
+ (getParameterSize): ... this. Changed all callers.
+ (skipType): Made private.
+
+ * net/sf/jode/jvm/CodeVerifier.java:
+ (initInfo): Use TypeSignature.getParameterTypes instead of skipType.
+
+ * net/sf/jode/jvm/SyntheticAnalyzer.java:
+ (checkGetClass): Be more lenient with the types, they are already
+ checked by the CodeVerifier. This is to support jdk-1.4.
+
+ * net/sf/jode/expr/InvokeOperator.java
+ (dumpExpression): Fixed the check for null outerExpr.
+
+ * net/sf/jode/flow/FlowBlock.java:
+ (checkConsistent): Allow lastModified in a finally block.
+ * net/sf/jode/flow/TransformExceptionHandlers.java: Reworked exception
+ handlers again. This time checked with javac 1.3, javac 1.1 and
+ jikes.
+ (checkTryCatchOrder): New method that was previously part of
+ analyze.
+ (analyze): Use checkTryCatchOrder. Don't merge try and catch flow
+ blocks anymore, leave it to the analyzeXXX methods.
+ (mergeTryCatch): New method.
+ (analyzeCatchBlock): Get catchFlow as parameter. Call
+ mergeTryCatch.
+ (transformSubroutine): Handle POP-only subroutines.
+ (removeJSR): Don't do special case for catchBlock any more. This
+ is because catchFlow isn't yet merged when this method is called.
+ (checkAndRemoveJSR): Likewise.
+ (checkAndRemoveMonitorExit): Likewise. Merge subroutine only if
+ we are the only predecessor.
+ (analyzeSynchronized): Get catchFlow as parameter. Call
+ mergeTryCatch.
+ (mergeFinallyBlocks): New method, calls mergeTryCatch and does the
+ common part of mergeFinally and mergeSpecialFinally.
+ (analyzeFinally): Simplified, after checking and removing JSR, it
+ does immediately analyze and transform subroutine to get the
+ finallyBlock. Then it throws away the catchFlow and calls
+ mergeFinallyBlocks.
+ (analyzeSpecialFinally): Simplified, after checking it only handles
+ the jumps in the try part and then call mergeFinallyBlocks.
+
2001-08-08 Jochen Hoenicke
More Documentation updates.
* build.xml: Release rules.
@@ -304,7 +357,7 @@
type can't be intersected, return tObject as common super type.
2001-07-15 Jochen Hoenicke
- Applied patch from Java 1.1 tree:
+ Applied patch from Jode 1.1 tree:
* jode/expr/Expression.java (updateParentTypes): Call setType,
instead of merging the types. Other childs want to know about the
@@ -317,7 +370,7 @@
innermost.
2001-07-14 Jochen Hoenicke
- Applied patches from the Java 1.1 tree:
+ Applied patches from the Jode 1.1 tree:
* jode/decompiler/TabbedPrintWriter.java: Better gnu style handling:
(openBraceClass) (closeBraceClass)
diff --git a/jode/build.xml b/jode/build.xml
index 153a52e..d22a039 100644
--- a/jode/build.xml
+++ b/jode/build.xml
@@ -19,7 +19,7 @@
-->
-
+
@@ -32,7 +32,7 @@
-
+
@@ -164,7 +164,7 @@
-
+
@@ -221,7 +221,9 @@
-
+
+
+
@@ -231,6 +233,14 @@
+
+
+
+
+
+
+
@@ -254,8 +264,15 @@
+
+
+
diff --git a/jode/config.props b/jode/config.props
index a78fa1d..3fd79b1 100644
--- a/jode/config.props
+++ b/jode/config.props
@@ -1,10 +1,11 @@
# Do you have online access for generating javadoc?
# If not, where are your local files.
javadoc.offline=false
-#javadoc.href=http://java.sun.com/products/jdk/1.2/docs/api/
javadoc.packagelistLoc=
+javadoc.href=http://java.sun.com/products/jdk/1.2/docs/api/
+#javadoc.href=file:/usr/doc/inet/java/jdk1.2/docs/api
+
#javadoc.offline=true
-javadoc.href=file:/usr/doc/inet/java/jdk1.2/docs/api
#javadoc.packagelistLoc=/usr/doc/inet/java/jdk1.2/docs/api
# Is Perl installed on your system?
diff --git a/jode/doc/feedback.php b/jode/doc/feedback.php
index a165044..e415db7 100644
--- a/jode/doc/feedback.php
+++ b/jode/doc/feedback.php
@@ -7,7 +7,7 @@ Please send me a short notice if you add a bug.
You can contact me per email via hoenicke at
-users.sourceforge.net. Please mention jode in the
+users.sourceforge.net. Please mention Jode in the
subject.
There is a mailing list. Check this page for subscription informations.
diff --git a/jode/doc/footer.inc b/jode/doc/footer.inc
index c97e581..1294ad1 100644
--- a/jode/doc/footer.inc
+++ b/jode/doc/footer.inc
@@ -3,7 +3,7 @@
|
diff --git a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java
index 7b65077..b388658 100644
--- a/jode/src/net/sf/jode/bytecode/BasicBlockReader.java
+++ b/jode/src/net/sf/jode/bytecode/BasicBlockReader.java
@@ -693,7 +693,7 @@ class BasicBlockReader implements Opcodes {
throw new ClassFormatException
("Illegal call of special method "+ref);
int nargs = input.readUnsignedByte();
- if (TypeSignature.getArgumentSize(ref.getType())
+ if (TypeSignature.getParameterSize(ref.getType())
!= nargs - 1)
throw new ClassFormatException
("Interface nargs mismatch: "+ref+" vs. "+nargs);
@@ -890,7 +890,7 @@ class BasicBlockReader implements Opcodes {
GlobalOptions.err.println("Illegal LVT length, ignoring it");
return;
}
- Vector[] lvt = new Vector[bb.maxLocals];
+ Vector[] lvt = new Vector[maxLocals];
for (int i=0; i < count; i++) {
LVTEntry lve = new LVTEntry();
lve.start = input.readUnsignedShort();
@@ -899,7 +899,8 @@ class BasicBlockReader implements Opcodes {
int typeIndex = input.readUnsignedShort();
int slot = input.readUnsignedShort();
if (nameIndex == 0 || cp.getTag(nameIndex) != cp.UTF8
- || typeIndex == 0 || cp.getTag(typeIndex) != cp.UTF8) {
+ || typeIndex == 0 || cp.getTag(typeIndex) != cp.UTF8
+ || slot >= maxLocals) {
// This is probably an evil lvt as created by HashJava
// simply ignore it.
diff --git a/jode/src/net/sf/jode/bytecode/BasicBlockWriter.java b/jode/src/net/sf/jode/bytecode/BasicBlockWriter.java
index b820929..83960aa 100644
--- a/jode/src/net/sf/jode/bytecode/BasicBlockWriter.java
+++ b/jode/src/net/sf/jode/bytecode/BasicBlockWriter.java
@@ -894,7 +894,8 @@ class BasicBlockWriter implements Opcodes {
output.writeShort
(gcp.putRef(gcp.INTERFACEMETHODREF, ref));
output.writeByte
- (TypeSignature.getArgumentSize(ref.getType()) + 1);
+ (TypeSignature
+ .getParameterSize(ref.getType()) + 1);
output.writeByte(0);
} else
output.writeShort(gcp.putRef(gcp.METHODREF, ref));
diff --git a/jode/src/net/sf/jode/bytecode/BasicBlocks.java b/jode/src/net/sf/jode/bytecode/BasicBlocks.java
index ba12142..42306d3 100644
--- a/jode/src/net/sf/jode/bytecode/BasicBlocks.java
+++ b/jode/src/net/sf/jode/bytecode/BasicBlocks.java
@@ -132,7 +132,7 @@ public class BasicBlocks extends BinaryInfo implements Opcodes {
public BasicBlocks(MethodInfo mi) {
methodInfo = mi;
int paramSize = (mi.isStatic() ? 0 : 1)
- + TypeSignature.getArgumentSize(mi.getType());
+ + TypeSignature.getParameterSize(mi.getType());
paramInfos = new LocalVariableInfo[paramSize];
for (int i=0; i< paramSize; i++)
paramInfos[i] = LocalVariableInfo.getInfo(i);
diff --git a/jode/src/net/sf/jode/bytecode/Reference.java b/jode/src/net/sf/jode/bytecode/Reference.java
index 1c1a8a8..d2cf195 100644
--- a/jode/src/net/sf/jode/bytecode/Reference.java
+++ b/jode/src/net/sf/jode/bytecode/Reference.java
@@ -24,7 +24,8 @@ import java.util.Iterator;
///#enddef
/**
- * This class represents a field or method reference.
+ * This class represents a field or method reference. It consists of
+ * the class name the method/field name and the type signature.
*/
public class Reference {
/**
diff --git a/jode/src/net/sf/jode/bytecode/ReferenceInstruction.java b/jode/src/net/sf/jode/bytecode/ReferenceInstruction.java
index 021c510..5c3179b 100644
--- a/jode/src/net/sf/jode/bytecode/ReferenceInstruction.java
+++ b/jode/src/net/sf/jode/bytecode/ReferenceInstruction.java
@@ -61,7 +61,7 @@ class ReferenceInstruction extends Instruction {
case opc_invokestatic:
case opc_invokeinterface:
poppush[0] = opcode != opc_invokestatic ? 1 : 0;
- poppush[0] += TypeSignature.getArgumentSize(typeSig);
+ poppush[0] += TypeSignature.getParameterSize(typeSig);
poppush[1] = TypeSignature.getReturnSize(typeSig);
break;
diff --git a/jode/src/net/sf/jode/bytecode/TypeSignature.java b/jode/src/net/sf/jode/bytecode/TypeSignature.java
index a088afe..9f08e59 100644
--- a/jode/src/net/sf/jode/bytecode/TypeSignature.java
+++ b/jode/src/net/sf/jode/bytecode/TypeSignature.java
@@ -21,7 +21,37 @@ package net.sf.jode.bytecode;
import net.sf.jode.util.UnifyHash;
/**
- * This class contains some static methods to handle type signatures.
+ * This class contains some static methods to handle type signatures.
+ *
+ * A type signature is a compact textual representation of a java
+ * types. It is described in the Java Virtual Machine Specification.
+ * Primitive types have a one letter type signature. Type signature
+ * of classes contains the class name. Type signatures for arrays and
+ * methods are recursively build from the type signatures of their
+ * elements.
+ *
+ * Here are a few examples:
+ * type signature | Java type |
+ * Z | boolean |
+ * B | byte |
+ * S | short |
+ * C | char |
+ * I | int |
+ * F | float |
+ * J | long |
+ * D | double |
+ * Ljava/lang/Object; |
+ * java.lang.Object |
+ * [[I | int[][] |
+ * (Ljava/lang/Object;I)V |
+ * method with argument types Object and
+ * int and void return type. |
+ * ()I |
+ * method without arguments
+ * and int return type. |
+ *
+ *
+ * @author Jochen Hoenicke
*/
public class TypeSignature {
/**
@@ -61,22 +91,20 @@ public class TypeSignature {
}
/**
- * Generate the signature for the given Class.
+ * Generates the type signature of the given Class.
* @param clazz a java.lang.Class, this may also be a primitive or
* array type.
- * @return the type signature (see section 4.3.2 Field Descriptors
- * of the JVM specification)
+ * @return the type signature.
*/
public static String getSignature(Class clazz) {
return appendSignature(new StringBuffer(), clazz).toString();
}
/**
- * Generate a method signature.
+ * Generates a method signature.
* @param paramT the java.lang.Class of the parameter types of the method.
* @param returnT the java.lang.Class of the return type of the method.
- * @return the method signature (see section 4.3.3 Method Descriptors
- * of the JVM specification)
+ * @return the method type signature
*/
public static String getSignature(Class paramT[], Class returnT) {
StringBuffer sig = new StringBuffer("(");
@@ -86,8 +114,8 @@ public class TypeSignature {
}
/**
- * Generate a Class for a type signature. This is the pendant to
- * getSignature.
+ * Generates a Class object for a type signature. This is the
+ * inverse function of getSignature.
* @param typeSig a single type signature
* @return the Class object representing that type.
*/
@@ -124,25 +152,43 @@ public class TypeSignature {
}
/**
- * Check if the given type is a two slot type. */
+ * Check if the given type is a two slot type. The only two slot
+ * types are long and double.
+ */
private static boolean usingTwoSlots(char type) {
return "JD".indexOf(type) >= 0;
}
/**
* Returns the number of words, an object of the given simple type
- * signature takes.
+ * signature takes. For long and double this is two, for all other
+ * types it is one.
*/
public static int getTypeSize(String typeSig) {
return usingTwoSlots(typeSig.charAt(0)) ? 2 : 1;
}
+ /**
+ * Gets the element type of an array.
+ * @param typeSig type signature of the array.
+ * @return type signature for the element type.
+ * @exception IllegalArgumentException if typeSig is not an array
+ * type signature.
+ */
public static String getElementType(String typeSig) {
if (typeSig.charAt(0) != '[')
throw new IllegalArgumentException();
return typeSig.substring(1);
}
+ /**
+ * Gets the ClassInfo for a class type.
+ * @param classpath the classpath in which the ClassInfo is searched.
+ * @param typeSig type signature of the class.
+ * @return the ClassInfo object for the class.
+ * @exception IllegalArgumentException if typeSig is not an class
+ * type signature.
+ */
public static ClassInfo getClassInfo(ClassPath classpath, String typeSig) {
if (typeSig.charAt(0) != 'L')
throw new IllegalArgumentException();
@@ -150,7 +196,13 @@ public class TypeSignature {
(typeSig.substring(1, typeSig.length()-1).replace('/', '.'));
}
- public static int skipType(String methodTypeSig, int position) {
+ /**
+ * Skips the next entry of a method type signature
+ * @param methodTypeSig type signature of the method.
+ * @param position the index to the last entry.
+ * @return the index to the next entry.
+ */
+ static int skipType(String methodTypeSig, int position) {
char c = methodTypeSig.charAt(position++);
while (c == '[')
c = methodTypeSig.charAt(position++);
@@ -160,10 +212,13 @@ public class TypeSignature {
}
/**
- * Returns the number of words, the arguments for the given method
- * type signature takes.
+ * Gets the number of words the parameters for the given method
+ * type signature takes. This is the sum of getTypeSize() for
+ * each parameter type.
+ * @param methodTypeSig the method type signature.
+ * @return the number of words the parameters take.
*/
- public static int getArgumentSize(String methodTypeSig) {
+ public static int getParameterSize(String methodTypeSig) {
int nargs = 0;
int i = 1;
for (;;) {
@@ -179,8 +234,11 @@ public class TypeSignature {
}
/**
- * Returns the number of words, an object of the given simple type
- * signature takes.
+ * Gets the size of the return type of the given method in words.
+ * This is zero for void return type, two for double or long return
+ * type and one otherwise.
+ * @param methodTypeSig the method type signature.
+ * @return the size of the return type in words.
*/
public static int getReturnSize(String methodTypeSig) {
int length = methodTypeSig.length();
@@ -195,8 +253,9 @@ public class TypeSignature {
}
/**
- * Returns the number of words, an object of the given simple type
- * signature takes.
+ * Gets the parameter type signatures of the given method signature.
+ * @param methodTypeSig the method type signature.
+ * @return an array containing all parameter types in correct order.
*/
public static String[] getParameterTypes(String methodTypeSig) {
int pos = 1;
@@ -215,6 +274,26 @@ public class TypeSignature {
return params;
}
+ /**
+ * Gets the return type for a method signature
+ * @param methodTypeSig the method signature.
+ * @return the return type for a method signature, `V' for void methods.
+ */
+ public static String getReturnType(String methodTypeSig) {
+ return methodTypeSig.substring(methodTypeSig.lastIndexOf(')')+1);
+ }
+
+ /**
+ * Gets the default value an object of the given type has. It is
+ * null for objects and arrays, Integer(0) for boolean and short
+ * integer types or Long(0L), Double(0.0), Float(0.0F) for long,
+ * double and float. This seems strange, but this way the type
+ * returned is the same as for FieldInfo.getConstant().
+ *
+ * @param typeSig the type signature.
+ * @return the default value.
+ * @exception IllegalArgumentException if this is a method type signature.
+ */
public static Object getDefaultValue(String typeSig) {
switch(typeSig.charAt(0)) {
case 'Z':
@@ -238,15 +317,7 @@ public class TypeSignature {
}
/**
- * Returns the number of words, an object of the given simple type
- * signature takes.
- */
- public static String getReturnType(String methodTypeSig) {
- return methodTypeSig.substring(methodTypeSig.lastIndexOf(')')+1);
- }
-
- /**
- * Check if there is a valid class name starting at index
+ * Checks if there is a valid class name starting at index
* in string typesig and ending with a semicolon.
* @return the index at which the class name ends.
* @exception IllegalArgumentException if there was an illegal character.
@@ -266,7 +337,7 @@ public class TypeSignature {
}
/**
- * Check if there is a valid simple type signature starting at index
+ * Checks if there is a valid simple type signature starting at index
* in string typesig.
* @return the index at which the type signature ends.
* @exception IllegalArgumentException if there was an illegal character.
@@ -285,6 +356,14 @@ public class TypeSignature {
return index;
}
+ /**
+ * Checks whether a given type signature is a valid (not method)
+ * type signature. Throws an exception otherwise.
+ * @param typeSig the type signature.
+ * @exception NullPointerException if typeSig is null.
+ * @exception IllegalArgumentException if typeSig is not a valid
+ * type signature or if it's a method type signature.
+ */
public static void checkTypeSig(String typesig)
throws IllegalArgumentException
{
@@ -298,6 +377,14 @@ public class TypeSignature {
}
}
+ /**
+ * Checks whether a given type signature is a valid method
+ * type signature. Throws an exception otherwise.
+ * @param typeSig the type signature.
+ * @exception NullPointerException if typeSig is null.
+ * @exception IllegalArgumentException if typeSig is not a valid
+ * method type signature.
+ */
public static void checkMethodTypeSig(String typesig)
throws IllegalArgumentException
{
diff --git a/jode/src/net/sf/jode/bytecode/package.html b/jode/src/net/sf/jode/bytecode/package.html
index 758de1d..dcf3e90 100644
--- a/jode/src/net/sf/jode/bytecode/package.html
+++ b/jode/src/net/sf/jode/bytecode/package.html
@@ -18,7 +18,7 @@
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-->
-JODE Bytecode Package
+Jode Bytecode Package
@@ -71,11 +71,36 @@ You can also use this package to create and write new classes:
...
+
+
+- You don't need to think of the constant pool, except when you want
+to write your custom attributes.
+- The set of opcodes is drastically reduced: For example you don't
+have to handle 20 different opcodes that all push a constant value on
+the stack. When reading it will automatically convert them to
+
ldc
or ldc2
and on writing it will convert
+them back.
+- Wide instructions are automatically generated when needed, large
+methods are supported.
+- The code is organized in {@link net.sf.jode.bytecode.BasicBlocks}
+which makes flow analysis much easier.
+- The memory consumption is quite moderate.
+
+
+Disadvantages
+
+- You can't change every byte. For example Jode decides itself if
+a lookup switch or table switch is generated.
+- Jode does a lot of checks when reading the bytecode and it is
+impossible to recover from errors. This makes it sometime hard to
+find out why the bytecode of a particular class files is invalid.
+
+
Jochen Hoenicke
-
+
-Last modified: Sun Aug 5 17:53:03 MEST 2001
+Last modified: Sat Aug 11 18:44:19 MEST 2001