[TS] Redo C -> TS call function naming to make it harder to screw up
[ldk-java] / typescript_strings.py
index c5d9f47747f13143c4e9503b7437bc10cb95e6df..a665019f73885154ffd2ff78f691c6384dee2e97 100644 (file)
@@ -125,19 +125,19 @@ async function finishInitializeWasm(wasmInstance: WebAssembly.Instance) {
        isWasmInitialized = true;
 }
 
+const fn_list = ["uuuuuu", "buuuuu", "bbbbbb", "ubuuuu", "uubuuu"];
+
 /* @internal */
 export async function initializeWasmFromUint8Array(wasmBinary: Uint8Array) {
-       imports.env["js_invoke_function_u"] = js_invoke;
-       imports.env["js_invoke_function_b"] = js_invoke;
+       for (const fn of fn_list) { imports.env["js_invoke_function_" + fn] = js_invoke; }
        const { instance: wasmInstance } = await WebAssembly.instantiate(wasmBinary, imports);
        await finishInitializeWasm(wasmInstance);
 }
 
 /* @internal */
 export async function initializeWasmFetch(uri: string) {
+       for (const fn of fn_list) { imports.env["js_invoke_function_" + fn] = js_invoke; }
        const stream = fetch(uri);
-       imports.env["js_invoke_function_u"] = js_invoke;
-       imports.env["js_invoke_function_b"] = js_invoke;
        const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);
        await finishInitializeWasm(wasmInstance);
 }"""
@@ -332,7 +332,7 @@ export class CommonBase {
        protected constructor(ptr: number, free_fn: (ptr: number) => void) {
                this.ptr = ptr;
                if (Number.isFinite(ptr) && ptr != 0){
-                       finalizer.register(this, get_freeer(ptr, free_fn));
+                       finalizer.register(this, get_freeer(ptr, free_fn), this);
                }
        }
        // In Java, protected means "any subclass can access fields on any other subclass'"
@@ -346,7 +346,10 @@ export class CommonBase {
        }
        protected static set_null_skip_free(o: CommonBase) {
                o.ptr = 0;
-               finalizer.unregister(o);
+               // @ts-ignore TypeScript is wrong about the returnvalue of unregister here!
+               const did_unregister: boolean = finalizer.unregister(o);
+               if (!did_unregister)
+                       throw new Error("FinalizationRegistry unregister should always unregister unless you double-free'd");
        }
 }
 
@@ -385,7 +388,7 @@ export class UnqualifiedError {
                this.script_pubkey = bindings.decodeUint8Array(bindings.TxOut_get_script_pubkey(ptr));
                this.value = bindings.TxOut_get_value(ptr);
        }
-       public constructor_new(value: bigint, script_pubkey: Uint8Array): TxOut {
+       public static constructor_new(value: bigint, script_pubkey: Uint8Array): TxOut {
                return new TxOut(null, bindings.TxOut_new(bindings.encodeUint8Array(script_pubkey), value));
        }
 }"""
@@ -1031,15 +1034,14 @@ export class {struct_name.replace("LDK","")} extends CommonBase {{
                         out_c = out_c + arg_info.ret_conv[1].replace('\n', '\n\t') + "\n"
 
                 fn_suffix = ""
-                if fn_line.ret_ty_info.c_ty == "uint64_t" or fn_line.ret_ty_info.c_ty == "int64_t":
-                    fn_suffix += "b_"
-                else:
-                    fn_suffix += "u_"
-                for arg in fn_line.args_ty:
+                assert len(fn_line.args_ty) < 6
+                for arg_info in fn_line.args_ty:
                     if arg_info.c_ty == "uint64_t" or arg_info.c_ty == "int64_t":
                         fn_suffix += "b"
                     else:
                         fn_suffix += "u"
+                for i in range(0, 6 - len(fn_line.args_ty)):
+                    fn_suffix += "u"
                 if fn_line.ret_ty_info.c_ty.endswith("Array"):
                     out_c += "\t" + fn_line.ret_ty_info.c_ty + " ret = (" + fn_line.ret_ty_info.c_ty + ")"
                     out_c += "js_invoke_function_" + fn_suffix + "(j_calls->instance_ptr, " + str(self.function_ptr_counter)
@@ -1057,9 +1059,11 @@ export class {struct_name.replace("LDK","")} extends CommonBase {{
 
                 for idx, arg_info in enumerate(fn_line.args_ty):
                     if arg_info.ret_conv is not None:
-                        out_c = out_c + ", (uint32_t)" + arg_info.ret_conv_name
+                        out_c += ", (uint32_t)" + arg_info.ret_conv_name
                     else:
-                        out_c = out_c + ", (uint32_t)" + arg_info.arg_name
+                        out_c += ", (uint32_t)" + arg_info.arg_name
+                for i in range(0, 6 - len(fn_line.args_ty)):
+                    out_c += ", 0"
                 out_c = out_c + ");\n"
                 if fn_line.ret_ty_info.arg_conv is not None:
                     out_c = out_c + "\t" + fn_line.ret_ty_info.arg_conv.replace("\n", "\n\t") + "\n\treturn " + fn_line.ret_ty_info.arg_conv_name + ";\n"
@@ -1238,18 +1242,28 @@ export class {struct_name.replace("LDK","")} extends CommonBase {{
 
         hu_name = struct_name.replace("LDKC2Tuple", "TwoTuple").replace("LDKC3Tuple", "ThreeTuple").replace("LDK", "")
         out_opaque_struct_human = f"{self.hu_struct_file_prefix}"
+        constructor_body = "super(ptr, bindings." + struct_name.replace("LDK","") + "_free);"
+        extra_docs = ""
+        extra_body = ""
         if struct_name.startswith("LDKLocked") or struct_name.startswith("LDKReadOnly"):
-            out_opaque_struct_human += "/** XXX: DO NOT USE THIS - it remains locked until the GC runs (if that ever happens */"
+            extra_docs = "\n * This type represents a lock and MUST BE MANUALLY FREE'd!"
+            constructor_body = 'super(ptr, () => { throw new Error("Locks must be manually freed with free()"); });'
+            extra_body = f"""
+       /** Releases this lock */
+       public free() {{
+               bindings.{struct_name.replace("LDK","")}_free(this.ptr);
+               CommonBase.set_null_skip_free(this);
+       }}"""
         formatted_doc_comment = struct_doc_comment.replace("\n", "\n * ")
         out_opaque_struct_human += f"""
-/**
+/**{extra_docs}
  * {formatted_doc_comment}
  */
 export class {hu_name} extends CommonBase {implementations}{{
        /* @internal */
        public constructor(_dummy: object, ptr: number) {{
-               super(ptr, bindings.{struct_name.replace("LDK","")}_free);
-       }}
+               {constructor_body}
+       }}{extra_body}
 
 """
         self.obj_defined([hu_name], "structs")