X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=typescript_strings.py;h=faa13d572d623a6b09d4dbba495ba473b5692203;hb=4dc5fc99fc92a6d0ea7e641a12dd0306838f8ae3;hp=621b62eebe04af7bf31d3502273c16d58a6f0603;hpb=18a58ec41f1775502365e58fe0e8bc467755c33a;p=ldk-java diff --git a/typescript_strings.py b/typescript_strings.py index 621b62ee..faa13d57 100644 --- a/typescript_strings.py +++ b/typescript_strings.py @@ -97,7 +97,19 @@ export default class CommonBase { finalizer.register(this, get_freeer(ptr, free_fn)); } } - public _test_only_get_ptr(): number { return this.ptr; } + // In Java, protected means "any subclass can access fields on any other subclass'" + // In TypeScript, protected means "any subclass can access parent fields on instances of itself" + // To work around this, we add accessors for other instances' protected fields here. + protected static add_ref_from(holder: CommonBase, referent: object) { + holder.ptrs_to.push(referent); + } + protected static get_ptr_of(o: CommonBase) { + return o.ptr; + } + protected static set_null_skip_free(o: CommonBase) { + o.ptr = 0; + finalizer.unregister(o); + } } """ @@ -294,6 +306,7 @@ void __attribute__((visibility("default"))) TS_free(uint32_t ptr) { self.hu_struct_file_prefix = """ import CommonBase from './CommonBase.mjs'; import * as bindings from '../bindings.mjs' +import * as InternalUtils from '../InternalUtils.mjs' """ self.c_fn_ty_pfx = "" @@ -305,6 +318,12 @@ import * as bindings from '../bindings.mjs' self.is_arr_some_check = ("", " != 0") self.get_native_arr_len_call = ("", "->arr_len") + with open(outdir + "/InternalUtils.mts", "w") as f: + f.write("export function check_arr_len(arr: Uint8Array, len: number): Uint8Array {\n") + f.write("\tif (arr.length != len) { throw new Error(\"Expected array of length \" + len + \"got \" + arr.length); }\n") + f.write("\treturn arr;\n") + f.write("}") + def release_native_arr_ptr_call(self, ty_info, arr_var, arr_ptr_var): return None def create_native_arr_call(self, arr_len, ty_info): @@ -349,13 +368,9 @@ import * as bindings from '../bindings.mjs' def wasm_import_header(self, target): res = """ -const memory = new WebAssembly.Memory({initial: 256}); - const imports: any = {}; imports.env = {}; -imports.env.memoryBase = 0; -imports.env.memory = memory; imports.env.tableBase = 0; imports.env.table = new WebAssembly.Table({initial: 4, element: 'anyfunc'}); @@ -422,16 +437,16 @@ const nextMultipleOfFour = (value: number) => { const encodeUint8Array = (inputArray) => { const cArrayPointer = wasm.TS_malloc(inputArray.length + 4); - const arrayLengthView = new Uint32Array(memory.buffer, cArrayPointer, 1); + const arrayLengthView = new Uint32Array(wasm.memory.buffer, cArrayPointer, 1); arrayLengthView[0] = inputArray.length; - const arrayMemoryView = new Uint8Array(memory.buffer, cArrayPointer + 4, inputArray.length); + const arrayMemoryView = new Uint8Array(wasm.memory.buffer, cArrayPointer + 4, inputArray.length); arrayMemoryView.set(inputArray); return cArrayPointer; } const encodeUint32Array = (inputArray) => { const cArrayPointer = wasm.TS_malloc((inputArray.length + 1) * 4); - const arrayMemoryView = new Uint32Array(memory.buffer, cArrayPointer, inputArray.length); + const arrayMemoryView = new Uint32Array(wasm.memory.buffer, cArrayPointer, inputArray.length); arrayMemoryView.set(inputArray, 1); arrayMemoryView[0] = inputArray.length; return cArrayPointer; @@ -439,7 +454,7 @@ const encodeUint32Array = (inputArray) => { const getArrayLength = (arrayPointer) => { const arraySizeViewer = new Uint32Array( - memory.buffer, // value + wasm.memory.buffer, // value arrayPointer, // offset 1 // one int ); @@ -448,7 +463,7 @@ const getArrayLength = (arrayPointer) => { const decodeUint8Array = (arrayPointer, free = true) => { const arraySize = getArrayLength(arrayPointer); const actualArrayViewer = new Uint8Array( - memory.buffer, // value + wasm.memory.buffer, // value arrayPointer + 4, // offset (ignoring length bytes) arraySize // uint8 count ); @@ -463,7 +478,7 @@ const decodeUint8Array = (arrayPointer, free = true) => { const decodeUint32Array = (arrayPointer, free = true) => { const arraySize = getArrayLength(arrayPointer); const actualArrayViewer = new Uint32Array( - memory.buffer, // value + wasm.memory.buffer, // value arrayPointer + 4, // offset (ignoring length bytes) arraySize // uint32 count ); @@ -481,7 +496,7 @@ const encodeString = (string) => { const memoryNeed = nextMultipleOfFour(string.length + 1); const stringPointer = wasm.TS_malloc(memoryNeed); const stringMemoryView = new Uint8Array( - memory.buffer, // value + wasm.memory.buffer, // value stringPointer, // offset string.length + 1 // length ); @@ -493,7 +508,7 @@ const encodeString = (string) => { } const decodeString = (stringPointer, free = true) => { - const memoryView = new Uint8Array(memory.buffer, stringPointer); + const memoryView = new Uint8Array(wasm.memory.buffer, stringPointer); let cursor = 0; let result = ''; @@ -516,6 +531,20 @@ const decodeString = (stringPointer, free = true) => { def var_decl_statement(self, ty_string, var_name, statement): return "const " + var_name + ": " + ty_string + " = " + statement + def get_ptr(self, var): + return "CommonBase.get_ptr_of(" + var + ")" + def set_null_skip_free(self, var): + return "CommonBase.set_null_skip_free(" + var + ");" + + def add_ref(self, holder, referent): + return "CommonBase.add_ref_from(" + holder + ", " + referent + ")" + + def obj_defined(self, struct_names, folder): + with open(self.outdir + "/index.mts", 'a') as index: + index.write(f"export * from './{folder}/{struct_names[0]}.mjs';\n") + with open(self.outdir + "/imports.mts.part", 'a') as imports: + imports.write(f"import {{ {', '.join(struct_names)} }} from '../{folder}/{struct_names[0]}.mjs';\n") + def native_c_unitary_enum_map(self, struct_name, variants, enum_doc_comment): out_c = "static inline LDK" + struct_name + " LDK" + struct_name + "_from_js(int32_t ord) {\n" out_c = out_c + "\tswitch (ord) {\n" @@ -549,6 +578,7 @@ const decodeString = (stringPointer, free = true) => { }} """ out_typescript_enum = f"export {{ {struct_name} }} from \"../bindings.mjs\";" + self.obj_defined([struct_name], "enums") return (out_c, out_typescript_enum, out_typescript) def c_unitary_enum_to_native_call(self, ty_info): @@ -960,6 +990,7 @@ const decodeString = (stringPointer, free = true) => { out_c += ("\t}\n}\n") out_java_enum += java_hu_class self.struct_file_suffixes[java_hu_type] = java_hu_subclasses + self.obj_defined([java_hu_type], "structs") return (out_java, out_java_enum, out_c) def map_opaque_struct(self, struct_name, struct_doc_comment): @@ -978,11 +1009,70 @@ export class {hu_name} extends CommonBase {implementations}{{ }} """ + self.obj_defined([hu_name], "structs") return out_opaque_struct_human def map_tuple(self, struct_name): return self.map_opaque_struct(struct_name, "A Tuple") + def map_result(self, struct_name, res_map, err_map): + human_ty = struct_name.replace("LDKCResult", "Result") + + suffixes = f"export class {human_ty}_OK extends {human_ty} {{\n" + if res_map.java_hu_ty != "void": + suffixes += "\tpublic res: " + res_map.java_hu_ty + ";\n" + suffixes += f""" + /* @internal */ + public constructor(_dummy: object, ptr: number) {{ + super(_dummy, ptr); +""" + if res_map.java_hu_ty == "void": + pass + elif res_map.to_hu_conv is not None: + suffixes += "\t\tconst res: " + res_map.java_ty + " = bindings." + struct_name.replace("LDK", "") + "_get_ok(ptr);\n" + suffixes += "\t\t" + res_map.to_hu_conv.replace("\n", "\n\t\t") + suffixes += "\n\t\tthis.res = " + res_map.to_hu_conv_name + ";\n" + else: + suffixes += "\t\tthis.res = bindings." + struct_name.replace("LDK", "") + "_get_ok(ptr);\n" + suffixes += "\t}\n}\n" + + suffixes += f"export class {human_ty}_Err extends {human_ty} {{\n" + if err_map.java_hu_ty != "void": + suffixes += "\tpublic err: " + err_map.java_hu_ty + ";\n" + suffixes += f""" + /* @internal */ + public constructor(_dummy: object, ptr: number) {{ + super(_dummy, ptr); +""" + if err_map.java_hu_ty == "void": + pass + elif err_map.to_hu_conv is not None: + suffixes += "\t\tconst err: " + err_map.java_ty + " = bindings." + struct_name.replace("LDK", "") + "_get_err(ptr);\n" + suffixes += "\t\t" + err_map.to_hu_conv.replace("\n", "\n\t\t") + suffixes += "\n\t\tthis.err = " + err_map.to_hu_conv_name + ";\n" + else: + suffixes += "\t\tthis.err = bindings." + struct_name.replace("LDK", "") + "_get_err(ptr);\n" + suffixes += "\t}\n}" + + self.struct_file_suffixes[human_ty] = suffixes + self.obj_defined([human_ty], "structs") + + return f"""{self.hu_struct_file_prefix} + +export class {human_ty} extends CommonBase {{ + protected constructor(_dummy: object, ptr: number) {{ + super(ptr, bindings.{struct_name.replace("LDK","")}_free); + }} + /* @internal */ + public static constr_from_ptr(ptr: number): {human_ty} {{ + if (bindings.{struct_name.replace("LDK", "")}_is_ok(ptr)) {{ + return new {human_ty}_OK(null, ptr); + }} else {{ + return new {human_ty}_Err(null, ptr); + }} + }} +""" + def fn_call_body(self, method_name, return_c_ty, return_java_ty, method_argument_string, native_call_argument_string): has_return_value = return_c_ty != 'void' needs_decoding = return_c_ty in self.wasm_decoding_map