Upgrade to WasmEdge 0.18.0
Due to the WasmEdge C API breaking changes, this document shows the guideline for programming with WasmEdge C API to upgrade from the 0.17.2 to the 0.18.0 version.
Concepts
The
WasmEdge_ModuleInstanceAdd*APIs returnWasmEdge_Result.The module instances are finalized after their first use in execution, which removes the locks from the hot path of execution. Therefore, the following APIs return
WasmEdge_Resultinstead ofvoid:WasmEdge_ModuleInstanceAddFunction()WasmEdge_ModuleInstanceAddTable()WasmEdge_ModuleInstanceAddMemory()WasmEdge_ModuleInstanceAddGlobal()
These APIs fail with the
WasmEdge_ErrCode_WrongVMWorkflowerror after the module instance is first used in execution, and do NOT take the ownership of the added instance on failure.Deprecated the
WasmEdge_VMForceDeleteRegisteredModule()API.WasmEdge now tracks the dependencies between the registered modules. The new
WasmEdge_VMDeleteRegisteredModule()API unregisters a module from the VM, and the module is destroyed only when no other module depends on it.The
WasmEdge_VMForceDeleteRegisteredModule()API is deprecated and moved into thewasmedge_deprecated.hheader. It still works but will be removed in the future.Removed the
wasmedge_processplug-in.The
wasmedge_processplug-in is removed. TheWasmEdge_ModuleInstanceInitWasmEdgeProcess()API is deprecated and moved into thewasmedge_deprecated.hheader. It has no effect unless an external plug-in namedwasmedge_processis loaded, and will be removed in the future.Introduced the stack size limit.
The execution now traps with the new
WasmEdge_ErrCode_CallStackExhaustederror when the call stack exceeds the limit, instead of crashing on the deep recursion. The limit defaults to 8 MiB in the interpreter mode and 512 KiB in the AOT and JIT modes. The new APIs are:WasmEdge_ConfigureSetMaxStackSize(): set the stack size limit in the configure context.WasmEdge_ConfigureGetMaxStackSize(): get the stack size limit from the configure context.
Introduced the lazy JIT run mode.
The new
WasmEdge_RunMode_LazyJITvalue is added into theWasmEdge_RunModeenumeration. In the lazy JIT mode, each function is compiled on its first call.
Add instances into module instances
Before the version 0.17.2, the WasmEdge_ModuleInstanceAdd* APIs returned void, and the module instance always took the ownership of the added instance.
WasmEdge_String ModName = WasmEdge_StringCreateByCString("module");
WasmEdge_ModuleInstanceContext *HostMod = WasmEdge_ModuleInstanceCreate(ModName);
WasmEdge_StringDelete(ModName);
WasmEdge_FunctionInstanceContext *HostFunc =
WasmEdge_FunctionInstanceCreate(/* ... ignored ... */);
WasmEdge_String FuncName = WasmEdge_StringCreateByCString("add");
WasmEdge_ModuleInstanceAddFunction(HostMod, FuncName, HostFunc);
WasmEdge_StringDelete(FuncName);
WasmEdge_ModuleInstanceDelete(HostMod);
After 0.18.0, these APIs return WasmEdge_Result. Developers should add all the instances before the module instance is first used in execution, and should destroy the instance by themselves if the API fails.
WasmEdge_String ModName = WasmEdge_StringCreateByCString("module");
WasmEdge_ModuleInstanceContext *HostMod = WasmEdge_ModuleInstanceCreate(ModName);
WasmEdge_StringDelete(ModName);
WasmEdge_FunctionInstanceContext *HostFunc =
WasmEdge_FunctionInstanceCreate(/* ... ignored ... */);
WasmEdge_String FuncName = WasmEdge_StringCreateByCString("add");
WasmEdge_Result Res =
WasmEdge_ModuleInstanceAddFunction(HostMod, FuncName, HostFunc);
WasmEdge_StringDelete(FuncName);
if (!WasmEdge_ResultOK(Res)) {
/* The module instance does not take the ownership on failure. */
WasmEdge_FunctionInstanceDelete(HostFunc);
}
WasmEdge_ModuleInstanceDelete(HostMod);
Delete the registered modules in VM
Before the version 0.17.2, developers could only forcibly delete a registered module from the VM context, and should guarantee the module dependencies by themselves.
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);
WasmEdge_String ModName = WasmEdge_StringCreateByCString("mod");
WasmEdge_VMRegisterModuleFromFile(VMCxt, ModName, "fibonacci.wasm");
WasmEdge_VMForceDeleteRegisteredModule(VMCxt, ModName);
WasmEdge_StringDelete(ModName);
WasmEdge_VMDelete(VMCxt);
After 0.18.0, developers should use the WasmEdge_VMDeleteRegisteredModule() API. The module is unregistered from the VM, and is destroyed only when there are no remaining dependencies from other modules.
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);
WasmEdge_String ModName = WasmEdge_StringCreateByCString("mod");
WasmEdge_VMRegisterModuleFromFile(VMCxt, ModName, "fibonacci.wasm");
WasmEdge_VMDeleteRegisteredModule(VMCxt, ModName);
WasmEdge_StringDelete(ModName);
WasmEdge_VMDelete(VMCxt);
Stack size limit configuration
After 0.18.0, developers can limit the call stack size of one execution in the configure context. The value 0 (default) selects the engine default, which is 8 MiB in the interpreter mode and 512 KiB in the AOT and JIT modes, and the value UINT64_MAX removes the limit.
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
WasmEdge_ConfigureSetMaxStackSize(ConfCxt, 1024 * 1024);
uint64_t StackSize = WasmEdge_ConfigureGetMaxStackSize(ConfCxt);
/* The `StackSize` will be 1048576. */
WasmEdge_ConfigureDelete(ConfCxt);
When the call stack exceeds the limit, the execution fails with the WasmEdge_ErrCode_CallStackExhausted error.
Run AOT-compiled WASM
Only the WasmEdge_RunMode_AOT run mode loads the AOT-compiled code. In the other run modes, the AOT custom sections in universal WASM are ignored, and the AOT-compiled shared libraries (.so, .dylib, or .dll) are rejected with the WasmEdge_ErrCode_MalformedMagic error.
WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
WasmEdge_ConfigureSetRunMode(ConfCxt, WasmEdge_RunMode_AOT);
WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, NULL);
/* ... Run the AOT-compiled WASM with the VM context. */
WasmEdge_VMDelete(VMCxt);
WasmEdge_ConfigureDelete(ConfCxt);