This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
wasm-micro-runtime/doc/export_native_api.md
wenyongh 7c5a84cf75 Update README, change wasi primitive lib position and add some exception checks (#146)
Add exception throw when some initial checks fail in executing main or specific function
2019-11-25 23:16:40 +08:00

3.6 KiB

The mechanism of exporting native API to WASM application

The basic working flow for WASM application calling into the native API is shown in the following diagram:

WAMR WASM API ext diagram

WAMR provides the macro EXPORT_WASM_API to enable users to export a native API to a WASM application. WAMR has implemented a base API for the timer and messaging by using EXPORT_WASM_API. This can be a point of reference for extending your own library.

static NativeSymbol extended_native_symbol_defs[] = {
    EXPORT_WASM_API(wasm_register_resource),
    EXPORT_WASM_API(wasm_response_send),
    EXPORT_WASM_API(wasm_post_request),
    EXPORT_WASM_API(wasm_sub_event),
    EXPORT_WASM_API(wasm_create_timer),
    EXPORT_WASM_API(wasm_timer_set_interval),
    EXPORT_WASM_API(wasm_timer_cancel),
    EXPORT_WASM_API(wasm_timer_restart)
};

#f03c15 Security attention: A WebAssembly application should only have access to its own memory space. As a result, the integrator should carefully design the native function to ensure that the memory accesses are safe. The native API to be exported to the WASM application must:

  • Only use 32 bits number for parameters
  • Should not pass data to the structure pointer (do data serialization instead)
  • Should do the pointer address conversion in the native API
  • Should not pass function pointer as callback

Below is a sample of a library extension. All code invoked across WASM and native world must be serialized and de-serialized, and the native world must do a boundary check for every incoming address from the WASM world.

Steps for exporting native API

WAMR implemented a framework for developers to export API's. Below is the procedure to expose the platform API's in three steps:

Step 1. Create a header file
Declare the API's for your WASM application source project to include.

Step 2. Create a source file
Export the platform API's, for example in products/linux/ext_lib_export.c

#include "lib_export.h"

static NativeSymbol extended_native_symbol_defs[] =
{
};

#include "ext_lib_export.h"

Step 3. Register new API's
Use the macro EXPORT_WASM_API and EXPORT_WASM_API2 to add exported API's into the array of extended_native_symbol_defs. The pre-defined MACRO EXPORT_WASM_API should be used to declare a function export:

#define EXPORT_WASM_API(symbol)  {#symbol, symbol}

Below code example shows how to extend the library to support customized():

//lib_export_impl.c
void customized()
{
   // your code
}


// lib_export_dec.h
#ifndef _LIB_EXPORT_DEC_H_
#define _LIB_EXPORT_DEC_H_
#ifdef __cplusplus
extern "C" {
#endif

void customized();

#ifdef __cplusplus
}
#endif
#endif


// ext_lib_export.c
#include "lib_export.h"
#include "lib_export_dec.h"

static NativeSymbol extended_native_symbol_defs[] =
{
    EXPORT_WASM_API(customized)
};

#include "ext_lib_export.h"

Use extended library

In the application source project, it will include the WAMR built-in API's header file and platform extension header files. Assuming the board vendor extends the library which added an API called customized(), the WASM application would be like this:

#include <stdio.h>
#include "lib_export_dec.h" // provided by the platform vendor

int main(int argc, char **argv)
{
    int I;
    char *buf = abcd;
    customized();                   // customized API provided by the platform vendor
    return i;
}