for (int i=0; i<caseCount; i++) {
cases[i] = i;
}
Label[] switchLabels = new Label[caseCount];
Label noMatch = b.createLabel();
List[] caseMethods = caseMethods(caseCount, properties);
for (int i=0; i<caseCount; i++) {
List matches = caseMethods[i];
if (matches == null || matches.size() == 0) {
switchLabels[i] = noMatch;
} else {
switchLabels[i] = b.createLabel();
}
}
if (properties.length > 1) {
b.loadLocal(propertyVar);
b.invokeVirtual(String.class.getName(), "hashCode", TypeDesc.INT, null);
b.loadConstant(0x7fffffff);
b.math(Opcode.IAND);
b.loadConstant(caseCount);
b.math(Opcode.IREM);
b.switchBranch(cases, switchLabels, noMatch);
}
// Params to invoke String.equals.
TypeDesc[] params = {TypeDesc.OBJECT};
for (int i=0; i<caseCount; i++) {
List matches = caseMethods[i];
if (matches == null || matches.size() == 0) {
continue;
}
switchLabels[i].setLocation();
int matchCount = matches.size();
for (int j=0; j<matchCount; j++) {
BeanProperty bp = (BeanProperty)matches.get(j);
// Test against name to find exact match.
b.loadConstant(bp.getName());
b.loadLocal(propertyVar);
b.invokeVirtual(String.class.getName(), "equals", TypeDesc.BOOLEAN, params);
Label notEqual;
if (j == matchCount - 1) {
notEqual = null;
b.ifZeroComparisonBranch(noMatch, "==");
} else {
notEqual = b.createLabel();
b.ifZeroComparisonBranch(notEqual, "==");
}
switch (methodType) {
case READ_METHOD: case TRY_READ_METHOD: default: {
b.loadLocal(beanVar);
b.invoke(bp.getReadMethod());
TypeDesc type = TypeDesc.forClass(bp.getType());
b.convert(type, type.toObjectType());
b.returnValue(TypeDesc.OBJECT);
break;
}
case WRITE_METHOD: case TRY_WRITE_METHOD: {
b.loadLocal(beanVar);
b.loadLocal(valueVar);
TypeDesc type = TypeDesc.forClass(bp.getType());
b.checkCast(type.toObjectType());
b.convert(type.toObjectType(), type);
b.invoke(bp.getWriteMethod());
if (methodType == WRITE_METHOD) {
b.returnVoid();
} else {
b.loadConstant(true);
b.returnValue(TypeDesc.BOOLEAN);
}
break;
}
case HAS_READ_METHOD: case HAS_WRITE_METHOD: {
b.loadConstant(true);
b.returnValue(TypeDesc.BOOLEAN);
break;
}
}
if (notEqual != null) {
notEqual.setLocation();
}
}
}
noMatch.setLocation();