public SubClassGenerator(ClassLoader parent) {
super(parent);
}
public <T> Class<? extends T> generate(Class<T> base, String name) {
ClassWriter cw = new ClassWriter(0);//?
cw.visit(49, ACC_PUBLIC, name.replace('.', '/'), null,
Type.getInternalName(base),null);
for (Constructor c : base.getDeclaredConstructors()) {
Class[] et = c.getExceptionTypes();
String[] exceptions = new String[et.length];
for (int i = 0; i < et.length; i++)
exceptions[i] = Type.getInternalName(et[i]);
String methodDescriptor = getMethodDescriptor(c);
MethodVisitor m = cw.visitMethod(c.getModifiers(), "<init>", methodDescriptor, null, exceptions);
m.visitCode();
int index=1;
m.visitVarInsn(ALOAD,0);
for (Class param : c.getParameterTypes()) {
Type t = Type.getType(param);
m.visitVarInsn(t.getOpcode(ILOAD), index);
index += t.getSize();
}
m.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(base), "<init>", methodDescriptor);
m.visitInsn(RETURN);
m.visitMaxs(index,index);
m.visitEnd();
}
cw.visitEnd();
byte[] image = cw.toByteArray();
Class<? extends T> c = defineClass(name, image, 0, image.length).asSubclass(base);
Jenkins h = Jenkins.getInstance();
if (h!=null) // null only during tests.