710 }
711 stackMapFrames.add(StackMapFrameInfo.of(dflt, locals, List.of()));
712 cb.labelBinding(dflt)
713 .loadConstant(labelConstants.length)
714 .ireturn()
715 .with(StackMapTableAttribute.of(stackMapFrames));
716 DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
717 };
718 }
719
720 /*
721 * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
722 */
723 private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
724 boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
725 List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
726 List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
727
728 byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
729 clb -> {
730 clb.withFlags(AccessFlag.FINAL, AccessFlag.SUPER, AccessFlag.SYNTHETIC)
731 .withMethodBody("typeSwitch",
732 addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
733 ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
734 generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
735 });
736
737 try {
738 // this class is linked at the indy callsite; so define a hidden nestmate
739 MethodHandles.Lookup lookup;
740 lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
741 MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
742 "typeSwitch",
743 addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
744 if (addExtraInfo) {
745 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
746 List.copyOf(extraClassLabels));
747 }
748 return typeSwitch;
749 } catch (Throwable t) {
750 throw new IllegalArgumentException(t);
|
710 }
711 stackMapFrames.add(StackMapFrameInfo.of(dflt, locals, List.of()));
712 cb.labelBinding(dflt)
713 .loadConstant(labelConstants.length)
714 .ireturn()
715 .with(StackMapTableAttribute.of(stackMapFrames));
716 DirectCodeBuilder.withMaxs(cb, 3, locals.size()); // enum labels use 3 stack, others use 2
717 };
718 }
719
720 /*
721 * Construct the method handle that represents the method int typeSwitch(Object, int, BiPredicate, List)
722 */
723 private static MethodHandle generateTypeSwitch(MethodHandles.Lookup caller, Class<?> selectorType, Object[] labelConstants) {
724 boolean addExtraInfo = needsExtraInfo(selectorType, labelConstants);
725 List<EnumDesc<?>> enumDescs = addExtraInfo ? new ArrayList<>() : null;
726 List<Class<?>> extraClassLabels = addExtraInfo ? new ArrayList<>() : null;
727
728 byte[] classBytes = ClassFile.of(ClassFile.StackMapsOption.DROP_STACK_MAPS).build(ConstantUtils.binaryNameToDesc(typeSwitchClassName(caller.lookupClass())),
729 clb -> {
730 clb.withFlags(AccessFlag.FINAL, (PreviewFeatures.isEnabled()) ? AccessFlag.IDENTITY : AccessFlag.SUPER, AccessFlag.SYNTHETIC)
731 .withMethodBody("typeSwitch",
732 addExtraInfo ? MTD_TYPE_SWITCH_EXTRA : MTD_TYPE_SWITCH,
733 ClassFile.ACC_FINAL | ClassFile.ACC_PUBLIC | ClassFile.ACC_STATIC,
734 generateTypeSwitchSkeleton(selectorType, labelConstants, enumDescs, extraClassLabels));
735 });
736
737 try {
738 // this class is linked at the indy callsite; so define a hidden nestmate
739 MethodHandles.Lookup lookup;
740 lookup = caller.defineHiddenClass(classBytes, true, NESTMATE, STRONG);
741 MethodHandle typeSwitch = lookup.findStatic(lookup.lookupClass(),
742 "typeSwitch",
743 addExtraInfo ? MT_TYPE_SWITCH_EXTRA : MT_TYPE_SWITCH);
744 if (addExtraInfo) {
745 typeSwitch = MethodHandles.insertArguments(typeSwitch, 2, new ResolvedEnumLabels(caller, enumDescs.toArray(new EnumDesc<?>[0])),
746 List.copyOf(extraClassLabels));
747 }
748 return typeSwitch;
749 } catch (Throwable t) {
750 throw new IllegalArgumentException(t);
|