Current host interop uses reflection, which requires pre-existing classes Work around this by: Generate a stub class that has the same interfaces and fields as the class we are generating. Use it as a type hint for this, and bind the simple name of the class to this stub (in resolve etc) Unmunge the
(String superName, NewInstanceExpr ret, String[] interfaceNames, Object frm)
| 8689 | * Unmunge the name (using a magic prefix) on any code gen for classes |
| 8690 | */ |
| 8691 | static Class compileStub(String superName, NewInstanceExpr ret, String[] interfaceNames, Object frm){ |
| 8692 | ClassWriter cw = classWriter(); |
| 8693 | ClassVisitor cv = cw; |
| 8694 | cv.visit(V1_8, ACC_PUBLIC + ACC_SUPER, COMPILE_STUB_PREFIX + "/" + ret.internalName, |
| 8695 | null,superName,interfaceNames); |
| 8696 | |
| 8697 | //instance fields for closed-overs |
| 8698 | for(ISeq s = RT.keys(ret.closes); s != null; s = s.next()) |
| 8699 | { |
| 8700 | LocalBinding lb = (LocalBinding) s.first(); |
| 8701 | int access = ACC_PUBLIC + (ret.isVolatile(lb) ? ACC_VOLATILE : |
| 8702 | ret.isMutable(lb) ? 0 : |
| 8703 | ACC_FINAL); |
| 8704 | if(lb.getPrimitiveType() != null) |
| 8705 | cv.visitField(access |
| 8706 | , lb.name, Type.getType(lb.getPrimitiveType()).getDescriptor(), |
| 8707 | null, null); |
| 8708 | else |
| 8709 | //todo - when closed-overs are fields, use more specific types here and in ctor and emitLocal? |
| 8710 | cv.visitField(access |
| 8711 | , lb.name, OBJECT_TYPE.getDescriptor(), null, null); |
| 8712 | } |
| 8713 | |
| 8714 | //ctor that takes closed-overs and does nothing |
| 8715 | Method m = new Method("<init>", Type.VOID_TYPE, ret.ctorTypes()); |
| 8716 | GeneratorAdapter ctorgen = new GeneratorAdapter(ACC_PUBLIC, |
| 8717 | m, |
| 8718 | null, |
| 8719 | null, |
| 8720 | cv); |
| 8721 | ctorgen.visitCode(); |
| 8722 | ctorgen.loadThis(); |
| 8723 | ctorgen.invokeConstructor(Type.getObjectType(superName), voidctor); |
| 8724 | ctorgen.returnValue(); |
| 8725 | ctorgen.endMethod(); |
| 8726 | |
| 8727 | if(ret.altCtorDrops > 0) |
| 8728 | { |
| 8729 | Type[] ctorTypes = ret.ctorTypes(); |
| 8730 | Type[] altCtorTypes = new Type[ctorTypes.length-ret.altCtorDrops]; |
| 8731 | for(int i=0;i<altCtorTypes.length;i++) |
| 8732 | altCtorTypes[i] = ctorTypes[i]; |
| 8733 | Method alt = new Method("<init>", Type.VOID_TYPE, altCtorTypes); |
| 8734 | ctorgen = new GeneratorAdapter(ACC_PUBLIC, |
| 8735 | alt, |
| 8736 | null, |
| 8737 | null, |
| 8738 | cv); |
| 8739 | ctorgen.visitCode(); |
| 8740 | ctorgen.loadThis(); |
| 8741 | ctorgen.loadArgs(); |
| 8742 | |
| 8743 | ctorgen.visitInsn(Opcodes.ACONST_NULL); //__meta |
| 8744 | ctorgen.visitInsn(Opcodes.ACONST_NULL); //__extmap |
| 8745 | ctorgen.visitInsn(Opcodes.ICONST_0); //__hash |
| 8746 | ctorgen.visitInsn(Opcodes.ICONST_0); //__hasheq |
| 8747 | |
| 8748 | ctorgen.invokeConstructor(Type.getObjectType(COMPILE_STUB_PREFIX + "/" + ret.internalName), |
no test coverage detected