public static void addValuesEqualCall ( final CodeBuilder b , final TypeDesc valueType , final boolean testForNull , final Label label , final boolean choice ) { if ( valueType . getTypeCode ( ) != TypeDesc . OBJECT_CODE ) { if ( valueType . getTypeCode ( ) == TypeDesc . FLOAT_CODE ) { // Special treatment to handle NaN. b . invokeStatic ( TypeDesc . FLOAT . toObjectType ( ) , "compare" , TypeDesc . INT , new TypeDesc [ ] { TypeDesc . FLOAT , TypeDesc . FLOAT } ) ; b . ifZeroComparisonBranch ( label , choice ? "==" : "!=" ) ; } else if ( valueType . getTypeCode ( ) == TypeDesc . DOUBLE_CODE ) { // Special treatment to handle NaN. b . invokeStatic ( TypeDesc . DOUBLE . toObjectType ( ) , "compare" , TypeDesc . INT , new TypeDesc [ ] { TypeDesc . DOUBLE , TypeDesc . DOUBLE } ) ; b . ifZeroComparisonBranch ( label , choice ? "==" : "!=" ) ; } else { b . ifComparisonBranch ( label , choice ? "==" : "!=" , valueType ) ; } return ; } if ( ! testForNull ) { String op = addEqualsCallTo ( b , valueType , choice ) ; b . ifZeroComparisonBranch ( label , op ) ; return ; } Label isNotNull = b . createLabel ( ) ; LocalVariable value = b . createLocalVariable ( null , valueType ) ; b . storeLocal ( value ) ; b . loadLocal ( value ) ; b . ifNullBranch ( isNotNull , false ) ; // First value popped off stack is null. Just test remaining one for null. b . ifNullBranch ( label , choice ) ; Label cont = b . createLabel ( ) ; b . branch ( cont ) ; // First value popped off stack is not null, but second one might be. isNotNull . setLocation ( ) ; if ( compareToType ( valueType ) == null ) { // Call equals method, but swap values so that the second value is // an argument into the equals method. b . loadLocal ( value ) ; b . swap ( ) ; } else { // Need to test for second argument too, since compareTo method // cannot cope with null. LocalVariable value2 = b . createLocalVariable ( null , valueType ) ; b . storeLocal ( value2 ) ; b . loadLocal ( value2 ) ; b . ifNullBranch ( label , ! choice ) ; // Load both values in preparation for calling compareTo method. b . loadLocal ( value ) ; b . loadLocal ( value2 ) ; } String op = addEqualsCallTo ( b , valueType , choice ) ; b . ifZeroComparisonBranch ( label , op ) ; cont . setLocation ( ) ; }
Generates code to compare two values on the stack and branch to the provided Label if they are not equal . Both values must be of the same type . If they are floating point values NaN is considered equal to NaN which is inconsistent with the usual treatment for NaN .