open static method
- @different
- String modulePath, {
- String? moduleName,
- ModuleLoader? moduleLoader,
- WasmType? wasmType,
- GlobalMemory? useAsGlobal,
Creates a instance based on the given module.
While for each DynamicLibrary a Memory object is
created, the Memory objects share the backing memory if
they are created based on the same module.
The wasmType parameter can be used to control if the module should be
loaded as standalone wasm module or as emscripten module.
The moduleName parameter is only used for debugging purposes. It is
needed for the EmscriptenModule to find the correct module. It is
ignored for the StandaloneWasmModule.
The useAsGlobal parameter can be used to control if the
newly created Memory object should be registered as Memory.global.
Loads a library file and provides access to its symbols.
Calling this function multiple times with the same path, even across
different isolates, only loads the library into the DartVM process once.
Multiple loads of the same library file produces DynamicLibrary objects
which are equal (==), but not identical.
Implementation
@different
static Future<DynamicLibrary> open(
String modulePath, {
String? moduleName,
ModuleLoader? moduleLoader,
WasmType? wasmType,
GlobalMemory? useAsGlobal,
}) async {
/// 64-bit wasm is not supported
if (wasmType == WasmType.wasm64Standalone ||
wasmType == WasmType.wasm64Emscripten) {
throw UnsupportedError('64-bit wasm is not supported');
}
moduleLoader ??= WebModuleLoader();
/// Initialize the native types in marshaller
initTypes();
registerOpaqueType<Utf8>(1);
registerOpaqueType<Utf16>(2);
final uri = Uri.parse(modulePath);
// extract the module name from the path if not provided
moduleName ??= path.basenameWithoutExtension(uri.pathSegments.last);
// Infer the wasm type
if (wasmType == null) {
final ext = path.extension(uri.pathSegments.last);
if (ext == '.js') {
wasmType = WasmType.wasm32Emscripten;
} else if (ext == '.wasm') {
wasmType = WasmType.wasm32Standalone;
} else {
if (await moduleLoader.exists('$modulePath.js')) {
modulePath = '$modulePath.js';
wasmType = WasmType.wasm32Emscripten;
} else if (await moduleLoader.exists('$modulePath.wasm')) {
modulePath = '$modulePath.wasm';
wasmType = WasmType.wasm32Standalone;
} else {
throw ArgumentError('No wasm or js file found at $modulePath');
}
}
}
late Module module;
if (wasmType == WasmType.wasm32Emscripten) {
await importLibrary(modulePath);
module = await EmscriptenModule.compile(moduleName);
} else {
final wasmBinary = await moduleLoader.load(modulePath);
module = await StandaloneWasmModule.compile(wasmBinary);
}
final Memory memory = createMemory(module);
switch (useAsGlobal ?? GlobalMemory.ifNotSet) {
case GlobalMemory.yes:
Memory.global = memory;
interop.WasmTable.global = module.indirectFunctionTable;
break;
case GlobalMemory.no:
break;
case GlobalMemory.ifNotSet:
Memory.global ??= memory;
interop.WasmTable.global ??= module.indirectFunctionTable;
break;
}
if (module is StandaloneWasmModule) {
try {
module
.lookup<NativeFunction<Void Function()>>(
'__wasm_call_ctors',
memory,
)
.asFunction<void Function()>()();
} catch (_) {
// Ignore if not present
}
}
return DynamicLibrary._(module, memory);
}