Update CI references to 0.0.122
[ldk-java] / csharp_strings.py
index b1ae3d20e2349c9547af623411744accbc3a26b2..a73ee2035d310be2568fa48f71b94ab9994ea3e4 100644 (file)
@@ -3,7 +3,9 @@ from enum import Enum
 import sys
 
 class Target(Enum):
-    CSHARP = 1,
+    WINDOWS = 1,
+    LINUX = 2,
+    PTHREAD = 3,
 
 def first_to_lower(string: str) -> str:
     first = string[0]
@@ -150,6 +152,28 @@ public class CommonBase {
        }
 }"""
 
+        self.witness_program_defn = """public class WitnessProgram : CommonBase {
+       /** The witness program bytes themselves */
+       public readonly byte[] program;
+       /** The witness version */
+       public readonly WitnessVersion version;
+
+       internal WitnessProgram(object _dummy, long ptr) : base(ptr) {
+               this.program = InternalUtils.decodeUint8Array(bindings.WitnessProgram_get_program(ptr));
+               this.version = new WitnessVersion(bindings.WitnessProgram_get_version(ptr));
+       }
+       static private long check_args(byte[] program, WitnessVersion version) {
+               if (program.Length < 2 || program.Length > 40) throw new ArgumentException();
+               if (version.getVal() == 0 && program.Length != 20 && program.Length != 32) throw new ArgumentException();
+               return InternalUtils.encodeUint8Array(program);
+       }
+       public WitnessProgram(byte[] program, WitnessVersion version) :
+               this(null, bindings.WitnessProgram_new(version.getVal(), check_args(program, version))) {}
+
+       ~WitnessProgram() {
+               if (ptr != 0) { bindings.WitnessProgram_free(ptr); }
+       }
+}"""
 
         self.c_file_pfx = """
 // On OSX jlong (ie long long) is not equivalent to int64_t, so we override here
@@ -166,7 +190,25 @@ public class CommonBase {
 
         self.c_file_pfx = self.c_file_pfx + "#include <stdio.h>\n#define DEBUG_PRINT(...) fprintf(stderr, __VA_ARGS__)\n"
 
-        if not DEBUG or sys.platform == "darwin":
+        if self.target == Target.WINDOWS:
+            self.c_file_pfx = self.c_file_pfx + """#include <heapapi.h>
+static HANDLE process_heap = NULL;
+static inline void* init_heap() {
+       if (UNLIKELY(process_heap == NULL)) {
+               // Assume pointer writes wont tear, which is true where we need it.
+               process_heap = GetProcessHeap();
+       }
+}
+static inline void* MALLOC(size_t a, const char* _) {
+       init_heap();
+       return HeapAlloc(process_heap, HEAP_ZERO_MEMORY, a);
+}
+#define do_MALLOC(a, b, _c) MALLOC(a, b)
+#define FREE(p) if ((uint64_t)(p) > 4096) { init_heap(); HeapFree(process_heap, 0, p); }
+#define CHECK_ACCESS(p)
+#define CHECK_INNER_FIELD_ACCESS_OR_NULL(v)
+"""
+        elif not DEBUG or self.target != Target.LINUX:
             self.c_file_pfx = self.c_file_pfx + """#define do_MALLOC(a, _b, _c) malloc(a)
 #define MALLOC(a, _) malloc(a)
 #define FREE(p) if ((uint64_t)(p) > 4096) { free(p); }
@@ -192,7 +234,7 @@ void __attribute__((constructor)) debug_log_version() {
 }
 """
 
-            if sys.platform != "darwin":
+            if self.target == Target.LINUX:
                 self.c_file_pfx += """
 // Running a leak check across all the allocations and frees of the JDK is a mess,
 // so instead we implement our own naive leak checker here, relying on the -wrap
@@ -350,6 +392,18 @@ _Static_assert(offsetof(LDKCVec_u8Z, datalen) == offsetof(LDKu8slice, datalen),
 
 _Static_assert(sizeof(void*) <= 8, "Pointers must fit into 64 bits");
 
+// Int types across Windows/Linux are different, so make sure we're using the right headers.
+_Static_assert(sizeof(void*) == sizeof(uintptr_t), "stdints must be correct");
+_Static_assert(sizeof(void*) == sizeof(intptr_t), "stdints must be correct");
+_Static_assert(sizeof(uint64_t) == 8, "stdints must be correct");
+_Static_assert(sizeof(int64_t) == 8, "stdints must be correct");
+_Static_assert(sizeof(uint32_t) == 4, "stdints must be correct");
+_Static_assert(sizeof(int32_t) == 4, "stdints must be correct");
+_Static_assert(sizeof(uint16_t) == 2, "stdints must be correct");
+_Static_assert(sizeof(int16_t) == 2, "stdints must be correct");
+_Static_assert(sizeof(uint8_t) == 1, "stdints must be correct");
+_Static_assert(sizeof(int8_t) == 1, "stdints must be correct");
+
 #define DECL_ARR_TYPE(ty, name) \\
        struct name##array { \\
                uint64_t arr_len; /* uint32_t would suffice but we want to align uint64_ts as well */ \\
@@ -391,11 +445,11 @@ static inline LDKStr str_ref_to_owned_c(const jstring str) {
 typedef bool jboolean;
 
 int64_t CS_LDK_allocate_buffer(int64_t len) {
-       return MALLOC(len, "C#-requested buffer");
+       return (int64_t)MALLOC(len, "C#-requested buffer");
 }
 
 void CS_LDK_free_buffer(int64_t buf) {
-       FREE(buf);
+       FREE((void*)buf);
 }
 
 jstring CS_LDK_get_ldk_c_bindings_version() {
@@ -522,12 +576,12 @@ int CS_LDK_register_{fn_suffix}_invoker(invoker_{fn_suffix} invoker) {{
         return "InternalUtils.getArrayLength(" + arr_name + ")"
 
     def get_java_arr_elem(self, elem_ty, arr_name, idx):
-        if elem_ty.c_ty == "int64_t" or elem_ty.c_ty == "uint64_t" or elem_ty.c_ty.endswith("Array") or elem_ty.c_ty == "uintptr_t":
+        if elem_ty.c_ty == "int64_t" or elem_ty.c_ty == "uint64_t":
+            return "InternalUtils.getU64ArrayElem(" + arr_name + ", " + idx + ")"
+        elif elem_ty.c_ty.endswith("Array") or elem_ty.c_ty == "uintptr_t" or elem_ty.rust_obj == "LDKStr":
             return "InternalUtils.getU64ArrayElem(" + arr_name + ", " + idx + ")"
         elif elem_ty.rust_obj == "LDKU5":
             return "InternalUtils.getU8ArrayElem(" + arr_name + ", " + idx + ")"
-        elif elem_ty.rust_obj == "LDKStr":
-            return "InternalUtils.getU32ArrayElem(" + arr_name + ", " + idx + ")"
         else:
             assert False
 
@@ -915,7 +969,10 @@ public class {struct_name.replace("LDK","")} : CommonBase {{
                 for arg_info in fn_line.args_ty:
                     fn_suffix += ty_to_c(arg_info.java_ty, arg_info)
                     fn_java_callback_args += ", " + arg_info.java_ty + " " + chr(ord("a") + idx)
-                    fn_c_callback_args += ", " + arg_info.c_ty + " " + chr(ord("a") + idx)
+                    if arg_info.c_ty.endswith("Array") or arg_info.c_ty == "jstring":
+                        fn_c_callback_args += ", int64_t " + chr(ord("a") + idx)
+                    else:
+                        fn_c_callback_args += ", " + arg_info.c_ty + " " + chr(ord("a") + idx)
                     if idx != 0:
                         fn_callback_call_args += ", "
                     fn_callback_call_args += chr(ord("a") + idx)
@@ -933,13 +990,16 @@ public class {struct_name.replace("LDK","")} : CommonBase {{
                     out_c += "\tuint64_t ret = js_invoke_function_" + fn_suffix + "(j_calls->instance_ptr, " + str(self.function_ptr_counter)
 
                 if fn_suffix not in self.function_ptrs:
-                    self.function_ptrs[fn_suffix] = {"args": [fn_java_callback_args, fn_c_callback_args], "ret": [fn_line.ret_ty_info.java_ty, fn_line.ret_ty_info.c_ty]}
+                    caller_ret_c_ty = fn_line.ret_ty_info.c_ty
+                    if fn_line.ret_ty_info.c_ty.endswith("Array") or fn_line.ret_ty_info.c_ty == "jstring":
+                        caller_ret_c_ty = "int64_t"
+                    self.function_ptrs[fn_suffix] = {"args": [fn_java_callback_args, fn_c_callback_args], "ret": [fn_line.ret_ty_info.java_ty, caller_ret_c_ty]}
                 self.function_ptrs[fn_suffix][self.function_ptr_counter] = (struct_name, fn_line.fn_name, fn_callback_call_args)
                 self.function_ptr_counter += 1
 
                 for idx, arg_info in enumerate(fn_line.args_ty):
                     if arg_info.ret_conv is not None:
-                        if arg_info.c_ty.endswith("Array"):
+                        if arg_info.c_ty.endswith("Array") or arg_info.c_ty == "jstring":
                             out_c += ", (int64_t)" + arg_info.ret_conv_name
                         else:
                             out_c += ", " + arg_info.ret_conv_name
@@ -1424,10 +1484,11 @@ public class {struct_name.replace("LDK","")} : CommonBase {{
                }}
        }}
        public delegate {jret} {fn_suffix}_callback(int obj_ptr, int fn_id{jargs});
+       static {fn_suffix}_callback {fn_suffix}_callback_inst = c_callback_{fn_suffix};
 """)
                 bindings.write(self.native_meth_decl(f"register_{fn_suffix}_invoker", "int") + f"({fn_suffix}_callback callee);\n")
                 # Easiest way to get a static run is just define a variable, even if we dont care
-                bindings.write(f"\tstatic int _run_{fn_suffix}_registration = register_{fn_suffix}_invoker(c_callback_{fn_suffix});")
+                bindings.write(f"\tstatic int _run_{fn_suffix}_registration = register_{fn_suffix}_invoker({fn_suffix}_callback_inst);")
 
             bindings.write("""
 }