com.markcrocker.purifier.testcases
Class SpecialCases
java.lang.Object
|
+--javax.microedition.midlet.MIDlet
|
+--com.markcrocker.purifier.testcases.SpecialCases
- All Implemented Interfaces:
- javax.microedition.lcdui.CommandListener, javax.microedition.lcdui.ItemStateListener
- public class SpecialCases
- extends javax.microedition.midlet.MIDlet
- implements javax.microedition.lcdui.CommandListener, javax.microedition.lcdui.ItemStateListener
The SpecialCases class file is designed to provide a set of Java structures
that can be used to check the Purifier StackMapGen.generate against special cases that it has been designed to recognize and compensate for.
Field Summary |
(package private) javax.microedition.lcdui.Display |
display
|
(package private) javax.microedition.lcdui.TextBox |
Hello
|
Method Summary |
void |
commandAction(javax.microedition.lcdui.Command c,
javax.microedition.lcdui.Displayable d)
|
void |
destroyApp(boolean unconditional)
|
void |
itemStateChanged(javax.microedition.lcdui.Item item)
|
void |
legitimateBogusInStackMap()
Produces a StackMap that legitimately has an ITEM_Bogus in the StackMap. |
void |
multipleBranchesWithSameTarget()
All branches in this method end up going to the iinc instruction at the
end of the method. |
void |
newObjectOnStack()
Puts an ITEM_NewObject on the stack. |
void |
pauseApp()
|
void |
startApp()
|
void |
takesLongPrimitivesAndObjects(long i,
java.lang.String s,
int j,
java.lang.String t,
long k,
java.lang.String u,
int l,
java.lang.String v)
Longs take up two slots in local variables. |
void |
typeNotDeclared()
the string, startsNull is stored on the LocalVariables array as an
ITEM_Null at first, because there is no way to tell what type it is when the Purifier gets to the aconst_null instruction. |
void |
unreferencedObjectSignatureInStackMap()
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 |
display
javax.microedition.lcdui.Display display
Hello
javax.microedition.lcdui.TextBox Hello
SpecialCases
public SpecialCases()
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
typeNotDeclared
public void typeNotDeclared()
- the string, startsNull is stored on the LocalVariables array as an
ITEM_Null at first, because there is no way to tell what type it is when the Purifier gets to the aconst_null instruction. Inside of the if block, the variable is set to [Ljava.lang.String;. Then at the iinc instruction, a conflict is detected between the two Frames. One has an ITEM_Null in the LocalVariables and the other has a [Ljava.lang.String; and the resolveConflicts method correctly determines that the latter is the correct one to use.
legitimateBogusInStackMap
public void legitimateBogusInStackMap()
- Produces a StackMap that legitimately has an ITEM_Bogus in the StackMap.
This is because the int j is stored in LocalVariables slot 2 and is not initialized unless the if block is used. Since j has only got a transient value and isn't used outside of the if block, then at the point that the StackMap entry is created the LocalVariables slot 2 is null (not ITEM_Null). Although trailing nulls are simply trimmed off of the StackMap, nulls in the middle are represented as ITEM_Bogus, which is what happens in this case.
takesLongPrimitivesAndObjects
public void takesLongPrimitivesAndObjects(long i,
java.lang.String s,
int j,
java.lang.String t,
long k,
java.lang.String u,
int l,
java.lang.String v)
- Longs take up two slots in local variables. Requires attention to detail
when setting up frame. The initial frame looks like:
Local Variables:
0: (type=Object, class=com.markcrocker.purifier.testcases.SpecialCases)
1: (type=Long)
2: null
3: (type=Object, class=java.lang.String)
4: (type=Integer)
5: (type=Object, class=java.lang.String)
6: (type=Long)
7: null
8: (type=Object, class=java.lang.String)
9: (type=Integer)
10: (type=Object, class=java.lang.String)
OperandStack:
Slots used: 0 MaxStack: 4.
The fact that slots 1 and 6 are Longs and 2 and 7 are nulls is the important point here. In CLDC 1.1, there has been a new type, ITEM_Top to deal with this situation and it is set up with the other way around. That is, slots 1 and 6 would hold ITEM_Top entries and 2 and 7 would hold the ITEM_Long entries.
unreferencedObjectSignatureInStackMap
public void unreferencedObjectSignatureInStackMap()
- Has an object signature that isn't in the ConstantPool. It occurs
because the .equals method expects a type of Ljava.lang.Object;, which isn't actually used anywhere in the rest of the method or any of the other methods in this class, so there's no point of putting an entry for it in the ConstantPool. This doesn't cause any problems because the invokeInstruction method recognizes that the Ljava.lang.String; that is used for the equals method argument is a better entry to use than the unknown object.
multipleBranchesWithSameTarget
public void multipleBranchesWithSameTarget()
- All branches in this method end up going to the iinc instruction at the
end of the method. Since Integer J and Integer I are just used inside of if blocks and do not appear outside, they are junk variables. However, the branch targets that contain them add them to the LocalVariables array (entries 2 and 3), so, when the iinc is investigated, there is a conflict because of the extra entries in the LocalVariables. The resolveConflicts method correctly notices that they are opposed by null entries in the straight-through Frame, so they are eliminated.
newObjectOnStack
public void newObjectOnStack()
- Puts an ITEM_NewObject on the stack. Also illustrates the stack
order swap issue.