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
           
 
Constructor Summary
UniqueProblemCases()
           
 
Method Summary
 void catchesNestedExceptions(java.lang.Integer[] I)
          Almost the same as the previous method, but unknown object never makes it into the LocalVariables array.
 void commandAction(javax.microedition.lcdui.Command c, javax.microedition.lcdui.Displayable d)
           
 void destroyApp(boolean unconditional)
           
 void itemStateChanged(javax.microedition.lcdui.Item item)
           
 void nestedExceptionHandlersConflictWithUnknown(java.lang.Integer[] I)
          Intended to show uninitialized try block frame, but fails for two totally unrelated reasons.
 void pauseApp()
           
 void startApp()
           
 void unreferencedHiddenObjectSignature()
          Has an object signature that isn't in the ConstantPool.
 void unreferencedObjectSignature()
          Has an object signature that isn't in the ConstantPool.
 
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
 

Field Detail

display

javax.microedition.lcdui.Display display

Hello

javax.microedition.lcdui.TextBox Hello
Constructor Detail

UniqueProblemCases

public UniqueProblemCases()
Method Detail

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.