734 // no intrinsic associated
735 break;
736 default:
737 throw newInternalError("Unknown intrinsic: "+intr);
738 }
739
740 MemberName member = name.function.member();
741 if (isStaticallyInvocable(member)) {
742 emitStaticInvoke(member, name);
743 } else {
744 emitInvoke(name);
745 }
746 }
747
748 // return statement
749 emitReturn(onStack);
750
751 classFileEpilogue();
752 bogusMethod(lambdaForm);
753
754 final byte[] classFile = cw.toByteArray();
755 maybeDump(className, classFile);
756 return classFile;
757 }
758
759 void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); }
760 void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); }
761 void emitArrayLength(Name name) { emitArrayOp(name, Opcodes.ARRAYLENGTH); }
762
763 void emitArrayOp(Name name, int arrayOpcode) {
764 assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
765 Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
766 assert elementType != null;
767 emitPushArguments(name);
768 if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
769 Wrapper w = Wrapper.forPrimitiveType(elementType);
770 arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
771 }
772 mv.visitInsn(arrayOpcode);
773 }
774
775 /**
776 * Emit an invoke for the given name.
777 */
778 void emitInvoke(Name name) {
|
734 // no intrinsic associated
735 break;
736 default:
737 throw newInternalError("Unknown intrinsic: "+intr);
738 }
739
740 MemberName member = name.function.member();
741 if (isStaticallyInvocable(member)) {
742 emitStaticInvoke(member, name);
743 } else {
744 emitInvoke(name);
745 }
746 }
747
748 // return statement
749 emitReturn(onStack);
750
751 classFileEpilogue();
752 bogusMethod(lambdaForm);
753
754 final byte[] classFile;
755 try {
756 classFile = cw.toByteArray();
757 } catch (RuntimeException e) {
758 // ASM throws RuntimeException if something goes wrong - capture these and wrap them in a meaningful
759 // exception to support falling back to LambdaForm interpretation
760 throw new BytecodeGenerationException(e);
761 }
762 maybeDump(className, classFile);
763 return classFile;
764 }
765
766 @SuppressWarnings("serial")
767 static final class BytecodeGenerationException extends RuntimeException {
768 BytecodeGenerationException(Exception cause) {
769 super(cause);
770 }
771 }
772
773 void emitArrayLoad(Name name) { emitArrayOp(name, Opcodes.AALOAD); }
774 void emitArrayStore(Name name) { emitArrayOp(name, Opcodes.AASTORE); }
775 void emitArrayLength(Name name) { emitArrayOp(name, Opcodes.ARRAYLENGTH); }
776
777 void emitArrayOp(Name name, int arrayOpcode) {
778 assert arrayOpcode == Opcodes.AALOAD || arrayOpcode == Opcodes.AASTORE || arrayOpcode == Opcodes.ARRAYLENGTH;
779 Class<?> elementType = name.function.methodType().parameterType(0).getComponentType();
780 assert elementType != null;
781 emitPushArguments(name);
782 if (arrayOpcode != Opcodes.ARRAYLENGTH && elementType.isPrimitive()) {
783 Wrapper w = Wrapper.forPrimitiveType(elementType);
784 arrayOpcode = arrayInsnOpcode(arrayTypeCode(w), arrayOpcode);
785 }
786 mv.visitInsn(arrayOpcode);
787 }
788
789 /**
790 * Emit an invoke for the given name.
791 */
792 void emitInvoke(Name name) {
|