mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-11 09:25:20 +00:00
Eable post-MVP feature wasm-c-api (#315)
This commit is contained in:
parent
32b2943369
commit
08d01b65c5
|
@ -1,6 +1,6 @@
|
|||
WebAssembly Micro Runtime
|
||||
=========================
|
||||
[Build WAMR VM core](./doc/build_wamr.md) | [Embed WAMR](./doc/embed_wamr.md) | [Export native function](./doc/export_native_api.md) | [Build WASM applications](./doc/build_wasm_app.md) | [Samples](https://github.com/bytecodealliance/wasm-micro-runtime#samples-and-demos)
|
||||
[Build WAMR VM core](./doc/build_wamr.md) | [Embed WAMR](./doc/embed_wamr.md) | [Export native function](./doc/export_native_api.md) | [Build WASM applications](./doc/build_wasm_app.md) | [Samples](https://github.com/bytecodealliance/wasm-micro-runtime#samples)
|
||||
|
||||
**A [Bytecode Alliance][BA] project**
|
||||
|
||||
|
@ -36,6 +36,7 @@ iwasm VM core
|
|||
- [Bulk memory operations](https://github.com/WebAssembly/bulk-memory-operations)
|
||||
- [Shared memory](https://github.com/WebAssembly/threads/blob/main/proposals/threads/Overview.md#shared-linear-memory)
|
||||
- [Multi-value](https://github.com/WebAssembly/multi-value)
|
||||
- [wasm-c-api](https://github.com/WebAssembly/wasm-c-api)
|
||||
|
||||
### Performance and memory usage
|
||||
The WAMR performance, footprint and memory usage data are available at the [performance](../../wiki/Performance) wiki page.
|
||||
|
@ -112,8 +113,7 @@ The WAMR [samples](./samples) integrate the iwasm VM core, application manager a
|
|||
- **[Simple](./samples/simple/README.md)**: The runtime is integrated with most of the WAMR APP libraries, and a few WASM applications are provided for testing the WAMR APP API set. It uses **built-in libc** and executes apps in **interpreter** mode by default.
|
||||
- **[littlevgl](./samples/littlevgl/README.md)**: Demonstrating the graphic user interface application usage on WAMR. The whole [LittlevGL](https://github.com/littlevgl/) 2D user graphic library and the UI application is built into WASM application. It uses **WASI libc** and executes apps in **AoT mode** by default.
|
||||
- **[gui](./samples/gui/README.md)**: Moved the [LittlevGL](https://github.com/littlevgl/) library into the runtime and defined a WASM application interface by wrapping the littlevgl API. It uses **WASI libc** and executes apps in **interpreter** mode by default.
|
||||
|
||||
|
||||
- **[wasm-c-api](./samples/wasm-c-api/README.md)**: they are samples from [wasm-c-api proposal](https://github.com/WebAssembly/wasm-c-api) and show supported APIs.
|
||||
|
||||
|
||||
Releases and acknowledgments
|
||||
|
|
|
@ -127,6 +127,11 @@ enum {
|
|||
/* WASM Interpreter labels-as-values feature */
|
||||
#define WASM_ENABLE_LABELS_AS_VALUES 1
|
||||
|
||||
/* Enable fast interpreter or not */
|
||||
#ifndef WASM_ENABLE_FAST_INTERP
|
||||
#define WASM_ENABLE_FAST_INTERP 0
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_FAST_INTERP != 0
|
||||
#define WASM_ENABLE_ABS_LABEL_ADDR 1
|
||||
#define WASM_DEBUG_PREPROCESSOR 0
|
||||
|
|
2745
core/iwasm/common/wasm_c_api.c
Normal file
2745
core/iwasm/common/wasm_c_api.c
Normal file
File diff suppressed because it is too large
Load Diff
180
core/iwasm/common/wasm_c_api_internal.h
Normal file
180
core/iwasm/common/wasm_c_api_internal.h
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WASM_C_API_INTERNAL_H
|
||||
#define _WASM_C_API_INTERNAL_H
|
||||
|
||||
#include "wasm_c_api.h"
|
||||
#include "wasm_runtime_common.h"
|
||||
|
||||
#ifndef own
|
||||
#define own
|
||||
#endif
|
||||
|
||||
/* Vectors */
|
||||
/* we will malloc resource for the vector's data field */
|
||||
/* we will release resource of data */
|
||||
/* caller needs to take care resource for the vector itself */
|
||||
#define DEFAULT_VECTOR_INIT_LENGTH (64)
|
||||
|
||||
WASM_DECLARE_VEC(store, *)
|
||||
WASM_DECLARE_VEC(module, *)
|
||||
WASM_DECLARE_VEC(instance, *)
|
||||
|
||||
/* Runtime Environment */
|
||||
typedef enum runtime_mode_e {
|
||||
INTERP_MODE = 0,
|
||||
JIT_MODE,
|
||||
AOT_MODE
|
||||
} runtime_mode_e;
|
||||
|
||||
struct wasm_engine_t {
|
||||
// support one store for now
|
||||
wasm_store_vec_t *stores;
|
||||
// Interpreter by deault
|
||||
runtime_mode_e mode;
|
||||
};
|
||||
|
||||
struct wasm_store_t {
|
||||
wasm_module_vec_t *modules;
|
||||
wasm_instance_vec_t *instances;
|
||||
};
|
||||
|
||||
/* Type Representations */
|
||||
struct wasm_valtype_t {
|
||||
wasm_valkind_t kind;
|
||||
};
|
||||
|
||||
struct wasm_functype_t {
|
||||
uint32 extern_kind;
|
||||
// gona to new and delete own
|
||||
wasm_valtype_vec_t *params;
|
||||
wasm_valtype_vec_t *results;
|
||||
};
|
||||
|
||||
struct wasm_globaltype_t {
|
||||
uint32 extern_kind;
|
||||
// gona to new and delete own
|
||||
wasm_valtype_t *val_type;
|
||||
wasm_mutability_t mutability;
|
||||
};
|
||||
|
||||
struct wasm_tabletype_t {
|
||||
uint32 extern_kind;
|
||||
// always be WASM_FUNCREF
|
||||
wasm_valtype_t *type;
|
||||
wasm_limits_t *limits;
|
||||
};
|
||||
|
||||
struct wasm_memorytype_t {
|
||||
uint32 extern_kind;
|
||||
wasm_limits_t *limits;
|
||||
};
|
||||
|
||||
struct wasm_externtype_t {
|
||||
uint32 extern_kind;
|
||||
uint8 data[1];
|
||||
};
|
||||
|
||||
struct wasm_import_type_t {
|
||||
uint32 extern_kind;
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
};
|
||||
|
||||
struct wasm_export_type_t {
|
||||
uint32 extern_kind;
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
};
|
||||
|
||||
/* Runtime Objects */
|
||||
struct wasm_ref_t {};
|
||||
|
||||
struct wasm_trap_t {
|
||||
wasm_byte_vec_t *message;
|
||||
};
|
||||
|
||||
struct wasm_func_t {
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
uint16 kind;
|
||||
|
||||
wasm_functype_t *func_type;
|
||||
|
||||
bool with_env;
|
||||
union {
|
||||
wasm_func_callback_t cb;
|
||||
struct callback_ext {
|
||||
void *env;
|
||||
wasm_func_callback_with_env_t cb;
|
||||
void (*finalizer)(void *);
|
||||
} cb_env;
|
||||
} u;
|
||||
/*
|
||||
* an index in both functions runtime instance lists
|
||||
* of interpreter mode and aot mode
|
||||
*/
|
||||
uint16 func_idx_rt;
|
||||
WASMModuleInstanceCommon *inst_comm_rt;
|
||||
};
|
||||
|
||||
struct wasm_global_t {
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
uint16 kind;
|
||||
|
||||
wasm_globaltype_t *type;
|
||||
wasm_val_t *init;
|
||||
/*
|
||||
* an index in both global runtime instance lists
|
||||
* of interpreter mode and aot mode
|
||||
*/
|
||||
uint16 global_idx_rt;
|
||||
WASMModuleInstanceCommon *inst_comm_rt;
|
||||
};
|
||||
|
||||
struct wasm_memory_t {
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
uint16 kind;
|
||||
|
||||
wasm_memorytype_t *type;
|
||||
/*
|
||||
* an index in both memory runtime instance lists
|
||||
* of interpreter mode and aot mode
|
||||
*/
|
||||
uint16 memory_idx_rt;
|
||||
WASMModuleInstanceCommon *inst_comm_rt;
|
||||
};
|
||||
|
||||
struct wasm_table_t {
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
uint16 kind;
|
||||
|
||||
wasm_tabletype_t *type;
|
||||
/*
|
||||
* an index in both table runtime instance lists
|
||||
* of interpreter mode and aot mode
|
||||
*/
|
||||
uint16 table_idx_rt;
|
||||
WASMModuleInstanceCommon *inst_comm_rt;
|
||||
};
|
||||
|
||||
struct wasm_extern_t {
|
||||
wasm_name_t *module_name;
|
||||
wasm_name_t *name;
|
||||
uint16 kind;
|
||||
uint8 data[1];
|
||||
};
|
||||
|
||||
struct wasm_instance_t {
|
||||
wasm_extern_vec_t *imports;
|
||||
wasm_extern_vec_t *exports;
|
||||
WASMModuleInstanceCommon *inst_comm_rt;
|
||||
};
|
||||
|
||||
#endif /* _WASM_C_API_INTERNAL_H */
|
|
@ -67,14 +67,11 @@ typedef struct WASMRegisteredModule {
|
|||
} WASMRegisteredModule;
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
typedef struct WASMMemoryInstanceCommon {
|
||||
uint32 module_type;
|
||||
uint8 memory_inst_data[1];
|
||||
} WASMMemoryInstanceCommon;
|
||||
|
||||
#endif
|
||||
|
||||
typedef package_type_t PackageType;
|
||||
typedef wasm_section_t WASMSection, AOTSection;
|
||||
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
|
||||
#include "bh_log.h"
|
||||
#include "wasm_shared_memory.h"
|
||||
|
||||
|
@ -120,5 +118,3 @@ shared_memory_set_memory_inst(WASMModuleCommon *module,
|
|||
(void)ret;
|
||||
return node;
|
||||
}
|
||||
|
||||
#endif /* end of WASM_ENABLE_SHARED_MEMORY */
|
||||
|
|
679
core/iwasm/include/wasm_c_api.h
Normal file
679
core/iwasm/include/wasm_c_api.h
Normal file
|
@ -0,0 +1,679 @@
|
|||
// WebAssembly C API
|
||||
|
||||
#ifndef WASM_H
|
||||
#define WASM_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifndef WASM_API_EXTERN
|
||||
#ifdef _WIN32
|
||||
#define WASM_API_EXTERN __declspec(dllimport)
|
||||
#else
|
||||
#define WASM_API_EXTERN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Auxiliaries
|
||||
|
||||
// Machine types
|
||||
#if (__STDC_VERSION__ > 199901L)
|
||||
inline void assertions() {
|
||||
static_assert(sizeof(float) == sizeof(uint32_t), "incompatible float type");
|
||||
static_assert(sizeof(double) == sizeof(uint64_t), "incompatible double type");
|
||||
static_assert(sizeof(intptr_t) == sizeof(uint32_t) ||
|
||||
sizeof(intptr_t) == sizeof(uint64_t),
|
||||
"incompatible pointer type");
|
||||
}
|
||||
#endif /* __STDC_VERSION__ > 199901L */
|
||||
|
||||
typedef char byte_t;
|
||||
typedef float float32_t;
|
||||
typedef double float64_t;
|
||||
|
||||
|
||||
// Ownership
|
||||
|
||||
#define own
|
||||
|
||||
// The qualifier `own` is used to indicate ownership of data in this API.
|
||||
// It is intended to be interpreted similar to a `const` qualifier:
|
||||
//
|
||||
// - `own wasm_xxx_t*` owns the pointed-to data
|
||||
// - `own wasm_xxx_t` distributes to all fields of a struct or union `xxx`
|
||||
// - `own wasm_xxx_vec_t` owns the vector as well as its elements(!)
|
||||
// - an `own` function parameter passes ownership from caller to callee
|
||||
// - an `own` function result passes ownership from callee to caller
|
||||
// - an exception are `own` pointer parameters named `out`, which are copy-back
|
||||
// output parameters passing back ownership from callee to caller
|
||||
//
|
||||
// Own data is created by `wasm_xxx_new` functions and some others.
|
||||
// It must be released with the corresponding `wasm_xxx_delete` function.
|
||||
//
|
||||
// Deleting a reference does not necessarily delete the underlying object,
|
||||
// it merely indicates that this owner no longer uses it.
|
||||
//
|
||||
// For vectors, `const wasm_xxx_vec_t` is used informally to indicate that
|
||||
// neither the vector nor its elements should be modified.
|
||||
// TODO: introduce proper `wasm_xxx_const_vec_t`?
|
||||
|
||||
|
||||
#define WASM_DECLARE_OWN(name) \
|
||||
typedef struct wasm_##name##_t wasm_##name##_t; \
|
||||
\
|
||||
WASM_API_EXTERN void wasm_##name##_delete(own wasm_##name##_t*);
|
||||
|
||||
|
||||
// Vectors
|
||||
// size: capacity
|
||||
// num_elems: current number of elements
|
||||
// size_of_elem: size of one element
|
||||
#define WASM_DECLARE_VEC(name, ptr_or_none) \
|
||||
typedef struct wasm_##name##_vec_t { \
|
||||
size_t size; \
|
||||
wasm_##name##_t ptr_or_none* data; \
|
||||
size_t num_elems; \
|
||||
size_t size_of_elem; \
|
||||
} wasm_##name##_vec_t; \
|
||||
\
|
||||
WASM_API_EXTERN void wasm_##name##_vec_new_empty(own wasm_##name##_vec_t* out); \
|
||||
WASM_API_EXTERN void wasm_##name##_vec_new_uninitialized( \
|
||||
own wasm_##name##_vec_t* out, size_t); \
|
||||
WASM_API_EXTERN void wasm_##name##_vec_new( \
|
||||
own wasm_##name##_vec_t* out, \
|
||||
size_t, own wasm_##name##_t ptr_or_none const[]); \
|
||||
WASM_API_EXTERN void wasm_##name##_vec_copy( \
|
||||
own wasm_##name##_vec_t* out, const wasm_##name##_vec_t*); \
|
||||
WASM_API_EXTERN void wasm_##name##_vec_delete(own wasm_##name##_vec_t*);
|
||||
|
||||
|
||||
// Byte vectors
|
||||
|
||||
typedef byte_t wasm_byte_t;
|
||||
WASM_DECLARE_VEC(byte, )
|
||||
|
||||
typedef wasm_byte_vec_t wasm_name_t;
|
||||
|
||||
#define wasm_name wasm_byte_vec
|
||||
#define wasm_name_new wasm_byte_vec_new
|
||||
#define wasm_name_new_empty wasm_byte_vec_new_empty
|
||||
#define wasm_name_new_new_uninitialized wasm_byte_vec_new_uninitialized
|
||||
#define wasm_name_copy wasm_byte_vec_copy
|
||||
#define wasm_name_delete wasm_byte_vec_delete
|
||||
|
||||
static inline void wasm_name_new_from_string(
|
||||
own wasm_name_t* out, const char* s
|
||||
) {
|
||||
wasm_name_new(out, strlen(s) + 1, s);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Runtime Environment
|
||||
|
||||
// Engine
|
||||
|
||||
WASM_DECLARE_OWN(engine)
|
||||
|
||||
WASM_API_EXTERN own wasm_engine_t* wasm_engine_new();
|
||||
|
||||
|
||||
// Store
|
||||
|
||||
WASM_DECLARE_OWN(store)
|
||||
|
||||
WASM_API_EXTERN own wasm_store_t* wasm_store_new(wasm_engine_t*);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Type Representations
|
||||
|
||||
// Type attributes
|
||||
|
||||
typedef uint8_t wasm_mutability_t;
|
||||
enum wasm_mutability_enum {
|
||||
WASM_CONST,
|
||||
WASM_VAR,
|
||||
};
|
||||
|
||||
typedef struct wasm_limits_t {
|
||||
uint32_t min;
|
||||
uint32_t max;
|
||||
} wasm_limits_t;
|
||||
|
||||
static const uint32_t wasm_limits_max_default = 0xffffffff;
|
||||
|
||||
|
||||
// Generic
|
||||
|
||||
#define WASM_DECLARE_TYPE(name) \
|
||||
WASM_DECLARE_OWN(name) \
|
||||
WASM_DECLARE_VEC(name, *) \
|
||||
\
|
||||
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(wasm_##name##_t*);
|
||||
|
||||
|
||||
// Value Types
|
||||
|
||||
WASM_DECLARE_TYPE(valtype)
|
||||
|
||||
typedef uint8_t wasm_valkind_t;
|
||||
enum wasm_valkind_enum {
|
||||
WASM_I32,
|
||||
WASM_I64,
|
||||
WASM_F32,
|
||||
WASM_F64,
|
||||
WASM_ANYREF = 128,
|
||||
WASM_FUNCREF,
|
||||
};
|
||||
|
||||
WASM_API_EXTERN own wasm_valtype_t* wasm_valtype_new(wasm_valkind_t);
|
||||
|
||||
WASM_API_EXTERN wasm_valkind_t wasm_valtype_kind(const wasm_valtype_t*);
|
||||
|
||||
static inline bool wasm_valkind_is_num(wasm_valkind_t k) {
|
||||
return k < WASM_ANYREF;
|
||||
}
|
||||
static inline bool wasm_valkind_is_ref(wasm_valkind_t k) {
|
||||
return k >= WASM_ANYREF;
|
||||
}
|
||||
|
||||
static inline bool wasm_valtype_is_num(const wasm_valtype_t* t) {
|
||||
return wasm_valkind_is_num(wasm_valtype_kind(t));
|
||||
}
|
||||
static inline bool wasm_valtype_is_ref(const wasm_valtype_t* t) {
|
||||
return wasm_valkind_is_ref(wasm_valtype_kind(t));
|
||||
}
|
||||
|
||||
|
||||
// Function Types
|
||||
|
||||
WASM_DECLARE_TYPE(functype)
|
||||
|
||||
WASM_API_EXTERN own wasm_functype_t* wasm_functype_new(
|
||||
own wasm_valtype_vec_t* params, own wasm_valtype_vec_t* results);
|
||||
|
||||
WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_params(const wasm_functype_t*);
|
||||
WASM_API_EXTERN const wasm_valtype_vec_t* wasm_functype_results(const wasm_functype_t*);
|
||||
|
||||
|
||||
// Global Types
|
||||
|
||||
WASM_DECLARE_TYPE(globaltype)
|
||||
|
||||
WASM_API_EXTERN own wasm_globaltype_t* wasm_globaltype_new(
|
||||
own wasm_valtype_t*, wasm_mutability_t);
|
||||
|
||||
WASM_API_EXTERN const wasm_valtype_t* wasm_globaltype_content(const wasm_globaltype_t*);
|
||||
WASM_API_EXTERN wasm_mutability_t wasm_globaltype_mutability(const wasm_globaltype_t*);
|
||||
|
||||
|
||||
// Table Types
|
||||
|
||||
WASM_DECLARE_TYPE(tabletype)
|
||||
|
||||
WASM_API_EXTERN own wasm_tabletype_t* wasm_tabletype_new(
|
||||
own wasm_valtype_t*, const wasm_limits_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_valtype_t* wasm_tabletype_element(const wasm_tabletype_t*);
|
||||
WASM_API_EXTERN const wasm_limits_t* wasm_tabletype_limits(const wasm_tabletype_t*);
|
||||
|
||||
|
||||
// Memory Types
|
||||
|
||||
WASM_DECLARE_TYPE(memorytype)
|
||||
|
||||
WASM_API_EXTERN own wasm_memorytype_t* wasm_memorytype_new(const wasm_limits_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_limits_t* wasm_memorytype_limits(const wasm_memorytype_t*);
|
||||
|
||||
|
||||
// Extern Types
|
||||
|
||||
WASM_DECLARE_TYPE(externtype)
|
||||
|
||||
typedef uint8_t wasm_externkind_t;
|
||||
enum wasm_externkind_enum {
|
||||
WASM_EXTERN_FUNC,
|
||||
WASM_EXTERN_GLOBAL,
|
||||
WASM_EXTERN_TABLE,
|
||||
WASM_EXTERN_MEMORY,
|
||||
};
|
||||
|
||||
WASM_API_EXTERN wasm_externkind_t wasm_externtype_kind(const wasm_externtype_t*);
|
||||
|
||||
WASM_API_EXTERN wasm_externtype_t* wasm_functype_as_externtype(wasm_functype_t*);
|
||||
WASM_API_EXTERN wasm_externtype_t* wasm_globaltype_as_externtype(wasm_globaltype_t*);
|
||||
WASM_API_EXTERN wasm_externtype_t* wasm_tabletype_as_externtype(wasm_tabletype_t*);
|
||||
WASM_API_EXTERN wasm_externtype_t* wasm_memorytype_as_externtype(wasm_memorytype_t*);
|
||||
|
||||
WASM_API_EXTERN wasm_functype_t* wasm_externtype_as_functype(wasm_externtype_t*);
|
||||
WASM_API_EXTERN wasm_globaltype_t* wasm_externtype_as_globaltype(wasm_externtype_t*);
|
||||
WASM_API_EXTERN wasm_tabletype_t* wasm_externtype_as_tabletype(wasm_externtype_t*);
|
||||
WASM_API_EXTERN wasm_memorytype_t* wasm_externtype_as_memorytype(wasm_externtype_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_functype_as_externtype_const(const wasm_functype_t*);
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_globaltype_as_externtype_const(const wasm_globaltype_t*);
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_tabletype_as_externtype_const(const wasm_tabletype_t*);
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_memorytype_as_externtype_const(const wasm_memorytype_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_functype_t* wasm_externtype_as_functype_const(const wasm_externtype_t*);
|
||||
WASM_API_EXTERN const wasm_globaltype_t* wasm_externtype_as_globaltype_const(const wasm_externtype_t*);
|
||||
WASM_API_EXTERN const wasm_tabletype_t* wasm_externtype_as_tabletype_const(const wasm_externtype_t*);
|
||||
WASM_API_EXTERN const wasm_memorytype_t* wasm_externtype_as_memorytype_const(const wasm_externtype_t*);
|
||||
|
||||
|
||||
// Import Types
|
||||
|
||||
WASM_DECLARE_TYPE(importtype)
|
||||
|
||||
WASM_API_EXTERN own wasm_importtype_t* wasm_importtype_new(
|
||||
own wasm_name_t* module, own wasm_name_t* name, own wasm_externtype_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_name_t* wasm_importtype_module(const wasm_importtype_t*);
|
||||
WASM_API_EXTERN const wasm_name_t* wasm_importtype_name(const wasm_importtype_t*);
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_importtype_type(const wasm_importtype_t*);
|
||||
|
||||
|
||||
// Export Types
|
||||
|
||||
WASM_DECLARE_TYPE(exporttype)
|
||||
|
||||
WASM_API_EXTERN own wasm_exporttype_t* wasm_exporttype_new(
|
||||
own wasm_name_t*, own wasm_externtype_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_name_t* wasm_exporttype_name(const wasm_exporttype_t*);
|
||||
WASM_API_EXTERN const wasm_externtype_t* wasm_exporttype_type(const wasm_exporttype_t*);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Runtime Objects
|
||||
|
||||
// Values
|
||||
|
||||
struct wasm_ref_t;
|
||||
|
||||
typedef struct wasm_val_t {
|
||||
wasm_valkind_t kind;
|
||||
union {
|
||||
int32_t i32;
|
||||
int64_t i64;
|
||||
float32_t f32;
|
||||
float64_t f64;
|
||||
struct wasm_ref_t* ref;
|
||||
} of;
|
||||
} wasm_val_t;
|
||||
|
||||
WASM_API_EXTERN void wasm_val_delete(own wasm_val_t* v);
|
||||
WASM_API_EXTERN void wasm_val_copy(own wasm_val_t* out, const wasm_val_t*);
|
||||
|
||||
WASM_DECLARE_VEC(val, )
|
||||
|
||||
|
||||
// References
|
||||
|
||||
#define WASM_DECLARE_REF_BASE(name) \
|
||||
WASM_DECLARE_OWN(name) \
|
||||
\
|
||||
WASM_API_EXTERN own wasm_##name##_t* wasm_##name##_copy(const wasm_##name##_t*); \
|
||||
WASM_API_EXTERN bool wasm_##name##_same(const wasm_##name##_t*, const wasm_##name##_t*);
|
||||
|
||||
#define WASM_DECLARE_REF(name) \
|
||||
WASM_DECLARE_REF_BASE(name) \
|
||||
\
|
||||
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*);
|
||||
|
||||
#define WASM_DECLARE_SHARABLE_REF(name) \
|
||||
WASM_DECLARE_REF(name) \
|
||||
WASM_DECLARE_OWN(shared_##name) \
|
||||
\
|
||||
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_DECLARE_REF_BASE(ref)
|
||||
|
||||
// Traps
|
||||
|
||||
typedef wasm_name_t wasm_message_t; // null terminated
|
||||
|
||||
WASM_DECLARE_REF_BASE(trap)
|
||||
|
||||
WASM_API_EXTERN own wasm_trap_t* wasm_trap_new(wasm_store_t* store, const wasm_message_t*);
|
||||
|
||||
WASM_API_EXTERN void wasm_trap_message(const wasm_trap_t*, own wasm_message_t* out);
|
||||
|
||||
// Modules
|
||||
#ifndef WASM_MODULE_T_DEFINED
|
||||
#define WASM_MODULE_T_DEFINED
|
||||
struct WASMModuleCommon;
|
||||
typedef struct WASMModuleCommon *wasm_module_t;
|
||||
#endif
|
||||
|
||||
WASM_API_EXTERN own wasm_module_t* wasm_module_new(
|
||||
wasm_store_t*, const wasm_byte_vec_t* binary);
|
||||
|
||||
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
|
||||
|
||||
WASM_API_EXTERN void wasm_module_delete(own wasm_module_t*);
|
||||
|
||||
WASM_API_EXTERN own wasm_module_t* wasm_module_copy(const wasm_module_t*);
|
||||
WASM_API_EXTERN bool wasm_module_same(const wasm_module_t*, const wasm_module_t*);
|
||||
|
||||
WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_vec_t* out);
|
||||
WASM_API_EXTERN void wasm_module_exports(const wasm_module_t*, own wasm_exporttype_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*);
|
||||
|
||||
|
||||
// Function Instances
|
||||
|
||||
WASM_DECLARE_REF(func)
|
||||
|
||||
typedef own wasm_trap_t* (*wasm_func_callback_t)(
|
||||
const wasm_val_t args[], wasm_val_t results[]);
|
||||
typedef own wasm_trap_t* (*wasm_func_callback_with_env_t)(
|
||||
void* env, const wasm_val_t args[], wasm_val_t results[]);
|
||||
|
||||
WASM_API_EXTERN own wasm_func_t* wasm_func_new(
|
||||
wasm_store_t*, const wasm_functype_t*, wasm_func_callback_t);
|
||||
WASM_API_EXTERN own wasm_func_t* wasm_func_new_with_env(
|
||||
wasm_store_t*, const wasm_functype_t* type, wasm_func_callback_with_env_t,
|
||||
void* env, void (*finalizer)(void*));
|
||||
|
||||
WASM_API_EXTERN own wasm_functype_t* wasm_func_type(const wasm_func_t*);
|
||||
WASM_API_EXTERN size_t wasm_func_param_arity(const wasm_func_t*);
|
||||
WASM_API_EXTERN size_t wasm_func_result_arity(const wasm_func_t*);
|
||||
|
||||
WASM_API_EXTERN own wasm_trap_t* wasm_func_call(
|
||||
const wasm_func_t*, const wasm_val_t args[], wasm_val_t results[]);
|
||||
|
||||
|
||||
// Global Instances
|
||||
|
||||
WASM_DECLARE_REF_BASE(global)
|
||||
|
||||
WASM_API_EXTERN own wasm_global_t* wasm_global_new(
|
||||
wasm_store_t*, const wasm_globaltype_t*, const wasm_val_t*);
|
||||
|
||||
WASM_API_EXTERN own wasm_globaltype_t* wasm_global_type(const wasm_global_t*);
|
||||
|
||||
WASM_API_EXTERN void wasm_global_get(const wasm_global_t*, own wasm_val_t* out);
|
||||
WASM_API_EXTERN void wasm_global_set(wasm_global_t*, const wasm_val_t*);
|
||||
|
||||
|
||||
// Table Instances
|
||||
|
||||
WASM_DECLARE_REF_BASE(table)
|
||||
|
||||
typedef uint32_t wasm_table_size_t;
|
||||
|
||||
WASM_API_EXTERN own wasm_table_t* wasm_table_new(
|
||||
wasm_store_t*, const wasm_tabletype_t*, wasm_ref_t* init);
|
||||
|
||||
WASM_API_EXTERN own wasm_tabletype_t* wasm_table_type(const wasm_table_t*);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// Memory Instances
|
||||
|
||||
WASM_DECLARE_REF_BASE(memory)
|
||||
|
||||
typedef uint32_t wasm_memory_pages_t;
|
||||
|
||||
static const size_t MEMORY_PAGE_SIZE = 0x10000;
|
||||
|
||||
WASM_API_EXTERN own wasm_memory_t* wasm_memory_new(wasm_store_t*, const wasm_memorytype_t*);
|
||||
|
||||
WASM_API_EXTERN own wasm_memorytype_t* wasm_memory_type(const wasm_memory_t*);
|
||||
|
||||
WASM_API_EXTERN byte_t* wasm_memory_data(wasm_memory_t*);
|
||||
WASM_API_EXTERN size_t wasm_memory_data_size(const wasm_memory_t*);
|
||||
|
||||
WASM_API_EXTERN wasm_memory_pages_t wasm_memory_size(const wasm_memory_t*);
|
||||
WASM_API_EXTERN bool wasm_memory_grow(wasm_memory_t*, wasm_memory_pages_t delta);
|
||||
|
||||
|
||||
// Externals
|
||||
|
||||
WASM_DECLARE_REF_BASE(extern)
|
||||
WASM_DECLARE_VEC(extern, *)
|
||||
|
||||
WASM_API_EXTERN wasm_externkind_t wasm_extern_kind(const wasm_extern_t*);
|
||||
WASM_API_EXTERN own wasm_externtype_t* wasm_extern_type(const wasm_extern_t*);
|
||||
|
||||
WASM_API_EXTERN wasm_extern_t* wasm_func_as_extern(wasm_func_t*);
|
||||
WASM_API_EXTERN wasm_extern_t* wasm_global_as_extern(wasm_global_t*);
|
||||
WASM_API_EXTERN wasm_extern_t* wasm_table_as_extern(wasm_table_t*);
|
||||
WASM_API_EXTERN wasm_extern_t* wasm_memory_as_extern(wasm_memory_t*);
|
||||
|
||||
WASM_API_EXTERN wasm_func_t* wasm_extern_as_func(wasm_extern_t*);
|
||||
WASM_API_EXTERN wasm_global_t* wasm_extern_as_global(wasm_extern_t*);
|
||||
WASM_API_EXTERN wasm_table_t* wasm_extern_as_table(wasm_extern_t*);
|
||||
WASM_API_EXTERN wasm_memory_t* wasm_extern_as_memory(wasm_extern_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_extern_t* wasm_func_as_extern_const(const wasm_func_t*);
|
||||
WASM_API_EXTERN const wasm_extern_t* wasm_global_as_extern_const(const wasm_global_t*);
|
||||
WASM_API_EXTERN const wasm_extern_t* wasm_table_as_extern_const(const wasm_table_t*);
|
||||
WASM_API_EXTERN const wasm_extern_t* wasm_memory_as_extern_const(const wasm_memory_t*);
|
||||
|
||||
WASM_API_EXTERN const wasm_func_t* wasm_extern_as_func_const(const wasm_extern_t*);
|
||||
WASM_API_EXTERN const wasm_global_t* wasm_extern_as_global_const(const wasm_extern_t*);
|
||||
WASM_API_EXTERN const wasm_table_t* wasm_extern_as_table_const(const wasm_extern_t*);
|
||||
WASM_API_EXTERN const wasm_memory_t* wasm_extern_as_memory_const(const wasm_extern_t*);
|
||||
|
||||
|
||||
// Module Instances
|
||||
|
||||
WASM_DECLARE_REF_BASE(instance)
|
||||
|
||||
WASM_API_EXTERN own wasm_instance_t* wasm_instance_new(
|
||||
wasm_store_t*, const wasm_module_t*, const wasm_extern_t* const imports[],
|
||||
own wasm_trap_t**
|
||||
);
|
||||
|
||||
WASM_API_EXTERN void wasm_instance_exports(const wasm_instance_t*, own wasm_extern_vec_t* out);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Convenience
|
||||
|
||||
// Value Type construction short-hands
|
||||
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_i32() {
|
||||
return wasm_valtype_new(WASM_I32);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_i64() {
|
||||
return wasm_valtype_new(WASM_I64);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_f32() {
|
||||
return wasm_valtype_new(WASM_F32);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_f64() {
|
||||
return wasm_valtype_new(WASM_F64);
|
||||
}
|
||||
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_anyref() {
|
||||
return wasm_valtype_new(WASM_ANYREF);
|
||||
}
|
||||
static inline own wasm_valtype_t* wasm_valtype_new_funcref() {
|
||||
return wasm_valtype_new(WASM_FUNCREF);
|
||||
}
|
||||
|
||||
|
||||
// Function Types construction short-hands
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_0_0() {
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new_empty(¶ms);
|
||||
wasm_valtype_vec_new_empty(&results);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_1_0(
|
||||
own wasm_valtype_t* p
|
||||
) {
|
||||
wasm_valtype_t* ps[1] = {p};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 1, ps);
|
||||
wasm_valtype_vec_new_empty(&results);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_2_0(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2
|
||||
) {
|
||||
wasm_valtype_t* ps[2] = {p1, p2};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 2, ps);
|
||||
wasm_valtype_vec_new_empty(&results);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_3_0(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3
|
||||
) {
|
||||
wasm_valtype_t* ps[3] = {p1, p2, p3};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 3, ps);
|
||||
wasm_valtype_vec_new_empty(&results);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_0_1(
|
||||
own wasm_valtype_t* r
|
||||
) {
|
||||
wasm_valtype_t* rs[1] = {r};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new_empty(¶ms);
|
||||
wasm_valtype_vec_new(&results, 1, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_1_1(
|
||||
own wasm_valtype_t* p, own wasm_valtype_t* r
|
||||
) {
|
||||
wasm_valtype_t* ps[1] = {p};
|
||||
wasm_valtype_t* rs[1] = {r};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 1, ps);
|
||||
wasm_valtype_vec_new(&results, 1, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_2_1(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* r
|
||||
) {
|
||||
wasm_valtype_t* ps[2] = {p1, p2};
|
||||
wasm_valtype_t* rs[1] = {r};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 2, ps);
|
||||
wasm_valtype_vec_new(&results, 1, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_3_1(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
|
||||
own wasm_valtype_t* r
|
||||
) {
|
||||
wasm_valtype_t* ps[3] = {p1, p2, p3};
|
||||
wasm_valtype_t* rs[1] = {r};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 3, ps);
|
||||
wasm_valtype_vec_new(&results, 1, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_0_2(
|
||||
own wasm_valtype_t* r1, own wasm_valtype_t* r2
|
||||
) {
|
||||
wasm_valtype_t* rs[2] = {r1, r2};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new_empty(¶ms);
|
||||
wasm_valtype_vec_new(&results, 2, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_1_2(
|
||||
own wasm_valtype_t* p, own wasm_valtype_t* r1, own wasm_valtype_t* r2
|
||||
) {
|
||||
wasm_valtype_t* ps[1] = {p};
|
||||
wasm_valtype_t* rs[2] = {r1, r2};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 1, ps);
|
||||
wasm_valtype_vec_new(&results, 2, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_2_2(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2,
|
||||
own wasm_valtype_t* r1, own wasm_valtype_t* r2
|
||||
) {
|
||||
wasm_valtype_t* ps[2] = {p1, p2};
|
||||
wasm_valtype_t* rs[2] = {r1, r2};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 2, ps);
|
||||
wasm_valtype_vec_new(&results, 2, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
static inline own wasm_functype_t* wasm_functype_new_3_2(
|
||||
own wasm_valtype_t* p1, own wasm_valtype_t* p2, own wasm_valtype_t* p3,
|
||||
own wasm_valtype_t* r1, own wasm_valtype_t* r2
|
||||
) {
|
||||
wasm_valtype_t* ps[3] = {p1, p2, p3};
|
||||
wasm_valtype_t* rs[2] = {r1, r2};
|
||||
wasm_valtype_vec_t params, results;
|
||||
wasm_valtype_vec_new(¶ms, 3, ps);
|
||||
wasm_valtype_vec_new(&results, 2, rs);
|
||||
return wasm_functype_new(¶ms, &results);
|
||||
}
|
||||
|
||||
|
||||
// Value construction short-hands
|
||||
|
||||
static inline void wasm_val_init_ptr(own wasm_val_t* out, void* p) {
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
out->kind = WASM_I32;
|
||||
out->of.i32 = (intptr_t)p;
|
||||
#elif UINTPTR_MAX == UINT64_MAX
|
||||
out->kind = WASM_I64;
|
||||
out->of.i64 = (intptr_t)p;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void* wasm_val_ptr(const wasm_val_t* val) {
|
||||
#if UINTPTR_MAX == UINT32_MAX
|
||||
return (void*)(intptr_t)val->of.i32;
|
||||
#elif UINTPTR_MAX == UINT64_MAX
|
||||
return (void*)(intptr_t)val->of.i64;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#undef own
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif // #ifdef WASM_H
|
|
@ -43,10 +43,13 @@ extern "C" {
|
|||
#define native_raw_set_return(val) *raw_ret = (val)
|
||||
|
||||
|
||||
#ifndef WASM_MODULE_T_DEFINED
|
||||
#define WASM_MODULE_T_DEFINED
|
||||
/* Uninstantiated WASM module loaded from WASM binary file
|
||||
or AoT binary file*/
|
||||
struct WASMModuleCommon;
|
||||
typedef struct WASMModuleCommon *wasm_module_t;
|
||||
#endif
|
||||
|
||||
/* Instantiated WASM module */
|
||||
struct WASMModuleInstanceCommon;
|
||||
|
|
|
@ -1095,9 +1095,11 @@ load_global_import(const WASMModule *parent_module,
|
|||
#endif
|
||||
|
||||
if (!ret) {
|
||||
#if WASM_ENABLE_SPEC_TEST != 0
|
||||
set_error_buf_v(error_buf, error_buf_size,
|
||||
"unknown import or incompatible import type");
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
global->module_name = sub_module_name;
|
||||
|
|
|
@ -995,9 +995,6 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst,
|
|||
error_buf, error_buf_size))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LOG_DEBUG("Instantiate a module %p -> %p", module, module_inst);
|
||||
|
||||
memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
|
||||
|
||||
module_inst->module = module;
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "bh_list.h"
|
||||
#include "bh_log.h"
|
||||
#include "bh_queue.h"
|
||||
#include "bh_vector.h"
|
||||
#include "runtime_timer.h"
|
||||
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ extend_vector(Vector *vector, uint32 length)
|
|||
{
|
||||
uint8 *data;
|
||||
|
||||
if (length <= vector->max_elements)
|
||||
if (length <= vector->max_elems)
|
||||
return true;
|
||||
|
||||
if (length < vector->size_elem * 3 / 2)
|
||||
|
@ -37,10 +37,10 @@ extend_vector(Vector *vector, uint32 length)
|
|||
return false;
|
||||
}
|
||||
|
||||
memcpy(data, vector->data, vector->size_elem * vector->max_elements);
|
||||
memcpy(data, vector->data, vector->size_elem * vector->max_elems);
|
||||
BH_FREE(vector->data);
|
||||
vector->data = data;
|
||||
vector->max_elements = length;
|
||||
vector->max_elems = length;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -62,8 +62,8 @@ bh_vector_init(Vector *vector, uint32 init_length, uint32 size_elem)
|
|||
}
|
||||
|
||||
vector->size_elem = size_elem;
|
||||
vector->max_elements = init_length;
|
||||
vector->num_elements = 0;
|
||||
vector->max_elems = init_length;
|
||||
vector->num_elems = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -75,7 +75,7 @@ bh_vector_set(Vector *vector, uint32 index, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (index >= vector->num_elements) {
|
||||
if (index >= vector->num_elems) {
|
||||
LOG_ERROR("Set vector elem failed: invalid elem index.\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ bool bh_vector_get(const Vector *vector, uint32 index, void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (index >= vector->num_elements) {
|
||||
if (index >= vector->num_elems) {
|
||||
LOG_ERROR("Get vector elem failed: invalid elem index.\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -112,24 +112,24 @@ bool bh_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (index >= vector->num_elements) {
|
||||
if (index >= vector->num_elems) {
|
||||
LOG_ERROR("Insert vector elem failed: invalid elem index.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!extend_vector(vector, vector->num_elements + 1)) {
|
||||
if (!extend_vector(vector, vector->num_elems + 1)) {
|
||||
LOG_ERROR("Insert vector elem failed: extend vector failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
p = vector->data + vector->size_elem * vector->num_elements;
|
||||
for (i = vector->num_elements - 1; i > index; i--) {
|
||||
p = vector->data + vector->size_elem * vector->num_elems;
|
||||
for (i = vector->num_elems - 1; i > index; i--) {
|
||||
memcpy(p, p - vector->size_elem, vector->size_elem);
|
||||
p -= vector->size_elem;
|
||||
}
|
||||
|
||||
memcpy(p, elem_buf, vector->size_elem);
|
||||
vector->num_elements++;
|
||||
vector->num_elems++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -140,14 +140,14 @@ bool bh_vector_append(Vector *vector, const void *elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!extend_vector(vector, vector->num_elements + 1)) {
|
||||
if (!extend_vector(vector, vector->num_elems + 1)) {
|
||||
LOG_ERROR("Append ector elem failed: extend vector failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(vector->data + vector->size_elem * vector->num_elements,
|
||||
memcpy(vector->data + vector->size_elem * vector->num_elems,
|
||||
elem_buf, vector->size_elem);
|
||||
vector->num_elements++;
|
||||
vector->num_elems++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (index >= vector->num_elements) {
|
||||
if (index >= vector->num_elems) {
|
||||
LOG_ERROR("Remove vector elem failed: invalid elem index.\n");
|
||||
return false;
|
||||
}
|
||||
|
@ -173,19 +173,19 @@ bh_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
|
|||
memcpy(old_elem_buf, p, vector->size_elem);
|
||||
}
|
||||
|
||||
for (i = index; i < vector->num_elements - 1; i++) {
|
||||
for (i = index; i < vector->num_elems - 1; i++) {
|
||||
memcpy(p, p + vector->size_elem, vector->size_elem);
|
||||
p += vector->size_elem;
|
||||
}
|
||||
|
||||
vector->num_elements--;
|
||||
vector->num_elems--;
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32
|
||||
bh_vector_size(const Vector *vector)
|
||||
{
|
||||
return vector ? vector->num_elements : 0;
|
||||
return vector ? vector->num_elems : 0;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -15,14 +15,14 @@ extern "C" {
|
|||
#define DEFAULT_VECTOR_INIT_SIZE 8
|
||||
|
||||
typedef struct Vector {
|
||||
/* size of each element */
|
||||
uint32 size_elem;
|
||||
/* max element number */
|
||||
uint32 max_elements;
|
||||
/* current element num */
|
||||
uint32 num_elements;
|
||||
size_t max_elems;
|
||||
/* vector data allocated */
|
||||
uint8 *data;
|
||||
/* current element num */
|
||||
size_t num_elems;
|
||||
/* size of each element */
|
||||
size_t size_elem;
|
||||
} Vector;
|
||||
|
||||
/**
|
||||
|
|
77
doc/wasm_c_api.md
Normal file
77
doc/wasm_c_api.md
Normal file
|
@ -0,0 +1,77 @@
|
|||
All samples come from the commit 340fd9528cc3b26d22fe30ee1628c8c3f2b8c53b
|
||||
of [wasm-c-api][https://github.com/WebAssembly/wasm-c-api].
|
||||
|
||||
Every user should be familiar with *APIs* listed in
|
||||
[wasm.h][https://github.com/WebAssembly/wasm-c-api/blob/master/include/wasm.h].
|
||||
|
||||
all [examples][https://github.com/WebAssembly/wasm-c-api/tree/master/example] are
|
||||
very helpful for learning.
|
||||
|
||||
Currently, we support partial of *APIs* and are going to support the rest of
|
||||
them in next releases.
|
||||
|
||||
Supported APIs:
|
||||
|
||||
``` c
|
||||
/* wasm_bytevec_t APIs ... */
|
||||
|
||||
wasm_engine_t *wasm_engine_new();
|
||||
wasm_engine_t *wasm_engine_new_with_args(mem_alloc_type_t, const MemAllocOption*, runtime_mode_e);
|
||||
void wasm_engine_delete(wasm_engine_t *);
|
||||
|
||||
wasm_store_t *wasm_store_new(wasm_engine_t *);
|
||||
void wasm_store_delete(wasm_store_t *);
|
||||
|
||||
/* wasm_valtype_t APIs ... */
|
||||
/* wasm_valtype_vec_t APIs ... */
|
||||
/* wasm_functype_vec_t APIs ... */
|
||||
/* wasm_globaltype_vec_t APIs ... */
|
||||
/* wasm_val_t APIs ... */
|
||||
/* wasm_trap_t partial APIs ... */
|
||||
|
||||
wasm_module_t *wasm_module_new(wasm_store_t *, const wasm_byte_vec_t *);
|
||||
void wasm_module_delete(wasm_module_t *);
|
||||
|
||||
wasm_func_t *wasm_func_new(wasm_store_t *, const wasm_functype_t *, wasm_func_callback_t);
|
||||
wasm_func_t *wasm_func_new_with_env(wasm_store_t *store, const wasm_functype_t *, wasm_func_callback_with_env_t, void *env, void (*finalizer)(void *));
|
||||
void wasm_func_delete(wasm_func_t *);
|
||||
wasm_fucn_t *wasm_func_copy(const wasm_func_t *);
|
||||
wasm_functype_t *wasm_func_type(const wasm_func_t *);
|
||||
wasm_trap_t * wasm_func_call(const wasm_func_t *, const wasm_val_t params[], wasm_val_t results[]);
|
||||
size_t wasm_func_param_arity(const wasm_func_t *);
|
||||
size_t wasm_func_result_arity(const wasm_func_t *);
|
||||
|
||||
wasm_global_t *wasm_global_new(wasm_store_t *, const wasm_globaltype_t *, const wasm_val_t *);
|
||||
wasm_global_t * wasm_global_copy(const wasm_global_t *);
|
||||
void wasm_global_delete(wasm_global_t *);
|
||||
bool wasm_global_same(const wasm_global_t *, const wasm_global_t *);
|
||||
void wasm_global_set(wasm_global_t *, const wasm_val_t *);
|
||||
void wasm_global_get(const wasm_global_t *, wasm_val_t *out);
|
||||
wasm_globaltype_t * wasm_global_type(const wasm_global_t *);
|
||||
|
||||
wasm_instance_t *wasm_instance_new(wasm_store_t *, const wasm_module_t *, const wasm_extern_t *const imports[], wasm_trap_t **traps);
|
||||
void wasm_instance_delete(wasm_instance_t *);
|
||||
void wasm_instance_exports(const wasm_instance_t *, wasm_extern_vec_t *out);
|
||||
|
||||
/* wasm_extern_t APIs */
|
||||
```
|
||||
|
||||
Unsupported APIs:
|
||||
|
||||
``` c
|
||||
/* wasm_tabletype_t APIs */
|
||||
/* wasm_memorytype_t APIs */
|
||||
/* wasm_externtype_t APIs */
|
||||
/* wasm_importtype_t APIs */
|
||||
/* wasm_exporttype_t APIs */
|
||||
/* wasm_ref_t APIs */
|
||||
/* wasm_shared_##name##_t APIs */
|
||||
|
||||
WASM_API_EXTERN bool wasm_module_validate(wasm_store_t*, const wasm_byte_vec_t* binary);
|
||||
WASM_API_EXTERN void wasm_module_imports(const wasm_module_t*, own wasm_importtype_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*);
|
||||
|
||||
/* wasm_table_t APIs */
|
||||
/* wasm_memory_t APIs */
|
||||
```
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
project(multi_module)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
################ runtime settings ################
|
||||
set(WAMR_BUILD_PLATFORM "linux")
|
||||
|
@ -18,7 +17,7 @@ set(WAMR_BUILD_INTERP 1)
|
|||
set(WAMR_BUILD_AOT 0)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set(WAMR_BUILD_LIBC_WASI 1)
|
||||
set(WAMR_BUILD_LIBC_WASI 0)
|
||||
set(WAMR_BUILD_FAST_INTERP 0)
|
||||
set(WAMR_BUILD_MULTI_MODULE 1)
|
||||
|
||||
|
|
89
samples/wasm-c-api/CMakeLists.txt
Normal file
89
samples/wasm-c-api/CMakeLists.txt
Normal file
|
@ -0,0 +1,89 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
project(c-api)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif()
|
||||
################ runtime settings ################
|
||||
set(WAMR_BUILD_PLATFORM "linux")
|
||||
|
||||
# Resetdefault linker flags
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
|
||||
# WAMR features switch
|
||||
set(WAMR_BUILD_TARGET "X86_64")
|
||||
|
||||
if(NOT DEFINED WAMR_BUILD_INTERP)
|
||||
set(WAMR_BUILD_INTERP 1)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED WAMR_BUILD_AOT)
|
||||
set(WAMR_BUILD_AOT 0)
|
||||
endif()
|
||||
|
||||
if(NOT DEFINED WAMR_BUILD_JOT)
|
||||
set(WAMR_BUILD_JIT 0)
|
||||
endif()
|
||||
|
||||
set(WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
set(WAMR_BUILD_LIBC_WASI 0)
|
||||
|
||||
if(NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
||||
set(WAMR_BUILD_FAST_INTERP 0)
|
||||
endif()
|
||||
|
||||
# compiling and linking flags
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections -pie -fPIE")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security -mindirect-branch-register")
|
||||
|
||||
# build out vmlib
|
||||
set(WAMR_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
|
||||
set(WAMRC ${WAMR_ROOT_DIR}/wamr-compiler/build/wamrc)
|
||||
include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
|
||||
|
||||
add_library(vmlib STATIC ${WAMR_RUNTIME_LIB_SOURCE})
|
||||
################################################
|
||||
|
||||
################ application related ################
|
||||
file(GLOB SOURCES src/*.c)
|
||||
add_library(c-api ${SOURCES})
|
||||
target_include_directories(c-api
|
||||
PRIVATE ${C_API_PATH}/include
|
||||
)
|
||||
target_link_libraries(c-api PRIVATE vmlib -lpthread -lm)
|
||||
|
||||
foreach(SRC ${SOURCES})
|
||||
get_filename_component(APPNAME ${SRC} NAME_WE)
|
||||
|
||||
# build executable for each .c
|
||||
add_executable(${APPNAME} ${SRC})
|
||||
message("create executable about ${APPNAME}")
|
||||
target_link_libraries(${APPNAME} c-api)
|
||||
|
||||
# copy .wasm
|
||||
add_custom_command(TARGET ${APPNAME} POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/${APPNAME}.wasm
|
||||
${PROJECT_BINARY_DIR}/
|
||||
BYPRODUCTS ${APPNAME}.wasm
|
||||
COMMENT "Copy ${SRC} to the output directory"
|
||||
)
|
||||
|
||||
# generate .aot file
|
||||
if(${WAMR_BUILD_AOT} EQUAL 1)
|
||||
if(EXISTS ${WAMRC})
|
||||
add_custom_command(TARGET ${APPNAME} POST_BUILD
|
||||
COMMAND ${WAMRC} -o ${APPNAME}.aot
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/src/${APPNAME}.wasm
|
||||
BYPRODUCTS ${APPNAME}.aot
|
||||
COMMENT "generate a aot file ${APPNAME}.aot"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
endforeach(SRC ${SOURCES})
|
||||
################################################
|
39
samples/wasm-c-api/README.md
Normal file
39
samples/wasm-c-api/README.md
Normal file
|
@ -0,0 +1,39 @@
|
|||
WAMR supports *wasm-c-api* in both *interpreter* mode and *aot* mode. By default,
|
||||
all samples are compiled and run in "interpreter" mode.
|
||||
|
||||
``` shell
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake ..
|
||||
$ make
|
||||
$ # it will build a library with c-api supporting.
|
||||
$ # Also copy *.wasm from ../src/
|
||||
$ # and generate executable files
|
||||
$ # now, it is ok to run samples
|
||||
$ ./hello
|
||||
$ ...
|
||||
$ ./global
|
||||
$ ...
|
||||
$ ./callback
|
||||
$ ...
|
||||
```
|
||||
|
||||
They can be compiled and run in *aot* mode when some compiling flags are given.
|
||||
|
||||
``` shell
|
||||
$ mkdir build
|
||||
$ cd build
|
||||
$ cmake -DWAMR_BUILD_INTERP=0 -DWAMR_BUILD_AOT=1 ..
|
||||
$ make
|
||||
$ # it will build a library with c-api supporting.
|
||||
$ # Also copy *.wasm from ../src/
|
||||
$ # and transform *.wasm to *.aot
|
||||
$ # and generate executable files
|
||||
$ # now, it is ok to run samples
|
||||
$ ./hello
|
||||
$ ...
|
||||
$ ./global
|
||||
$ ...
|
||||
$ ./callback
|
||||
$ ...
|
||||
```
|
168
samples/wasm-c-api/src/callback.c
Normal file
168
samples/wasm-c-api/src/callback.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "wasm_c_api.h"
|
||||
|
||||
#define own
|
||||
|
||||
// Print a Wasm value
|
||||
void wasm_val_print(wasm_val_t val) {
|
||||
switch (val.kind) {
|
||||
case WASM_I32: {
|
||||
printf("%" PRIu32, val.of.i32);
|
||||
} break;
|
||||
case WASM_I64: {
|
||||
printf("%" PRIu64, val.of.i64);
|
||||
} break;
|
||||
case WASM_F32: {
|
||||
printf("%f", val.of.f32);
|
||||
} break;
|
||||
case WASM_F64: {
|
||||
printf("%g", val.of.f64);
|
||||
} break;
|
||||
case WASM_ANYREF:
|
||||
case WASM_FUNCREF: {
|
||||
if (val.of.ref == NULL) {
|
||||
printf("null");
|
||||
} else {
|
||||
printf("ref(%p)", val.of.ref);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
// A function to be called from Wasm code.
|
||||
own wasm_trap_t* print_callback(
|
||||
const wasm_val_t args[], wasm_val_t results[]
|
||||
) {
|
||||
printf("Calling back...\n> ");
|
||||
wasm_val_print(args[0]);
|
||||
printf("\n");
|
||||
|
||||
wasm_val_copy(&results[0], &args[0]);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// A function closure.
|
||||
own wasm_trap_t* closure_callback(
|
||||
void* env, const wasm_val_t args[], wasm_val_t results[]
|
||||
) {
|
||||
int i = *(int*)env;
|
||||
printf("Calling back closure...\n");
|
||||
printf("> %d\n", i);
|
||||
|
||||
results[0].kind = WASM_I32;
|
||||
results[0].of.i32 = (int32_t)i;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
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");
|
||||
FILE* file = fopen("callback.wasm", "rb");
|
||||
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");
|
||||
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 print functions.
|
||||
printf("Creating callback...\n");
|
||||
own wasm_functype_t* print_type = wasm_functype_new_1_1(wasm_valtype_new_i32(), wasm_valtype_new_i32());
|
||||
own wasm_func_t* print_func = wasm_func_new(store, print_type, print_callback);
|
||||
|
||||
int i = 42;
|
||||
own wasm_functype_t* closure_type = wasm_functype_new_0_1(wasm_valtype_new_i32());
|
||||
own wasm_func_t* closure_func = wasm_func_new_with_env(store, closure_type, closure_callback, &i, NULL);
|
||||
|
||||
wasm_functype_delete(print_type);
|
||||
wasm_functype_delete(closure_type);
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
const wasm_extern_t* imports[] = {
|
||||
wasm_func_as_extern(print_func), wasm_func_as_extern(closure_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(print_func);
|
||||
wasm_func_delete(closure_func);
|
||||
|
||||
// Extract export.
|
||||
printf("Extracting export...\n");
|
||||
own wasm_extern_vec_t exports;
|
||||
wasm_instance_exports(instance, &exports);
|
||||
if (exports.size == 0) {
|
||||
printf("> Error accessing exports!\n");
|
||||
return 1;
|
||||
}
|
||||
const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
|
||||
if (run_func == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_module_delete(module);
|
||||
wasm_instance_delete(instance);
|
||||
|
||||
// Call.
|
||||
printf("Calling export...\n");
|
||||
wasm_val_t args[2];
|
||||
args[0].kind = WASM_I32;
|
||||
args[0].of.i32 = 3;
|
||||
args[1].kind = WASM_I32;
|
||||
args[1].of.i32 = 4;
|
||||
wasm_val_t results[1];
|
||||
if (wasm_func_call(run_func, args, results)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_extern_vec_delete(&exports);
|
||||
|
||||
// Print result.
|
||||
printf("Printing result...\n");
|
||||
printf("> %u\n", results[0].of.i32);
|
||||
|
||||
// Shut down.
|
||||
printf("Shutting down...\n");
|
||||
wasm_store_delete(store);
|
||||
wasm_engine_delete(engine);
|
||||
|
||||
// All done.
|
||||
printf("Done.\n");
|
||||
return 0;
|
||||
}
|
BIN
samples/wasm-c-api/src/callback.wasm
Normal file
BIN
samples/wasm-c-api/src/callback.wasm
Normal file
Binary file not shown.
10
samples/wasm-c-api/src/callback.wat
Normal file
10
samples/wasm-c-api/src/callback.wat
Normal file
|
@ -0,0 +1,10 @@
|
|||
(module
|
||||
(func $print (import "" "print") (param i32) (result i32))
|
||||
(func $closure (import "" "closure") (result i32))
|
||||
(func (export "run") (param $x i32) (param $y i32) (result i32)
|
||||
(i32.add
|
||||
(call $print (i32.add (local.get $x) (local.get $y)))
|
||||
(call $closure)
|
||||
)
|
||||
)
|
||||
)
|
236
samples/wasm-c-api/src/global.c
Normal file
236
samples/wasm-c-api/src/global.c
Normal file
|
@ -0,0 +1,236 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "wasm_c_api.h"
|
||||
|
||||
#define own
|
||||
|
||||
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_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]);
|
||||
}
|
||||
|
||||
|
||||
#define check(val, type, expected) \
|
||||
if (val.of.type != expected) { \
|
||||
printf("> Error reading value\n"); \
|
||||
exit(1); \
|
||||
}
|
||||
|
||||
#define check_global(global, type, expected) \
|
||||
{ \
|
||||
wasm_val_t val; \
|
||||
wasm_global_get(global, &val); \
|
||||
check(val, type, expected); \
|
||||
}
|
||||
|
||||
#define check_call(func, type, expected) \
|
||||
{ \
|
||||
wasm_val_t results[1]; \
|
||||
wasm_func_call(func, NULL, results); \
|
||||
check(results[0], type, expected); \
|
||||
}
|
||||
|
||||
|
||||
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("global.aot", "rb");
|
||||
#else
|
||||
FILE* file = fopen("global.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");
|
||||
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 globals.
|
||||
printf("Creating globals...\n");
|
||||
own wasm_globaltype_t* const_f32_type = wasm_globaltype_new(
|
||||
wasm_valtype_new(WASM_F32), WASM_CONST);
|
||||
own wasm_globaltype_t* const_i64_type = wasm_globaltype_new(
|
||||
wasm_valtype_new(WASM_I64), WASM_CONST);
|
||||
own wasm_globaltype_t* var_f32_type = wasm_globaltype_new(
|
||||
wasm_valtype_new(WASM_F32), WASM_VAR);
|
||||
own wasm_globaltype_t* var_i64_type = wasm_globaltype_new(
|
||||
wasm_valtype_new(WASM_I64), WASM_VAR);
|
||||
|
||||
wasm_val_t val_f32_1 = {.kind = WASM_F32, .of = {.f32 = 1}};
|
||||
own wasm_global_t* const_f32_import =
|
||||
wasm_global_new(store, const_f32_type, &val_f32_1);
|
||||
wasm_val_t val_i64_2 = {.kind = WASM_I64, .of = {.i64 = 2}};
|
||||
own wasm_global_t* const_i64_import =
|
||||
wasm_global_new(store, const_i64_type, &val_i64_2);
|
||||
wasm_val_t val_f32_3 = {.kind = WASM_F32, .of = {.f32 = 3}};
|
||||
own wasm_global_t* var_f32_import =
|
||||
wasm_global_new(store, var_f32_type, &val_f32_3);
|
||||
wasm_val_t val_i64_4 = {.kind = WASM_I64, .of = {.i64 = 4}};
|
||||
own wasm_global_t* var_i64_import =
|
||||
wasm_global_new(store, var_i64_type, &val_i64_4);
|
||||
|
||||
wasm_globaltype_delete(const_f32_type);
|
||||
wasm_globaltype_delete(const_i64_type);
|
||||
wasm_globaltype_delete(var_f32_type);
|
||||
wasm_globaltype_delete(var_i64_type);
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
const wasm_extern_t* imports[] = {
|
||||
wasm_global_as_extern(const_f32_import),
|
||||
wasm_global_as_extern(const_i64_import),
|
||||
wasm_global_as_extern(var_f32_import),
|
||||
wasm_global_as_extern(var_i64_import)
|
||||
};
|
||||
own wasm_instance_t* instance =
|
||||
wasm_instance_new(store, module, imports, NULL);
|
||||
if (!instance) {
|
||||
printf("> Error instantiating module!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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* const_f32_export = get_export_global(&exports, i++);
|
||||
wasm_global_t* const_i64_export = get_export_global(&exports, i++);
|
||||
wasm_global_t* var_f32_export = get_export_global(&exports, i++);
|
||||
wasm_global_t* var_i64_export = get_export_global(&exports, i++);
|
||||
wasm_func_t* get_const_f32_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_const_i64_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_var_f32_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_var_i64_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_const_f32_export = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_const_i64_export = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_var_f32_export = get_export_func(&exports, i++);
|
||||
wasm_func_t* get_var_i64_export = get_export_func(&exports, i++);
|
||||
wasm_func_t* set_var_f32_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* set_var_i64_import = get_export_func(&exports, i++);
|
||||
wasm_func_t* set_var_f32_export = get_export_func(&exports, i++);
|
||||
wasm_func_t* set_var_i64_export = get_export_func(&exports, i++);
|
||||
|
||||
// Try cloning.
|
||||
own wasm_global_t* copy = wasm_global_copy(var_f32_import);
|
||||
assert(wasm_global_same(var_f32_import, copy));
|
||||
wasm_global_delete(copy);
|
||||
|
||||
// Interact.
|
||||
printf("Accessing globals...\n");
|
||||
|
||||
// Check initial values.
|
||||
check_global(const_f32_import, f32, 1);
|
||||
check_global(const_i64_import, i64, 2);
|
||||
check_global(var_f32_import, f32, 3);
|
||||
check_global(var_i64_import, i64, 4);
|
||||
check_global(const_f32_export, f32, 5);
|
||||
check_global(const_i64_export, i64, 6);
|
||||
check_global(var_f32_export, f32, 7);
|
||||
check_global(var_i64_export, i64, 8);
|
||||
|
||||
check_call(get_const_f32_import, f32, 1);
|
||||
check_call(get_const_i64_import, i64, 2);
|
||||
check_call(get_var_f32_import, f32, 3);
|
||||
check_call(get_var_i64_import, i64, 4);
|
||||
check_call(get_const_f32_export, f32, 5);
|
||||
check_call(get_const_i64_export, i64, 6);
|
||||
check_call(get_var_f32_export, f32, 7);
|
||||
check_call(get_var_i64_export, i64, 8);
|
||||
|
||||
// Modify variables through API and check again.
|
||||
wasm_val_t val33 = {.kind = WASM_F32, .of = {.f32 = 33}};
|
||||
wasm_global_set(var_f32_import, &val33);
|
||||
wasm_val_t val34 = {.kind = WASM_I64, .of = {.i64 = 34}};
|
||||
wasm_global_set(var_i64_import, &val34);
|
||||
wasm_val_t val37 = {.kind = WASM_F32, .of = {.f32 = 37}};
|
||||
wasm_global_set(var_f32_export, &val37);
|
||||
wasm_val_t val38 = {.kind = WASM_I64, .of = {.i64 = 38}};
|
||||
wasm_global_set(var_i64_export, &val38);
|
||||
|
||||
check_global(var_f32_import, f32, 33);
|
||||
check_global(var_i64_import, i64, 34);
|
||||
check_global(var_f32_export, f32, 37);
|
||||
check_global(var_i64_export, i64, 38);
|
||||
|
||||
check_call(get_var_f32_import, f32, 33);
|
||||
check_call(get_var_i64_import, i64, 34);
|
||||
check_call(get_var_f32_export, f32, 37);
|
||||
check_call(get_var_i64_export, i64, 38);
|
||||
|
||||
// Modify variables through calls and check again.
|
||||
wasm_val_t args73[] = { {.kind = WASM_F32, .of = {.f32 = 73}} };
|
||||
wasm_func_call(set_var_f32_import, args73, NULL);
|
||||
wasm_val_t args74[] = { {.kind = WASM_I64, .of = {.i64 = 74}} };
|
||||
wasm_func_call(set_var_i64_import, args74, NULL);
|
||||
wasm_val_t args77[] = { {.kind = WASM_F32, .of = {.f32 = 77}} };
|
||||
wasm_func_call(set_var_f32_export, args77, NULL);
|
||||
wasm_val_t args78[] = { {.kind = WASM_I64, .of = {.i64 = 78}} };
|
||||
wasm_func_call(set_var_i64_export, args78, NULL);
|
||||
|
||||
check_global(var_f32_import, f32, 73);
|
||||
check_global(var_i64_import, i64, 74);
|
||||
check_global(var_f32_export, f32, 77);
|
||||
check_global(var_i64_export, i64, 78);
|
||||
|
||||
check_call(get_var_f32_import, f32, 73);
|
||||
check_call(get_var_i64_import, i64, 74);
|
||||
check_call(get_var_f32_export, f32, 77);
|
||||
check_call(get_var_i64_export, i64, 78);
|
||||
|
||||
wasm_global_delete(const_f32_import);
|
||||
wasm_global_delete(const_i64_import);
|
||||
wasm_global_delete(var_f32_import);
|
||||
wasm_global_delete(var_i64_import);
|
||||
wasm_extern_vec_delete(&exports);
|
||||
wasm_instance_delete(instance);
|
||||
|
||||
// Shut down.
|
||||
printf("Shutting down...\n");
|
||||
wasm_store_delete(store);
|
||||
wasm_engine_delete(engine);
|
||||
|
||||
// All done.
|
||||
printf("Done.\n");
|
||||
return 0;
|
||||
}
|
BIN
samples/wasm-c-api/src/global.wasm
Normal file
BIN
samples/wasm-c-api/src/global.wasm
Normal file
Binary file not shown.
27
samples/wasm-c-api/src/global.wat
Normal file
27
samples/wasm-c-api/src/global.wat
Normal file
|
@ -0,0 +1,27 @@
|
|||
(module
|
||||
(global $f32_import (import "" "const f32") f32)
|
||||
(global $i64_import (import "" "const i64") i64)
|
||||
(global $mut_f32_import (import "" "var f32") (mut f32))
|
||||
(global $mut_i64_import (import "" "var i64") (mut i64))
|
||||
|
||||
(global $f32_export (export "const f32") f32 (f32.const 5))
|
||||
(global $i64_export (export "const i64") i64 (i64.const 6))
|
||||
(global $mut_f32_export (export "var f32") (mut f32) (f32.const 7))
|
||||
(global $mut_i64_export (export "var i64") (mut i64) (i64.const 8))
|
||||
|
||||
(func (export "get const f32 import") (result f32) (global.get $f32_import))
|
||||
(func (export "get const i64 import") (result i64) (global.get $i64_import))
|
||||
(func (export "get var f32 import") (result f32) (global.get $mut_f32_import))
|
||||
(func (export "get var i64 import") (result i64) (global.get $mut_i64_import))
|
||||
|
||||
(func (export "get const f32 export") (result f32) (global.get $f32_export))
|
||||
(func (export "get const i64 export") (result i64) (global.get $i64_export))
|
||||
(func (export "get var f32 export") (result f32) (global.get $mut_f32_export))
|
||||
(func (export "get var i64 export") (result i64) (global.get $mut_i64_export))
|
||||
|
||||
(func (export "set var f32 import") (param f32) (global.set $mut_f32_import (local.get 0)))
|
||||
(func (export "set var i64 import") (param i64) (global.set $mut_i64_import (local.get 0)))
|
||||
|
||||
(func (export "set var f32 export") (param f32) (global.set $mut_f32_export (local.get 0)))
|
||||
(func (export "set var f64 export") (param i64) (global.set $mut_i64_export (local.get 0)))
|
||||
)
|
112
samples/wasm-c-api/src/hello.c
Normal file
112
samples/wasm-c-api/src/hello.c
Normal file
|
@ -0,0 +1,112 @@
|
|||
#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* hello_callback(
|
||||
const wasm_val_t args[], wasm_val_t results[]
|
||||
) {
|
||||
printf("Calling back...\n");
|
||||
printf("> Hello World!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
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("hello.aot", "rb");
|
||||
#else
|
||||
FILE* file = fopen("hello.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");
|
||||
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 print functions.
|
||||
printf("Creating callback...\n");
|
||||
own wasm_functype_t* hello_type = wasm_functype_new_0_0();
|
||||
own wasm_func_t* hello_func =
|
||||
wasm_func_new(store, hello_type, hello_callback);
|
||||
|
||||
wasm_functype_delete(hello_type);
|
||||
|
||||
// Instantiate.
|
||||
printf("Instantiating module...\n");
|
||||
const wasm_extern_t* imports[] = { wasm_func_as_extern(hello_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(hello_func);
|
||||
|
||||
// Extract export.
|
||||
printf("Extracting export...\n");
|
||||
own wasm_extern_vec_t exports;
|
||||
wasm_instance_exports(instance, &exports);
|
||||
if (exports.size == 0) {
|
||||
printf("> Error accessing exports!\n");
|
||||
return 1;
|
||||
}
|
||||
const wasm_func_t* run_func = wasm_extern_as_func(exports.data[0]);
|
||||
if (run_func == NULL) {
|
||||
printf("> Error accessing export!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
wasm_module_delete(module);
|
||||
wasm_instance_delete(instance);
|
||||
|
||||
// Call.
|
||||
printf("Calling export...\n");
|
||||
if (wasm_func_call(run_func, NULL, NULL)) {
|
||||
printf("> Error calling function!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
BIN
samples/wasm-c-api/src/hello.wasm
Normal file
BIN
samples/wasm-c-api/src/hello.wasm
Normal file
Binary file not shown.
4
samples/wasm-c-api/src/hello.wat
Normal file
4
samples/wasm-c-api/src/hello.wat
Normal file
|
@ -0,0 +1,4 @@
|
|||
(module
|
||||
(func $hello (import "" "hello"))
|
||||
(func (export "run") (call $hello))
|
||||
)
|
Loading…
Reference in New Issue
Block a user