mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 15:32:05 +00:00
Remove unnecessary functions and implement more APIs: - wasm_##name##same - wasm##name##as_ref - wasm_ref_as##name## - wasm_ref_delete - wasm_module_validate - wasm_table_get/set/size - wasm_memory_size - wasm_config_new - wasm_foreign_new And add more wasm-c-api samples, update the related documen, add more CI rules. Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
This commit is contained in:
parent
4193949ef5
commit
edb184f709
25
.github/workflows/android.yml
vendored
25
.github/workflows/android.yml
vendored
|
@ -33,14 +33,14 @@ jobs:
|
||||||
cmake ..
|
cmake ..
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Classic interp]
|
- name: Build iwasm [classic interp]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/android
|
cd product-mini/platforms/android
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Multi module]
|
- name: Build iwasm [multi module]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/android
|
cd product-mini/platforms/android
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
@ -89,3 +89,24 @@ jobs:
|
||||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [disable hardware boundary check]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/android
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_DISABLE_HW_BOUND_CHECK=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [reference types]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/android
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_REF_TYPES=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [128-bit SIMD]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/android
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_SIMD=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
|
41
.github/workflows/linux.yml
vendored
41
.github/workflows/linux.yml
vendored
|
@ -31,14 +31,14 @@ jobs:
|
||||||
cmake ..
|
cmake ..
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Classic interp]
|
- name: Build iwasm [classic interp]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/linux
|
cd product-mini/platforms/linux
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Multi module]
|
- name: Build iwasm [multi module]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/linux
|
cd product-mini/platforms/linux
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
|
@ -87,6 +87,27 @@ jobs:
|
||||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [disable hardware boundary check]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/linux
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_DISABLE_HW_BOUND_CHECK=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [reference types]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/linux
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_REF_TYPES=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [128-bit SIMD]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/linux
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_SIMD=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
- name: Cache LLVM libraries
|
- name: Cache LLVM libraries
|
||||||
uses: actions/cache@v2
|
uses: actions/cache@v2
|
||||||
id: cache_llvm
|
id: cache_llvm
|
||||||
|
@ -132,7 +153,10 @@ jobs:
|
||||||
./callback_chain
|
./callback_chain
|
||||||
./global
|
./global
|
||||||
./hello
|
./hello
|
||||||
|
./hostref
|
||||||
|
./memory
|
||||||
./reflect
|
./reflect
|
||||||
|
./table
|
||||||
./trap
|
./trap
|
||||||
cd .. && rm -r build
|
cd .. && rm -r build
|
||||||
- name: Build Sample [wasm-c-api] [Jit]
|
- name: Build Sample [wasm-c-api] [Jit]
|
||||||
|
@ -145,7 +169,10 @@ jobs:
|
||||||
./callback_chain
|
./callback_chain
|
||||||
./global
|
./global
|
||||||
./hello
|
./hello
|
||||||
|
./hostref
|
||||||
|
./memory
|
||||||
./reflect
|
./reflect
|
||||||
|
./table
|
||||||
./trap
|
./trap
|
||||||
cd .. && rm -r build
|
cd .. && rm -r build
|
||||||
- name: Build Sample [wasm-c-api] [Aot]
|
- name: Build Sample [wasm-c-api] [Aot]
|
||||||
|
@ -158,7 +185,10 @@ jobs:
|
||||||
./callback_chain
|
./callback_chain
|
||||||
./global
|
./global
|
||||||
./hello
|
./hello
|
||||||
|
./hostref
|
||||||
|
./memory
|
||||||
./reflect
|
./reflect
|
||||||
|
./table
|
||||||
./trap
|
./trap
|
||||||
cd .. && rm -r build
|
cd .. && rm -r build
|
||||||
- name: Build Sample [basic]
|
- name: Build Sample [basic]
|
||||||
|
@ -187,3 +217,10 @@ jobs:
|
||||||
cmake ..
|
cmake ..
|
||||||
make -j $(nproc)
|
make -j $(nproc)
|
||||||
./spawn_thread
|
./spawn_thread
|
||||||
|
- name: Build Sample [ref-types]
|
||||||
|
run: |
|
||||||
|
cd samples/ref-types
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake ..
|
||||||
|
make -j $(nproc)
|
||||||
|
./hello
|
||||||
|
|
53
.github/workflows/mac.yml
vendored
53
.github/workflows/mac.yml
vendored
|
@ -26,63 +26,84 @@ jobs:
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Classic interp]
|
- name: Build iwasm [classic interp]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
cmake .. -DWAMR_BUILD_FAST_INTERP=0
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [Multi module]
|
- name: Build iwasm [multi module]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_MULTI_MODULE=1
|
cmake .. -DWAMR_BUILD_MULTI_MODULE=1
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [lib-pthread]
|
- name: Build iwasm [lib-pthread]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_LIB_PTHREAD=1
|
cmake .. -DWAMR_BUILD_LIB_PTHREAD=1
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [aot only]
|
- name: Build iwasm [aot only]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0
|
cmake .. -DWAMR_BUILD_AOT=1 -DWAMR_BUILD_INTERP=0
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [interp only]
|
- name: Build iwasm [interp only]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_AOT=0
|
cmake .. -DWAMR_BUILD_AOT=0
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [memory profiling]
|
- name: Build iwasm [memory profiling]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_MEMORY_PROFILING=1
|
cmake .. -DWAMR_BUILD_MEMORY_PROFILING=1
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [tail call]
|
- name: Build iwasm [tail call]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_TAIL_CALL=1
|
cmake .. -DWAMR_BUILD_TAIL_CALL=1
|
||||||
make
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: Build iwasm [custom name section]
|
- name: Build iwasm [custom name section]
|
||||||
run: |
|
run: |
|
||||||
cd product-mini/platforms/darwin
|
cd product-mini/platforms/darwin
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||||
make
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [disable hardware boundary check]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/darwin
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_DISABLE_HW_BOUND_CHECK=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [ref types]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/darwin
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_REF_TYPES=1
|
||||||
|
make -j $(nproc)
|
||||||
|
cd .. && rm -rf build
|
||||||
|
- name: Build iwasm [128-bit SIMD]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/darwin
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_SIMD=1
|
||||||
|
make -j $(nproc)
|
||||||
cd .. && rm -rf build
|
cd .. && rm -rf build
|
||||||
- name: download and install wabt
|
- name: download and install wabt
|
||||||
run: |
|
run: |
|
||||||
|
@ -96,6 +117,12 @@ jobs:
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
cmake ..
|
cmake ..
|
||||||
make
|
make
|
||||||
./hello
|
|
||||||
./global
|
|
||||||
./callback
|
./callback
|
||||||
|
./callback_chain
|
||||||
|
./global
|
||||||
|
./hello
|
||||||
|
./hostref
|
||||||
|
./memory
|
||||||
|
./reflect
|
||||||
|
./table
|
||||||
|
./trap
|
||||||
|
|
21
.github/workflows/windows.yml
vendored
21
.github/workflows/windows.yml
vendored
|
@ -60,4 +60,25 @@ jobs:
|
||||||
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
cmake .. -DWAMR_BUILD_CUSTOM_NAME_SECTION=1
|
||||||
cmake --build . --config Release
|
cmake --build . --config Release
|
||||||
cd .. && rm -force -r build
|
cd .. && rm -force -r build
|
||||||
|
- name: Build iwasm [disable hardware boundary check]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/windows
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_DISABLE_HW_BOUND_CHECK=1
|
||||||
|
cmake --build . --config Release
|
||||||
|
cd .. && rm -force -r build
|
||||||
|
- name: Build iwasm [reference types]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/windows
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_REF_TYPES=1
|
||||||
|
cmake --build . --config Release
|
||||||
|
cd .. && rm -force -r build
|
||||||
|
- name: Build iwasm [128-bit SIMD]
|
||||||
|
run: |
|
||||||
|
cd product-mini/platforms/windows
|
||||||
|
mkdir build && cd build
|
||||||
|
cmake .. -DWAMR_BUILD_SIMD=1
|
||||||
|
cmake --build . --config Release
|
||||||
|
cd .. && rm -force -r build
|
||||||
|
|
||||||
|
|
|
@ -2822,9 +2822,12 @@ aot_table_grow(AOTModuleInstance *module_inst, uint32 tbl_idx,
|
||||||
return orig_tbl_sz;
|
return orig_tbl_sz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tbl_inst->cur_size > UINT32_MAX - inc_entries) {
|
||||||
|
return (uint32)-1;
|
||||||
|
}
|
||||||
|
|
||||||
entry_count = tbl_inst->cur_size + inc_entries;
|
entry_count = tbl_inst->cur_size + inc_entries;
|
||||||
/* prevent from integer overflow */
|
if (entry_count > tbl_inst->max_size) {
|
||||||
if (entry_count < tbl_inst->cur_size || entry_count > tbl_inst->max_size) {
|
|
||||||
return (uint32)-1;
|
return (uint32)-1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,7 +6,7 @@
|
||||||
#ifndef _WASM_C_API_INTERNAL_H
|
#ifndef _WASM_C_API_INTERNAL_H
|
||||||
#define _WASM_C_API_INTERNAL_H
|
#define _WASM_C_API_INTERNAL_H
|
||||||
|
|
||||||
#include "wasm_c_api.h"
|
#include "../include/wasm_c_api.h"
|
||||||
#include "wasm_runtime_common.h"
|
#include "wasm_runtime_common.h"
|
||||||
|
|
||||||
#ifndef own
|
#ifndef own
|
||||||
|
@ -19,9 +19,9 @@
|
||||||
/* caller needs to take care resource for the vector itself */
|
/* caller needs to take care resource for the vector itself */
|
||||||
#define DEFAULT_VECTOR_INIT_LENGTH (64)
|
#define DEFAULT_VECTOR_INIT_LENGTH (64)
|
||||||
|
|
||||||
WASM_DECLARE_VEC(store, *)
|
|
||||||
WASM_DECLARE_VEC(module, *)
|
|
||||||
WASM_DECLARE_VEC(instance, *)
|
WASM_DECLARE_VEC(instance, *)
|
||||||
|
WASM_DECLARE_VEC(module, *)
|
||||||
|
WASM_DECLARE_VEC(store, *)
|
||||||
|
|
||||||
/* Runtime Environment */
|
/* Runtime Environment */
|
||||||
struct wasm_engine_t {
|
struct wasm_engine_t {
|
||||||
|
@ -32,6 +32,7 @@ struct wasm_engine_t {
|
||||||
struct wasm_store_t {
|
struct wasm_store_t {
|
||||||
wasm_module_vec_t *modules;
|
wasm_module_vec_t *modules;
|
||||||
wasm_instance_vec_t *instances;
|
wasm_instance_vec_t *instances;
|
||||||
|
Vector *foreigns;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Type Representations */
|
/* Type Representations */
|
||||||
|
@ -82,8 +83,25 @@ struct wasm_exporttype_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Runtime Objects */
|
/* Runtime Objects */
|
||||||
|
enum wasm_reference_kind {
|
||||||
|
WASM_REF_foreign,
|
||||||
|
WASM_REF_func,
|
||||||
|
WASM_REF_global,
|
||||||
|
WASM_REF_memory,
|
||||||
|
WASM_REF_table,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct wasm_host_info {
|
||||||
|
void *info;
|
||||||
|
void (*finalizer)(void *);
|
||||||
|
};
|
||||||
|
|
||||||
struct wasm_ref_t {
|
struct wasm_ref_t {
|
||||||
uint32 obj;
|
wasm_store_t *store;
|
||||||
|
enum wasm_reference_kind kind;
|
||||||
|
struct wasm_host_info host_info;
|
||||||
|
uint32 ref_idx_rt;
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_trap_t {
|
struct wasm_trap_t {
|
||||||
|
@ -91,11 +109,22 @@ struct wasm_trap_t {
|
||||||
Vector *frames;
|
Vector *frames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct wasm_foreign_t {
|
||||||
|
wasm_store_t *store;
|
||||||
|
enum wasm_reference_kind kind;
|
||||||
|
struct wasm_host_info host_info;
|
||||||
|
int32 ref_cnt;
|
||||||
|
uint32 foreign_idx_rt;
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt;
|
||||||
|
};
|
||||||
|
|
||||||
struct wasm_func_t {
|
struct wasm_func_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_name_t *module_name;
|
wasm_name_t *module_name;
|
||||||
wasm_name_t *name;
|
wasm_name_t *name;
|
||||||
uint16 kind;
|
uint16 kind;
|
||||||
|
|
||||||
|
struct wasm_host_info host_info;
|
||||||
wasm_functype_t *type;
|
wasm_functype_t *type;
|
||||||
|
|
||||||
bool with_env;
|
bool with_env;
|
||||||
|
@ -117,10 +146,12 @@ struct wasm_func_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_global_t {
|
struct wasm_global_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_name_t *module_name;
|
wasm_name_t *module_name;
|
||||||
wasm_name_t *name;
|
wasm_name_t *name;
|
||||||
uint16 kind;
|
uint16 kind;
|
||||||
|
|
||||||
|
struct wasm_host_info host_info;
|
||||||
wasm_globaltype_t *type;
|
wasm_globaltype_t *type;
|
||||||
wasm_val_t *init;
|
wasm_val_t *init;
|
||||||
/*
|
/*
|
||||||
|
@ -132,10 +163,12 @@ struct wasm_global_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_memory_t {
|
struct wasm_memory_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_name_t *module_name;
|
wasm_name_t *module_name;
|
||||||
wasm_name_t *name;
|
wasm_name_t *name;
|
||||||
uint16 kind;
|
uint16 kind;
|
||||||
|
|
||||||
|
struct wasm_host_info host_info;
|
||||||
wasm_memorytype_t *type;
|
wasm_memorytype_t *type;
|
||||||
/*
|
/*
|
||||||
* an index in both memory runtime instance lists
|
* an index in both memory runtime instance lists
|
||||||
|
@ -146,10 +179,12 @@ struct wasm_memory_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_table_t {
|
struct wasm_table_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_name_t *module_name;
|
wasm_name_t *module_name;
|
||||||
wasm_name_t *name;
|
wasm_name_t *name;
|
||||||
uint16 kind;
|
uint16 kind;
|
||||||
|
|
||||||
|
struct wasm_host_info host_info;
|
||||||
wasm_tabletype_t *type;
|
wasm_tabletype_t *type;
|
||||||
/*
|
/*
|
||||||
* an index in both table runtime instance lists
|
* an index in both table runtime instance lists
|
||||||
|
@ -160,16 +195,49 @@ struct wasm_table_t {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_extern_t {
|
struct wasm_extern_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_name_t *module_name;
|
wasm_name_t *module_name;
|
||||||
wasm_name_t *name;
|
wasm_name_t *name;
|
||||||
wasm_externkind_t kind;
|
wasm_externkind_t kind;
|
||||||
uint8 data[1];
|
uint8 data[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct wasm_instance_t {
|
struct wasm_instance_t {
|
||||||
|
wasm_store_t *store;
|
||||||
wasm_extern_vec_t *imports;
|
wasm_extern_vec_t *imports;
|
||||||
wasm_extern_vec_t *exports;
|
wasm_extern_vec_t *exports;
|
||||||
|
struct wasm_host_info host_info;
|
||||||
WASMModuleInstanceCommon *inst_comm_rt;
|
WASMModuleInstanceCommon *inst_comm_rt;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
wasm_ref_t *
|
||||||
|
wasm_ref_new_internal(wasm_store_t *store,
|
||||||
|
enum wasm_reference_kind kind,
|
||||||
|
uint32 obj_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
|
|
||||||
|
wasm_foreign_t *
|
||||||
|
wasm_foreign_new_internal(wasm_store_t *store,
|
||||||
|
uint32 foreign_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
|
|
||||||
|
wasm_func_t *
|
||||||
|
wasm_func_new_internal(wasm_store_t *store,
|
||||||
|
uint16 func_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
|
|
||||||
|
wasm_global_t *
|
||||||
|
wasm_global_new_internal(wasm_store_t *store,
|
||||||
|
uint16 global_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
|
|
||||||
|
wasm_memory_t *
|
||||||
|
wasm_memory_new_internal(wasm_store_t *store,
|
||||||
|
uint16 memory_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
|
|
||||||
|
wasm_table_t *
|
||||||
|
wasm_table_new_internal(wasm_store_t *store,
|
||||||
|
uint16 table_idx_rt,
|
||||||
|
WASMModuleInstanceCommon *inst_comm_rt);
|
||||||
#endif /* _WASM_C_API_INTERNAL_H */
|
#endif /* _WASM_C_API_INTERNAL_H */
|
||||||
|
|
|
@ -3977,57 +3977,6 @@ wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 *
|
|
||||||
wasm_runtime_get_memory_data(const WASMModuleInstanceCommon *module_inst_comm,
|
|
||||||
uint32 memory_inst_idx)
|
|
||||||
{
|
|
||||||
#if WASM_ENABLE_INTERP != 0
|
|
||||||
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
|
|
||||||
WASMModuleInstance *module_inst =
|
|
||||||
(WASMModuleInstance *)module_inst_comm;
|
|
||||||
WASMMemoryInstance *memory_inst =
|
|
||||||
module_inst->memories[memory_inst_idx];
|
|
||||||
return memory_inst->memory_data;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WASM_ENABLE_AOT != 0
|
|
||||||
if (module_inst_comm->module_type == Wasm_Module_AoT) {
|
|
||||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
|
|
||||||
AOTMemoryInstance *memory_inst =
|
|
||||||
((AOTMemoryInstance**)module_inst->memories.ptr)[memory_inst_idx];
|
|
||||||
return memory_inst->memory_data.ptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32
|
|
||||||
wasm_runtime_get_memory_data_size(
|
|
||||||
const WASMModuleInstanceCommon *module_inst_comm,
|
|
||||||
uint32 memory_inst_idx)
|
|
||||||
{
|
|
||||||
#if WASM_ENABLE_INTERP != 0
|
|
||||||
if (module_inst_comm->module_type == Wasm_Module_Bytecode) {
|
|
||||||
WASMModuleInstance *module_inst =
|
|
||||||
(WASMModuleInstance *)module_inst_comm;
|
|
||||||
WASMMemoryInstance *memory_inst =
|
|
||||||
module_inst->memories[memory_inst_idx];
|
|
||||||
return memory_inst->cur_page_count * memory_inst->num_bytes_per_page;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WASM_ENABLE_AOT != 0
|
|
||||||
if (module_inst_comm->module_type == Wasm_Module_AoT) {
|
|
||||||
AOTModuleInstance *module_inst = (AOTModuleInstance *)module_inst_comm;
|
|
||||||
AOTMemoryInstance *memory_inst =
|
|
||||||
((AOTMemoryInstance**)module_inst->memories.ptr)[memory_inst_idx];
|
|
||||||
return memory_inst->cur_page_count * memory_inst->num_bytes_per_page;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
argv_to_params(wasm_val_t *out_params,
|
argv_to_params(wasm_val_t *out_params,
|
||||||
const uint32 *argv,
|
const uint32 *argv,
|
||||||
|
@ -4058,6 +4007,23 @@ argv_to_params(wasm_val_t *out_params,
|
||||||
u32[0] = *argv++;
|
u32[0] = *argv++;
|
||||||
u32[1] = *argv++;
|
u32[1] = *argv++;
|
||||||
break;
|
break;
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
case VALUE_TYPE_EXTERNREF:
|
||||||
|
param->kind = WASM_ANYREF;
|
||||||
|
|
||||||
|
if (NULL_REF == *argv) {
|
||||||
|
param->of.ref = NULL;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!wasm_externref_ref2obj(*argv,
|
||||||
|
(void **)¶m->of.ref)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
argv++;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4067,7 +4033,8 @@ argv_to_params(wasm_val_t *out_params,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
results_to_argv(uint32 *out_argv,
|
results_to_argv(WASMModuleInstanceCommon *module_inst,
|
||||||
|
uint32 *out_argv,
|
||||||
const wasm_val_t *results,
|
const wasm_val_t *results,
|
||||||
WASMType *func_type)
|
WASMType *func_type)
|
||||||
{
|
{
|
||||||
|
@ -4087,6 +4054,15 @@ results_to_argv(uint32 *out_argv,
|
||||||
*argv++ = u32[0];
|
*argv++ = u32[0];
|
||||||
*argv++ = u32[1];
|
*argv++ = u32[1];
|
||||||
break;
|
break;
|
||||||
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
|
case VALUE_TYPE_EXTERNREF:
|
||||||
|
if (!wasm_externref_obj2ref(module_inst, result->of.ref,
|
||||||
|
argv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
argv++;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -4134,7 +4110,7 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
||||||
char trap_message[128] = { 0 };
|
char trap_message[128] = { 0 };
|
||||||
bh_memcpy_s(
|
bh_memcpy_s(
|
||||||
trap_message, 127, trap->message->data,
|
trap_message, 127, trap->message->data,
|
||||||
(trap->message->size < 127 ? trap->message->size : 127));
|
(trap->message->size < 127 ? (uint32)trap->message->size : 127));
|
||||||
wasm_runtime_set_exception(module_inst, trap_message);
|
wasm_runtime_set_exception(module_inst, trap_message);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -4152,7 +4128,7 @@ wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!results_to_argv(argv, results, func_type)) {
|
if (!results_to_argv(module_inst, argv, results, func_type)) {
|
||||||
wasm_runtime_set_exception(module_inst, "unsupported result type");
|
wasm_runtime_set_exception(module_inst, "unsupported result type");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
|
@ -796,14 +796,6 @@ wasm_runtime_get_export_table_type(const WASMModuleCommon *module_comm,
|
||||||
uint32 *out_min_size,
|
uint32 *out_min_size,
|
||||||
uint32 *out_max_size);
|
uint32 *out_max_size);
|
||||||
|
|
||||||
uint8 *
|
|
||||||
wasm_runtime_get_memory_data(const WASMModuleInstanceCommon *module_inst_comm,
|
|
||||||
uint32 memory_inst_idx);
|
|
||||||
|
|
||||||
uint32
|
|
||||||
wasm_runtime_get_memory_data_size(const WASMModuleInstanceCommon *module_inst_comm,
|
|
||||||
uint32 memory_inst_idx);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
wasm_runtime_invoke_c_api_native(WASMModuleInstanceCommon *module_inst,
|
||||||
void *func_ptr, WASMType *func_type,
|
void *func_ptr, WASMType *func_type,
|
||||||
|
|
|
@ -25,6 +25,7 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx,
|
||||||
|
|
||||||
while (i < tbl_idx && i < comp_ctx->comp_data->import_table_count) {
|
while (i < tbl_idx && i < comp_ctx->comp_data->import_table_count) {
|
||||||
offset += offsetof(AOTTableInstance, data);
|
offset += offsetof(AOTTableInstance, data);
|
||||||
|
/* avoid loading from current AOTTableInstance */
|
||||||
offset += sizeof(uint32) * aot_get_imp_tbl_data_slots(imp_tbls + i);
|
offset += sizeof(uint32) * aot_get_imp_tbl_data_slots(imp_tbls + i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
@ -37,6 +38,7 @@ get_tbl_inst_offset(const AOTCompContext *comp_ctx,
|
||||||
i -= comp_ctx->comp_data->import_table_count;
|
i -= comp_ctx->comp_data->import_table_count;
|
||||||
while (i < tbl_idx && i < comp_ctx->comp_data->table_count) {
|
while (i < tbl_idx && i < comp_ctx->comp_data->table_count) {
|
||||||
offset += offsetof(AOTTableInstance, data);
|
offset += offsetof(AOTTableInstance, data);
|
||||||
|
/* avoid loading from current AOTTableInstance */
|
||||||
offset += sizeof(uint32) * aot_get_tbl_data_slots(tbls + i);
|
offset += sizeof(uint32) * aot_get_tbl_data_slots(tbls + i);
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
|
@ -573,6 +573,12 @@ WASM_API_EXTERN own wasm_instance_t* wasm_instance_new(
|
||||||
own wasm_trap_t**
|
own wasm_trap_t**
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// please refer to wasm_runtime_instantiate(...) in core/iwasm/include/wasm_export.h
|
||||||
|
WASM_API_EXTERN own wasm_instance_t* wasm_instance_new_with_args(
|
||||||
|
wasm_store_t*, const wasm_module_t*, const wasm_extern_t *const imports[],
|
||||||
|
own wasm_trap_t**, const uint32_t stack_size, const uint32_t heap_size
|
||||||
|
);
|
||||||
|
|
||||||
WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
|
WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
|
||||||
|
|
||||||
|
|
||||||
|
@ -764,6 +770,7 @@ static inline void* wasm_val_ptr(const wasm_val_t* val) {
|
||||||
#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}}
|
#define WASM_REF_VAL(r) {.kind = WASM_ANYREF, .of = {.ref = r}}
|
||||||
#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}}
|
#define WASM_INIT_VAL {.kind = WASM_ANYREF, .of = {.ref = NULL}}
|
||||||
|
|
||||||
|
#define KILOBYTE(n) ((n) * 1024)
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -7881,7 +7881,7 @@ fail_data_cnt_sec_require:
|
||||||
#if WASM_ENABLE_REF_TYPES != 0
|
#if WASM_ENABLE_REF_TYPES != 0
|
||||||
case WASM_OP_TABLE_INIT:
|
case WASM_OP_TABLE_INIT:
|
||||||
{
|
{
|
||||||
uint8 seg_ref_type, tbl_ref_type;
|
uint8 seg_ref_type = 0, tbl_ref_type = 0;
|
||||||
|
|
||||||
if (!wasm_get_ref_types_flag()) {
|
if (!wasm_get_ref_types_flag()) {
|
||||||
goto unsupported_opcode;
|
goto unsupported_opcode;
|
||||||
|
|
|
@ -476,9 +476,11 @@ tables_instantiate(const WASMModule *module,
|
||||||
/* instantiate tables from import section */
|
/* instantiate tables from import section */
|
||||||
import = module->import_tables;
|
import = module->import_tables;
|
||||||
for (i = 0; i < module->import_table_count; i++, import++) {
|
for (i = 0; i < module->import_table_count; i++, import++) {
|
||||||
|
uint32 max_size_fixed = 0;
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
WASMTableInstance *table_inst_linked = NULL;
|
WASMTableInstance *table_inst_linked = NULL;
|
||||||
WASMModuleInstance *module_inst_linked = NULL;
|
WASMModuleInstance *module_inst_linked = NULL;
|
||||||
|
|
||||||
if (import->u.table.import_module) {
|
if (import->u.table.import_module) {
|
||||||
if (!(module_inst_linked =
|
if (!(module_inst_linked =
|
||||||
get_sub_module_inst(module_inst, import->u.table.import_module))) {
|
get_sub_module_inst(module_inst, import->u.table.import_module))) {
|
||||||
|
@ -499,12 +501,14 @@ tables_instantiate(const WASMModule *module,
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
/* in order to save memory, alloc resource as few as possible */
|
||||||
|
max_size_fixed = import->u.table.possible_grow
|
||||||
|
? import->u.table.max_size
|
||||||
|
: import->u.table.init_size;
|
||||||
|
|
||||||
/* it is a built-in table, every module has its own */
|
/* it is a built-in table, every module has its own */
|
||||||
total_size = offsetof(WASMTableInstance, base_addr);
|
total_size = offsetof(WASMTableInstance, base_addr);
|
||||||
total_size +=
|
total_size += (uint64)max_size_fixed * sizeof(uint32);
|
||||||
import->u.table.possible_grow
|
|
||||||
? sizeof(uint32) * (uint64)import->u.table.max_size
|
|
||||||
: sizeof(uint32) * (uint64)import->u.table.init_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(table = tables[table_index++] = runtime_malloc
|
if (!(table = tables[table_index++] = runtime_malloc
|
||||||
|
@ -515,6 +519,7 @@ tables_instantiate(const WASMModule *module,
|
||||||
|
|
||||||
/* Set all elements to -1 to mark them as uninitialized elements */
|
/* Set all elements to -1 to mark them as uninitialized elements */
|
||||||
memset(table, -1, (uint32)total_size);
|
memset(table, -1, (uint32)total_size);
|
||||||
|
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
table->table_inst_linked = table_inst_linked;
|
table->table_inst_linked = table_inst_linked;
|
||||||
if (table_inst_linked != NULL) {
|
if (table_inst_linked != NULL) {
|
||||||
|
@ -527,21 +532,26 @@ tables_instantiate(const WASMModule *module,
|
||||||
{
|
{
|
||||||
table->elem_type = import->u.table.elem_type;
|
table->elem_type = import->u.table.elem_type;
|
||||||
table->cur_size = import->u.table.init_size;
|
table->cur_size = import->u.table.init_size;
|
||||||
table->max_size = import->u.table.max_size;
|
table->max_size = max_size_fixed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* instantiate tables from table section */
|
/* instantiate tables from table section */
|
||||||
for (i = 0; i < module->table_count; i++) {
|
for (i = 0; i < module->table_count; i++) {
|
||||||
|
uint32 max_size_fixed = 0;
|
||||||
|
|
||||||
total_size = offsetof(WASMTableInstance, base_addr);
|
total_size = offsetof(WASMTableInstance, base_addr);
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
/* in case, a module which imports this table will grow it */
|
/* in case, a module which imports this table will grow it */
|
||||||
total_size += sizeof(uint32) * (uint64)module->tables[i].max_size;
|
max_size_fixed = module->tables[i].max_size;
|
||||||
#else
|
#else
|
||||||
total_size += module->tables[i].possible_grow
|
max_size_fixed =
|
||||||
? sizeof(uint32) * (uint64)module->tables[i].max_size
|
module->tables[i].possible_grow
|
||||||
: sizeof(uint32) * (uint64)module->tables[i].init_size;
|
? module->tables[i].max_size
|
||||||
|
: module->tables[i].init_size;
|
||||||
#endif
|
#endif
|
||||||
|
total_size += sizeof(uint32) * (uint64)max_size_fixed;
|
||||||
|
|
||||||
if (!(table = tables[table_index++] = runtime_malloc
|
if (!(table = tables[table_index++] = runtime_malloc
|
||||||
(total_size, error_buf, error_buf_size))) {
|
(total_size, error_buf, error_buf_size))) {
|
||||||
tables_deinstantiate(tables, table_count);
|
tables_deinstantiate(tables, table_count);
|
||||||
|
@ -552,7 +562,7 @@ tables_instantiate(const WASMModule *module,
|
||||||
memset(table, -1, (uint32)total_size);
|
memset(table, -1, (uint32)total_size);
|
||||||
table->elem_type = module->tables[i].elem_type;
|
table->elem_type = module->tables[i].elem_type;
|
||||||
table->cur_size = module->tables[i].init_size;
|
table->cur_size = module->tables[i].init_size;
|
||||||
table->max_size = module->tables[i].max_size;
|
table->max_size = max_size_fixed;
|
||||||
#if WASM_ENABLE_MULTI_MODULE != 0
|
#if WASM_ENABLE_MULTI_MODULE != 0
|
||||||
table->table_inst_linked = NULL;
|
table->table_inst_linked = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -2150,10 +2160,12 @@ wasm_enlarge_table(WASMModuleInstance *module_inst,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (inc_entries > UINT32_MAX - table_inst->cur_size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
entry_count = table_inst->cur_size + inc_entries;
|
entry_count = table_inst->cur_size + inc_entries;
|
||||||
/* prevent from integer overflow */
|
if (entry_count > table_inst->max_size) {
|
||||||
if (entry_count < table_inst->cur_size
|
|
||||||
|| entry_count > table_inst->max_size) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -456,4 +456,3 @@ wasm_interp_dump_call_stack(struct WASMExecEnv *exec_env);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* end of _WASM_RUNTIME_H */
|
#endif /* end of _WASM_RUNTIME_H */
|
||||||
|
|
||||||
|
|
|
@ -12,59 +12,26 @@ them in next releases.
|
||||||
|
|
||||||
a summary of unsupported APIs
|
a summary of unsupported APIs
|
||||||
|
|
||||||
- Configuration
|
|
||||||
|
|
||||||
``` c
|
|
||||||
WASM_API_EXTERN own wasm_config_t* wasm_config_new(void);
|
|
||||||
```
|
|
||||||
|
|
||||||
- References
|
- References
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*); \
|
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*);
|
||||||
WASM_API_EXTERN void* wasm_##name##_get_host_info(const wasm_##name##_t*); \
|
|
||||||
WASM_API_EXTERN void wasm_##name##_set_host_info(wasm_##name##_t*, void*); \
|
|
||||||
WASM_API_EXTERN void wasm_##name##_set_host_info_with_finalizer( \
|
|
||||||
WASM_API_EXTERN wasm_ref_t* wasm_##name##_as_ref(wasm_##name##_t*); \
|
|
||||||
WASM_API_EXTERN wasm_##name##_t* wasm_ref_as_##name(wasm_ref_t*); \
|
|
||||||
WASM_API_EXTERN const wasm_ref_t* wasm_##name##_as_ref_const(const wasm_##name##_t*); \
|
|
||||||
WASM_API_EXTERN const wasm_##name##_t* wasm_ref_as_##name##_const(const wasm_ref_t*);
|
|
||||||
WASM_API_EXTERN own wasm_shared_##name##_t* wasm_##name##_share(const wasm_##name##_t*); \
|
|
||||||
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_obtain(wasm_store_t*, const wasm_shared_##name##_t*);
|
||||||
```
|
```
|
||||||
|
|
||||||
- Frames
|
|
||||||
|
|
||||||
``` c
|
|
||||||
WASM_API_EXTERN own wasm_frame_t* wasm_frame_copy(const wasm_frame_t*);
|
|
||||||
WASM_API_EXTERN struct wasm_instance_t* wasm_frame_instance(const wasm_frame_t*);
|
|
||||||
WASM_API_EXTERN uint32_t wasm_frame_func_index(const wasm_frame_t*);
|
|
||||||
WASM_API_EXTERN size_t wasm_frame_func_offset(const wasm_frame_t*);
|
|
||||||
WASM_API_EXTERN size_t wasm_frame_module_offset(const wasm_frame_t*);
|
|
||||||
WASM_API_EXTERN own wasm_frame_t* wasm_trap_origin(const wasm_trap_t*);
|
|
||||||
WASM_API_EXTERN void wasm_trap_trace(const wasm_trap_t*, own wasm_frame_vec_t* out);
|
|
||||||
```
|
|
||||||
|
|
||||||
Foreign Objects
|
|
||||||
|
|
||||||
``` c
|
|
||||||
WASM_API_EXTERN own wasm_foreign_t* wasm_foreign_new(wasm_store_t*);
|
|
||||||
```
|
|
||||||
|
|
||||||
- Several Module APIs
|
- Several Module APIs
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
|
|
||||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
|
||||||
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
WASM_API_EXTERN void wasm_module_serialize(const wasm_module_t*, own wasm_byte_vec_t* out);
|
||||||
|
WASM_API_EXTERN own wasm_module_t* wasm_module_deserialize(wasm_store_t*, const wasm_byte_vec_t*);
|
||||||
```
|
```
|
||||||
|
|
||||||
- Table Operations APIs
|
we tend to grow a table or a memory by opcode only and not support growing both
|
||||||
|
by host-side function callings.
|
||||||
|
|
||||||
|
- Table Grow APIs
|
||||||
|
|
||||||
``` c
|
``` c
|
||||||
WASM_API_EXTERN own wasm_ref_t* wasm_table_get(const wasm_table_t*, wasm_table_size_t index);
|
|
||||||
WASM_API_EXTERN bool wasm_table_set(wasm_table_t*, wasm_table_size_t index, wasm_ref_t*);
|
|
||||||
WASM_API_EXTERN wasm_table_size_t wasm_table_size(const wasm_table_t*);
|
|
||||||
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
WASM_API_EXTERN bool wasm_table_grow(wasm_table_t*, wasm_table_size_t delta, wasm_ref_t* init);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||||
set(WAMR_BUILD_LIBC_WASI 0)
|
set(WAMR_BUILD_LIBC_WASI 0)
|
||||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||||
set(WAMR_BUILD_DUMP_CALL_STACK 1)
|
set(WAMR_BUILD_DUMP_CALL_STACK 1)
|
||||||
|
set(WAMR_BUILD_REF_TYPES 1)
|
||||||
|
|
||||||
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
||||||
set(WAMR_BUILD_FAST_INTERP 1)
|
set(WAMR_BUILD_FAST_INTERP 1)
|
||||||
|
@ -101,12 +102,15 @@ include (${SHARED_DIR}/utils/uncommon/shared_uncommon.cmake)
|
||||||
set(MM_UTIL src/utils/multi_module_utils.c)
|
set(MM_UTIL src/utils/multi_module_utils.c)
|
||||||
# build executable for each .c
|
# build executable for each .c
|
||||||
set(EXAMPLES
|
set(EXAMPLES
|
||||||
hello
|
|
||||||
callback
|
callback
|
||||||
global
|
|
||||||
reflect
|
|
||||||
trap
|
|
||||||
callback_chain
|
callback_chain
|
||||||
|
global
|
||||||
|
hello
|
||||||
|
hostref
|
||||||
|
memory
|
||||||
|
reflect
|
||||||
|
table
|
||||||
|
trap
|
||||||
)
|
)
|
||||||
|
|
||||||
foreach(EX ${EXAMPLES})
|
foreach(EX ${EXAMPLES})
|
||||||
|
@ -123,7 +127,7 @@ foreach(EX ${EXAMPLES})
|
||||||
set(WAT ${CMAKE_CURRENT_LIST_DIR}/src/${EX}.wat)
|
set(WAT ${CMAKE_CURRENT_LIST_DIR}/src/${EX}.wat)
|
||||||
|
|
||||||
add_custom_target(${EX}_WASM
|
add_custom_target(${EX}_WASM
|
||||||
COMMAND ${WAT2WASM} ${WAT} -o ${PROJECT_BINARY_DIR}/${EX}.wasm
|
COMMAND ${WAT2WASM} ${WAT} --enable-reference-types -o ${PROJECT_BINARY_DIR}/${EX}.wasm
|
||||||
DEPENDS ${WAT}
|
DEPENDS ${WAT}
|
||||||
BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.wasm
|
BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.wasm
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
@ -133,7 +137,7 @@ foreach(EX ${EXAMPLES})
|
||||||
# generate .aot file
|
# generate .aot file
|
||||||
if(${WAMR_BUILD_AOT} EQUAL 1)
|
if(${WAMR_BUILD_AOT} EQUAL 1)
|
||||||
add_custom_target(${EX}_AOT
|
add_custom_target(${EX}_AOT
|
||||||
COMMAND ${WAMRC} -o ${PROJECT_BINARY_DIR}/${EX}.aot
|
COMMAND ${WAMRC} --enable-ref-types -o ${PROJECT_BINARY_DIR}/${EX}.aot
|
||||||
${PROJECT_BINARY_DIR}/${EX}.wasm
|
${PROJECT_BINARY_DIR}/${EX}.wasm
|
||||||
DEPENDS ${EX}_WASM
|
DEPENDS ${EX}_WASM
|
||||||
BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot
|
BYPRODUCTS ${PROJECT_BINARY_DIR}/${EX}.aot
|
||||||
|
|
263
samples/wasm-c-api/src/hostref.c
Normal file
263
samples/wasm-c-api/src/hostref.c
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "wasm_c_api.h"
|
||||||
|
|
||||||
|
#define own
|
||||||
|
|
||||||
|
|
||||||
|
// A function to be called from Wasm code.
|
||||||
|
own wasm_trap_t* callback(
|
||||||
|
const wasm_val_t args[], wasm_val_t results[]
|
||||||
|
) {
|
||||||
|
printf("Calling back...\n> ");
|
||||||
|
printf("> %p\n",
|
||||||
|
args[0].of.ref ? wasm_ref_get_host_info(args[0].of.ref) : NULL);
|
||||||
|
wasm_val_copy(&results[0], &args[0]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
|
||||||
|
printf("> Error accessing function export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_func(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_global_t* get_export_global(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_global(exports->data[i])) {
|
||||||
|
printf("> Error accessing global export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_global(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_table(exports->data[i])) {
|
||||||
|
printf("> Error accessing table export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_table(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
own wasm_ref_t* call_v_r(const wasm_func_t* func) {
|
||||||
|
printf("call_v_r... "); fflush(stdout);
|
||||||
|
wasm_val_t rs[] = { WASM_INIT_VAL };
|
||||||
|
if (wasm_func_call(func, NULL, rs)) {
|
||||||
|
printf("> Error calling function!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("okay\n");
|
||||||
|
return rs[0].of.ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_r_v(const wasm_func_t* func, wasm_ref_t* ref) {
|
||||||
|
printf("call_r_v... "); fflush(stdout);
|
||||||
|
wasm_val_t vs[1] = { WASM_REF_VAL(ref) };
|
||||||
|
if (wasm_func_call(func, vs, NULL)) {
|
||||||
|
printf("> Error calling function!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("okay\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
own wasm_ref_t* call_r_r(const wasm_func_t* func, wasm_ref_t* ref) {
|
||||||
|
printf("call_r_r... "); fflush(stdout);
|
||||||
|
wasm_val_t vs[1] = { WASM_REF_VAL(ref) };
|
||||||
|
wasm_val_t rs[1] = { WASM_INIT_VAL };
|
||||||
|
if (wasm_func_call(func, vs, rs)) {
|
||||||
|
printf("> Error calling function!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("okay\n");
|
||||||
|
return rs[0].of.ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void call_ir_v(const wasm_func_t* func, int32_t i, wasm_ref_t* ref) {
|
||||||
|
printf("call_ir_v... "); fflush(stdout);
|
||||||
|
wasm_val_t vs[2] = { WASM_I32_VAL(i), WASM_REF_VAL(ref) };
|
||||||
|
if (wasm_func_call(func, vs, NULL)) {
|
||||||
|
printf("> Error calling function!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("okay\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
own wasm_ref_t* call_i_r(const wasm_func_t* func, int32_t i) {
|
||||||
|
printf("call_i_r... "); fflush(stdout);
|
||||||
|
wasm_val_t vs[1] = { WASM_I32_VAL(i) };
|
||||||
|
wasm_val_t rs[1] = { WASM_INIT_VAL };
|
||||||
|
if (wasm_func_call(func, vs, rs)) {
|
||||||
|
printf("> Error calling function!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
printf("okay\n");
|
||||||
|
return rs[0].of.ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
check(own wasm_ref_t *actual, const wasm_ref_t *expected, bool release_ref)
|
||||||
|
{
|
||||||
|
if (actual != expected
|
||||||
|
&& !(actual && expected && wasm_ref_same(actual, expected))) {
|
||||||
|
printf("> Error reading reference, expected %p, got %p\n",
|
||||||
|
expected ? wasm_ref_get_host_info(expected) : NULL,
|
||||||
|
actual ? wasm_ref_get_host_info(actual) : NULL);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (release_ref && actual)
|
||||||
|
wasm_ref_delete(actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
// Initialize.
|
||||||
|
printf("Initializing...\n");
|
||||||
|
wasm_engine_t* engine = wasm_engine_new();
|
||||||
|
wasm_store_t* store = wasm_store_new(engine);
|
||||||
|
|
||||||
|
// Load binary.
|
||||||
|
printf("Loading binary...\n");
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
|
||||||
|
FILE* file = fopen("hostref.aot", "rb");
|
||||||
|
#else
|
||||||
|
FILE* file = fopen("hostref.wasm", "rb");
|
||||||
|
#endif
|
||||||
|
if (!file) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fseek(file, 0L, SEEK_END);
|
||||||
|
size_t file_size = ftell(file);
|
||||||
|
fseek(file, 0L, SEEK_SET);
|
||||||
|
wasm_byte_vec_t binary;
|
||||||
|
wasm_byte_vec_new_uninitialized(&binary, file_size);
|
||||||
|
if (fread(binary.data, file_size, 1, file) != 1) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
fclose(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Compile.
|
||||||
|
printf("Compiling module...\n");
|
||||||
|
own wasm_module_t* module = wasm_module_new(store, &binary);
|
||||||
|
if (!module) {
|
||||||
|
printf("> Error compiling module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_byte_vec_delete(&binary);
|
||||||
|
|
||||||
|
// Create external callback function.
|
||||||
|
printf("Creating callback...\n");
|
||||||
|
own wasm_functype_t* callback_type = wasm_functype_new_1_1(
|
||||||
|
wasm_valtype_new(WASM_ANYREF), wasm_valtype_new(WASM_ANYREF));
|
||||||
|
own wasm_func_t* callback_func =
|
||||||
|
wasm_func_new(store, callback_type, callback);
|
||||||
|
|
||||||
|
wasm_functype_delete(callback_type);
|
||||||
|
|
||||||
|
// Instantiate.
|
||||||
|
printf("Instantiating module...\n");
|
||||||
|
const wasm_extern_t* imports[] = { wasm_func_as_extern(callback_func) };
|
||||||
|
own wasm_instance_t* instance =
|
||||||
|
wasm_instance_new(store, module, imports, NULL);
|
||||||
|
if (!instance) {
|
||||||
|
printf("> Error instantiating module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_func_delete(callback_func);
|
||||||
|
wasm_module_delete(module);
|
||||||
|
|
||||||
|
// Extract export.
|
||||||
|
printf("Extracting exports...\n");
|
||||||
|
own wasm_extern_vec_t exports;
|
||||||
|
wasm_instance_exports(instance, &exports);
|
||||||
|
size_t i = 0;
|
||||||
|
wasm_global_t* global = get_export_global(&exports, i++);
|
||||||
|
wasm_table_t* table = get_export_table(&exports, i++);
|
||||||
|
wasm_func_t* global_set = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* global_get = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* table_set = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* table_get = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* func_call = get_export_func(&exports, i++);
|
||||||
|
|
||||||
|
wasm_instance_delete(instance);
|
||||||
|
|
||||||
|
// Create host references.
|
||||||
|
printf("Creating host references...\n");
|
||||||
|
own wasm_ref_t* host1 = wasm_foreign_as_ref(wasm_foreign_new(store));
|
||||||
|
own wasm_ref_t* host2 = wasm_foreign_as_ref(wasm_foreign_new(store));
|
||||||
|
wasm_ref_set_host_info(host1, (void*)1);
|
||||||
|
wasm_ref_set_host_info(host2, (void*)2);
|
||||||
|
|
||||||
|
// Some sanity checks.
|
||||||
|
check(NULL, NULL, true);
|
||||||
|
check(wasm_ref_copy(host1), host1, true);
|
||||||
|
check(wasm_ref_copy(host2), host2, true);
|
||||||
|
|
||||||
|
own wasm_val_t val;
|
||||||
|
val.kind = WASM_ANYREF;
|
||||||
|
val.of.ref = wasm_ref_copy(host1);
|
||||||
|
check(wasm_ref_copy(val.of.ref), host1, true);
|
||||||
|
own wasm_ref_t* ref = val.of.ref;
|
||||||
|
check(wasm_ref_copy(ref), host1, true);
|
||||||
|
wasm_ref_delete(val.of.ref);
|
||||||
|
|
||||||
|
// Interact.
|
||||||
|
printf("Accessing global...\n");
|
||||||
|
check(call_v_r(global_get), NULL, false);
|
||||||
|
call_r_v(global_set, host1);
|
||||||
|
check(call_v_r(global_get), host1, false);
|
||||||
|
call_r_v(global_set, host2);
|
||||||
|
check(call_v_r(global_get), host2, false);
|
||||||
|
call_r_v(global_set, NULL);
|
||||||
|
check(call_v_r(global_get), NULL, false);
|
||||||
|
|
||||||
|
wasm_global_get(global, &val);
|
||||||
|
assert(val.kind == WASM_ANYREF);
|
||||||
|
check(val.of.ref, NULL, false);
|
||||||
|
val.of.ref = host2;
|
||||||
|
wasm_global_set(global, &val);
|
||||||
|
check(call_v_r(global_get), host2, false);
|
||||||
|
wasm_global_get(global, &val);
|
||||||
|
assert(val.kind == WASM_ANYREF);
|
||||||
|
check(val.of.ref, host2, false);
|
||||||
|
|
||||||
|
printf("Accessing table...\n");
|
||||||
|
check(call_i_r(table_get, 0), NULL, false);
|
||||||
|
check(call_i_r(table_get, 1), NULL, false);
|
||||||
|
call_ir_v(table_set, 0, host1);
|
||||||
|
call_ir_v(table_set, 1, host2);
|
||||||
|
check(call_i_r(table_get, 0), host1, false);
|
||||||
|
check(call_i_r(table_get, 1), host2, false);
|
||||||
|
call_ir_v(table_set, 0, NULL);
|
||||||
|
check(call_i_r(table_get, 0), NULL, false);
|
||||||
|
|
||||||
|
check(wasm_table_get(table, 2), NULL, false);
|
||||||
|
|
||||||
|
printf("Accessing function...\n");
|
||||||
|
check(call_r_r(func_call, NULL), NULL, false);
|
||||||
|
check(call_r_r(func_call, host1), host1, false);
|
||||||
|
check(call_r_r(func_call, host2), host2, false);
|
||||||
|
|
||||||
|
wasm_ref_delete(host1);
|
||||||
|
wasm_ref_delete(host2);
|
||||||
|
|
||||||
|
wasm_extern_vec_delete(&exports);
|
||||||
|
|
||||||
|
// Shut down.
|
||||||
|
printf("Shutting down...\n");
|
||||||
|
wasm_store_delete(store);
|
||||||
|
wasm_engine_delete(engine);
|
||||||
|
|
||||||
|
// All done.
|
||||||
|
printf("Done.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
24
samples/wasm-c-api/src/hostref.wat
Normal file
24
samples/wasm-c-api/src/hostref.wat
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
(module
|
||||||
|
(import "" "f" (func $fun (param externref) (result externref)))
|
||||||
|
|
||||||
|
(global $glob (export "global") (mut externref) (ref.null extern))
|
||||||
|
(table $tab (export "table") 10 externref)
|
||||||
|
|
||||||
|
(func (export "global.set") (param $r externref)
|
||||||
|
(global.set $glob (local.get $r))
|
||||||
|
)
|
||||||
|
(func (export "global.get") (result externref)
|
||||||
|
(global.get $glob)
|
||||||
|
)
|
||||||
|
|
||||||
|
(func (export "table.set") (param $i i32) (param $r externref)
|
||||||
|
(table.set $tab (local.get $i) (local.get $r))
|
||||||
|
)
|
||||||
|
(func (export "table.get") (param $i i32) (result externref)
|
||||||
|
(table.get $tab (local.get $i))
|
||||||
|
)
|
||||||
|
|
||||||
|
(func (export "func.call") (param $r externref) (result externref)
|
||||||
|
(call $fun (local.get $r))
|
||||||
|
)
|
||||||
|
)
|
209
samples/wasm-c-api/src/memory.c
Normal file
209
samples/wasm-c-api/src/memory.c
Normal file
|
@ -0,0 +1,209 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "wasm_c_api.h"
|
||||||
|
|
||||||
|
#define own
|
||||||
|
|
||||||
|
|
||||||
|
wasm_memory_t* get_export_memory(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_memory(exports->data[i])) {
|
||||||
|
printf("> Error accessing memory export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_memory(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
|
||||||
|
printf("> Error accessing function export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_func(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void check(bool success) {
|
||||||
|
if (!success) {
|
||||||
|
printf("> Error, expected success\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_call(wasm_func_t* func, int i, wasm_val_t args[], int32_t expected) {
|
||||||
|
wasm_val_t results[1] = { WASM_INIT_VAL };
|
||||||
|
if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) {
|
||||||
|
printf("> Error on result\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_call0(wasm_func_t* func, int32_t expected) {
|
||||||
|
check_call(func, 0, NULL, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_call1(wasm_func_t* func, int32_t arg, int32_t expected) {
|
||||||
|
wasm_val_t args[] = { WASM_I32_VAL(arg) };
|
||||||
|
check_call(func, 1, args, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_call2(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
|
||||||
|
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||||
|
check_call(func, 2, args, expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_ok(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||||
|
if (wasm_func_call(func, args, NULL)) {
|
||||||
|
printf("> Error on result, expected empty\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_ok2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||||
|
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||||
|
check_ok(func, 2, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_trap(wasm_func_t* func, int i, wasm_val_t args[]) {
|
||||||
|
wasm_val_t results[1] = { WASM_INIT_VAL };
|
||||||
|
own wasm_trap_t* trap = wasm_func_call(func, args, results);
|
||||||
|
if (! trap) {
|
||||||
|
printf("> Error on result, expected trap\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
wasm_trap_delete(trap);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_trap1(wasm_func_t* func, int32_t arg) {
|
||||||
|
wasm_val_t args[] = { WASM_I32_VAL(arg) };
|
||||||
|
check_trap(func, 1, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_trap2(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||||
|
wasm_val_t args[] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||||
|
check_trap(func, 2, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
// Initialize.
|
||||||
|
printf("Initializing...\n");
|
||||||
|
wasm_engine_t* engine = wasm_engine_new();
|
||||||
|
wasm_store_t* store = wasm_store_new(engine);
|
||||||
|
|
||||||
|
// Load binary.
|
||||||
|
printf("Loading binary...\n");
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
|
||||||
|
FILE* file = fopen("memory.aot", "rb");
|
||||||
|
#else
|
||||||
|
FILE* file = fopen("memory.wasm", "rb");
|
||||||
|
#endif
|
||||||
|
if (!file) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fseek(file, 0L, SEEK_END);
|
||||||
|
size_t file_size = ftell(file);
|
||||||
|
fseek(file, 0L, SEEK_SET);
|
||||||
|
wasm_byte_vec_t binary;
|
||||||
|
wasm_byte_vec_new_uninitialized(&binary, file_size);
|
||||||
|
if (fread(binary.data, file_size, 1, file) != 1) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
fclose(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Compile.
|
||||||
|
printf("Compiling module...\n");
|
||||||
|
own wasm_module_t* module = wasm_module_new(store, &binary);
|
||||||
|
if (!module) {
|
||||||
|
printf("> Error compiling module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_byte_vec_delete(&binary);
|
||||||
|
|
||||||
|
// Instantiate.
|
||||||
|
printf("Instantiating module...\n");
|
||||||
|
own wasm_instance_t* instance =
|
||||||
|
wasm_instance_new_with_args(store, module, NULL, NULL, KILOBYTE(8), 0);
|
||||||
|
if (!instance) {
|
||||||
|
printf("> Error instantiating module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract export.
|
||||||
|
printf("Extracting exports...\n");
|
||||||
|
own wasm_extern_vec_t exports;
|
||||||
|
wasm_instance_exports(instance, &exports);
|
||||||
|
size_t i = 0;
|
||||||
|
wasm_memory_t* memory = get_export_memory(&exports, i++);
|
||||||
|
wasm_func_t* size_func = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* load_func = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* store_func = get_export_func(&exports, i++);
|
||||||
|
|
||||||
|
wasm_module_delete(module);
|
||||||
|
|
||||||
|
if (!memory || !wasm_memory_data(memory)) {
|
||||||
|
printf("> Error getting memory!\n");
|
||||||
|
wasm_extern_vec_delete(&exports);
|
||||||
|
wasm_instance_delete(instance);
|
||||||
|
wasm_store_delete(store);
|
||||||
|
wasm_engine_delete(engine);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try cloning.
|
||||||
|
own wasm_memory_t* copy = wasm_memory_copy(memory);
|
||||||
|
assert(wasm_memory_same(memory, copy));
|
||||||
|
wasm_memory_delete(copy);
|
||||||
|
|
||||||
|
// Check initial memory.
|
||||||
|
printf("Checking memory...\n");
|
||||||
|
check(wasm_memory_size(memory) >= 2);
|
||||||
|
check(wasm_memory_data_size(memory) >= 0x20000);
|
||||||
|
check(wasm_memory_data(memory)[0] == 0);
|
||||||
|
check(wasm_memory_data(memory)[0x1000] == 1);
|
||||||
|
check(wasm_memory_data(memory)[0x1003] == 4);
|
||||||
|
|
||||||
|
(void)size_func;
|
||||||
|
check_call1(load_func, 0, 0);
|
||||||
|
check_call1(load_func, 0x1000, 1);
|
||||||
|
check_call1(load_func, 0x1003, 4);
|
||||||
|
check_call1(load_func, 0x1ffff, 0);
|
||||||
|
check_trap1(load_func, 0x20000);
|
||||||
|
|
||||||
|
// Mutate memory.
|
||||||
|
printf("Mutating memory...\n");
|
||||||
|
wasm_memory_data(memory)[0x1003] = 5;
|
||||||
|
check_ok2(store_func, 0x1002, 6);
|
||||||
|
check_trap2(store_func, 0x20000, 0);
|
||||||
|
|
||||||
|
check(wasm_memory_data(memory)[0x1002] == 6);
|
||||||
|
check(wasm_memory_data(memory)[0x1003] == 5);
|
||||||
|
check_call1(load_func, 0x1002, 6);
|
||||||
|
check_call1(load_func, 0x1003, 5);
|
||||||
|
|
||||||
|
// Grow memory.
|
||||||
|
// DO NOT SUPPORT
|
||||||
|
printf("Bypass Growing memory...\n");
|
||||||
|
wasm_extern_vec_delete(&exports);
|
||||||
|
wasm_instance_delete(instance);
|
||||||
|
|
||||||
|
// Create stand-alone memory.
|
||||||
|
// DO NOT SUPPORT
|
||||||
|
// TODO(wasm+): Once Wasm allows multiple memories, turn this into import.
|
||||||
|
printf("Bypass Creating stand-alone memory...\n");
|
||||||
|
|
||||||
|
// Shut down.
|
||||||
|
printf("Shutting down...\n");
|
||||||
|
wasm_store_delete(store);
|
||||||
|
wasm_engine_delete(engine);
|
||||||
|
|
||||||
|
// All done.
|
||||||
|
printf("Done.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
11
samples/wasm-c-api/src/memory.wat
Normal file
11
samples/wasm-c-api/src/memory.wat
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
(module
|
||||||
|
(memory (export "memory") 2 3)
|
||||||
|
|
||||||
|
(func (export "size") (result i32) (memory.size))
|
||||||
|
(func (export "load") (param i32) (result i32) (i32.load8_s (local.get 0)))
|
||||||
|
(func (export "store") (param i32 i32)
|
||||||
|
(i32.store8 (local.get 0) (local.get 1))
|
||||||
|
)
|
||||||
|
|
||||||
|
(data (i32.const 0x1000) "\01\02\03\04")
|
||||||
|
)
|
182
samples/wasm-c-api/src/table.c
Normal file
182
samples/wasm-c-api/src/table.c
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "wasm_c_api.h"
|
||||||
|
|
||||||
|
#define own
|
||||||
|
|
||||||
|
// A function to be called from Wasm code.
|
||||||
|
own wasm_trap_t* neg_callback(
|
||||||
|
const wasm_val_t args[], wasm_val_t results[]
|
||||||
|
) {
|
||||||
|
printf("Calling back...\n");
|
||||||
|
results[0].kind = WASM_I32;
|
||||||
|
results[0].of.i32 = -args[0].of.i32;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wasm_table_t* get_export_table(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_table(exports->data[i])) {
|
||||||
|
printf("> Error accessing table export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_table(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_func_t* get_export_func(const wasm_extern_vec_t* exports, size_t i) {
|
||||||
|
if (exports->size <= i || !wasm_extern_as_func(exports->data[i])) {
|
||||||
|
printf("> Error accessing function export %zu!\n", i);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return wasm_extern_as_func(exports->data[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void check(bool success) {
|
||||||
|
if (!success) {
|
||||||
|
printf("> Error, expected success\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_table(wasm_table_t* table, int32_t i, bool expect_set) {
|
||||||
|
own wasm_ref_t* ref = wasm_table_get(table, i);
|
||||||
|
check((ref != NULL) == expect_set);
|
||||||
|
if (ref) wasm_ref_delete(ref);
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_call(wasm_func_t* func, int32_t arg1, int32_t arg2, int32_t expected) {
|
||||||
|
wasm_val_t args[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||||
|
wasm_val_t results[1] = { WASM_INIT_VAL };
|
||||||
|
if (wasm_func_call(func, args, results) || results[0].of.i32 != expected) {
|
||||||
|
printf("> Error on result\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void check_trap(wasm_func_t* func, int32_t arg1, int32_t arg2) {
|
||||||
|
wasm_val_t args[2] = { WASM_I32_VAL(arg1), WASM_I32_VAL(arg2) };
|
||||||
|
wasm_val_t results[1] = { WASM_INIT_VAL };
|
||||||
|
own wasm_trap_t* trap = wasm_func_call(func, args, results);
|
||||||
|
if (! trap) {
|
||||||
|
printf("> Error on result, expected trap\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
wasm_trap_delete(trap);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, const char* argv[]) {
|
||||||
|
// Initialize.
|
||||||
|
printf("Initializing...\n");
|
||||||
|
wasm_engine_t* engine = wasm_engine_new();
|
||||||
|
wasm_store_t* store = wasm_store_new(engine);
|
||||||
|
|
||||||
|
// Load binary.
|
||||||
|
printf("Loading binary...\n");
|
||||||
|
#if WASM_ENABLE_AOT != 0 && WASM_ENABLE_INTERP == 0
|
||||||
|
FILE* file = fopen("table.aot", "rb");
|
||||||
|
#else
|
||||||
|
FILE* file = fopen("table.wasm", "rb");
|
||||||
|
#endif
|
||||||
|
if (!file) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fseek(file, 0L, SEEK_END);
|
||||||
|
size_t file_size = ftell(file);
|
||||||
|
fseek(file, 0L, SEEK_SET);
|
||||||
|
wasm_byte_vec_t binary;
|
||||||
|
wasm_byte_vec_new_uninitialized(&binary, file_size);
|
||||||
|
if (fread(binary.data, file_size, 1, file) != 1) {
|
||||||
|
printf("> Error loading module!\n");
|
||||||
|
fclose(file);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
// Compile.
|
||||||
|
printf("Compiling module...\n");
|
||||||
|
own wasm_module_t* module = wasm_module_new(store, &binary);
|
||||||
|
if (!module) {
|
||||||
|
printf("> Error compiling module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
wasm_byte_vec_delete(&binary);
|
||||||
|
|
||||||
|
// Instantiate.
|
||||||
|
printf("Instantiating module...\n");
|
||||||
|
own wasm_instance_t *instance =
|
||||||
|
wasm_instance_new(store, module, NULL, NULL);
|
||||||
|
if (!instance) {
|
||||||
|
printf("> Error instantiating module!\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract export.
|
||||||
|
printf("Extracting exports...\n");
|
||||||
|
own wasm_extern_vec_t exports;
|
||||||
|
wasm_instance_exports(instance, &exports);
|
||||||
|
size_t i = 0;
|
||||||
|
wasm_table_t* table = get_export_table(&exports, i++);
|
||||||
|
wasm_func_t* call_indirect = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* f = get_export_func(&exports, i++);
|
||||||
|
wasm_func_t* g = get_export_func(&exports, i++);
|
||||||
|
|
||||||
|
wasm_module_delete(module);
|
||||||
|
|
||||||
|
// Create external function.
|
||||||
|
printf("Creating callback...\n");
|
||||||
|
own wasm_functype_t* neg_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
|
||||||
|
|
||||||
|
wasm_functype_delete(neg_type);
|
||||||
|
|
||||||
|
// Try cloning.
|
||||||
|
own wasm_table_t* copy = wasm_table_copy(table);
|
||||||
|
assert(wasm_table_same(table, copy));
|
||||||
|
wasm_table_delete(copy);
|
||||||
|
|
||||||
|
// Check initial table.
|
||||||
|
printf("Checking table...\n");
|
||||||
|
check(wasm_table_size(table) == 2);
|
||||||
|
check_table(table, 0, false);
|
||||||
|
check_table(table, 1, true);
|
||||||
|
check_trap(call_indirect, 0, 0);
|
||||||
|
check_call(call_indirect, 7, 1, 7);
|
||||||
|
check_trap(call_indirect, 0, 2);
|
||||||
|
|
||||||
|
// Mutate table.
|
||||||
|
printf("Mutating table...\n");
|
||||||
|
check(wasm_table_set(table, 0, wasm_func_as_ref(g)));
|
||||||
|
check(wasm_table_set(table, 1, NULL));
|
||||||
|
check(! wasm_table_set(table, 2, wasm_func_as_ref(f)));
|
||||||
|
check_table(table, 0, true);
|
||||||
|
check_table(table, 1, false);
|
||||||
|
check_call(call_indirect, 7, 0, 666);
|
||||||
|
check_trap(call_indirect, 0, 1);
|
||||||
|
check_trap(call_indirect, 0, 2);
|
||||||
|
|
||||||
|
// Grow table.
|
||||||
|
// DO NOT SUPPORT
|
||||||
|
printf("Bypass Growing table...\n");
|
||||||
|
wasm_extern_vec_delete(&exports);
|
||||||
|
wasm_instance_delete(instance);
|
||||||
|
|
||||||
|
// Create stand-alone table.
|
||||||
|
// DO NOT SUPPORT
|
||||||
|
// TODO(wasm+): Once Wasm allows multiple tables, turn this into import.
|
||||||
|
printf("Bypass Creating stand-alone table...\n");
|
||||||
|
|
||||||
|
// Shut down.
|
||||||
|
printf("Shutting down...\n");
|
||||||
|
wasm_store_delete(store);
|
||||||
|
wasm_engine_delete(engine);
|
||||||
|
|
||||||
|
// All done.
|
||||||
|
printf("Done.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
12
samples/wasm-c-api/src/table.wat
Normal file
12
samples/wasm-c-api/src/table.wat
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
(module
|
||||||
|
(table (export "table") 2 10 funcref)
|
||||||
|
|
||||||
|
(func (export "call_indirect") (param i32 i32) (result i32)
|
||||||
|
(call_indirect (param i32) (result i32) (local.get 0) (local.get 1))
|
||||||
|
)
|
||||||
|
|
||||||
|
(func $f (export "f") (param i32) (result i32) (local.get 0))
|
||||||
|
(func (export "g") (param i32) (result i32) (i32.const 666))
|
||||||
|
|
||||||
|
(elem (i32.const 1) $f)
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user