com.markcrocker.purifier.testcases
Class UniqueProblemCases
java.lang.Object
|
+--javax.microedition.midlet.MIDlet
|
+--com.markcrocker.purifier.testcases.UniqueProblemCases
- All Implemented Interfaces:
- javax.microedition.lcdui.CommandListener, javax.microedition.lcdui.ItemStateListener
- public class UniqueProblemCases
- extends javax.microedition.midlet.MIDlet
- implements javax.microedition.lcdui.CommandListener, javax.microedition.lcdui.ItemStateListener
The UniqueProblemCases class contains methods that are intended to illustrate
cases where the Purifier has problems. This class has some methods that rely on the absense of certain entries in the ConstantPool, so they're located here instead of the ProblemCases class.
Field Summary |
(package private) javax.microedition.lcdui.Display |
display
|
(package private) javax.microedition.lcdui.TextBox |
Hello
|
Methods inherited from class javax.microedition.midlet.MIDlet |
getAppProperty, notifyDestroyed, notifyPaused, resumeRequest |
Methods inherited from class java.lang.Object |
, clone, equals, finalize, getClass, hashCode, notify, notifyAll, registerNatives, toString, wait, wait, wait |
display
javax.microedition.lcdui.Display display
Hello
javax.microedition.lcdui.TextBox Hello
UniqueProblemCases
public UniqueProblemCases()
startApp
public void startApp()
throws javax.microedition.midlet.MIDletStateChangeException
- Overrides:
startApp
in class javax.microedition.midlet.MIDlet
pauseApp
public void pauseApp()
- Overrides:
pauseApp
in class javax.microedition.midlet.MIDlet
destroyApp
public void destroyApp(boolean unconditional)
throws javax.microedition.midlet.MIDletStateChangeException
- Overrides:
destroyApp
in class javax.microedition.midlet.MIDlet
itemStateChanged
public void itemStateChanged(javax.microedition.lcdui.Item item)
- Specified by:
itemStateChanged
in interface javax.microedition.lcdui.ItemStateListener
commandAction
public void commandAction(javax.microedition.lcdui.Command c,
javax.microedition.lcdui.Displayable d)
- Specified by:
commandAction
in interface javax.microedition.lcdui.CommandListener
nestedExceptionHandlersConflictWithUnknown
public void nestedExceptionHandlersConflictWithUnknown(java.lang.Integer[] I)
- Intended to show uninitialized try block frame, but fails for two totally
unrelated reasons. The primary reasons are discussed in the
ProblemCases.nestedExceptionHandlersConflict
method JavaDoc.
Even though the bytecode is identical, this case is slightly different because java.lang.String is not in the ConstantPool, which results in there being an unknown object stored in the LocalVariables. The resolveConflicts method handles this differently than in the nestedExceptionHandlersConflict method where the conflicting entries are replaced with a null. This time, since the NullPointerException is conflicting with an unknown object, so the NullPointerException wins.
The bytecode for this method is:
0: iconst_0
1: istore_2
2: iload_2
3: ifne #33
6: aload_1
7: iload_2
8: aaload
9: astore_3
10: aload_3
11: invokevirtual java.lang.Integer.toString ()Ljava/lang/String; (11)
14: astore %4
16: goto #24
19: astore %4
21: bipush 7
23: istore_2
24: goto #30
27: astore_3
28: iconst_3
29: istore_2
30: iinc %2 1
33: return
java.lang.String isn't in the ConstantPool, so String t ends up as an unknown object that gets stored in LocalVariables slot 4 at offset 14. At offset 24 there is a conflict between this unknown and the NullPointerException that gets stored in slot 4 by the inner excetion handler at offset 19. Since the challenger is challenging an unknown, the unknown looses and the Purifier puts an NPE in the StackMap at offset 24:
offset = 24,
locals = {
(type=Object, (17)class=com.markcrocker.purifier.testcases.UniqueProblemCases),
(type=Object, (84)class=[Ljava.lang.Integer;),
(type=Integer),
(type=Object, (15)class=java.lang.Integer),
(type=Object, (12)class=java.lang.NullPointerException)
}
Sun's StackMap has:
offset = 24
locals = {
(type=Object, (23)class=com.markcrocker.purifier.testcases.ProblemCases),
(type=Object, (102)class=[Ljava.lang.Integer;),
(type=Integer),
(type=Object, (21)class=java.lang.Integer),
(type=Object, (104)class=java.lang.Object)
}
Note that the JavaDoc generator messes up the formatting of this. See the actual source code for better formatting.
catchesNestedExceptions
public void catchesNestedExceptions(java.lang.Integer[] I)
- Almost the same as the
previous
method, but unknown object never makes it into the LocalVariables array. This makes it clear that there's something wierd about the way that Sun puts a java.lang.Ojbect to the LocalVariables array where an Integer and an Exception conflict. The Purifier deletes the entry as junk just like it does in the ProblemCases.nestedExceptionHandlersConflict method.
unreferencedObjectSignature
public void unreferencedObjectSignature()
- Has an object signature that isn't in the ConstantPool. If the comments
are removed, then the compiler will add the object class to the ConstantPool because the StackMap will need to reference the object class and it will no longer be unreferenced.
unreferencedHiddenObjectSignature
public void unreferencedHiddenObjectSignature()
- Has an object signature that isn't in the ConstantPool. Unlike the
previous method, this unknown object LocalVariables entry is not destined for the StackMap, so the compiler can treat it as junk data and omit it from the ConstantPool.