self.util_fn_pfx = """package org.ldk.structs;
import org.ldk.impl.bindings;
+import org.ldk.enums.*;
+import org.ldk.util.*;
import java.util.Arrays;
import javax.annotation.Nullable;
-import org.ldk.enums.*;
public class UtilMethods {
"""
#include <stdatomic.h>
#include <stdlib.h>
+#define LIKELY(v) __builtin_expect(!!(v), 1)
+#define UNLIKELY(v) __builtin_expect(!!(v), 0)
+
"""
if self.target == Target.ANDROID:
out_java_enum = "package org.ldk.enums;\n\n"
out_java = ""
out_c = ""
- out_c = out_c + "static inline LDK" + struct_name + " LDK" + struct_name + "_from_java(" + self.c_fn_args_pfx + ") {\n"
- out_c = out_c + "\tswitch ((*env)->CallIntMethod(env, clz, ordinal_meth)) {\n"
+ out_c += "static inline LDK" + struct_name + " LDK" + struct_name + "_from_java(" + self.c_fn_args_pfx + ") {\n"
+ out_c += "\tjint ord = (*env)->CallIntMethod(env, clz, ordinal_meth);\n"
+ out_c += "\tif (UNLIKELY((*env)->ExceptionCheck(env))) {\n"
+ out_c += "\t\t(*env)->ExceptionDescribe(env);\n"
+ out_c += "\t\t(*env)->FatalError(env, \"A call to " + struct_name + ".ordinal() from rust threw an exception.\");\n"
+ out_c += "\t}\n"
+ out_c += "\tswitch (ord) {\n"
if enum_doc_comment is not None:
out_java_enum += "/**\n * " + enum_doc_comment.replace("\n", "\n * ") + "\n */\n"
out_java_enum = out_java_enum + "\tstatic { init(); }\n"
out_java_enum = out_java_enum + "}"
out_java = out_java + "\tstatic { " + struct_name + ".values(); /* Force enum statics to run */ }\n"
- out_c = out_c + "\t}\n"
- out_c = out_c + "\tabort();\n"
- out_c = out_c + "}\n"
+ out_c += "\t}\n"
+ out_c += "\t(*env)->FatalError(env, \"A call to " + struct_name + ".ordinal() from rust returned an invalid value.\");\n"
+ out_c += "\tabort(); // Unreachable, but will let the compiler know we don't return here\n"
+ out_c += "}\n"
out_c = out_c + "static jclass " + struct_name + "_class = NULL;\n"
for var, _ in variants:
out_c = out_c + "static jmethodID " + struct_name + "_" + var + "_meth = NULL;\n"
out_c = out_c + self.c_fn_ty_pfx + "void JNICALL Java_org_ldk_impl_bindings_00024" + struct_name.replace("_", "_1") + "_init (" + self.c_fn_args_pfx + ") {\n"
for var_name in variants:
- out_c = out_c + "\t" + struct_name + "_" + var_name + "_class =\n"
- if self.target == Target.ANDROID:
- out_c = out_c + "\t\t(*env)->NewGlobalRef(env, (*env)->FindClass(env, \"org/ldk/impl/bindings$" + struct_name + "$" + var_name + "\"));\n"
- else:
- out_c = out_c + "\t\t(*env)->NewGlobalRef(env, (*env)->FindClass(env, \"Lorg/ldk/impl/bindings$" + struct_name + "$" + var_name + ";\"));\n"
- out_c = out_c + "\tCHECK(" + struct_name + "_" + var_name + "_class != NULL);\n"
- out_c = out_c + "\t" + struct_name + "_" + var_name + "_meth = (*env)->GetMethodID(env, " + struct_name + "_" + var_name + "_class, \"<init>\", \"(" + init_meth_jty_strs[var_name] + ")V\");\n"
- out_c = out_c + "\tCHECK(" + struct_name + "_" + var_name + "_meth != NULL);\n"
+ out_c += "\t" + struct_name + "_" + var_name + "_class =\n"
+ out_c += "\t\t(*env)->NewGlobalRef(env, (*env)->FindClass(env, \"org/ldk/impl/bindings$" + struct_name + "$" + var_name + "\"));\n"
+ out_c += "\tCHECK(" + struct_name + "_" + var_name + "_class != NULL);\n"
+ out_c += "\t" + struct_name + "_" + var_name + "_meth = (*env)->GetMethodID(env, " + struct_name + "_" + var_name + "_class, \"<init>\", \"(" + init_meth_jty_strs[var_name] + ")V\");\n"
+ out_c += "\tCHECK(" + struct_name + "_" + var_name + "_meth != NULL);\n"
out_c = out_c + "}\n"
return out_c
out_c = out_c + ", " + arg_info.arg_name
out_c = out_c + ");\n"
- out_c += "\tif ((*env)->ExceptionCheck(env)) {\n"
+ out_c += "\tif (UNLIKELY((*env)->ExceptionCheck(env))) {\n"
out_c += "\t\t(*env)->ExceptionDescribe(env);\n"
out_c += "\t\t(*env)->FatalError(env, \"A call to " + fn_line.fn_name + " in " + struct_name + " from rust threw an exception.\");\n"
out_c += "\t}\n"
out_java += (arg_conv_info.java_ty + " " + arg_conv_info.arg_name)
out_java_struct = ""
+ extra_java_struct_out = ""
if not args_known:
out_java_struct += ("\t// Skipped " + method_name + "\n")
else:
out_java_struct += "\tpublic static " + return_type_info.java_hu_ty + " with_default("
else:
out_java_struct += "\tpublic static " + return_type_info.java_hu_ty + " " + meth_n + "("
+ elif meth_n == "clone_ptr":
+ out_java_struct += ("\t" + return_type_info.java_hu_ty + " " + meth_n + "(")
else:
+ if meth_n == "hash" and return_type_info.java_hu_ty == "long":
+ extra_java_struct_out = "\t@Override public int hashCode() {\n"
+ extra_java_struct_out += "\t\treturn (int)this.hash();\n"
+ extra_java_struct_out += "\t}\n"
+ elif meth_n == "eq" and return_type_info.java_hu_ty == "boolean":
+ extra_java_struct_out = "\t@Override public boolean equals(Object o) {\n"
+ extra_java_struct_out += "\t\tif (!(o instanceof " + struct_meth + ")) return false;\n"
+ extra_java_struct_out += "\t\treturn this.eq((" + struct_meth + ")o);\n"
+ extra_java_struct_out += "\t}\n"
out_java_struct += ("\tpublic " + return_type_info.java_hu_ty + " " + meth_n + "(")
for idx, arg in enumerate(argument_types):
if idx != 0:
out_java_struct += ("\t\treturn ret;\n")
out_java_struct += ("\t}\n\n")
- return (out_java, out_c, out_java_struct)
+ return (out_java, out_c, out_java_struct + extra_java_struct_out)