@SuppressWarnings("unchecked")
void writeSysCall(Class clazz, int INVOKE_TYPE, String method, Class returnClazz, Class... paramClasses) {
if (INVOKE_TYPE != INVOKESPECIAL && clazz != null) {
if (compiler.getScope().isDebugMode()) {
if (!methodExists(clazz, method, paramClasses)) {
throw new NoSuchMethodException(clazz, method, paramClasses);
}
}
}
Type[] args = new Type[paramClasses.length];
if (INVOKE_TYPE == INVOKEVIRTUAL || INVOKE_TYPE == INVOKEINTERFACE)
stackPop();
for (int i = 0; i < args.length; i++) {
args[i] = Type.getType(paramClasses[i]);
stackPop();
}
String owner = clazz == null ? this.method.clazz.node.name : Type.getInternalName(clazz);
if (clazz == null && this.method.clazz.entity.isTrait())
throw new CriticalException("[Compiler Error] Cannot use current classname in Trait");
code.add(new MethodInsnNode(
INVOKE_TYPE, owner, method, Type.getMethodDescriptor(Type.getType(returnClazz), args),
clazz != null && clazz.isInterface()
));
if (returnClazz != void.class) {
stackPush(null, StackItem.Type.valueOf(returnClazz));
}
}