in dubbo-wasm/dubbo-wasm-api/src/main/java/org/apache/dubbo/wasm/WasmLoader.java [93:146]
public WasmLoader(final Class<?> wasmClass,
final Function<Class<?>, String> nameInitializer,
final BiFunction<Store<Void>, Supplier<ByteBuffer>, Map<String, Func>> initializer) {
final Class<?> clazz = Objects.nonNull(wasmClass) ? wasmClass : this.getClass();
String wasmName = null;
try {
if (Objects.nonNull(nameInitializer)) {
wasmName = nameInitializer.apply(clazz);
}
if (Objects.isNull(wasmName) || wasmName.isEmpty()) {
wasmName = buildWasmName(clazz);
}
if (Objects.isNull(wasmName) || wasmName.isEmpty()) {
throw new DubboWasmInitException("Illegal WASM file name");
}
this.wasmName = wasmName.endsWith(".wasm") ? wasmName : wasmName + ".wasm";
// locate `.wasm` lib.
URL resource = clazz.getClassLoader().getResource(wasmName);
if (Objects.isNull(resource)) {
throw new DubboWasmInitException("Can't find wasm file: " + wasmName);
}
// Reads the WebAssembly module as bytes.
byte[] wasmBytes = Files.readAllBytes(Paths.get(resource.toURI()));
// Instantiates the WebAssembly module.
if (Objects.nonNull(initializer)) {
Map<String, Func> wasmFunctionMap = initializer.apply(store, this::getBuffer);
if (Objects.nonNull(wasmFunctionMap) && !wasmFunctionMap.isEmpty()) {
wasmCallJavaFuncMap.putAll(wasmFunctionMap);
}
}
Map<String, Func> wasmFunctionMap = initWasmCallJavaFunc(store, this::getBuffer);
if (Objects.nonNull(wasmFunctionMap) && !wasmFunctionMap.isEmpty()) {
wasmCallJavaFuncMap.putAll(wasmFunctionMap);
}
this.module = Module.fromBinary(store.engine(), wasmBytes);
WasiCtx.addToLinker(linker);
// maybe need define many functions
if (!wasmCallJavaFuncMap.isEmpty()) {
wasmCallJavaFuncMap.forEach((funcName, wasmCallJavaFunc) ->
linker.define(store, IMPORT_WASM_MODULE_NAME, funcName, Extern.fromFunc(wasmCallJavaFunc)));
}
linker.module(store, "", module);
// Let the `wasmCallJavaFunc` function to refer this as a placeholder of Memory because
// we have to add the function as import before loading the module exporting Memory.
Optional<Extern> extern = this.getWasmExtern(MEMORY_METHOD_NAME);
if (!extern.isPresent()) {
throw new DubboWasmInitException(MEMORY_METHOD_NAME + " function not find in wasm file: " + wasmName);
}
this.memRef.set(extern.get().memory());
Runtime.getRuntime().addShutdownHook(new Thread(this::close));
} catch (URISyntaxException | IOException e) {
throw new DubboWasmInitException(e);
}
}