WasmEdge C 0.10.0 API Documentation

WasmEdge C API denotes an interface to access the WasmEdge runtime. The followings are the guides to working with the C APIs of WasmEdge.

This document is for the 0.10.0 version. For the older 0.9.1 version, please refer to the document here.

Developers can refer here to upgrade to 0.10.0.

Table of Contents

WasmEdge Installation

Download And Install

The easiest way to install WasmEdge is to run the following command. Your system should have git and wget as prerequisites.

1. curl -sSf https://raw.githubusercontent.com/WasmEdge/WasmEdge/master/utils/install.sh | bash -s -- -v 0.10.0

For more details, please refer to the Installation Guide for the WasmEdge installation.

Compile Sources

After the installation of WasmEdge, the following guide can help you to test for the availability of the WasmEdge C API.

  1. Prepare the test C file (and assumed saved as test.c):

1. #include <wasmedge/wasmedge.h> 2. #include <stdio.h> 3. int main() { 4. printf("WasmEdge version: %s\n", WasmEdge_VersionGet()); 5. return 0; 6. } 2. Compile the file with gcc or clang.

1. gcc test.c -lwasmedge_c 3. Run and get the expected output.

1. $ ./a.out 2. WasmEdge version: 0.10.0

WasmEdge Basics

In this part, we will introduce the utilities and concepts of WasmEdge shared library.

Version

The Version related APIs provide developers to check for the WasmEdge shared library version.

1. #include <wasmedge/wasmedge.h>
2. printf("WasmEdge version: %s\n", WasmEdge_VersionGet());
3. printf("WasmEdge version major: %u\n", WasmEdge_VersionGetMajor());
4. printf("WasmEdge version minor: %u\n", WasmEdge_VersionGetMinor());
5. printf("WasmEdge version patch: %u\n", WasmEdge_VersionGetPatch());

Logging Settings

The WasmEdge_LogSetErrorLevel() and WasmEdge_LogSetDebugLevel() APIs can set the logging system to debug level or error level. By default, the error level is set, and the debug info is hidden.

Value Types

In WasmEdge, developers should convert the values to WasmEdge_Value objects through APIs for matching to the WASM value types.

  1. Number types: i32, i64, f32, f64, and v128 for the SIMD proposal

1. WasmEdge_Value Val; 2. Val = WasmEdge_ValueGenI32(123456); 3. printf("%d\n", WasmEdge_ValueGetI32(Val)); 4. /* Will print "123456" */ 5. Val = WasmEdge_ValueGenI64(1234567890123LL); 6. printf("%ld\n", WasmEdge_ValueGetI64(Val)); 7. /* Will print "1234567890123" */ 8. Val = WasmEdge_ValueGenF32(123.456f); 9. printf("%f\n", WasmEdge_ValueGetF32(Val)); 10. /* Will print "123.456001" */ 11. Val = WasmEdge_ValueGenF64(123456.123456789); 12. printf("%.10f\n", WasmEdge_ValueGetF64(Val)); 13. /* Will print "123456.1234567890" */ 2. Reference types: funcref and externref for the Reference-Types proposal

`` 1. WasmEdge_Value Val; 2. void *Ptr; 3. bool IsNull; 4. uint32_t Num = 10; 5. /* Genreate a externref to NULL. */ 6. Val = WasmEdge_ValueGenNullRef(WasmEdge_RefType_ExternRef); 7. IsNull = WasmEdge_ValueIsNullRef(Val); 8. /* TheIsNullwill beTRUE. */ 9. Ptr = WasmEdge_ValueGetExternRef(Val); 10. /* ThePtrwill beNULL`. */

  1. / Get the function instance by creation or from module instance. /
  2. const WasmEdge_FunctionInstanceContext *FuncCxt = ...;
  3. / Genreate a funcref with the given function instance context. /
  4. Val = WasmEdge_ValueGenFuncRef(FuncCxt);
  5. const WasmEdge_FunctionInstanceContext *GotFuncCxt = WasmEdge_ValueGetFuncRef(Val);
  6. / The GotFuncCxt will be the same as FuncCxt. /

  7. / Genreate a externref to Num. /

  8. Val = WasmEdge_ValueGenExternRef(&Num);
  9. Ptr = WasmEdge_ValueGetExternRef(Val);
  10. / The Ptr will be &Num. /
  11. printf("%u\n", (uint32_t )Ptr);
  12. / Will print "10" /
  13. Num += 55;
  14. printf("%u\n", (uint32_t )Ptr);
  15. / Will print "65" / ```

Strings

The WasmEdge_String object is for the instance names when invoking a WASM function or finding the contexts of instances.

  1. Create a WasmEdge_String from a C string (const char * with NULL termination) or a buffer with length.

The content of the C string or buffer will be copied into the WasmEdge_String object.

1. char Buf[4] = {50, 55, 60, 65}; 2. WasmEdge_String Str1 = WasmEdge_StringCreateByCString("test"); 3. WasmEdge_String Str2 = WasmEdge_StringCreateByBuffer(Buf, 4); 4. /* The objects should be deleted by `WasmEdge_StringDelete()`. */ 5. WasmEdge_StringDelete(Str1); 6. WasmEdge_StringDelete(Str2); 2. Wrap a WasmEdge_String to a buffer with length.

The content will not be copied, and the caller should guarantee the life cycle of the input buffer.

1. const char CStr[] = "test"; 2. WasmEdge_String Str = WasmEdge_StringWrap(CStr, 4); 3. /* The object should __NOT__ be deleted by `WasmEdge_StringDelete()`. */ 3. String comparison

1. const char CStr[] = "abcd"; 2. char Buf[4] = {0x61, 0x62, 0x63, 0x64}; 3. WasmEdge_String Str1 = WasmEdge_StringWrap(CStr, 4); 4. WasmEdge_String Str2 = WasmEdge_StringCreateByBuffer(Buf, 4); 5. bool IsEq = WasmEdge_StringIsEqual(Str1, Str2); 6. /* The `IsEq` will be `TRUE`. */ 7. WasmEdge_StringDelete(Str2); 4. Convert to C string

1. char Buf[256]; 2. WasmEdge_String Str = WasmEdge_StringCreateByCString("test_wasmedge_string"); 3. uint32_t StrLength = WasmEdge_StringCopy(Str, Buf, sizeof(Buf)); 4. /* StrLength will be 20 */ 5. printf("String: %s\n", Buf); 6. /* Will print "test_wasmedge_string". */

Results

The WasmEdge_Result object specifies the execution status. APIs about WASM execution will return the WasmEdge_Result to denote the status.

1. WasmEdge_Result Res = WasmEdge_Result_Success;
2. bool IsSucceeded = WasmEdge_ResultOK(Res);
3. /* The `IsSucceeded` will be `TRUE`. */
4. uint32_t Code = WasmEdge_ResultGetCode(Res);
5. /* The `Code` will be 0. */
6. const char *Msg = WasmEdge_ResultGetMessage(Res);
7. /* The `Msg` will be "success". */

Contexts

The objects, such as VM, Store, and Function, are composed of Contexts. All of the contexts can be created by calling the corresponding creation APIs and should be destroyed by calling the corresponding deletion APIs. Developers have responsibilities to manage the contexts for memory management.

1. /* Create the configure context. */
2. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
3. /* Delete the configure context. */
4. WasmEdge_ConfigureDelete(ConfCxt);

The details of other contexts will be introduced later.

WASM Data Structures

The WASM data structures are used for creating instances or can be queried from instance contexts. The details of instances creation will be introduced in the Instances.

  1. Limit

The WasmEdge_Limit struct is defined in the header:

1. /// Struct of WASM limit. 2. typedef struct WasmEdge_Limit { 3. /// Boolean to describe has max value or not. 4. bool HasMax; 5. /// Minimum value. 6. uint32_t Min; 7. /// Maximum value. Will be ignored if the `HasMax` is false. 8. uint32_t Max; 9. } WasmEdge_Limit;

Developers can initialize the struct by assigning it’s value, and the Max value is needed to be larger or equal to the Min value. The API WasmEdge_LimitIsEqual() is provided to compare with 2 WasmEdge_Limit structs. 2. Function type context

The Function Type context is used for the Function creation, checking the value types of a Function instance, or getting the function type with function name from VM. Developers can use the Function Type context APIs to get the parameter or return value types information.

``` 1. enum WasmEdge_ValType ParamList[2] = { WasmEdge_ValType_I32, WasmEdge_ValType_I64 }; 2. enum WasmEdge_ValType ReturnList[1] = { WasmEdge_ValType_FuncRef }; 3. WasmEdge_FunctionTypeContext *FuncTypeCxt = WasmEdge_FunctionTypeCreate(ParamList, 2, ReturnList, 1);

  1. enum WasmEdge_ValType Buf[16];
  2. uint32_t ParamLen = WasmEdge_FunctionTypeGetParametersLength(FuncTypeCxt);
  3. / ParamLen will be 2. /
  4. uint32_t GotParamLen = WasmEdge_FunctionTypeGetParameters(FuncTypeCxt, Buf, 16);
  5. / GotParamLen will be 2, and Buf[0] and Buf[1] will be the same as ParamList. /
  6. uint32_t ReturnLen = WasmEdge_FunctionTypeGetReturnsLength(FuncTypeCxt);
  7. / ReturnLen will be 1. /
  8. uint32_t GotReturnLen = WasmEdge_FunctionTypeGetReturns(FuncTypeCxt, Buf, 16);
  9. / GotReturnLen will be 1, and Buf[0] will be the same as ReturnList. /

  10. WasmEdge_FunctionTypeDelete(FuncTypeCxt); ```

  11. Table type context

The Table Type context is used for Table instance creation or getting information from Table instances.

``` 1. WasmEdge_Limit TabLim = {.HasMax = true, .Shared = false, .Min = 10, .Max = 20}; 2. WasmEdge_TableTypeContext *TabTypeCxt = WasmEdge_TableTypeCreate(WasmEdge_RefType_ExternRef, TabLim);

  1. enum WasmEdge_RefType GotRefType = WasmEdge_TableTypeGetRefType(TabTypeCxt);
  2. / GotRefType will be WasmEdge_RefType_ExternRef. /
  3. WasmEdge_Limit GotTabLim = WasmEdge_TableTypeGetLimit(TabTypeCxt);
  4. / GotTabLim will be the same value as TabLim. /

  5. WasmEdge_TableTypeDelete(TabTypeCxt); ```

  6. Memory type context

The Memory Type context is used for Memory instance creation or getting information from Memory instances.

``` 1. WasmEdge_Limit MemLim = {.HasMax = true, .Shared = false, .Min = 10, .Max = 20}; 2. WasmEdge_MemoryTypeContext *MemTypeCxt = WasmEdge_MemoryTypeCreate(MemLim);

  1. WasmEdge_Limit GotMemLim = WasmEdge_MemoryTypeGetLimit(MemTypeCxt);
  2. / GotMemLim will be the same value as MemLim. /

  3. WasmEdge_MemoryTypeDelete(MemTypeCxt) ```

  4. Global type context

The Global Type context is used for Global instance creation or getting information from Global instances.

``` 1. WasmEdge_GlobalTypeContext *GlobTypeCxt = WasmEdge_GlobalTypeCreate(WasmEdge_ValType_F64, WasmEdge_Mutability_Var);

  1. WasmEdge_ValType GotValType = WasmEdge_GlobalTypeGetValType(GlobTypeCxt);
  2. / GotValType will be WasmEdge_ValType_F64. /
  3. WasmEdge_Mutability GotValMut = WasmEdge_GlobalTypeGetMutability(GlobTypeCxt);
  4. / GotValMut will be WasmEdge_Mutability_Var. /

  5. WasmEdge_GlobalTypeDelete(GlobTypeCxt); ```

  6. Import type context

The Import Type context is used for getting the imports information from a AST Module. Developers can get the external type (function, table, memory, or global), import module name, and external name from an Import Type context. The details about querying Import Type contexts will be introduced in the AST Module.

`` 1. WasmEdge_ASTModuleContext *ASTCxt = ...; 2. /* Assume thatASTCxtis returned by theWasmEdge_LoaderContextfor the result of loading a WASM file. */ 3. const WasmEdge_ImportTypeContext *ImpType = ...; 4. /* Assume thatImpTypeis queried from theASTCxt` for the import. */

  1. enum WasmEdge_ExternalType ExtType = WasmEdge_ImportTypeGetExternalType(ImpType);
  2. /*
    • The ExtType can be one of WasmEdge_ExternalType_Function, WasmEdge_ExternalType_Table,
    • WasmEdge_ExternalType_Memory, or WasmEdge_ExternalType_Global.
  3. */
  4. WasmEdge_String ModName = WasmEdge_ImportTypeGetModuleName(ImpType);
  5. WasmEdge_String ExtName = WasmEdge_ImportTypeGetExternalName(ImpType);
  6. / The ModName and ExtName should not be destroyed and the string buffers are binded into the ASTCxt. /
  7. const WasmEdge_FunctionTypeContext *FuncTypeCxt = WasmEdge_ImportTypeGetFunctionType(ASTCxt, ImpType);
  8. / If the ExtType is not WasmEdge_ExternalType_Function, the FuncTypeCxt will be NULL. /
  9. const WasmEdge_TableTypeContext *TabTypeCxt = WasmEdge_ImportTypeGetTableType(ASTCxt, ImpType);
  10. / If the ExtType is not WasmEdge_ExternalType_Table, the TabTypeCxt will be NULL. /
  11. const WasmEdge_MemoryTypeContext *MemTypeCxt = WasmEdge_ImportTypeGetMemoryType(ASTCxt, ImpType);
  12. / If the ExtType is not WasmEdge_ExternalType_Memory, the MemTypeCxt will be NULL. /
  13. const WasmEdge_GlobalTypeContext *GlobTypeCxt = WasmEdge_ImportTypeGetGlobalType(ASTCxt, ImpType);
  14. / If the ExtType is not WasmEdge_ExternalType_Global, the GlobTypeCxt will be NULL. / ```
  15. Export type context

The Export Type context is used for getting the exports information from a AST Module. Developers can get the external type (function, table, memory, or global) and external name from an Export Type context. The details about querying Export Type contexts will be introduced in the AST Module.

`` 1. WasmEdge_ASTModuleContext *ASTCxt = ...; 2. /* Assume thatASTCxtis returned by theWasmEdge_LoaderContextfor the result of loading a WASM file. */ 3. const WasmEdge_ExportTypeContext *ExpType = ...; 4. /* Assume thatExpTypeis queried from theASTCxt` for the export. */

  1. enum WasmEdge_ExternalType ExtType = WasmEdge_ExportTypeGetExternalType(ExpType);
  2. /*
    • The ExtType can be one of WasmEdge_ExternalType_Function, WasmEdge_ExternalType_Table,
    • WasmEdge_ExternalType_Memory, or WasmEdge_ExternalType_Global.
  3. */
  4. WasmEdge_String ExtName = WasmEdge_ExportTypeGetExternalName(ExpType);
  5. / The ExtName should not be destroyed and the string buffer is binded into the ASTCxt. /
  6. const WasmEdge_FunctionTypeContext *FuncTypeCxt = WasmEdge_ExportTypeGetFunctionType(ASTCxt, ExpType);
  7. / If the ExtType is not WasmEdge_ExternalType_Function, the FuncTypeCxt will be NULL. /
  8. const WasmEdge_TableTypeContext *TabTypeCxt = WasmEdge_ExportTypeGetTableType(ASTCxt, ExpType);
  9. / If the ExtType is not WasmEdge_ExternalType_Table, the TabTypeCxt will be NULL. /
  10. const WasmEdge_MemoryTypeContext *MemTypeCxt = WasmEdge_ExportTypeGetMemoryType(ASTCxt, ExpType);
  11. / If the ExtType is not WasmEdge_ExternalType_Memory, the MemTypeCxt will be NULL. /
  12. const WasmEdge_GlobalTypeContext *GlobTypeCxt = WasmEdge_ExportTypeGetGlobalType(ASTCxt, ExpType);
  13. / If the ExtType is not WasmEdge_ExternalType_Global, the GlobTypeCxt will be NULL. / ```

Async

After calling the asynchronous execution APIs, developers will get the WasmEdge_Async object. Developers own the object and should call the WasmEdge_AsyncDelete() API to destroy it.

  1. Wait for the asynchronous execution

Developers can wait the execution until finished:

1. WasmEdge_Async *Async = ...; /* Ignored. Asynchronous execute a function. */ 2. /* Blocking and waiting for the execution. */ 3. WasmEdge_AsyncWait(Async); 4. WasmEdge_AsyncDelete(Async);

Or developers can wait for a time limit. If the time limit exceeded, developers can choose to cancel the execution. For the interruptible execution in AOT mode, developers should set TRUE thourgh the WasmEdge_ConfigureCompilerSetInterruptible() API into the configure context for the AOT compiler.

1. WasmEdge_Async *Async = ...; /* Ignored. Asynchronous execute a function. */ 2. /* Blocking and waiting for the execution for 1 second. */ 3. bool IsEnd = WasmEdge_AsyncWaitFor(Async, 1000); 4. if (IsEnd) { 5. /* The execution finished. Developers can get the result. */ 6. WasmEdge_Result Res = WasmEdge_AsyncGet(/* ... Ignored */); 7. } else { 8. /* The time limit exceeded. Developers can keep waiting or cancel the execution. */ 9. WasmEdge_AsyncCancel(Async); 10. WasmEdge_Result Res = WasmEdge_AsyncGet(Async, 0, NULL); 11. /* The result error code will be `WasmEdge_ErrCode_Interrupted`. */ 12. } 13. WasmEdge_AsyncDelete(Async); 2. Get the execution result of the asynchronous execution

Developers can use the WasmEdge_AsyncGetReturnsLength() API to get the return value list length. This function will block and wait for the execution. If the execution has finished, this function will return the length immediately. If the execution failed, this function will return 0. This function can help the developers to create the buffer to get the return values. If developers have already known the buffer length, they can skip this function and use the WasmEdge_AsyncGet() API to get the result.

1. WasmEdge_Async *Async = ...; /* Ignored. Asynchronous execute a function. */ 2. /* Blocking and waiting for the execution and get the return value list length. */ 3. uint32_t Arity = WasmEdge_AsyncGetReturnsLength(Async); 4. WasmEdge_AsyncDelete(Async);

The WasmEdge_AsyncGet() API will block and wait for the execution. If the execution has finished, this function will fill the return values into the buffer and return the execution result immediately.

1. WasmEdge_Async *Async = ...; /* Ignored. Asynchronous execute a function. */ 2. /* Blocking and waiting for the execution and get the return values. */ 3. const uint32_t BUF_LEN = 256; 4. WasmEdge_Value Buf[BUF_LEN]; 5. WasmEdge_Result Res = WasmEdge_AsyncGet(Async, Buf, BUF_LEN); 6. WasmEdge_AsyncDelete(Async);

Configurations

The configuration context, WasmEdge_ConfigureContext, manages the configurations for Loader, Validator, Executor, VM, and Compiler. Developers can adjust the settings about the proposals, VM host pre-registrations (such as WASI), and AOT compiler options, and then apply the Configure context to create other runtime contexts.

  1. Proposals

WasmEdge supports turning on or off the WebAssembly proposals. This configuration is effective in any contexts created with the Configure context.

1. enum WasmEdge_Proposal { 2. WasmEdge_Proposal_ImportExportMutGlobals = 0, 3. WasmEdge_Proposal_NonTrapFloatToIntConversions, 4. WasmEdge_Proposal_SignExtensionOperators, 5. WasmEdge_Proposal_MultiValue, 6. WasmEdge_Proposal_BulkMemoryOperations, 7. WasmEdge_Proposal_ReferenceTypes, 8. WasmEdge_Proposal_SIMD, 9. WasmEdge_Proposal_TailCall, 10. WasmEdge_Proposal_MultiMemories, 11. WasmEdge_Proposal_Annotations, 12. WasmEdge_Proposal_Memory64, 13. WasmEdge_Proposal_ExceptionHandling, 14. WasmEdge_Proposal_ExtendedConst, 15. WasmEdge_Proposal_Threads, 16. WasmEdge_Proposal_FunctionReferences 17. };

Developers can add or remove the proposals into the Configure context.

1. /* 2. * By default, the following proposals have turned on initially: 3. * * Import/Export of mutable globals 4. * * Non-trapping float-to-int conversions 5. * * Sign-extension operators 6. * * Multi-value returns 7. * * Bulk memory operations 8. * * Reference types 9. * * Fixed-width SIMD 10. * 11. * For the current WasmEdge version, the following proposals are supported 12. * (turned of by default) additionally: 13. * * Tail-call 14. * * Multiple memories 15. * * Extended-const 16. */ 17. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 18. WasmEdge_ConfigureAddProposal(ConfCxt, WasmEdge_Proposal_MultiMemories); 19. WasmEdge_ConfigureRemoveProposal(ConfCxt, WasmEdge_Proposal_ReferenceTypes); 20. bool IsBulkMem = WasmEdge_ConfigureHasProposal(ConfCxt, WasmEdge_Proposal_BulkMemoryOperations); 21. /* The `IsBulkMem` will be `TRUE`. */ 22. WasmEdge_ConfigureDelete(ConfCxt); 2. Host registrations

This configuration is used for the VM context to turn on the WASI or wasmedge_process supports and only effective in VM contexts.

1. enum WasmEdge_HostRegistration { 2. WasmEdge_HostRegistration_Wasi = 0, 3. WasmEdge_HostRegistration_WasmEdge_Process 4. };

The details will be introduced in the preregistrations of VM context.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. bool IsHostWasi = WasmEdge_ConfigureHasHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 3. /* The `IsHostWasi` will be `FALSE`. */ 4. WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 5. IsHostWasi = WasmEdge_ConfigureHasHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 6. /* The `IsHostWasi` will be `TRUE`. */ 7. WasmEdge_ConfigureDelete(ConfCxt); 3. Maximum memory pages

Developers can limit the page size of memory instances by this configuration. When growing the page size of memory instances in WASM execution and exceeding the limited size, the page growing will fail. This configuration is only effective in the Executor and VM contexts.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. uint32_t PageSize = WasmEdge_ConfigureGetMaxMemoryPage(ConfCxt); 3. /* By default, the maximum memory page size is 65536. */ 4. WasmEdge_ConfigureSetMaxMemoryPage(ConfCxt, 1024); 5. /* Limit the memory size of each memory instance with not larger than 1024 pages (64 MiB). */ 6. PageSize = WasmEdge_ConfigureGetMaxMemoryPage(ConfCxt); 7. /* The `PageSize` will be 1024. */ 8. WasmEdge_ConfigureDelete(ConfCxt); 4. AOT compiler options

The AOT compiler options configure the behavior about optimization level, output format, dump IR, and generic binary.

``` 1. enum WasmEdge_CompilerOptimizationLevel { 2. // Disable as many optimizations as possible. 3. WasmEdge_CompilerOptimizationLevel_O0 = 0, 4. // Optimize quickly without destroying debuggability. 5. WasmEdge_CompilerOptimizationLevel_O1, 6. // Optimize for fast execution as much as possible without triggering 7. // significant incremental compile time or code size growth. 8. WasmEdge_CompilerOptimizationLevel_O2, 9. // Optimize for fast execution as much as possible. 10. WasmEdge_CompilerOptimizationLevel_O3, 11. // Optimize for small code size as much as possible without triggering 12. // significant incremental compile time or execution time slowdowns. 13. WasmEdge_CompilerOptimizationLevel_Os, 14. // Optimize for small code size as much as possible. 15. WasmEdge_CompilerOptimizationLevel_Oz 16. };

  1. enum WasmEdge_CompilerOutputFormat {
  2. // Native dynamic library format.
  3. WasmEdge_CompilerOutputFormat_Native = 0,
  4. // WebAssembly with AOT compiled codes in custom section.
  5. WasmEdge_CompilerOutputFormat_Wasm
  6. }; ```

These configurations are only effective in Compiler contexts.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. /* By default, the optimization level is O3. */ 3. WasmEdge_ConfigureCompilerSetOptimizationLevel(ConfCxt, WasmEdge_CompilerOptimizationLevel_O2); 4. /* By default, the output format is universal WASM. */ 5. WasmEdge_ConfigureCompilerSetOutputFormat(ConfCxt, WasmEdge_CompilerOutputFormat_Native); 6. /* By default, the dump IR is `FALSE`. */ 7. WasmEdge_ConfigureCompilerSetDumpIR(ConfCxt, TRUE); 8. /* By default, the generic binary is `FALSE`. */ 9. WasmEdge_ConfigureCompilerSetGenericBinary(ConfCxt, TRUE); 10. /* By default, the interruptible is `FALSE`. 11. /* Set this option to `TRUE` to support the interruptible execution in AOT mode. */ 12. WasmEdge_ConfigureCompilerSetInterruptible(ConfCxt, TRUE); 13. WasmEdge_ConfigureDelete(ConfCxt); 5. Statistics options

The statistics options configure the behavior about instruction counting, cost measuring, and time measuring in both runtime and AOT compiler. These configurations are effective in Compiler, VM, and Executor contexts.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. /* By default, the intruction counting is `FALSE` when running a compiled-WASM or a pure-WASM. */ 3. WasmEdge_ConfigureStatisticsSetInstructionCounting(ConfCxt, TRUE); 4. /* By default, the cost measurement is `FALSE` when running a compiled-WASM or a pure-WASM. */ 5. WasmEdge_ConfigureStatisticsSetCostMeasuring(ConfCxt, TRUE); 6. /* By default, the time measurement is `FALSE` when running a compiled-WASM or a pure-WASM. */ 7. WasmEdge_ConfigureStatisticsSetTimeMeasuring(ConfCxt, TRUE); 8. WasmEdge_ConfigureDelete(ConfCxt);

Statistics

The statistics context, WasmEdge_StatisticsContext, provides the instruction counter, cost summation, and cost limitation at runtime.

Before using statistics, the statistics configuration must be set. Otherwise, the return values of calling statistics are undefined behaviour.

  1. Instruction counter

The instruction counter can help developers to profile the performance of WASM running. Developers can retrieve the Statistics context from the VM context, or create a new one for the Executor creation. The details will be introduced in the next partitions.

1. WasmEdge_StatisticsContext *StatCxt = WasmEdge_StatisticsCreate(); 2. /* 3. * ... 4. * After running the WASM functions with the `Statistics` context 5. */ 6. uint32_t Count = WasmEdge_StatisticsGetInstrCount(StatCxt); 7. double IPS = WasmEdge_StatisticsGetInstrPerSecond(StatCxt); 8. WasmEdge_StatisticsDelete(StatCxt); 2. Cost table

The cost table is to accumulate the cost of instructions with their weights. Developers can set the cost table array (the indices are the byte code value of instructions, and the values are the cost of instructions) into the Statistics context. If the cost limit value is set, the execution will return the cost limit exceeded error immediately when exceeds the cost limit in runtime.

1. WasmEdge_StatisticsContext *StatCxt = WasmEdge_StatisticsCreate(); 2. uint64_t CostTable[16] = { 3. 0, 0, 4. 10, /* 0x02: Block */ 5. 11, /* 0x03: Loop */ 6. 12, /* 0x04: If */ 7. 12, /* 0x05: Else */ 8. 0, 0, 0, 0, 0, 0, 9. 20, /* 0x0C: Br */ 10. 21, /* 0x0D: Br_if */ 11. 22, /* 0x0E: Br_table */ 12. 0 13. }; 14. /* Developers can set the costs of each instruction. The value not covered will be 0. */ 15. WasmEdge_StatisticsSetCostTable(StatCxt, CostTable, 16); 16. WasmEdge_StatisticsSetCostLimit(StatCxt, 5000000); 17. /* 18. * ... 19. * After running the WASM functions with the `Statistics` context 20. */ 21. uint64_t Cost = WasmEdge_StatisticsGetTotalCost(StatCxt); 22. WasmEdge_StatisticsDelete(StatCxt);

WasmEdge VM

In this partition, we will introduce the functions of WasmEdge_VMContext object and show examples of executing WASM functions.

WASM Execution Example With VM Context

The following shows the example of running the WASM for getting the Fibonacci. This example uses the fibonacci.wasm, and the corresponding WAT file is at fibonacci.wat.

1. (module
2. (export "fib" (func $fib))
3. (func $fib (param $n i32) (result i32)
4. (if
5. (i32.lt_s (get_local $n)(i32.const 2))
6. (return (i32.const 1))
7. )
8. (return
9. (i32.add
10. (call $fib (i32.sub (get_local $n)(i32.const 2)))
11. (call $fib (i32.sub (get_local $n)(i32.const 1)))
12. )
13. )
14. )
15. )
  1. Run WASM functions rapidly

Assume that the WASM file fibonacci.wasm is copied into the current directory, and the C file test.c is as following:

``` 1. #include 2. #include 3. int main() { 4. / Create the configure context and add the WASI support. / 5. / This step is not necessary unless you need WASI support. / 6. WasmEdge_ConfigureContext ConfCxt = WasmEdge_ConfigureCreate(); 7. WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 8. / The configure and store context to the VM creation can be NULL. / 9. WasmEdge_VMContext VMCxt = WasmEdge_VMCreate(ConfCxt, NULL);

  1. / The parameters and returns arrays. /
  2. WasmEdge_Value Params[1] = { WasmEdge_ValueGenI32(5) };
  3. WasmEdge_Value Returns[1];
  4. / Function name. /
  5. WasmEdge_String FuncName = WasmEdge_StringCreateByCString("fib");
  6. / Run the WASM function from file. /
  7. WasmEdge_Result Res = WasmEdge_VMRunWasmFromFile(VMCxt, "fibonacci.wasm", FuncName, Params, 1, Returns, 1);
  8. /*
    • Developers can run the WASM binary from buffer with the WasmEdge_VMRunWasmFromBuffer() API,
    • or from WasmEdge_ASTModuleContext object with the WasmEdge_VMRunWasmFromASTModule() API.
  9. */

  10. if (WasmEdge_ResultOK(Res)) {

  11. printf("Get the result: %d\n", WasmEdge_ValueGetI32(Returns[0]));
  12. } else {
  13. printf("Error message: %s\n", WasmEdge_ResultGetMessage(Res));
  14. }

  15. / Resources deallocations. /

  16. WasmEdge_VMDelete(VMCxt);
  17. WasmEdge_ConfigureDelete(ConfCxt);
  18. WasmEdge_StringDelete(FuncName);
  19. return 0;
  20. } ```

Then you can compile and run: (the 5th Fibonacci number is 8 in 0-based index)

1. $ gcc test.c -lwasmedge_c 2. $ ./a.out 3. Get the result: 8 2. Instantiate and run WASM functions manually

Besides the above example, developers can run the WASM functions step-by-step with VM context APIs:

``` 1. #include 2. #include 3. int main() { 4. / Create the configure context and add the WASI support. / 5. / This step is not necessary unless you need the WASI support. / 6. WasmEdge_ConfigureContext ConfCxt = WasmEdge_ConfigureCreate(); 7. WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 8. / The configure and store context to the VM creation can be NULL. / 9. WasmEdge_VMContext VMCxt = WasmEdge_VMCreate(ConfCxt, NULL);

  1. / The parameters and returns arrays. /
  2. WasmEdge_Value Params[1] = { WasmEdge_ValueGenI32(10) };
  3. WasmEdge_Value Returns[1];
  4. / Function name. /
  5. WasmEdge_String FuncName = WasmEdge_StringCreateByCString("fib");
  6. / Result. /
  7. WasmEdge_Result Res;

  8. / Step 1: Load WASM file. /

  9. Res = WasmEdge_VMLoadWasmFromFile(VMCxt, "fibonacci.wasm");
  10. /*
    • Developers can load the WASM binary from buffer with the WasmEdge_VMLoadWasmFromBuffer() API,
    • or from WasmEdge_ASTModuleContext object with the WasmEdge_VMLoadWasmFromASTModule() API.
  11. */
  12. if (!WasmEdge_ResultOK(Res)) {
  13. printf("Loading phase failed: %s\n", WasmEdge_ResultGetMessage(Res));
  14. return 1;
  15. }
  16. / Step 2: Validate the WASM module. /
  17. Res = WasmEdge_VMValidate(VMCxt);
  18. if (!WasmEdge_ResultOK(Res)) {
  19. printf("Validation phase failed: %s\n", WasmEdge_ResultGetMessage(Res));
  20. return 1;
  21. }
  22. / Step 3: Instantiate the WASM module. /
  23. Res = WasmEdge_VMInstantiate(VMCxt);
  24. /*
    • Developers can load, validate, and instantiate another WASM module to replace the
    • instantiated one. In this case, the old module will be cleared, but the registered
    • modules are still kept.
  25. */
  26. if (!WasmEdge_ResultOK(Res)) {
  27. printf("Instantiation phase failed: %s\n", WasmEdge_ResultGetMessage(Res));
  28. return 1;
  29. }
  30. / Step 4: Execute WASM functions. You can execute functions repeatedly after instantiation. /
  31. Res = WasmEdge_VMExecute(VMCxt, FuncName, Params, 1, Returns, 1);
  32. if (WasmEdge_ResultOK(Res)) {
  33. printf("Get the result: %d\n", WasmEdge_ValueGetI32(Returns[0]));
  34. } else {
  35. printf("Execution phase failed: %s\n", WasmEdge_ResultGetMessage(Res));
  36. }

  37. / Resources deallocations. /

  38. WasmEdge_VMDelete(VMCxt);
  39. WasmEdge_ConfigureDelete(ConfCxt);
  40. WasmEdge_StringDelete(FuncName);
  41. return 0;
  42. } ```

Then you can compile and run: (the 10th Fibonacci number is 89 in 0-based index)

1. $ gcc test.c -lwasmedge_c 2. $ ./a.out 3. Get the result: 89

The following graph explains the status of the VM context.

1. |========================| 2. |------->| VM: Initiated | 3. | |========================| 4. | | 5. | LoadWasm 6. | | 7. | v 8. | |========================| 9. |--------| VM: Loaded |<-------| 10. | |========================| | 11. | | ^ | 12. | Validate | | 13. Cleanup | LoadWasm | 14. | v | LoadWasm 15. | |========================| | 16. |--------| VM: Validated | | 17. | |========================| | 18. | | ^ | 19. | Instantiate | | 20. | | RegisterModule | 21. | v | | 22. | |========================| | 23. |--------| VM: Instantiated |--------| 24. |========================| 25. | ^ 26. | | 27. -------------- 28. Instantiate, Execute, ExecuteRegistered

The status of the VM context would be Inited when created. After loading WASM successfully, the status will be Loaded. After validating WASM successfully, the status will be Validated. After instantiating WASM successfully, the status will be Instantiated, and developers can invoke functions. Developers can register WASM or module instances in any status, but they should instantiate WASM again. Developers can also load WASM in any status, and they should validate and instantiate the WASM module before function invocation. When in the Instantiated status, developers can instantiate the WASM module again to reset the old WASM runtime structures.

VM Creations

The VM creation API accepts the Configure context and the Store context. If developers only need the default settings, just pass NULL to the creation API. The details of the Store context will be introduced in Store.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate();
2. WasmEdge_StoreContext *StoreCxt = WasmEdge_StoreCreate();
3. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, StoreCxt);
4. /* The caller should guarantee the life cycle if the store context. */
5. WasmEdge_StatisticsContext *StatCxt = WasmEdge_VMGetStatisticsContext(VMCxt);
6. /* The VM context already contains the statistics context and can be retrieved by this API. */
7. /*
8. * Note that the retrieved store and statistics contexts from the VM contexts by VM APIs
9. * should __NOT__ be destroyed and owned by the VM contexts.
10. */
11. WasmEdge_VMDelete(VMCxt);
12. WasmEdge_StoreDelete(StoreCxt);
13. WasmEdge_ConfigureDelete(ConfCxt);

Preregistrations

WasmEdge provides the following built-in pre-registrations.

  1. WASI (WebAssembly System Interface)

Developers can turn on the WASI support for VM in the Configure context.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_Wasi); 3. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, NULL); 4. /* The following API can retrieve the pre-registration module instances from the VM context. */ 5. /* This API will return `NULL` if the corresponding pre-registration is not set into the configuration. */ 6. WasmEdge_ModuleInstanceContext *WasiModule = 7. WasmEdge_VMGetImportModuleContext(VMCxt, WasmEdge_HostRegistration_Wasi); 8. /* Initialize the WASI. */ 9. WasmEdge_ModuleInstanceInitWASI(WasiModule, /* ... ignored */ ); 10. WasmEdge_VMDelete(VMCxt); 11. WasmEdge_ConfigureDelete(ConfCxt);

And also can create the WASI module instance from API. The details will be introduced in the Host Functions and the Host Module Registrations. 2. WasmEdge_Process

This pre-registration is for the process interface for WasmEdge on Rust sources. After turning on this pre-registration, the VM will support the wasmedge_process host functions.

1. WasmEdge_ConfigureContext *ConfCxt = WasmEdge_ConfigureCreate(); 2. WasmEdge_ConfigureAddHostRegistration(ConfCxt, WasmEdge_HostRegistration_WasmEdge_Process); 3. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(ConfCxt, NULL); 4. /* The following API can retrieve the pre-registration module instances from the VM context. */ 5. /* This API will return `NULL` if the corresponding pre-registration is not set into the configuration. */ 6. WasmEdge_ModuleInstanceContext *ProcModule = 7. WasmEdge_VMGetImportModuleContext(VMCxt, WasmEdge_HostRegistration_WasmEdge_Process); 8. /* Initialize the WasmEdge_Process. */ 9. WasmEdge_ModuleInstanceInitWasmEdgeProcess(ProcModule, /* ... ignored */ ); 10. WasmEdge_VMDelete(VMCxt); 11. WasmEdge_ConfigureDelete(ConfCxt);

And also can create the WasmEdge_Process module instance from API. The details will be introduced in the Host Functions and the Host Module Registrations.

Host Module Registrations

Host functions are functions outside WebAssembly and passed to WASM modules as imports. In WasmEdge, the host functions are composed into host modules as WasmEdge_ModuleInstanceContext objects with module names. Please refer to the Host Functions in WasmEdge Runtime for the details. In this chapter, we show the example for registering the host modules into a VM context.

1. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);
2. WasmEdge_ModuleInstanceContext *WasiModule =
3. WasmEdge_ModuleInstanceCreateWASI( /* ... ignored ... */ );
4. /* You can also create and register the WASI host modules by this API. */
5. WasmEdge_Result Res = WasmEdge_VMRegisterModuleFromImport(VMCxt, WasiModule);
6. /* The result status should be checked. */

8. /* ... */

10. WasmEdge_ModuleInstanceDelete(WasiModule);
11. /* The created module instances should be deleted by the developers when the VM deallocation. */
12. WasmEdge_VMDelete(VMCxt);

WASM Registrations And Executions

In WebAssembly, the instances in WASM modules can be exported and can be imported by other WASM modules. WasmEdge VM provides APIs for developers to register and export any WASM modules, and execute the functions or host functions in the registered WASM modules.

  1. Register the WASM modules with exported module names

Unless the module instances have already contained the module names, every WASM module should be named uniquely when registering. Assume that the WASM file fibonacci.wasm is copied into the current directory.

1. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL); 2. WasmEdge_String ModName = WasmEdge_StringCreateByCString("mod"); 3. WasmEdge_Result Res = WasmEdge_VMRegisterModuleFromFile(VMCxt, ModName, "fibonacci.wasm"); 4. /* 5. * Developers can register the WASM module from buffer with the `WasmEdge_VMRegisterModuleFromBuffer()` API, 6. * or from `WasmEdge_ASTModuleContext` object with the `WasmEdge_VMRegisterModuleFromASTModule()` API. 7. */ 8. /* 9. * The result status should be checked. 10. * The error will occur if the WASM module instantiation failed or the module name conflicts. 11. */ 12. WasmEdge_StringDelete(ModName); 13. WasmEdge_VMDelete(VMCxt); 2. Execute the functions in registered WASM modules

Assume that the C file test.c is as follows:

``` 1. #include 2. #include 3. int main() { 4. WasmEdge_VMContext *VMCxt = WasmEdge_VMCreate(NULL, NULL);

  1. / The parameters and returns arrays. /
  2. WasmEdge_Value Params[1] = { WasmEdge_ValueGenI32(20) };
  3. WasmEdge_Value Returns[1];
  4. / Names. /
  5. WasmEdge_String ModName = WasmEdge_StringCreateByCString("mod");
  6. WasmEdge_String FuncName = WasmEdge_StringCreateByCString("fib");
  7. / Result. /
  8. WasmEdge_Result Res;

  9. / Register the WASM module into VM. /

  10. Res = WasmEdge_VMRegisterModuleFromFile(VMCxt, ModName, "fibonacci.wasm");
  11. /*
    • Developers can register the WASM module from buffer with the WasmEdge_VMRegisterModuleFromBuffer() API,
    • or from WasmEdge_ASTModuleContext object with the WasmEdge_VMRegisterModuleFromASTModule() API.
  12. */
  13. if (!WasmEdge_ResultOK(Res)) {
  14. printf("WASM registration failed: %s\n", WasmEdge_ResultGetMessage(Res));
  15. return 1;
  16. }
  17. /*
    • The function "fib" in the "fibonacci.wasm" was exported with the module name "mod".
    • As the same as host functions, other modules can import the function "mod" "fib".
  18. */

  19. /*

    • Execute WASM functions in registered modules.
    • Unlike the execution of functions, the registered functions can be invoked without
    • WasmEdge_VMInstantiate() because the WASM module was instantiated when registering.
    • Developers can also invoke the host functions directly with this API.
  20. */
  21. Res = WasmEdge_VMExecuteRegistered(VMCxt, ModName, FuncName, Params, 1, Returns, 1);
  22. if (WasmEdge_ResultOK(Res)) {
  23. printf("Get the result: %d\n", WasmEdge_ValueGetI32(Returns[0]));
  24. } else {
  25. printf("Execution phase failed: %s\n", WasmEdge_ResultGetMessage(Res));
  26. }
  27. WasmEdge_StringDelete(ModName);
  28. WasmEdge_StringDelete(FuncName);
  29. WasmEdge_VMDelete(VMCxt);
  30. return 0;
  31. } ```

Then you can compile and run: (the 20th Fibonacci number is 89 in 0-based index)

``` 1. $ gcc test.c -lwasmedge_c 2. $ ./a.out

(本文超出站点单文档体积上限,已截断)