625 }
626
627 // finally, invoke the constructor and return
628 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true));
629 mv.visitInsn(ARETURN);
630 mv.visitMaxs(0, 0);
631 mv.visitEnd();
632
633 // emit copyWith()
634 mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
635 mv.visitCode();
636 // make instance
637 mv.visitTypeInsn(NEW, className);
638 mv.visitInsn(DUP);
639 // load mt, lf
640 mv.visitVarInsn(ALOAD, 1);
641 mv.visitVarInsn(ALOAD, 2);
642 // put fields on the stack
643 emitPushFields(types, className, mv);
644 // finally, invoke the constructor and return
645 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true));
646 mv.visitInsn(ARETURN);
647 mv.visitMaxs(0, 0);
648 mv.visitEnd();
649
650 // for each type, emit copyWithExtendT()
651 for (byte bt = 0; bt < ARG_TYPE_LIMIT; bt++) {
652 char t = basicTypeChar(bt);
653 mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
654 mv.visitCode();
655 // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
656 // obtain constructor
657 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
658 int iconstInsn = ICONST_0 + bt;
659 assert(iconstInsn <= ICONST_5);
660 mv.visitInsn(iconstInsn);
661 mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG);
662 mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
663 mv.visitInsn(ICONST_0);
664 mv.visitInsn(AALOAD);
665 // load mt, lf
666 mv.visitVarInsn(ALOAD, 1);
667 mv.visitVarInsn(ALOAD, 2);
668 // put fields on the stack
669 emitPushFields(types, className, mv);
670 // put narg on stack
671 mv.visitVarInsn(typeLoadOp(t), 3);
672 // finally, invoke the constructor and return
673 mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false), false);
674 mv.visitInsn(ARETURN);
675 mv.visitMaxs(0, 0);
676 mv.visitEnd();
677 }
678
679 // emit class initializer
680 mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
681 mv.visitCode();
|
625 }
626
627 // finally, invoke the constructor and return
628 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true));
629 mv.visitInsn(ARETURN);
630 mv.visitMaxs(0, 0);
631 mv.visitEnd();
632
633 // emit copyWith()
634 mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "copyWith", makeSignature("", false), null, null);
635 mv.visitCode();
636 // make instance
637 mv.visitTypeInsn(NEW, className);
638 mv.visitInsn(DUP);
639 // load mt, lf
640 mv.visitVarInsn(ALOAD, 1);
641 mv.visitVarInsn(ALOAD, 2);
642 // put fields on the stack
643 emitPushFields(types, className, mv);
644 // finally, invoke the constructor and return
645 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", makeSignature(types, true), false);
646 mv.visitInsn(ARETURN);
647 mv.visitMaxs(0, 0);
648 mv.visitEnd();
649
650 // for each type, emit copyWithExtendT()
651 for (byte bt = 0; bt < ARG_TYPE_LIMIT; bt++) {
652 char t = basicTypeChar(bt);
653 mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "copyWithExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
654 mv.visitCode();
655 // return SPECIES_DATA.extendWith(t).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
656 // obtain constructor
657 mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
658 int iconstInsn = ICONST_0 + bt;
659 assert(iconstInsn <= ICONST_5);
660 mv.visitInsn(iconstInsn);
661 mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWith", BMHSPECIES_DATA_EWI_SIG, false);
662 mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
663 mv.visitInsn(ICONST_0);
664 mv.visitInsn(AALOAD);
665 // load mt, lf
666 mv.visitVarInsn(ALOAD, 1);
667 mv.visitVarInsn(ALOAD, 2);
668 // put fields on the stack
669 emitPushFields(types, className, mv);
670 // put narg on stack
671 mv.visitVarInsn(typeLoadOp(t), 3);
672 // finally, invoke the constructor and return
673 mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false), false);
674 mv.visitInsn(ARETURN);
675 mv.visitMaxs(0, 0);
676 mv.visitEnd();
677 }
678
679 // emit class initializer
680 mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
681 mv.visitCode();
|