Skip to content

Commit

Permalink
minor changes (bytecodealliance#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
Weining2019 authored Mar 11, 2020
1 parent 0fdd49e commit aa42335
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 48 deletions.
2 changes: 1 addition & 1 deletion core/iwasm/interpreter/iwasm_interp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ include_directories(${IWASM_INTERP_DIR})
if (WAMR_BUILD_FAST_INTERP EQUAL 1)
set (INTERPRETER "wasm_interp_fast.c")
else ()
set (INTERPRETER "wasm_interp.c")
set (INTERPRETER "wasm_interp_classic.c")
endif ()

file (GLOB_RECURSE source_all
Expand Down
File renamed without changes.
12 changes: 6 additions & 6 deletions core/iwasm/interpreter/wasm_interp_fast.c
Original file line number Diff line number Diff line change
Expand Up @@ -874,12 +874,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
}
goto return_func;

HANDLE_OP (WASM_OP_CALL):
fidx = frame_lp[GET_OFFSET()];
bh_assert(fidx < module->function_count);
cur_func = module->functions + fidx;
goto call_func_from_interp;

HANDLE_OP (WASM_OP_CALL_INDIRECT):
{
WASMType *cur_type, *cur_func_type;
Expand Down Expand Up @@ -2056,6 +2050,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
frame_ip = frame->ip;
goto call_func_from_entry;

HANDLE_OP (WASM_OP_CALL):
fidx = frame_lp[GET_OFFSET()];
bh_assert(fidx < module->function_count);
cur_func = module->functions + fidx;
goto call_func_from_interp;

#if WASM_ENABLE_LABELS_AS_VALUES == 0
default:
wasm_set_exception(module, "WASM interp failed: unsupported opcode.");
Expand Down
39 changes: 22 additions & 17 deletions doc/export_native_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Exporting native API steps

#### Step 1: Declare the function interface in WASM app

Create a header file in a WASM app and declare the functions that are exported from native. In this example, we declare foo and foo2 as below in the header file "example.h"
Create a header file in a WASM app and declare the functions that are exported from native. In this example, we declare foo and foo2 as below in the header file `example.h`

```c
/*** file name: example.h ***/
Expand All @@ -22,7 +22,7 @@ void foo2(char * msg, char * buffer, int buf_len);
#### Step 2: Define the native API
Define the native functions which are executed from the WASM app in the runtime source file. The native function can be any name, for example **foo_native** and **foo2** here:
Then we should define the native functions in runtime source tree for handling the calls from the WASM app. The native function can be any name, for example **foo_native** and **foo2** here:
``` C
int foo_native(wasm_exec_env_t exec_env , int a, int b)
Expand All @@ -36,7 +36,7 @@ void foo2(wasm_exec_env_t exec_env, char * msg, uint8 * buffer, int buf_len)
}
```

The first parameter exec_env must be defined using type **wasm_exec_env_t** which is the calling convention for exporting native API by WAMR.
The first parameter exec_env must be defined using type **wasm_exec_env_t** which is the calling convention by WAMR.

The rest parameters should be in the same types as the parameters of WASM function foo(), but there are a few special cases that are explained in section "Buffer address conversion and boundary check". Regarding the parameter names, they don't have to be the same, but we would suggest using the same names for easy maintenance.

Expand Down Expand Up @@ -64,9 +64,7 @@ static NativeSymbol native_symbols[] =
}
};

// ensure the memory and runtime initialization is finsihed
// before registering the native functions
bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf));
// initialize the runtime before registering the native functions
wasm_runtime_init();

int n_native_symbols = sizeof(native_symbols) / sizeof(NativeSymbol);
Expand All @@ -87,28 +85,30 @@ The function signature field in **NativeSymbol** structure is a string for descr

Each letter in the "()" represents a parameter type, and the one following after ")" represents the return value type. The meaning of each letter:

- 'i': i32
- 'I': i64
- 'f': f32
- 'F': f64
- '*': the parameter is a buffer address in WASM application
- '~': the parameter is the byte length of WASM buffer as referred by preceding argument "\*". It must follow after '*', otherwise, registration will fail
- '$': the parameter is a string in WASM application
- '**i**': i32
- '**I**': i64
- '**f**': f32
- '**F**': f64
- '**\***': the parameter is a buffer address in WASM application
- '**~**': the parameter is the byte length of WASM buffer as referred by preceding argument "\*". It must follow after '*', otherwise, registration will fail
- '**$**': the parameter is a string in WASM application

The signature can defined as NULL, then all function parameters are assumed as i32 data type.

**Use EXPORT_WASM_API_WITH_SIG**

The above foo2 NativeSymbol element can be also defined with macro EXPORT_WASM_API_WITH_SIG. This macro can be used when the native function name is the same as the WASM symbol name.
The `NativeSymbol` element for `foo2 ` above can be also defined with macro EXPORT_WASM_API_WITH_SIG. This macro can be used when the native function name is the same as the WASM symbol name.

```c
static NativeSymbol native_symbols[] =
{
EXPORT_WASM_API_WITH_SIG(foo2, "($*~)")
EXPORT_WASM_API_WITH_SIG(foo2, "($*~)") // wasm symbol name will be "foo2"
};
```


## Call exported API in wasm application
## Call exported API in WASM application

Now we can call the exported native API in wasm application like this:
``` C
Expand All @@ -121,7 +121,7 @@ int main(int argc, char **argv)
char * msg = "hello";
char buffer[100];

int c = foo(a, b); // call into native foo_native()
int c = foo(a, b); // call into native foo_native()
foo2(msg, buffer, sizeof(buffer)); // call into native foo2()

return 0;
Expand All @@ -143,6 +143,11 @@ The signature letter '$', '\*' and '\~' help the runtime do automatic address co
As function parameters are always passed in 32 bits numbers, you can also use 'i' for the pointer type argument, then you must do all the address conversion and boundary checking in your native function. For example, if you change the foo2 signature to "(iii)", then you will implement the native part as the following sample:
```c
//
// If the function signature used i32 data type ("i")
// for buffer address or string parameters, here
// is how to do address conversation and boundary check manually
//
void foo2(wasm_exec_env_t exec_env,
uint32 msg_offset,
uint32 buffer_offset,
Expand Down
2 changes: 1 addition & 1 deletion product-mini/platforms/alios-things/aos.mk
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ $(NAME)_SOURCES := ${SHARED_ROOT}/platform/alios/bh_assert.c \
src/main.c

ifeq (${WAMR_BUILD_INTERP}, 1)
$(NAME)_SOURCES += ${IWASM_ROOT}/interpreter/wasm_interp.c \
$(NAME)_SOURCES += ${IWASM_ROOT}/interpreter/wasm_interp_classic.c \
${IWASM_ROOT}/interpreter/wasm_loader.c \
${IWASM_ROOT}/interpreter/wasm_runtime.c
endif
Expand Down
2 changes: 1 addition & 1 deletion product-mini/platforms/zephyr/simple/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
/* initialize runtime environment */
if (!wasm_runtime_full_init(&init_args)) {
bh_printf("Init runtime environment failed.\n");
return -1;
return;
}

#if WASM_ENABLE_LOG != 0
Expand Down
62 changes: 40 additions & 22 deletions samples/littlevgl/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,46 @@ Build and Run
Test on Zephyr
================================
We can use a STM32 NUCLEO_F767ZI board with ILI9341 display and XPT2046 touch screen to run the test. Then use host_tool to remotely install wasm app into STM32.
- Build WASM VM into Zephyr system</br>
a. clone zephyr source code</br>
Refer to Zephyr getting started.</br>
https://docs.zephyrproject.org/latest/getting_started/index.html</br>
`west init zephyrproject`</br>
`cd zephyrproject`</br>
`west update`</br>
b. copy samples</br>
`cd zephyr/samples/`</br>
`cp -a <wamr_root>samples/littlevgl/vgl-wasm-runtime vgl-wasm-runtime`</br>
`cd vgl-wasm-runtime/zephyr_build`</br>
c. create a link to wamr root dir</br>
` ln -s <wamr_root> wamr`</br>
d. build source code</br>
Since ui_app incorporated LittlevGL source code, so it needs more RAM on the device to install the application.
It is recommended that RAM SIZE not less than 380KB.
In our test use nucleo_f767zi, which is supported by Zephyr.

`mkdir build && cd build`</br>
`source ../../../../zephyr-env.sh`</br>
`cmake -GNinja -DBOARD=nucleo_f767zi ..`</br>
` ninja flash`</br>
- Build WASM VM into Zephyr system
a. clone zephyr source code
Refer to Zephyr getting started.
https://docs.zephyrproject.org/latest/getting_started/index.html

```bash
west init zephyrproject
cd zephyrproject
west update
```

b. copy samples
```bash
cd zephyr/samples/
cp -a <wamr_root>samples/littlevgl/vgl-wasm-runtime vgl-wasm-runtime
cd vgl-wasm-runtime/zephyr_build
```
c. create a link to wamr root dir
```bash
ln -s <wamr_root> wamr
```

d. build source code
Since ui_app incorporated LittlevGL source code, so it needs more RAM on the device to install the application. It is recommended that RAM SIZE not less than 380KB. In our test use nucleo_f767zi, which is supported by Zephyr. Since the littlevgl wasm app is quite big (~100KB in wasm format and ~200KB in AOT format ), there isn't enough SRAM to build interpreter and AOT together. You can only choose one of them:

- Interpreter
``` Bash
mkdir build && cd build
source ../../../../zephyr-env.sh
cmake -GNinja -DBOARD=nucleo_f767zi -DWAMR_BUILD_INTERP=1 -DWAMR_BUILD_AOT=0 ..
ninja flash
```

- AOT
``` Bash
mkdir build && cd build
source ../../../../zephyr-env.sh
cmake -GNinja -DBOARD=nucleo_f767zi -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_AOT=1 ..
ninja flash
```

- Hardware Connections

Expand Down

0 comments on commit aa42335

Please sign in to comment.