"""
- self.bindings_footer = ""
+ self.bindings_footer = """
+ export async function initializeWasm(allowDoubleInitialization: boolean = false): Promise<void> {
+ if(isWasmInitialized && !allowDoubleInitialization) {
+ return;
+ }
+ const wasmInstance = await WebAssembly.instantiate(wasmModule, imports)
+ wasm = wasmInstance.exports;
+ isWasmInitialized = true;
+ }
+ """
self.common_base = """
export default class CommonBase {
else:
return None
-
def wasm_import_header(self, target):
if target == Target.NODEJS:
return """
console.error("ABORT");
};
-const wasmInstance = await WebAssembly.instantiate(wasmModule, imports)
-const wasm = wasmInstance.exports;
+let wasm = null;
+let isWasmInitialized: boolean = false;
+
// WASM CODEC
}
const encodeArray = (inputArray) => {
- // TODO: (matt) is this correct, or should it go back to length * 4?
- // const cArrayPointer = wasm.wasm_malloc(inputArray.length * 4);
- const cArrayPointer = wasm.wasm_malloc(nextMultipleOfFour(inputArray.length));
-
- const arrayMemoryView = new Uint32Array(memory.buffer, cArrayPointer, inputArray.length);
- arrayMemoryView.set(inputArray);
- return cArrayPointer;
+ const cArrayPointer = wasm.wasm_malloc((inputArray.length + 1) * 4);
+ const arrayMemoryView = new Uint32Array(memory.buffer, cArrayPointer + 4, inputArray.length);
+ arrayMemoryView.set(inputArray, 1);
+ arrayMemoryView[0] = inputArray.length;
+ return cArrayPointer;
}
-const decodeArray = (arrayPointer, free = true) => {
- const arraySizeViewer = new Uint32Array(
- memory.buffer, // value
- arrayPointer, // offset
- 1 // one int
- );
- const arraySize = arraySizeViewer[0];
- const actualArrayViewer = new Uint32Array(
- memory.buffer, // value
- arrayPointer, // offset
- arraySize + 1
- );
- const actualArray = actualArrayViewer.slice(1, arraySize + 1);
- if (free) {
- // wasm.free_array(arrayPointer);
- wasm.wasm_free(arrayPointer); // TODO: check if passing *void still captures remaining values
- }
- return actualArray;
+const getArrayLength = (arrayPointer) => {
+ const arraySizeViewer = new Uint32Array(
+ memory.buffer, // value
+ arrayPointer, // offset
+ 1 // one int
+ );
+ return arraySizeViewer[0];
+}
+const decodeUint8Array = (arrayPointer, free = true) => {
+ const arraySize = getArrayLength(arrayPointer);
+ const actualArrayViewer = new Uint8Array(
+ memory.buffer, // value
+ arrayPointer + 4, // offset (ignoring length bytes)
+ arraySize // uint8 count
+ );
+ // Clone the contents, TODO: In the future we should wrap the Viewer in a class that
+ // will free the underlying memory when it becomes unreachable instead of copying here.
+ const actualArray = actualArrayViewer.slice(0, arraySize);
+ if (free) {
+ wasm.free(arrayPointer);
+ }
+ return actualArray;
+}
+const decodeUint32Array = (arrayPointer, free = true) => {
+ const arraySize = getArrayLength(arrayPointer);
+ const actualArrayViewer = new Uint32Array(
+ memory.buffer, // value
+ arrayPointer + 4, // offset (ignoring length bytes)
+ arraySize // uint32 count
+ );
+ // Clone the contents, TODO: In the future we should wrap the Viewer in a class that
+ // will free the underlying memory when it becomes unreachable instead of copying here.
+ const actualArray = actualArrayViewer.slice(0, arraySize);
+ if (free) {
+ wasm.free(arrayPointer);
+ }
+ return actualArray;
}
const encodeString = (string) => {
method_argument_string += f"{arg_conv_info.arg_name}: {arg_conv_info.java_ty}"
native_call_argument_string += native_argument
+ has_return_value = return_type_info.c_ty != 'void'
needs_decoding = return_type_info.c_ty in self.wasm_decoding_map
- return_value = 'nativeResponseValue'
- if needs_decoding:
+ return_statement = 'return nativeResponseValue;'
+ if not has_return_value:
+ return_statement = '// debug statements here'
+ elif needs_decoding:
converter = self.wasm_decoding_map[return_type_info.c_ty]
- return_value = f"{converter}(nativeResponseValue)"
+ return_statement = f"return {converter}(nativeResponseValue);"
out_java = f"""\texport function {method_name}({method_argument_string}): {return_type_info.java_ty} {{
+ if(!isWasmInitialized){{
+ throw new Error("initializeWasm() must be awaited first!");
+ }}
const nativeResponseValue = wasm.{method_name}({native_call_argument_string});
- return {return_value};
- \n\t}}
+ {return_statement}\n\t}}
\n"""