paramTypes = constructor.getParameterTypes();
returnType = constructor.getDeclaringClass();
}
final int paramTypesLen = paramTypes.length;
final MethodWriter m = classWriter.visitMethod(Constants.ACC_PUBLIC, "invoke", "(Lwebit/script/Context;[Ljava/lang/Object;)Ljava/lang/Object;", null);
if (paramTypesLen == 0) {
if (isStatic) {
m.invokeStatic(ownerClass, destName, destDesc);
ASMUtil.visitBoxIfNeed(m, returnType);
m.visitInsn(Constants.ARETURN);
} else if (isConstructor) {
m.visitTypeInsn(Constants.NEW, ownerClass);
m.visitInsn(Constants.DUP);
m.visitMethodInsn(Constants.INVOKESPECIAL, ownerClass, "<init>", "()V");
m.visitInsn(Constants.ARETURN);
} else {
Label toExcaption = new Label();
m.visitVarInsn(Constants.ALOAD, 2);
m.visitJumpInsn(Constants.IFNULL, toExcaption);
m.visitVarInsn(Constants.ALOAD, 2);
m.visitInsn(Constants.ARRAYLENGTH);
m.visitJumpInsn(Constants.IFEQ, toExcaption);
m.visitVarInsn(Constants.ALOAD, 2);
m.visitInsn(Constants.ICONST_0);
m.visitInsn(Constants.AALOAD);
m.visitJumpInsn(Constants.IFNULL, toExcaption);
m.visitVarInsn(Constants.ALOAD, 2);
m.visitInsn(Constants.ICONST_0);
m.visitInsn(Constants.AALOAD);
m.checkCast(ownerClass);
m.visitMethodInsn(isInterface ? Constants.INVOKEINTERFACE
: Constants.INVOKEVIRTUAL, ownerClass, destName, destDesc);
ASMUtil.visitBoxIfNeed(m, returnType);
m.visitInsn(Constants.ARETURN);
m.visitLabel(toExcaption);
ASMUtil.visitScriptRuntimeException(m, "First argument can't be null.");
}
} else {
if (isConstructor) {
m.visitTypeInsn(Constants.NEW, ownerClass);
m.visitInsn(Constants.DUP);
}
m.visitVarInsn(Constants.ALOAD, 2);
m.push(isStatic || isConstructor ? paramTypesLen : paramTypesLen + 1);
m.invokeStatic("webit/script/util/ArrayUtil", "ensureMinSize", "([Ljava/lang/Object;I)[Ljava/lang/Object;");
m.visitVarInsn(Constants.ASTORE, 2);
int paramCount = 0;
if (!isStatic && !isConstructor) {
m.visitVarInsn(Constants.ALOAD, 2);
m.visitInsn(Constants.ICONST_0);
m.visitInsn(Constants.AALOAD);
m.checkCast(ownerClass);
paramCount++;
}
for (Class paramType : paramTypes) {
m.visitVarInsn(Constants.ALOAD, 2);
m.push(paramCount);
m.visitInsn(Constants.AALOAD);
m.checkCast(ASMUtil.getBoxedInternalName(paramType));
ASMUtil.visitUnboxIfNeed(m, paramType);
paramCount++;
}
//Invoke Method
m.visitMethodInsn(isStatic ? Constants.INVOKESTATIC
: isConstructor ? Constants.INVOKESPECIAL : isInterface ? Constants.INVOKEINTERFACE
: Constants.INVOKEVIRTUAL, ownerClass, destName, destDesc);
ASMUtil.visitBoxIfNeed(m, returnType);
m.visitInsn(Constants.ARETURN);
}
m.visitMaxs();
return (MethodDeclare) ASMUtil.loadClass(className, classWriter).newInstance();
}