X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=typescript_strings.py;h=670eb2ae73124346a41e919247f43d601e12a63f;hb=1ef2dc8b8a3e0e244ad82ac08e286df489eca4b7;hp=c0a0cccbf0ed816764fb3a285cf6dae2620400ba;hpb=9d652fa3984c75323634bbe004bd7cac4906f950;p=ldk-java diff --git a/typescript_strings.py b/typescript_strings.py index c0a0cccb..670eb2ae 100644 --- a/typescript_strings.py +++ b/typescript_strings.py @@ -36,12 +36,14 @@ class Consts: self.bindings_header = """ import * as version from './version.mjs'; +import { UInt5 } from './structs/CommonBase.mjs'; const imports: any = {}; imports.env = {}; var js_objs: Array> = []; var js_invoke: Function; +var getRandomValues: Function; imports.wasi_snapshot_preview1 = { "fd_write": (fd: number, iovec_array_ptr: number, iovec_array_len: number) => { @@ -66,7 +68,7 @@ imports.wasi_snapshot_preview1 = { }, "random_get": (buf_ptr: number, buf_len: number) => { const buf = new Uint8Array(wasm.memory.buffer, buf_ptr, buf_len); - crypto.getRandomValues(buf); + getRandomValues(buf); return 0; }, "environ_sizes_get": (environ_var_count_ptr: number, environ_len_ptr: number) => { @@ -90,25 +92,15 @@ imports.wasi_snapshot_preview1 = { var wasm: any = null; let isWasmInitialized: boolean = false; -""" - if target == Target.NODEJS: - self.bindings_header += """import * as fs from 'fs'; -import { webcrypto as crypto } from 'crypto'; -/* @internal */ -export async function initializeWasm(path: string) { - const source = fs.readFileSync(path); - imports.env["js_invoke_function"] = js_invoke; - const { instance: wasmInstance } = await WebAssembly.instantiate(source, imports);""" - else: - self.bindings_header += """ -/* @internal */ -export async function initializeWasm(uri: string) { - const stream = fetch(uri); - imports.env["js_invoke_function"] = js_invoke; - const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports);""" +async function finishInitializeWasm(wasmInstance: WebAssembly.Instance) { + if (typeof crypto === "undefined") { + var crypto_import = (await import('crypto')).webcrypto; + getRandomValues = crypto_import.getRandomValues.bind(crypto_import); + } else { + getRandomValues = crypto.getRandomValues.bind(crypto); + } - self.bindings_header += """ wasm = wasmInstance.exports; if (!wasm.test_bigint_pass_deadbeef0badf00d(BigInt("0xdeadbeef0badf00d"))) { throw new Error(\"Currently need BigInt-as-u64 support, try ----experimental-wasm-bigint"); @@ -128,12 +120,33 @@ export async function initializeWasm(uri: string) { console.log(\"Loaded LDK-Java Bindings with LDK \" + ldk_version + \" and LDK-C-Bindings \" + c_bindings_version); isWasmInitialized = true; -}; +} + +/* @internal */ +export async function initializeWasmFromUint8Array(wasmBinary: Uint8Array) { + imports.env["js_invoke_function"] = js_invoke; + const { instance: wasmInstance } = await WebAssembly.instantiate(wasmBinary, imports); + await finishInitializeWasm(wasmInstance); +} +/* @internal */ +export async function initializeWasmFetch(uri: string) { + const stream = fetch(uri); + imports.env["js_invoke_function"] = js_invoke; + const { instance: wasmInstance } = await WebAssembly.instantiateStreaming(stream, imports); + await finishInitializeWasm(wasmInstance); +}""" + + self.bindings_header += """ // WASM CODEC -const nextMultipleOfFour = (value: number) => { - return Math.ceil(value / 4) * 4; +/* @internal */ +export function uint5ArrToBytes(inputArray: Array): Uint8Array { + const arr = new Uint8Array(inputArray.length); + for (var i = 0; i < inputArray.length; i++) { + arr[i] = inputArray[i].getVal(); + } + return arr; } /* @internal */ @@ -212,6 +225,13 @@ export function getU32ArrayElem(arrayPointer: number, idx: number): number { return actualArrayViewer[idx]; } +/* @internal */ +export function getU8ArrayElem(arrayPointer: number, idx: number): number { + const actualArrayViewer = new Uint8Array(wasm.memory.buffer, arrayPointer + 4, idx + 1); + return actualArrayViewer[idx]; +} + + /* @internal */ export function encodeString(str: string): number { const charArray = new TextEncoder().encode(str); @@ -247,10 +267,16 @@ export function debugPrintRemainingAllocs() { self.bindings_header += "/* @internal */ export function debugPrintRemainingAllocs() { }\n" with open(outdir + "/index.mts", 'a') as index: - index.write("""import { initializeWasm as bindingsInit } from './bindings.mjs'; -export function initializeWasm(path: string) { - bindingsInit(path); + index.write("""import { initializeWasmFetch, initializeWasmFromUint8Array } from './bindings.mjs'; +/** Initializes the WASM backend by calling `fetch()` on the given URI - Browser only */ +export async function initializeWasmWebFetch(uri: string) { + await initializeWasmFetch(uri); } +/** Initializes the WASM backend given a Uint8Array of the .wasm binary file - Browser or Node.JS */ +export async function initializeWasmFromBinary(bin: Uint8Array) { + await initializeWasmFromUint8Array(bin); +} + """) self.bindings_version_file = """export function get_ldk_java_bindings_version(): String { @@ -268,7 +294,7 @@ function get_freeer(ptr: number, free_fn: (ptr: number) => void) { } } -export default class CommonBase { +export class CommonBase { protected ptr: number; protected ptrs_to: object[] = []; protected constructor(ptr: number, free_fn: (ptr: number) => void) { @@ -291,6 +317,19 @@ export default class CommonBase { finalizer.unregister(o); } } + +export class UInt5 { + public constructor(private val: number) { + if (val > 32 || val < 0) throw new Error("UInt5 value is out of range"); + } + public getVal(): number { + return this.val; + } +} + +export class UnqualifiedError { + public constructor(val: number) {} +} """ self.txout_defn = """export class TxOut extends CommonBase { @@ -557,7 +596,7 @@ jstring __attribute__((export_name("TS_get_ldk_version"))) get_ldk_version() { }""" self.hu_struct_file_prefix = """ -import CommonBase from './CommonBase.mjs'; +import { CommonBase, UInt5, UnqualifiedError } from './CommonBase.mjs'; import * as bindings from '../bindings.mjs' """ @@ -576,7 +615,7 @@ import * as bindings from '../bindings.mjs' return None def create_native_arr_call(self, arr_len, ty_info): if ty_info.c_ty == "ptrArray": - assert ty_info.subty is not None and ty_info.subty.c_ty.endswith("Array") + assert ty_info.rust_obj == "LDKCVec_u5Z" or (ty_info.subty is not None and ty_info.subty.c_ty.endswith("Array")) return "init_" + ty_info.c_ty + "(" + arr_len + ", __LINE__)" def set_native_arr_contents(self, arr_name, arr_len, ty_info): if ty_info.c_ty == "int8_tArray": @@ -607,6 +646,8 @@ import * as bindings from '../bindings.mjs' return None def map_hu_array_elems(self, arr_name, conv_name, arr_ty, elem_ty): + if elem_ty.rust_obj == "LDKu5": + return arr_name + " != null ? bindings.uint5ArrToBytes(" + arr_name + ") : null" assert elem_ty.c_ty == "uint32_t" or elem_ty.c_ty.endswith("Array") return arr_name + " != null ? " + arr_name + ".map(" + conv_name + " => " + elem_ty.from_hu_conv[0] + ") : null" @@ -630,6 +671,8 @@ import * as bindings from '../bindings.mjs' def get_java_arr_elem(self, elem_ty, arr_name, idx): if elem_ty.c_ty == "uint32_t" or elem_ty.c_ty == "uintptr_t" or elem_ty.c_ty.endswith("Array"): return "bindings.getU32ArrayElem(" + arr_name + ", " + idx + ")" + elif elem_ty.rust_obj == "LDKu5": + return "bindings.getU8ArrayElem(" + arr_name + ", " + idx + ")" else: assert False def constr_hu_array(self, ty_info, arr_len): @@ -683,6 +726,9 @@ import * as bindings from '../bindings.mjs' 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 fully_qualified_hu_ty_path(self, ty): + return ty.java_hu_ty + 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"