*/
public final void visit_checkcast(VmConstClass classRef) {
// Resolve classRef
classRef.resolve(loader);
final VmType<?> resolvedType = classRef.getResolvedVmClass();
final Label curInstrLabel = getCurInstrLabel();
if (resolvedType.isInterface() || resolvedType.isArray()) {
// ClassRef is an interface or array, do the slow test
// Pre-claim ECX
L1AHelper.requestRegister(eContext, helper.AAX);
// check that top item is a reference
final RefItem ref = vstack.popRef();
// Load the ref
ref.load(eContext);
final GPR refr = ref.getRegister();
final GPR classr = helper.AAX;
final GPR cntr = (GPR) L1AHelper.requestRegister(eContext,
JvmType.INT, false);
final GPR tmpr = (GPR) L1AHelper.requestRegister(eContext,
JvmType.REFERENCE, false);
// Resolve the class
writeResolveAndLoadClassToReg(classRef, classr);
helper.writeClassInitialize(curInstrLabel, classr, tmpr, resolvedType);
final Label okLabel = new Label(curInstrLabel + "cc-ok");
/* Is objectref null? */
os.writeTEST(refr, refr);
os.writeJCC(okLabel, X86Constants.JZ);
/* Is instanceof? */
instanceOf(refr, classr, tmpr, cntr, okLabel, true);
/* Not instanceof */
// Call classCastFailed
os.writePUSH(refr);
os.writePUSH(classr);
// Release temp registers here, so invokeJavaMethod can use it
L1AHelper.releaseRegister(eContext, cntr);
L1AHelper.releaseRegister(eContext, tmpr);
L1AHelper.releaseRegister(eContext, classr);
invokeJavaMethod(context.getClassCastFailedMethod());
/* Normal exit */
os.setObjectRef(okLabel);
// Leave ref on stack
vstack.push(ref);
} else {
// classRef is a class, do the fast test
// Pre-claim EAX/RAX
L1AHelper.requestRegister(eContext, helper.AAX);
// check that top item is a reference
final RefItem ref = vstack.popRef();
// Load the ref
ref.load(eContext);
final GPR refr = ref.getRegister();
final GPR tmpr = (GPR) L1AHelper.requestRegister(eContext,
JvmType.REFERENCE, false);
final Label okLabel = new Label(curInstrLabel + "cc-ok");
// Is objectref null?
os.writeTEST(refr, refr);
os.writeJCC(okLabel, X86Constants.JZ);
// Is instanceof?