+ tsmb.returnValue(TypeDesc.INT);
+ tsmb.finish();
+ }
+ }
+
+ public static void equals(MethodBuilderBase mb, TypeDesc typeDesc, Label failure) {
+ if(typeDesc.isPrimitive())
+ mb.ifComparisonBranch(failure, "!=", typeDesc);
+ else {
+ Label isNull = mb.createLabel();
+ Label finished = mb.createLabel();
+ mb.swap();
+ mb.dup();
+ mb.ifNullBranch(isNull, true);
+ mb.swap();
+ mb.invokeVirtual("java/lang/Object", "equals", TypeDesc.BOOLEAN, Constants.OBJECTS[1]);
+ mb.ifZeroComparisonBranch(failure, "==");
+ mb.branch(finished);
+ mb.setLocation(isNull);
+ mb.pop();
+ mb.ifNullBranch(failure, false);
+ mb.setLocation(finished);
+ }
+ }
+
+ /**
+ * Calculates the hash code of a value in stack.
+ */
+ public static void hashCode(MethodBuilderBase mb, TypeDesc typeDesc) {
+ switch(typeDesc.getTypeCode()) {
+ case TypeDesc.INT_CODE:
+ break;
+ case TypeDesc.OBJECT_CODE: {
+ Label isNull = mb.createLabel();
+ Label finished = mb.createLabel();
+ mb.dup();
+ mb.ifNullBranch(isNull, true);
+ mb.invokeVirtual("java/lang/Object", "hashCode", TypeDesc.INT, Constants.EMPTY_TYPEDESC_ARRAY);
+ mb.branch(finished);
+ mb.setLocation(isNull);
+ mb.pop();
+ mb.loadConstant(0);
+ mb.setLocation(finished);
+ } break;
+ case TypeDesc.DOUBLE_CODE:
+ mb.invokeStatic("java/lang/Double", "doubleToLongBits", TypeDesc.LONG, new TypeDesc[] { TypeDesc.DOUBLE });
+ case TypeDesc.LONG_CODE:
+ mb.dup2();
+ mb.loadConstant(32);
+ mb.math(Opcodes.LSHR);
+ mb.math(Opcodes.LXOR);
+ mb.convert(TypeDesc.LONG, TypeDesc.INT);
+ break;
+ case TypeDesc.FLOAT_CODE:
+ mb.invokeStatic("java/lang/Float", "floatToIntBits", TypeDesc.INT, new TypeDesc[] { TypeDesc.FLOAT });
+ break;
+ default:
+ mb.convert(typeDesc, TypeDesc.INT);