WebAssembly Micro Runtime first version

This commit is contained in:
Wang Xin
2019-05-07 10:18:18 +08:00
parent 15aa50914b
commit a75a5f0f41
252 changed files with 33487 additions and 0 deletions

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _EXT_LIB_EXPORT_H_
#define _EXT_LIB_EXPORT_H_
#include "lib-export.h"
#ifdef __cplusplus
extern "C" {
#endif
int
get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis)
{
*p_ext_lib_apis = extended_native_symbol_defs;
return sizeof(extended_native_symbol_defs) / sizeof(NativeSymbol);
}
#ifdef __cplusplus
}
#endif
#endif /* end of _EXT_LIB_EXPORT_H_ */

View File

@ -0,0 +1,57 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _LIB_EXPORT_H_
#define _LIB_EXPORT_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef struct NativeSymbol {
const char *symbol;
void *func_ptr;
} NativeSymbol;
#define EXPORT_WASM_API(symbol) {#symbol, symbol}
#define EXPORT_WASM_API2(symbol) {#symbol, symbol##_wrapper}
/**
* Get the exported APIs of base lib
*
* @param p_base_lib_apis return the exported API array of base lib
*
* @return the number of the exported API
*/
int
get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
/**
* Get the exported APIs of extend lib
*
* @param p_base_lib_apis return the exported API array of extend lib
*
* @return the number of the exported API
*/
int
get_extend_lib_export_apis(NativeSymbol **p_base_lib_apis);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,421 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_EXPORT_H
#define _WASM_EXPORT_H
#include <inttypes.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Uninstantiated WASM module loaded from WASM binary file */
struct WASMModule;
typedef struct WASMModule *wasm_module_t;
/* Instantiated WASM module */
struct WASMModuleInstance;
typedef struct WASMModuleInstance *wasm_module_inst_t;
/* Function instance */
struct WASMFunctionInstance;
typedef struct WASMFunctionInstance *wasm_function_inst_t;
/* WASM section */
typedef struct wasm_section {
struct wasm_section *next;
/* section type */
int section_type;
/* section body, not include type and size */
uint8_t *section_body;
/* section body size */
uint32_t section_body_size;
} wasm_section_t, *wasm_section_list_t;
/* Execution environment, e.g. stack info */
typedef struct WASMExecEnv {
uint8_t *stack;
uint32_t stack_size;
} *wasm_exec_env_t;
/* Package Type */
typedef enum {
Wasm_Module_Bytecode = 0,
Wasm_Module_AoT,
Package_Type_Unknown = 0xFFFF
} package_type_t;
/**
* Initialize the WASM runtime environment.
*
* @return true if success, false otherwise
*/
bool
wasm_runtime_init();
/**
* Destroy the WASM runtime environment.
*/
void
wasm_runtime_destroy();
/**
* Get the package type of a buffer.
*
* @param buf the package buffer
* @param size the package buffer size
*
* @return the package type, return Package_Type_Unknown if the type is unknown
*/
package_type_t
get_package_type(const uint8_t *buf, uint32_t size);
/**
* Load a WASM module from a specified byte buffer.
*
* @param buf the byte buffer which contains the WASM binary data
* @param size the size of the buffer
* @param error_buf output of the exception info
* @param error_buf_size the size of the exception string
*
* @return return WASM module loaded, NULL if failed
*/
wasm_module_t
wasm_runtime_load(const uint8_t *buf, uint32_t size,
char *error_buf, uint32_t error_buf_size);
/**
* Load a WASM module from a specified WASM section list.
*
* @param section_list the section list which contains each section data
* @param error_buf output of the exception info
* @param error_buf_size the size of the exception string
*
* @return return WASM module loaded, NULL if failed
*/
wasm_module_t
wasm_runtime_load_from_sections(wasm_section_list_t section_list,
char *error_buf, uint32_t error_buf_size);
/**
* Unload a WASM module.
*
* @param module the module to be unloaded
*/
void
wasm_runtime_unload(wasm_module_t module);
/**
* Instantiate a WASM module.
*
* @param module the WASM module to instantiate
* @param stack_size the default stack size of the module instance, a stack
* will be created when function wasm_runtime_call_wasm() is called
* to run WASM function and the exec_env argument passed to
* wasm_runtime_call_wasm() is NULL. That means this parameter is
* ignored if exec_env is not NULL.
* @param heap_size the default heap size of the module instance, a heap will
* be created besides the app memory space. Both wasm app and native
* function can allocate memory from the heap. If heap_size is 0, the
* default heap size will be used.
* @param error_buf buffer to output the error info if failed
* @param error_buf_size the size of the error buffer
*
* @return return the instantiated WASM module instance, NULL if failed
*/
wasm_module_inst_t
wasm_runtime_instantiate(const wasm_module_t module,
uint32_t stack_size, uint32_t heap_size,
char *error_buf, uint32_t error_buf_size);
/**
* Deinstantiate a WASM module instance, destroy the resources.
*
* @param module_inst the WASM module instance to destroy
*/
void
wasm_runtime_deinstantiate(wasm_module_inst_t module_inst);
/**
* Load WASM module instance from AOT file.
*
* @param aot_file the AOT file of a WASM module
* @param aot_file_size the AOT file size
* @param heap_size the default heap size of the module instance, a heap will
* be created besides the app memory space. Both wasm app and native
* function can allocate memory from the heap. If heap_size is 0, the
* default heap size will be used.
* @param error_buf buffer to output the error info if failed
* @param error_buf_size the size of the error buffer
*
* @return the instantiated WASM module instance, NULL if failed
*/
wasm_module_inst_t
wasm_runtime_load_aot(uint8_t *aot_file, uint32_t aot_file_size,
uint32_t heap_size,
char *error_buf, uint32_t error_buf_size);
/**
* Lookup an exported function in the WASM module instance.
*
* @param module_inst the module instance
* @param name the name of the function
* @param signature the signature of the function, use "i32"/"i64"/"f32"/"f64"
* to represent the type of i32/i64/f32/f64, e.g. "(i32i64)" "(i32)f32"
*
* @return the function instance found, if the module instance is loaded from
* the AOT file, the return value is the function pointer
*/
wasm_function_inst_t
wasm_runtime_lookup_function(const wasm_module_inst_t module_inst,
const char *name, const char *signature);
/**
* Create execution environment.
*
* @param stack_size the stack size to execute a WASM function
*
* @return the execution environment
*/
wasm_exec_env_t
wasm_runtime_create_exec_env(uint32_t stack_size);
/**
* Destroy the execution environment.
*
* @param env the execution environment to destroy
*/
void
wasm_runtime_destory_exec_env(wasm_exec_env_t env);
/**
* Call the given WASM function of a WASM module instance with
* arguments (bytecode and AoT).
*
* @param module_inst the WASM module instance which the function belongs to
* @param exec_env the execution environment to call the function. If the module
* instance is created by AoT mode, it is ignored and just set it to NULL.
* If the module instance is created by bytecode mode and it is NULL,
* a temporary env object will be created
* @param function the function to be called
* @param argc the number of arguments
* @param argv the arguments. If the function method has return value,
* the first (or first two in case 64-bit return value) element of
* argv stores the return value of the called WASM function after this
* function returns.
*
* @return true if success, false otherwise and exception will be thrown,
* the caller can call wasm_runtime_get_exception to get exception info.
*/
bool
wasm_runtime_call_wasm(wasm_module_inst_t module_inst,
wasm_exec_env_t exec_env,
wasm_function_inst_t function,
uint32_t argc, uint32_t argv[]);
/**
* Get exception info of the WASM module instance.
*
* @param module_inst the WASM module instance
*
* @return the exception string
*/
const char*
wasm_runtime_get_exception(wasm_module_inst_t module_inst);
/**
* Clear exception info of the WASM module instance.
*
* @param module_inst the WASM module instance
*/
void
wasm_runtime_clear_exception(wasm_module_inst_t module_inst);
/**
* Attach the current native thread to a WASM module instance.
* A native thread cannot be attached simultaneously to two WASM module
* instances. The WASM module instance will be attached to the native
* thread which it is instantiated in by default.
*
* @param module_inst the WASM module instance to attach
* @param thread_data the thread data that current native thread requires
* the WASM module instance to store
*
* @return true if SUCCESS, false otherwise
*/
bool
wasm_runtime_attach_current_thread(wasm_module_inst_t module_inst,
void *thread_data);
/**
* Detach the current native thread from a WASM module instance.
*
* @param module_inst the WASM module instance to detach
*/
void
wasm_runtime_detach_current_thread(wasm_module_inst_t module_inst);
/**
* Get the thread data that the current native thread requires the WASM
* module instance to store when attaching.
*
* @return the thread data stored when attaching
*/
void*
wasm_runtime_get_current_thread_data();
/**
* Get current WASM module instance of the current native thread
*
* @return current WASM module instance of the current native thread, NULL
* if not found
*/
wasm_module_inst_t
wasm_runtime_get_current_module_inst();
/**
* Allocate memory from the heap of WASM module instance
*
* @param module_inst the WASM module instance which contains heap
* @param size the size bytes to allocate
*
* @return the allocated memory address, which is a relative offset to the
* base address of the module instance's memory space, the value range
* is (-heap_size, 0). Note that it is not an absolute address.
* Return non-zero if success, zero if failed.
*/
int32_t
wasm_runtime_module_malloc(wasm_module_inst_t module_inst, uint32_t size);
/**
* Free memory to the heap of WASM module instance
*
* @param module_inst the WASM module instance which contains heap
* @param ptr the pointer to free
*/
void
wasm_runtime_module_free(wasm_module_inst_t module_inst, int32_t ptr);
/**
* Allocate memory from the heap of WASM module instance and initialize
* the memory with src
*
* @param module_inst the WASM module instance which contains heap
* @param src the source data to copy
* @param size the size of the source data
*
* @return the allocated memory address, which is a relative offset to the
* base address of the module instance's memory space, the value range
* is (-heap_size, 0). Note that it is not an absolute address.
* Return non-zero if success, zero if failed.
*/
int32_t
wasm_runtime_module_dup_data(wasm_module_inst_t module_inst,
const char *src, uint32_t size);
/**
* Validate the app address, check whether it belongs to WASM module
* instance's address space, or in its heap space or memory space.
*
* @param module_inst the WASM module instance
* @param app_offset the app address to validate, which is a relative address
* @param size the size bytes of the app address
*
* @return true if success, false otherwise. If failed, an exception will
* be thrown.
*/
bool
wasm_runtime_validate_app_addr(wasm_module_inst_t module_inst,
int32_t app_offset, uint32_t size);
/**
* Validate the native address, check whether it belongs to WASM module
* instance's address space, or in its heap space or memory space.
*
* @param module_inst the WASM module instance
* @param native_ptr the native address to validate, which is an absolute
* address
* @param size the size bytes of the app address
*
* @return true if success, false otherwise. If failed, an exception will
* be thrown.
*/
bool
wasm_runtime_validate_native_addr(wasm_module_inst_t module_inst,
void *native_ptr, uint32_t size);
/**
* Convert app address(relative address) to native address(absolute address)
*
* @param module_inst the WASM module instance
* @param app_offset the app adress
*
* @return the native address converted
*/
void *
wasm_runtime_addr_app_to_native(wasm_module_inst_t module_inst,
int32_t app_offset);
/**
* Convert native address(absolute address) to app address(relative address)
*
* @param module_inst the WASM module instance
* @param native_ptr the native address
*
* @return the app address converted
*/
int32_t
wasm_runtime_addr_native_to_app(wasm_module_inst_t module_inst,
void *native_ptr);
/**
* Find the unique main function from a WASM module instance
* and execute that function.
*
* @param module_inst the WASM module instance
* @param argc the number of arguments
* @param argv the arguments array
*
* @return true if the main function is called, false otherwise.
*/
bool
wasm_application_execute_main(wasm_module_inst_t module_inst,
int argc, char *argv[]);
/**
* Find the specified function in argv[0] from WASM module of current instance
* and execute that function.
*
* @param module_inst the WASM module instance
* @param name the name of the function to execute
* @param argc the number of arguments
* @param argv the arguments array
*
* @return true if the specified function is called, false otherwise.
*/
bool
wasm_application_execute_func(wasm_module_inst_t module_inst,
const char *name, int argc, char *argv[]);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_EXPORT_H */

View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WASM_HASHMAP_H
#define WASM_HASHMAP_H
#include "wasm_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Maximum initial size of hash map */
#define HASH_MAP_MAX_SIZE 65536
struct HashMap;
typedef struct HashMap HashMap;
/* Hash function: to get the hash value of key. */
typedef uint32 (*HashFunc)(const void *key);
/* Key equal function: to check whether two keys are equal. */
typedef bool (*KeyEqualFunc)(void *key1, void *key2);
/* Key destroy function: to destroy the key, auto called
when an hash element is removed. */
typedef void (*KeyDestroyFunc)(void *key);
/* Value destroy function: to destroy the value, auto called
when an hash element is removed. */
typedef void (*ValueDestroyFunc)(void *key);
/**
* Create a hash map.
*
* @param size: the initial size of the hash map
* @param use_lock whether to lock the hash map when operating on it
* @param hash_func hash function of the key, must be specified
* @param key_equal_func key equal function, check whether two keys
* are equal, must be specified
* @param key_destroy_func key destroy function, called when an hash element
* is removed if it is not NULL
* @param value_destroy_func value destroy function, called when an hash
* element is removed if it is not NULL
*
* @return the hash map created, NULL if failed
*/
HashMap*
wasm_hash_map_create(uint32 size, bool use_lock,
HashFunc hash_func,
KeyEqualFunc key_equal_func,
KeyDestroyFunc key_destroy_func,
ValueDestroyFunc value_destroy_func);
/**
* Insert an element to the hash map
*
* @param map the hash map to insert element
* @key the key of the element
* @value the value of the element
*
* @return true if success, false otherwise
* Note: fail if key is NULL or duplicated key exists in the hash map,
*/
bool
wasm_hash_map_insert(HashMap *map, void *key, void *value);
/**
* Find an element in the hash map
*
* @param map the hash map to find element
* @key the key of the element
*
* @return the value of the found element if success, NULL otherwise
*/
void*
wasm_hash_map_find(HashMap *map, void *key);
/**
* Update an element in the hash map with new value
*
* @param map the hash map to update element
* @key the key of the element
* @value the new value of the element
* @p_old_value if not NULL, copies the old value to it
*
* @return true if success, false otherwise
* Note: the old value won't be destroyed by value destory function,
* it will be copied to p_old_value for user to process.
*/
bool
wasm_hash_map_update(HashMap *map, void *key, void *value,
void **p_old_value);
/**
* Remove an element from the hash map
*
* @param map the hash map to remove element
* @key the key of the element
* @p_old_key if not NULL, copies the old key to it
* @p_old_value if not NULL, copies the old value to it
*
* @return true if success, false otherwise
* Note: the old key and old value won't be destroyed by key destroy
* function and value destroy function, they will be copied to
* p_old_key and p_old_value for user to process.
*/
bool
wasm_hash_map_remove(HashMap *map, void *key,
void **p_old_key, void **p_old_value);
/**
* Destroy the hashmap
*
* @param map the hash map to destroy
*
* @return true if success, false otherwise
* Note: the key destroy function and value destroy function will be
* called to destroy each element's key and value if they are
* not NULL.
*/
bool
wasm_hash_map_destroy(HashMap *map);
#ifdef __cplusplus
}
#endif
#endif /* endof WASM_HASHMAP_H */

View File

@ -0,0 +1,94 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @brief This log system supports wrapping multiple outputs into one
* log message. This is useful for outputting variable-length logs
* without additional memory overhead (the buffer for concatenating
* the message), e.g. exception stack trace, which cannot be printed
* by a single log calling without the help of an additional buffer.
* Avoiding additional memory buffer is useful for resource-constraint
* systems. It can minimize the impact of log system on applications
* and logs can be printed even when no enough memory is available.
* Functions with prefix "_" are private functions. Only macros that
* are not start with "_" are exposed and can be used.
*/
#ifndef _WASM_LOG_H
#define _WASM_LOG_H
#include "wasm_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* The following functions are the primitive operations of this log system.
* A normal usage of the log system is to call wasm_log_begin and then call
* wasm_log_printf or wasm_log_vprintf one or multiple times and then call
* wasm_log_end to wrap (mark) the previous outputs into one log message.
* The wasm_log and macros LOG_ERROR etc. can be used to output log messages
* by one log calling.
*/
int _wasm_log_init (void);
void _wasm_log_set_verbose_level (int level);
bool _wasm_log_begin (int level);
void _wasm_log_printf (const char *fmt, ...);
void _wasm_log_vprintf (const char *fmt, va_list ap);
void _wasm_log_end (void);
void _wasm_log (int level, const char *file, int line,
const char *fmt, ...);
#if WASM_ENABLE_LOG != 0
# define wasm_log_init() _wasm_log_init ()
# define wasm_log_set_verbose_level(l) _wasm_log_set_verbose_level (l)
# define wasm_log_begin(l) _wasm_log_begin (l)
# define wasm_log_printf(...) _wasm_log_printf (__VA_ARGS__)
# define wasm_log_vprintf(...) _wasm_log_vprintf (__VA_ARGS__)
# define wasm_log_end() _wasm_log_end ()
# define wasm_log(...) _wasm_log (__VA_ARGS__)
#else /* WASM_ENABLE_LOG != 0 */
# define wasm_log_init() 0
# define wasm_log_set_verbose_level(l) (void)0
# define wasm_log_begin() false
# define wasm_log_printf(...) (void)0
# define wasm_log_vprintf(...) (void)0
# define wasm_log_end() (void)0
# define wasm_log(...) (void)0
#endif /* WASM_ENABLE_LOG != 0 */
#define LOG_ERROR(...) wasm_log (0, NULL, 0, __VA_ARGS__)
#define LOG_WARNING(...) wasm_log (1, NULL, 0, __VA_ARGS__)
#define LOG_VERBOSE(...) wasm_log (2, NULL, 0, __VA_ARGS__)
#if defined(WASM_DEBUG)
# define LOG_DEBUG(...) _wasm_log (1, __FILE__, __LINE__, __VA_ARGS__)
#else /* defined(WASM_DEBUG) */
# define LOG_DEBUG(...) (void)0
#endif /* defined(WASM_DEBUG) */
#define LOG_PROFILE_HEAP_GC(heap, size) \
LOG_VERBOSE("PROF.HEAP.GC: HEAP=%08X SIZE=%d", heap, size)
#ifdef __cplusplus
}
#endif
#endif /* _WASM_LOG_H */

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_VECTOR_H
#define _WASM_VECTOR_H
#include "wasm_platform.h"
#ifdef __cplusplus
extern "C" {
#endif
#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;
/* vector data allocated */
uint8 *data;
} Vector;
/**
* Initialize vector
*
* @param vector the vector to init
* @param init_length the initial length of the vector
* @param size_elem size of each element
*
* @return true if success, false otherwise
*/
bool
wasm_vector_init(Vector *vector, uint32 init_length, uint32 size_elem);
/**
* Set element of vector
*
* @param vector the vector to set
* @param index the index of the element to set
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
wasm_vector_set(Vector *vector, uint32 index, const void *elem_buf);
/**
* Get element of vector
*
* @param vector the vector to get
* @param index the index of the element to get
* @param elem_buf the element buffer to store the element data,
* whose length must be no less than element size
*
* @return true if success, false otherwise
*/
bool
wasm_vector_get(const Vector *vector, uint32 index, void *elem_buf);
/**
* Insert element of vector
*
* @param vector the vector to insert
* @param index the index of the element to insert
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
wasm_vector_insert(Vector *vector, uint32 index, const void *elem_buf);
/**
* Append element to the end of vector
*
* @param vector the vector to append
* @param elem_buf the element buffer which stores the element data
*
* @return true if success, false otherwise
*/
bool
wasm_vector_append(Vector *vector, const void *elem_buf);
/**
* Remove element from vector
*
* @param vector the vector to remove element
* @param index the index of the element to remove
* @param old_elem_buf if not NULL, copies the element data to the buffer
*
* @return true if success, false otherwise
*/
bool
wasm_vector_remove(Vector *vector, uint32 index, void *old_elem_buf);
/**
* Return the size of the vector
*
* @param vector the vector to get size
*
* @return return the size of the vector
*/
uint32
wasm_vector_size(const Vector *vector);
/**
* Destroy the vector
*
* @param vector the vector to destroy
*
* @return true if success, false otherwise
*/
bool
wasm_vector_destroy(Vector *vector);
#ifdef __cplusplus
}
#endif
#endif /* endof _WASM_VECTOR_H */

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_ASSERT_H
#define _WASM_ASSERT_H
#include "bh_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
#define wasm_assert bh_assert
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_ASSERT_H */

View File

@ -0,0 +1,23 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_CONFIG_H
#define _WASM_CONFIG_H
#include "config.h"
#endif /* end of _WASM_CONFIG_H */

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_MEMORY_H
#define _WASM_MEMORY_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_memory.h"
#define wasm_malloc bh_malloc
#define wasm_free bh_free
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_MEMORY_H */

View File

@ -0,0 +1,24 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_PLATFORM_LOG
#define _WASM_PLATFORM_LOG
#define wasm_printf printf
#define wasm_vprintf vprintf
#endif /* _WASM_PLATFORM_LOG */

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @file wasm_thread.h
* @brief This file contains Beihai platform abstract layer interface for
* thread relative function.
*/
#ifndef _WASM_THREAD_H
#define _WASM_THREAD_H
#ifdef __cplusplus
extern "C" {
#endif
#include "bh_thread.h"
#define ws_thread_sys_init vm_thread_sys_init
#define ws_thread_sys_destroy vm_thread_sys_destroy
#define ws_self_thread vm_self_thread
#define ws_tls_put(ptr) vm_tls_put(0, ptr)
#define ws_tls_get() vm_tls_get(0)
static inline int
ws_mutex_init(korp_mutex *mutex, bool is_recursive)
{
if (is_recursive)
return vm_recursive_mutex_init(mutex);
else
return vm_mutex_init(mutex);
}
#define ws_mutex_destroy vm_mutex_destroy
#define ws_mutex_lock vm_mutex_lock
#define ws_mutex_unlock vm_mutex_unlock
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_THREAD_H */

View File

@ -0,0 +1,38 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_TYPES_H
#define _WASM_TYPES_H
#include "wasm_config.h"
typedef unsigned char uint8;
typedef char int8;
typedef unsigned short uint16;
typedef short int16;
typedef unsigned int uint32;
typedef int int32;
#include "wasm_platform.h"
#ifndef __cplusplus
#define true 1
#define false 0
#define inline __inline
#endif
#endif /* end of _WASM_TYPES_H */

View File

@ -0,0 +1,25 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L)
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${PLATFORM_LIB_DIR})
include_directories(${PLATFORM_LIB_DIR}/../include)
file (GLOB_RECURSE source_all ${PLATFORM_LIB_DIR}/*.c)
set (WASM_PLATFORM_LIB_SOURCE ${source_all})

View File

@ -0,0 +1,333 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _GNU_SOURCE
#define _GNU_SOURCE /* for O_DIRECT */
#endif
#include "wasm-native.h"
#include "wasm-runtime.h"
#include "wasm_log.h"
#include "wasm_memory.h"
#include "wasm_platform_log.h"
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <fcntl.h>
#include <errno.h>
#define get_module_inst() \
wasm_runtime_get_current_module_inst()
#define validate_app_addr(offset, size) \
wasm_runtime_validate_app_addr(module_inst, offset, size)
#define addr_app_to_native(offset) \
wasm_runtime_addr_app_to_native(module_inst, offset)
#define addr_native_to_app(ptr) \
wasm_runtime_addr_native_to_app(module_inst, ptr)
#define module_malloc(size) \
wasm_runtime_module_malloc(module_inst, size)
#define module_free(offset) \
wasm_runtime_module_free(module_inst, offset)
static int32
__syscall0_wrapper(int32 arg0)
{
switch (arg0) {
case 199: /* getuid */
/* TODO */
default:
printf("##_syscall0 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall1_wrapper(int32 arg0, int32 arg1)
{
switch (arg0) {
case 6: /* close */
/* TODO */
default:
printf("##_syscall1 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall2_wrapper(int32 arg0, int32 arg1, int32 arg2)
{
switch (arg0) {
case 183: /* getcwd */
/* TODO */
default:
printf("##_syscall2 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall3_wrapper(int32 arg0, int32 arg1, int32 arg2, int32 arg3)
{
WASMModuleInstance *module_inst = get_module_inst();
switch (arg0) {
case 54: /* ioctl */
{
/* Implement syscall 54 and syscall 146 to support printf()
for non SIDE_MODULE=1 mode */
struct winsize *wsz;
if (!validate_app_addr(arg3, sizeof(struct winsize)))
return 0;
wsz = (struct winsize*)addr_app_to_native(arg3);
return syscall(54, arg1, arg2, wsz);
}
case 145: /* readv */
case 146: /* writev */
{
/* Implement syscall 54 and syscall 146 to support printf()
for non SIDE_MODULE=1 mode */
uint32 iovcnt = arg3, i;
struct iovec *vec_begin, *vec;
if (!validate_app_addr(arg2, sizeof(struct iovec)))
return 0;
vec_begin = vec = (struct iovec*)addr_app_to_native(arg2);
for (i = 0; i < iovcnt; i++, vec++) {
if (vec->iov_len > 0) {
if (!validate_app_addr((int32)vec->iov_base, 1))
return 0;
vec->iov_base = addr_app_to_native((int32)vec->iov_base);
}
}
if (arg0 == 145)
return syscall(145, arg1, vec_begin, arg3);
else
return syscall(146, arg1, vec_begin, arg3);
}
case 3: /* read*/
case 5: /* open */
case 221: /* fcntl */
/* TODO */
default:
printf("##_syscall3 called, syscall id: %d\n", arg0);
}
return 0;
}
static int32
__syscall4_wrapper(int32 arg0, int32 arg1, int32 arg2,
int32 arg3, int32 arg4)
{
printf("##_syscall4 called, syscall id: %d\n", arg0);
return 0;
}
static int32
__syscall5_wrapper(int32 arg0, int32 arg1, int32 arg2,
int32 arg3, int32 arg4, int32 arg5)
{
switch (arg0) {
case 140: /* llseek */
/* TODO */
default:
printf("##_syscall5 called, args[0]: %d\n", arg0);
}
return 0;
}
#define GET_EMCC_SYSCALL_ARGS() \
WASMModuleInstance *module_inst = get_module_inst(); \
int32 *args; \
if (!validate_app_addr(args_off, 1)) \
return 0; \
args = addr_app_to_native(args_off) \
#define EMCC_SYSCALL_WRAPPER0(id) \
static int32 ___syscall##id##_wrapper(int32 _id) { \
return __syscall0_wrapper(id); \
}
#define EMCC_SYSCALL_WRAPPER1(id) \
static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
GET_EMCC_SYSCALL_ARGS(); \
return __syscall1_wrapper(id, args[0]); \
}
#define EMCC_SYSCALL_WRAPPER2(id) \
static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
GET_EMCC_SYSCALL_ARGS(); \
return __syscall2_wrapper(id, args[0], args[1]); \
}
#define EMCC_SYSCALL_WRAPPER3(id) \
static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
GET_EMCC_SYSCALL_ARGS(); \
return __syscall3_wrapper(id, args[0], args[1], args[2]); \
}
#define EMCC_SYSCALL_WRAPPER4(id) \
static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
GET_EMCC_SYSCALL_ARGS(); \
return __syscall4_wrapper(id, args[0], args[1], args[2], args[3]);\
}
#define EMCC_SYSCALL_WRAPPER5(id) \
static int32 ___syscall##id##_wrapper(int32 _id, int32 args_off) {\
GET_EMCC_SYSCALL_ARGS(); \
return __syscall5_wrapper(id, args[0], args[1], args[2], \
args[3], args[4]); \
}
EMCC_SYSCALL_WRAPPER0(199)
EMCC_SYSCALL_WRAPPER1(6)
EMCC_SYSCALL_WRAPPER2(183)
EMCC_SYSCALL_WRAPPER3(3)
EMCC_SYSCALL_WRAPPER3(5)
EMCC_SYSCALL_WRAPPER3(54)
EMCC_SYSCALL_WRAPPER3(145)
EMCC_SYSCALL_WRAPPER3(146)
EMCC_SYSCALL_WRAPPER3(221)
EMCC_SYSCALL_WRAPPER5(140)
static int32
getTotalMemory_wrapper()
{
WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
WASMMemoryInstance *memory = module_inst->default_memory;
return NumBytesPerPage * memory->cur_page_count;
}
static int32
enlargeMemory_wrapper()
{
bool ret;
WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
WASMMemoryInstance *memory = module_inst->default_memory;
uint32 DYNAMICTOP_PTR_offset = module_inst->DYNAMICTOP_PTR_offset;
uint32 addr_data_offset = *(uint32*)(memory->global_data + DYNAMICTOP_PTR_offset);
uint32 *DYNAMICTOP_PTR = (uint32*)(memory->memory_data + addr_data_offset);
uint32 memory_size_expected = *DYNAMICTOP_PTR;
uint32 total_page_count = (memory_size_expected + NumBytesPerPage - 1) / NumBytesPerPage;
if (total_page_count < memory->cur_page_count) {
return 1;
}
else {
ret = wasm_runtime_enlarge_memory(module_inst, total_page_count -
memory->cur_page_count);
return ret ? 1 : 0;
}
}
static void
_abort_wrapper(int32 code)
{
WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
char buf[32];
snprintf(buf, sizeof(buf), "env.abort(%i)", code);
wasm_runtime_set_exception(module_inst, buf);
}
static void
abortOnCannotGrowMemory_wrapper()
{
WASMModuleInstance *module_inst = wasm_runtime_get_current_module_inst();
wasm_runtime_set_exception(module_inst, "abort on cannot grow memory");
}
static void
___setErrNo_wrapper(int32 error_no)
{
errno = error_no;
}
/* TODO: add function parameter/result types check */
#define REG_NATIVE_FUNC(module_name, func_name) \
{#module_name, #func_name, func_name##_wrapper}
typedef struct WASMNativeFuncDef {
const char *module_name;
const char *func_name;
void *func_ptr;
} WASMNativeFuncDef;
static WASMNativeFuncDef native_func_defs[] = {
REG_NATIVE_FUNC(env, __syscall0),
REG_NATIVE_FUNC(env, __syscall1),
REG_NATIVE_FUNC(env, __syscall2),
REG_NATIVE_FUNC(env, __syscall3),
REG_NATIVE_FUNC(env, __syscall4),
REG_NATIVE_FUNC(env, __syscall5),
REG_NATIVE_FUNC(env, ___syscall3),
REG_NATIVE_FUNC(env, ___syscall5),
REG_NATIVE_FUNC(env, ___syscall6),
REG_NATIVE_FUNC(env, ___syscall54),
REG_NATIVE_FUNC(env, ___syscall140),
REG_NATIVE_FUNC(env, ___syscall145),
REG_NATIVE_FUNC(env, ___syscall146),
REG_NATIVE_FUNC(env, ___syscall183),
REG_NATIVE_FUNC(env, ___syscall199),
REG_NATIVE_FUNC(env, ___syscall221),
REG_NATIVE_FUNC(env, _abort),
REG_NATIVE_FUNC(env, abortOnCannotGrowMemory),
REG_NATIVE_FUNC(env, enlargeMemory),
REG_NATIVE_FUNC(env, getTotalMemory),
REG_NATIVE_FUNC(env, ___setErrNo),
};
void*
wasm_platform_native_func_lookup(const char *module_name,
const char *func_name)
{
uint32 size = sizeof(native_func_defs) / sizeof(WASMNativeFuncDef);
WASMNativeFuncDef *func_def = native_func_defs;
WASMNativeFuncDef *func_def_end = func_def + size;
if (!module_name || !func_name)
return NULL;
while (func_def < func_def_end) {
if (!strcmp(func_def->module_name, module_name)
&& !strcmp(func_def->func_name, func_name))
return (void*)(uintptr_t)func_def->func_ptr;
func_def++;
}
return NULL;
}

View File

@ -0,0 +1,96 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_log.h"
#include "wasm_platform.h"
#include "wasm_memory.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <dlfcn.h>
bool is_little_endian = false;
bool __is_little_endian()
{
union w
{
int a;
char b;
}c;
c.a = 1;
return (c.b == 1);
}
int
wasm_platform_init()
{
if (__is_little_endian())
is_little_endian = true;
return 0;
}
char*
wasm_read_file_to_buffer(const char *filename, int *ret_size)
{
char *buffer;
int file;
int file_size, read_size;
struct stat stat_buf;
if (!filename || !ret_size) {
LOG_ERROR("Read file to buffer failed: invalid filename or ret size.\n");
return NULL;
}
if ((file = open(filename, O_RDONLY, 0)) == -1) {
LOG_ERROR("Read file to buffer failed: open file %s failed.\n",
filename);
return NULL;
}
if (fstat(file, &stat_buf) != 0) {
LOG_ERROR("Read file to buffer failed: fstat file %s failed.\n",
filename);
close(file);
return NULL;
}
file_size = stat_buf.st_size;
if (!(buffer = wasm_malloc(file_size))) {
LOG_ERROR("Read file to buffer failed: alloc memory failed.\n");
close(file);
return NULL;
}
read_size = read(file, buffer, file_size);
close(file);
if (read_size < file_size) {
LOG_ERROR("Read file to buffer failed: read file content failed.\n");
wasm_free(buffer);
return NULL;
}
*ret_size = file_size;
return buffer;
}

View File

@ -0,0 +1,104 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_PLATFORM_H
#define _WASM_PLATFORM_H
#include "wasm_config.h"
#include "wasm_types.h"
#include <inttypes.h>
#include <stdbool.h>
typedef uint64_t uint64;
typedef int64_t int64;
typedef float float32;
typedef double float64;
#ifndef NULL
# define NULL ((void*) 0)
#endif
#define WASM_PLATFORM "Linux"
#include <stdarg.h>
#include <ctype.h>
#include <pthread.h>
#include <limits.h>
#include <semaphore.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
typedef pthread_t korp_tid;
typedef pthread_mutex_t korp_mutex;
int wasm_platform_init();
extern bool is_little_endian;
#include <string.h>
/* The following operations declared in string.h may be defined as
macros on Linux, so don't declare them as functions here. */
/* memset */
/* memcpy */
/* memmove */
/* #include <stdio.h> */
/* Unit test framework is based on C++, where the declaration of
snprintf is different. */
#ifndef __cplusplus
int snprintf(char *buffer, size_t count, const char *format, ...);
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* #include <math.h> */
#ifndef __cplusplus
double sqrt(double x);
#endif
#include <stdio.h>
extern int fopen_s(FILE ** pFile, const char *filename, const char *mode);
char*
wasm_read_file_to_buffer(const char *filename, int *ret_size);
void*
wasm_dlsym(void *handle, const char *symbol);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,126 @@
# $FreeBSD$
# @(#)COPYRIGHT 8.2 (Berkeley) 3/21/94
The compilation of software known as FreeBSD is distributed under the
following terms:
Copyright (c) 1992-2019 The FreeBSD Project.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
The 4.4BSD and 4.4BSD-Lite software is distributed under the following
terms:
All of the documentation and software included in the 4.4BSD and 4.4BSD-Lite
Releases is copyrighted by The Regents of the University of California.
Copyright 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
The Regents of the University of California. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. All advertising materials mentioning features or use of this software
must display the following acknowledgement:
This product includes software developed by the University of
California, Berkeley and its contributors.
4. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
The Institute of Electrical and Electronics Engineers and the American
National Standards Committee X3, on Information Processing Systems have
given us permission to reprint portions of their documentation.
In the following statement, the phrase ``this text'' refers to portions
of the system documentation.
Portions of this text are reprinted and reproduced in electronic form in
the second BSD Networking Software Release, from IEEE Std 1003.1-1988, IEEE
Standard Portable Operating System Interface for Computer Environments
(POSIX), copyright C 1988 by the Institute of Electrical and Electronics
Engineers, Inc. In the event of any discrepancy between these versions
and the original IEEE Standard, the original IEEE Standard is the referee
document.
In the following statement, the phrase ``This material'' refers to portions
of the system documentation.
This material is reproduced with permission from American National
Standards Committee X3, on Information Processing Systems. Computer and
Business Equipment Manufacturers Association (CBEMA), 311 First St., NW,
Suite 500, Washington, DC 20001-2178. The developmental work of
Programming Language C was completed by the X3J11 Technical Committee.
The views and conclusions contained in the software and documentation are
those of the authors and should not be interpreted as representing official
policies, either expressed or implied, of the Regents of the University
of California.
NOTE: The copyright of UC Berkeley's Berkeley Software Distribution ("BSD")
source has been updated. The copyright addendum may be found at
ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change and is
included below.
July 22, 1999
To All Licensees, Distributors of Any Version of BSD:
As you know, certain of the Berkeley Software Distribution ("BSD") source
code files require that further distributions of products containing all or
portions of the software, acknowledge within their advertising materials
that such products contain software developed by UC Berkeley and its
contributors.
Specifically, the provision reads:
" * 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors."
Effective immediately, licensees and distributors are no longer required to
include the acknowledgement within advertising materials. Accordingly, the
foregoing paragraph of those BSD Unix files containing it is hereby deleted
in its entirety.
William Hoskins
Director, Office of Technology Licensing
University of California, Berkeley

View File

@ -0,0 +1,26 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm-native.h"
void*
wasm_platform_native_func_lookup(const char *module_name,
const char *func_name)
{
return NULL;
}

View File

@ -0,0 +1,581 @@
/*-
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD
*
* Copyright (c) 2004 David Schultz <das@FreeBSD.ORG>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
#include "wasm_log.h"
#include "wasm_platform.h"
#include "wasm_platform_log.h"
#include "wasm_memory.h"
#define __FDLIBM_STDC__
typedef uint32_t u_int32_t;
typedef uint64_t u_int64_t;
typedef union u32double_tag {
int *pint;
double *pdouble;
} U32DOUBLE;
static inline int *
pdouble2pint(double *pdouble)
{
U32DOUBLE u;
u.pdouble = pdouble;
return u.pint;
}
typedef union
{
double value;
struct
{
u_int32_t lsw;
u_int32_t msw;
} parts;
struct
{
u_int64_t w;
} xparts;
} ieee_double_shape_type_little;
typedef union
{
double value;
struct
{
u_int32_t msw;
u_int32_t lsw;
} parts;
struct
{
u_int64_t w;
} xparts;
} ieee_double_shape_type_big;
typedef union {
double d;
struct {
unsigned int manl :32;
unsigned int manh :20;
unsigned int exp :11;
unsigned int sign :1;
} bits;
} IEEEd2bits_L;
typedef union {
double d;
struct {
unsigned int sign :1;
unsigned int exp :11;
unsigned int manh :20;
unsigned int manl :32;
} bits;
} IEEEd2bits_B;
#define __HIL(x) *(1+pdouble2pint(&x))
#define __LOL(x) *(pdouble2pint(&x))
#define __HIB(x) *(int*)&x
#define __LOB(x) *(1+(int*)&x)
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS_L(ix0,ix1,d) \
do { \
ieee_double_shape_type_little ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS_L(d,ix0,ix1) \
do { \
ieee_double_shape_type_little iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Get two 32 bit ints from a double. */
#define EXTRACT_WORDS_B(ix0,ix1,d) \
do { \
ieee_double_shape_type_big ew_u; \
ew_u.value = (d); \
(ix0) = ew_u.parts.msw; \
(ix1) = ew_u.parts.lsw; \
} while (0)
/* Set a double from two 32 bit ints. */
#define INSERT_WORDS_B(d,ix0,ix1) \
do { \
ieee_double_shape_type_big iw_u; \
iw_u.parts.msw = (ix0); \
iw_u.parts.lsw = (ix1); \
(d) = iw_u.value; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD_L(i,d) \
do { \
ieee_double_shape_type_little gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Get the more significant 32 bit int from a double. */
#define GET_HIGH_WORD_B(i,d) \
do { \
ieee_double_shape_type_big gh_u; \
gh_u.value = (d); \
(i) = gh_u.parts.msw; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD_L(d,v) \
do { \
ieee_double_shape_type_little sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Set the more significant 32 bits of a double from an int. */
#define SET_HIGH_WORD_B(d,v) \
do { \
ieee_double_shape_type_big sh_u; \
sh_u.value = (d); \
sh_u.parts.msw = (v); \
(d) = sh_u.value; \
} while (0)
/* Macro wrappers. */
#define EXTRACT_WORDS(ix0,ix1,d) do { \
if (is_little_endian) \
EXTRACT_WORDS_L(ix0,ix1,d); \
else \
EXTRACT_WORDS_B(ix0,ix1,d); \
} while (0)
#define INSERT_WORDS(d,ix0,ix1) do { \
if (is_little_endian) \
INSERT_WORDS_L(d,ix0,ix1); \
else \
INSERT_WORDS_B(d,ix0,ix1); \
} while (0)
#define GET_HIGH_WORD(i,d) \
do { \
if (is_little_endian) \
GET_HIGH_WORD_L(i,d); \
else \
GET_HIGH_WORD_B(i,d); \
} while (0)
#define SET_HIGH_WORD(d,v) \
do { \
if (is_little_endian) \
SET_HIGH_WORD_L(d,v); \
else \
SET_HIGH_WORD_B(d,v); \
} while (0)
#define __HI(x) (is_little_endian ? __HIL(x) : __HIB(x))
#define __LO(x) (is_little_endian ? __LOL(x) : __LOB(x))
/*
* Attempt to get strict C99 semantics for assignment with non-C99 compilers.
*/
#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
#define STRICT_ASSIGN(type, lval, rval) ((lval) = (rval))
#else
#define STRICT_ASSIGN(type, lval, rval) do { \
volatile type __lval; \
\
if (sizeof(type) >= sizeof(long double)) \
(lval) = (rval); \
else { \
__lval = (rval); \
(lval) = __lval; \
} \
} while (0)
#endif
#ifdef __FDLIBM_STDC__
static const double huge = 1.0e300;
#else
static double huge = 1.0e300;
#endif
#ifdef __STDC__
static const double
#else
static double
#endif
tiny = 1.0e-300;
#ifdef __STDC__
static const double
#else
static double
#endif
one= 1.00000000000000000000e+00; /* 0x3FF00000, 0x00000000 */
#ifdef __STDC__
static const double
#else
static double
#endif
TWO52[2]={
4.50359962737049600000e+15, /* 0x43300000, 0x00000000 */
-4.50359962737049600000e+15, /* 0xC3300000, 0x00000000 */
};
static double freebsd_sqrt(double x);
static double freebsd_floor(double x);
static double freebsd_ceil(double x);
static double freebsd_fabs(double x);
static double freebsd_rint(double x);
static int freebsd_isnan(double x);
static double freebsd_sqrt(double x) /* wrapper sqrt */
{
double z;
int32_t sign = (int)0x80000000;
int32_t ix0,s0,q,m,t,i;
u_int32_t r,t1,s1,ix1,q1;
EXTRACT_WORDS(ix0,ix1,x);
/* take care of Inf and NaN */
if((ix0&0x7ff00000)==0x7ff00000) {
return x*x+x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if(ix0<=0) {
if(((ix0&(~sign))|ix1)==0) return x;/* sqrt(+-0) = +-0 */
else if(ix0<0)
return (x-x)/(x-x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix0>>20);
if(m==0) { /* subnormal x */
while(ix0==0) {
m -= 21;
ix0 |= (ix1>>11); ix1 <<= 21;
}
for(i=0;(ix0&0x00100000)==0;i++) ix0<<=1;
m -= i-1;
ix0 |= (ix1>>(32-i));
ix1 <<= i;
}
m -= 1023; /* unbias exponent */
ix0 = (ix0&0x000fffff)|0x00100000;
if(m&1){ /* odd m, double x to make it even */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
}
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
q = q1 = s0 = s1 = 0; /* [q,q1] = sqrt(x) */
r = 0x00200000; /* r = moving bit from right to left */
while(r!=0) {
t = s0+r;
if(t<=ix0) {
s0 = t+r;
ix0 -= t;
q += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
r = sign;
while(r!=0) {
t1 = s1+r;
t = s0;
if((t<ix0)||((t==ix0)&&(t1<=ix1))) {
s1 = t1+r;
if(((t1&sign)==sign)&&(s1&sign)==0) s0 += 1;
ix0 -= t;
if (ix1 < t1) ix0 -= 1;
ix1 -= t1;
q1 += r;
}
ix0 += ix0 + ((ix1&sign)>>31);
ix1 += ix1;
r>>=1;
}
/* use floating add to find out rounding direction */
if((ix0|ix1)!=0) {
z = one-tiny; /* trigger inexact flag */
if (z>=one) {
z = one+tiny;
if (q1==(u_int32_t)0xffffffff) { q1=0; q += 1;}
else if (z>one) {
if (q1==(u_int32_t)0xfffffffe) q+=1;
q1+=2;
} else
q1 += (q1&1);
}
}
ix0 = (q>>1)+0x3fe00000;
ix1 = q1>>1;
if ((q&1)==1) ix1 |= sign;
ix0 += (m <<20);
INSERT_WORDS(z,ix0,ix1);
return z;
}
static double freebsd_floor(double x)
{
int32_t i0,i1,j0;
u_int32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0>=0) {i0=i1=0;}
else if(((i0&0x7fffffff)|i1)!=0)
{ i0=0xbff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0<0) {
if(j0==20) i0+=1;
else {
j = i1+(1<<(52-j0));
if(j<i1) i0 +=1 ; /* got a carry */
i1=j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
static double freebsd_ceil(double x)
{
int32_t i0,i1,j0;
u_int32_t i,j;
EXTRACT_WORDS(i0,i1,x);
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) { /* raise inexact if x != 0 */
if(huge+x>0.0) {/* return 0*sign(x) if |x|<1 */
if(i0<0) {i0=0x80000000;i1=0;}
else if((i0|i1)!=0) { i0=0x3ff00000;i1=0;}
}
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) i0 += (0x00100000)>>j0;
i0 &= (~i); i1=0;
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
if(huge+x>0.0) { /* raise inexact flag */
if(i0>0) {
if(j0==20) i0+=1;
else {
j = i1 + (1<<(52-j0));
if(j<i1) i0+=1; /* got a carry */
i1 = j;
}
}
i1 &= (~i);
}
}
INSERT_WORDS(x,i0,i1);
return x;
}
static double freebsd_rint(double x)
{
int32_t i0,j0,sx;
u_int32_t i,i1;
double w,t;
EXTRACT_WORDS(i0,i1,x);
sx = (i0>>31)&1;
j0 = ((i0>>20)&0x7ff)-0x3ff;
if(j0<20) {
if(j0<0) {
if(((i0&0x7fffffff)|i1)==0) return x;
i1 |= (i0&0x0fffff);
i0 &= 0xfffe0000;
i0 |= ((i1|-i1)>>12)&0x80000;
SET_HIGH_WORD(x,i0);
STRICT_ASSIGN(double,w,TWO52[sx]+x);
t = w-TWO52[sx];
GET_HIGH_WORD(i0,t);
SET_HIGH_WORD(t,(i0&0x7fffffff)|(sx<<31));
return t;
} else {
i = (0x000fffff)>>j0;
if(((i0&i)|i1)==0) return x; /* x is integral */
i>>=1;
if(((i0&i)|i1)!=0) {
/*
* Some bit is set after the 0.5 bit. To avoid the
* possibility of errors from double rounding in
* w = TWO52[sx]+x, adjust the 0.25 bit to a lower
* guard bit. We do this for all j0<=51. The
* adjustment is trickiest for j0==18 and j0==19
* since then it spans the word boundary.
*/
if(j0==19) i1 = 0x40000000; else
if(j0==18) i1 = 0x80000000; else
i0 = (i0&(~i))|((0x20000)>>j0);
}
}
} else if (j0>51) {
if(j0==0x400) return x+x; /* inf or NaN */
else return x; /* x is integral */
} else {
i = ((u_int32_t)(0xffffffff))>>(j0-20);
if((i1&i)==0) return x; /* x is integral */
i>>=1;
if((i1&i)!=0) i1 = (i1&(~i))|((0x40000000)>>(j0-20));
}
INSERT_WORDS(x,i0,i1);
STRICT_ASSIGN(double,w,TWO52[sx]+x);
return w-TWO52[sx];
}
static int freebsd_isnan(double d)
{
if (is_little_endian) {
IEEEd2bits_L u;
u.d = d;
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
}
else {
IEEEd2bits_B u;
u.d = d;
return (u.bits.exp == 2047 && (u.bits.manl != 0 || u.bits.manh != 0));
}
}
static double freebsd_fabs(double x)
{
u_int32_t high;
GET_HIGH_WORD(high,x);
SET_HIGH_WORD(x,high&0x7fffffff);
return x;
}
double sqrt(double x)
{
return freebsd_sqrt(x);
}
double floor(double x)
{
return freebsd_floor(x);
}
double ceil(double x)
{
return freebsd_ceil(x);
}
double fmin(double x, double y)
{
return x < y ? x : y;
}
double fmax(double x, double y)
{
return x > y ? x : y;
}
double rint(double x)
{
return freebsd_rint(x);
}
double fabs(double x)
{
return freebsd_fabs(x);
}
int isnan(double x)
{
return freebsd_isnan(x);
}
double trunc(double x)
{
return (x > 0) ? freebsd_floor(x) : freebsd_ceil(x);
}
int signbit(double x)
{
return ((__HI(x) & 0x80000000) >> 31);
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_platform.h"
#ifndef CONFIG_AEE_ENABLE
static int
_stdout_hook_iwasm(int c)
{
printk("%c", (char)c);
return 1;
}
extern void __stdout_hook_install(int (*hook)(int));
#endif
bool is_little_endian = false;
bool __is_little_endian()
{
union w
{
int a;
char b;
}c;
c.a = 1;
return (c.b == 1);
}
int wasm_platform_init()
{
if (__is_little_endian())
is_little_endian = true;
#ifndef CONFIG_AEE_ENABLE
/* Enable printf() in Zephyr */
__stdout_hook_install(_stdout_hook_iwasm);
#endif
return 0;
}

View File

@ -0,0 +1,105 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_PLATFORM_H
#define _WASM_PLATFORM_H
#include "wasm_config.h"
#include "wasm_types.h"
#include <autoconf.h>
#include <zephyr.h>
#include <kernel.h>
#include <inttypes.h>
#include <stdbool.h>
typedef uint64_t uint64;
typedef int64_t int64;
typedef float float32;
typedef double float64;
#ifndef NULL
# define NULL ((void*) 0)
#endif
#define WASM_PLATFORM "Zephyr"
#include <stdarg.h>
#include <ctype.h>
#include <limits.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
/**
* Return the offset of the given field in the given type.
*
* @param Type the type containing the filed
* @param field the field in the type
*
* @return the offset of field in Type
*/
#ifndef offsetof
#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
#endif
typedef struct k_thread korp_thread;
typedef korp_thread *korp_tid;
typedef struct k_mutex korp_mutex;
int wasm_platform_init();
extern bool is_little_endian;
#include <string.h>
/* The following operations declared in string.h may be defined as
macros on Linux, so don't declare them as functions here. */
/* memset */
/* memcpy */
/* memmove */
/* #include <stdio.h> */
/* Unit test framework is based on C++, where the declaration of
snprintf is different. */
#ifndef __cplusplus
int snprintf(char *buffer, size_t count, const char *format, ...);
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* math functions */
double sqrt(double x);
double floor(double x);
double ceil(double x);
double fmin(double x, double y);
double fmax(double x, double y);
double rint(double x);
double fabs(double x);
double trunc(double x);
int signbit(double x);
int isnan(double x);
void*
wasm_dlsym(void *handle, const char *symbol);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,22 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set (UTILS_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${UTILS_LIB_DIR})
file (GLOB_RECURSE source_all ${UTILS_LIB_DIR}/*.c )
set (WASM_UTILS_LIB_SOURCE ${source_all})

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_platform.h"
static bool sort_flag = false;
typedef struct NativeSymbol {
const char *symbol;
void *func_ptr;
} NativeSymbol;
static bool
sort_symbol_ptr(NativeSymbol *ptr, int len)
{
int i, j;
NativeSymbol temp;
for (i = 0; i < len - 1; ++i) {
for (j = i + 1; j < len; ++j) {
if (strcmp((ptr+i)->symbol, (ptr+j)->symbol) > 0) {
temp = ptr[i];
ptr[i] = ptr[j];
ptr[j] = temp;
}
}
}
return true;
}
static void *
lookup_symbol(NativeSymbol *ptr, int len, const char *symbol)
{
int low = 0, mid, ret;
int high = len - 1;
while (low <= high) {
mid = (low + high) / 2;
ret = strcmp(symbol, ptr[mid].symbol);
if (ret == 0)
return ptr[mid].func_ptr;
else if (ret < 0)
high = mid - 1;
else
low = mid + 1;
}
return NULL;
}
int
get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
int
get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis);
static NativeSymbol *base_native_symbol_defs;
static NativeSymbol *ext_native_symbol_defs;
static int base_native_symbol_len;
static int ext_native_symbol_len;
void *
wasm_dlsym(void *handle, const char *symbol)
{
void *ret;
if (!sort_flag) {
base_native_symbol_len = get_base_lib_export_apis(&base_native_symbol_defs);
ext_native_symbol_len = get_ext_lib_export_apis(&ext_native_symbol_defs);
if (base_native_symbol_len > 0)
sort_symbol_ptr(base_native_symbol_defs, base_native_symbol_len);
if (ext_native_symbol_len > 0)
sort_symbol_ptr(ext_native_symbol_defs, ext_native_symbol_len);
sort_flag = true;
}
if (!symbol)
return NULL;
if ((ret = lookup_symbol(base_native_symbol_defs, base_native_symbol_len,
symbol))
|| (ret = lookup_symbol(ext_native_symbol_defs, ext_native_symbol_len,
symbol)))
return ret;
return NULL;
}

View File

@ -0,0 +1,301 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_hashmap.h"
#include "wasm_log.h"
#include "wasm_thread.h"
#include "wasm_memory.h"
typedef struct HashMapElem {
void *key;
void *value;
struct HashMapElem *next;
} HashMapElem;
struct HashMap {
/* size of element array */
uint32 size;
/* lock for elements */
korp_mutex *lock;
/* hash function of key */
HashFunc hash_func;
/* key equal function */
KeyEqualFunc key_equal_func;
KeyDestroyFunc key_destroy_func;
ValueDestroyFunc value_destroy_func;
HashMapElem *elements[1];
};
HashMap*
wasm_hash_map_create(uint32 size, bool use_lock,
HashFunc hash_func,
KeyEqualFunc key_equal_func,
KeyDestroyFunc key_destroy_func,
ValueDestroyFunc value_destroy_func)
{
HashMap *map;
uint32 total_size;
if (size > HASH_MAP_MAX_SIZE) {
LOG_ERROR("HashMap create failed: size is too large.\n");
return NULL;
}
if (!hash_func || !key_equal_func) {
LOG_ERROR("HashMap create failed: hash function or key equal function "
" is NULL.\n");
return NULL;
}
total_size = offsetof(HashMap, elements) +
sizeof(HashMapElem) * size +
(use_lock ? sizeof(korp_mutex) : 0);
if (!(map = wasm_malloc(total_size))) {
LOG_ERROR("HashMap create failed: alloc memory failed.\n");
return NULL;
}
memset(map, 0, total_size);
if (use_lock) {
map->lock = (korp_mutex*)
((uint8*)map + offsetof(HashMap, elements) + sizeof(HashMapElem) * size);
if (ws_mutex_init(map->lock, false)) {
LOG_ERROR("HashMap create failed: init map lock failed.\n");
wasm_free(map);
return NULL;
}
}
map->size = size;
map->hash_func = hash_func;
map->key_equal_func = key_equal_func;
map->key_destroy_func = key_destroy_func;
map->value_destroy_func = value_destroy_func;
return map;
}
bool
wasm_hash_map_insert(HashMap *map, void *key, void *value)
{
uint32 index;
HashMapElem *elem;
if (!map || !key) {
LOG_ERROR("HashMap insert elem failed: map or key is NULL.\n");
return false;
}
if (map->lock) {
ws_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
elem = map->elements[index];
while (elem) {
if (map->key_equal_func(elem->key, key)) {
LOG_ERROR("HashMap insert elem failed: duplicated key found.\n");
goto fail;
}
elem = elem->next;
}
if (!(elem = wasm_malloc(sizeof(HashMapElem)))) {
LOG_ERROR("HashMap insert elem failed: alloc memory failed.\n");
goto fail;
}
elem->key = key;
elem->value = value;
elem->next = map->elements[index];
map->elements[index] = elem;
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return true;
fail:
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return false;
}
void*
wasm_hash_map_find(HashMap *map, void *key)
{
uint32 index;
HashMapElem *elem;
void *value;
if (!map || !key) {
LOG_ERROR("HashMap find elem failed: map or key is NULL.\n");
return NULL;
}
if (map->lock) {
ws_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
elem = map->elements[index];
while (elem) {
if (map->key_equal_func(elem->key, key)) {
value = elem->value;
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return value;
}
elem = elem->next;
}
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return NULL;
}
bool
wasm_hash_map_update(HashMap *map, void *key, void *value,
void **p_old_value)
{
uint32 index;
HashMapElem *elem;
if (!map || !key) {
LOG_ERROR("HashMap update elem failed: map or key is NULL.\n");
return false;
}
if (map->lock) {
ws_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
elem = map->elements[index];
while (elem) {
if (map->key_equal_func(elem->key, key)) {
if (p_old_value)
*p_old_value = elem->value;
elem->value = value;
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return true;
}
elem = elem->next;
}
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return false;
}
bool
wasm_hash_map_remove(HashMap *map, void *key,
void **p_old_key, void **p_old_value)
{
uint32 index;
HashMapElem *elem, *prev;
if (!map || !key) {
LOG_ERROR("HashMap remove elem failed: map or key is NULL.\n");
return false;
}
if (map->lock) {
ws_mutex_lock(map->lock);
}
index = map->hash_func(key) % map->size;
prev = elem = map->elements[index];
while (elem) {
if (map->key_equal_func(elem->key, key)) {
if (p_old_key)
*p_old_key = elem->key;
if (p_old_value)
*p_old_value = elem->value;
if (elem == map->elements[index])
map->elements[index] = elem->next;
else
prev->next = elem->next;
wasm_free(elem);
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return true;
}
prev = elem;
elem = elem->next;
}
if (map->lock) {
ws_mutex_unlock(map->lock);
}
return false;
}
bool
wasm_hash_map_destroy(HashMap *map)
{
uint32 index;
HashMapElem *elem, *next;
if (!map) {
LOG_ERROR("HashMap destroy failed: map is NULL.\n");
return false;
}
if (map->lock) {
ws_mutex_lock(map->lock);
}
for (index = 0; index < map->size; index++) {
elem = map->elements[index];
while (elem) {
next = elem->next;
if (map->key_destroy_func) {
map->key_destroy_func(elem->key);
}
if (map->value_destroy_func) {
map->value_destroy_func(elem->value);
}
wasm_free(elem);
elem = next;
}
}
if (map->lock) {
ws_mutex_unlock(map->lock);
ws_mutex_destroy(map->lock);
}
wasm_free(map);
return true;
}

View File

@ -0,0 +1,102 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_log.h"
#include "wasm_platform_log.h"
#include "wasm_thread.h"
/**
* The verbose level of the log system. Only those verbose logs whose
* levels are less than or equal to this value are outputed.
*/
static int log_verbose_level;
/**
* The lock for protecting the global output stream of logs.
*/
static korp_mutex log_stream_lock;
int
_wasm_log_init ()
{
log_verbose_level = 1;
return ws_mutex_init (&log_stream_lock, false);
}
void
_wasm_log_set_verbose_level (int level)
{
log_verbose_level = level;
}
bool
_wasm_log_begin (int level)
{
korp_tid self;
if (level > log_verbose_level) {
return false;
}
/* Try to own the log stream and start the log output. */
ws_mutex_lock (&log_stream_lock);
self = ws_self_thread ();
wasm_printf ("[%X]: ", (int)self);
return true;
}
void
_wasm_log_vprintf (const char *fmt, va_list ap)
{
wasm_vprintf (fmt, ap);
}
void
_wasm_log_printf (const char *fmt, ...)
{
va_list ap;
va_start (ap, fmt);
_wasm_log_vprintf (fmt, ap);
va_end (ap);
}
void
_wasm_log_end ()
{
ws_mutex_unlock (&log_stream_lock);
}
void
_wasm_log (int level, const char *file, int line,
const char *fmt, ...)
{
if (_wasm_log_begin (level)) {
va_list ap;
if (file)
_wasm_log_printf ("%s:%d ", file, line);
va_start (ap, fmt);
_wasm_log_vprintf (fmt, ap);
va_end (ap);
_wasm_log_end ();
}
}

View File

@ -0,0 +1,217 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm_log.h"
#include "wasm_vector.h"
#include "wasm_memory.h"
static uint8*
alloc_vector_data(uint32 length, uint32 size_elem)
{
uint64 total_size = ((uint64)size_elem) * length;
uint8 *data;
if (total_size > UINT32_MAX) {
return NULL;
}
if ((data = wasm_malloc((uint32)total_size))) {
memset(data, 0, (uint32)total_size);
}
return data;
}
static bool
extend_vector(Vector *vector, uint32 length)
{
uint8 *data;
if (length <= vector->max_elements)
return true;
if (length < vector->size_elem * 3 / 2)
length = vector->size_elem * 3 / 2;
if (!(data = alloc_vector_data(length, vector->size_elem))) {
return false;
}
memcpy(data, vector->data, vector->size_elem * vector->max_elements);
free(vector->data);
vector->data = data;
vector->max_elements = length;
return true;
}
bool
wasm_vector_init(Vector *vector, uint32 init_length, uint32 size_elem)
{
if (!vector) {
LOG_ERROR("Init vector failed: vector is NULL.\n");
return false;
}
if (init_length == 0) {
init_length = 4;
}
if (!(vector->data = alloc_vector_data(init_length, size_elem))) {
LOG_ERROR("Init vector failed: alloc memory failed.\n");
return false;
}
vector->size_elem = size_elem;
vector->max_elements = init_length;
vector->num_elements = 0;
return true;
}
bool
wasm_vector_set(Vector *vector, uint32 index, const void *elem_buf)
{
if (!vector || !elem_buf) {
LOG_ERROR("Set vector elem failed: vector or elem buf is NULL.\n");
return false;
}
if (index >= vector->num_elements) {
LOG_ERROR("Set vector elem failed: invalid elem index.\n");
return false;
}
memcpy(vector->data + vector->size_elem * index,
elem_buf, vector->size_elem);
return true;
}
bool wasm_vector_get(const Vector *vector, uint32 index, void *elem_buf)
{
if (!vector || !elem_buf) {
LOG_ERROR("Get vector elem failed: vector or elem buf is NULL.\n");
return false;
}
if (index >= vector->num_elements) {
LOG_ERROR("Get vector elem failed: invalid elem index.\n");
return false;
}
memcpy(elem_buf, vector->data + vector->size_elem * index,
vector->size_elem);
return true;
}
bool wasm_vector_insert(Vector *vector, uint32 index, const void *elem_buf)
{
uint32 i;
uint8 *p;
if (!vector || !elem_buf) {
LOG_ERROR("Insert vector elem failed: vector or elem buf is NULL.\n");
return false;
}
if (index >= vector->num_elements) {
LOG_ERROR("Insert vector elem failed: invalid elem index.\n");
return false;
}
if (!extend_vector(vector, vector->num_elements + 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--) {
memcpy(p, p - vector->size_elem, vector->size_elem);
p -= vector->size_elem;
}
memcpy(p, elem_buf, vector->size_elem);
vector->num_elements++;
return true;
}
bool wasm_vector_append(Vector *vector, const void *elem_buf)
{
if (!vector || !elem_buf) {
LOG_ERROR("Append vector elem failed: vector or elem buf is NULL.\n");
return false;
}
if (!extend_vector(vector, vector->num_elements + 1)) {
LOG_ERROR("Append ector elem failed: extend vector failed.\n");
return false;
}
memcpy(vector->data + vector->size_elem * vector->num_elements,
elem_buf, vector->size_elem);
vector->num_elements++;
return true;
}
bool
wasm_vector_remove(Vector *vector, uint32 index, void *old_elem_buf)
{
uint32 i;
uint8 *p;
if (!vector) {
LOG_ERROR("Remove vector elem failed: vector is NULL.\n");
return false;
}
if (index >= vector->num_elements) {
LOG_ERROR("Remove vector elem failed: invalid elem index.\n");
return false;
}
p = vector->data + vector->size_elem * index;
if (old_elem_buf) {
memcpy(old_elem_buf, p, vector->size_elem);
}
for (i = index; i < vector->num_elements - 1; i++) {
memcpy(p, p + vector->size_elem, vector->size_elem);
p += vector->size_elem;
}
vector->num_elements--;
return true;
}
uint32
wasm_vector_size(const Vector *vector)
{
return vector ? vector->num_elements : 0;
}
bool
wasm_vector_destroy(Vector *vector)
{
if (!vector) {
LOG_ERROR("Destroy vector elem failed: vector is NULL.\n");
return false;
}
if (vector->data)
wasm_free(vector->data);
memset(vector, 0, sizeof(Vector));
return true;
}

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "wasm-runtime.h"
void invokeNative(uint32 argv[], uint32 argc, void (*native_code)())
{
WASMThread *self;
switch(argc) {
case 0:
native_code();
break;
case 1:
native_code(argv[0]);
break;
case 2:
native_code(argv[0], argv[1]);
break;
case 3:
native_code(argv[0], argv[1], argv[2]);
break;
case 4:
native_code(argv[0], argv[1], argv[2], argv[3]);
break;
case 5:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4]);
break;
case 6:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);
break;
case 7:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
break;
case 8:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]);
break;
case 9:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
break;
case 10:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9]);
break;
case 11:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
break;
case 12:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11]);
break;
case 13:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12]);
break;
case 14:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13]);
break;
case 15:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14]);
break;
case 16:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15]);
break;
case 17:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16]);
break;
case 18:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17]);
break;
case 19:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18]);
break;
case 20:
native_code(argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8], argv[9], argv[10], argv[11], argv[12], argv[13], argv[14], argv[15], argv[16], argv[17], argv[18], argv[19]);
break;
default:
/* FIXME: If this happen, add more cases. */
self = wasm_runtime_get_self();
wasm_runtime_set_exception(self->module_inst, "the argument number of native function exceeds maximum");
return;
}
}

View File

@ -0,0 +1,56 @@
// Copyright (C) 2019 Intel Corporation. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Author: Ivan Volosyuk
//
.text
.align 2
.globl invokeNative
.type invokeNative, @function
invokeNative:
push %ebp
movl %esp, %ebp
push %ecx
movl 8(%ebp), %eax /* eax = argv */
movl 12(%ebp), %ecx /* ecx = argc */
test %ecx, %ecx
je restore_ecx /* if ecx == 0, skip pushing arguments */
leal -4(%eax,%ecx,4), %eax /* eax = eax + ecx * 4 - 4 */
subl %esp, %eax /* eax = eax - esp */
1:
push 0(%esp,%eax)
loop 1b /* loop ecx counts */
restore_ecx:
movl -4(%ebp), %ecx /* restore ecx */
movl 16(%ebp), %eax /* eax = func_ptr */
call *%eax
leave
ret

View File

@ -0,0 +1,28 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
set (VMCORE_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
include_directories(${VMCORE_LIB_DIR})
include_directories(${VMCORE_LIB_DIR}/../include)
if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c)
else ()
file (GLOB_RECURSE source_all ${VMCORE_LIB_DIR}/*.c ${VMCORE_LIB_DIR}/*.s)
list (REMOVE_ITEM source_all ${VMCORE_LIB_DIR}/invokeNative_general.c)
endif ()
set (VMCORE_LIB_SOURCE ${source_all})

View File

@ -0,0 +1,390 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include "wasm.h"
#include "wasm-interp.h"
#include "wasm-runtime.h"
#include "wasm-thread.h"
#include "wasm_assert.h"
#include "wasm_log.h"
#include "wasm_memory.h"
#include "wasm_platform_log.h"
static WASMFunctionInstance*
resolve_main_function(const WASMModuleInstance *module_inst)
{
uint32 i;
for (i = 0; i < module_inst->export_func_count; i++)
if (!strcmp(module_inst->export_functions[i].name, "_main")
|| !strcmp(module_inst->export_functions[i].name, "main"))
return module_inst->export_functions[i].function;
LOG_ERROR("WASM execute application failed: main function not found.\n");
return NULL;
}
static bool
check_main_func_type(const WASMType *type)
{
if (!(type->param_count == 0 || type->param_count == 2)
||type->result_count > 1) {
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
return false;
}
if (type->param_count == 2
&& !(type->types[0] == VALUE_TYPE_I32
&& type->types[1] == VALUE_TYPE_I32)) {
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
return false;
}
if (type->result_count
&& type->types[type->param_count] != VALUE_TYPE_I32) {
LOG_ERROR("WASM execute application failed: invalid main function type.\n");
return false;
}
return true;
}
bool
wasm_application_execute_main(WASMModuleInstance *module_inst,
int argc, char *argv[])
{
WASMFunctionInstance *func = resolve_main_function(module_inst);
uint32 argc1 = 0, argv1[2] = { 0 };
uint32 total_argv_size = 0, total_size;
int32 argv_buf_offset, i;
char *argv_buf, *p;
int32 *argv_offsets;
if (!func || func->is_import_func)
return false;
if (!check_main_func_type(func->u.func->func_type))
return false;
if (func->u.func->func_type->param_count) {
for (i = 0; i < argc; i++)
total_argv_size += strlen(argv[i]) + 1;
total_argv_size = align_uint(total_argv_size, 4);
total_size = total_argv_size + sizeof(int32) * argc;
if (!(argv_buf_offset = wasm_runtime_module_malloc(module_inst, total_size)))
return false;
argv_buf = p = wasm_runtime_addr_app_to_native(module_inst, argv_buf_offset);
argv_offsets = (int32*)(p + total_argv_size);
for (i = 0; i < argc; i++) {
memcpy(p, argv[i], strlen(argv[i]) + 1);
argv_offsets[i] = argv_buf_offset + (p - argv_buf);
p += strlen(argv[i]) + 1;
}
argc1 = 2;
argv1[0] = argc;
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
}
return wasm_runtime_call_wasm(module_inst, NULL, func, argc1, argv1);
}
static WASMFunctionInstance*
resolve_function(const WASMModuleInstance *module_inst, char *name)
{
uint32 i;
for (i = 0; i < module_inst->export_func_count; i++)
if (!strcmp(module_inst->export_functions[i].name, name))
return module_inst->export_functions[i].function;
return NULL;
}
union ieee754_float {
float f;
/* This is the IEEE 754 single-precision format. */
union {
struct {
unsigned int negative:1;
unsigned int exponent:8;
unsigned int mantissa:23;
} ieee_big_endian;
struct {
unsigned int mantissa:23;
unsigned int exponent:8;
unsigned int negative:1;
} ieee_little_endian;
} ieee;
};
union ieee754_double {
double d;
/* This is the IEEE 754 double-precision format. */
union {
struct {
unsigned int negative:1;
unsigned int exponent:11;
/* Together these comprise the mantissa. */
unsigned int mantissa0:20;
unsigned int mantissa1:32;
} ieee_big_endian;
struct {
/* Together these comprise the mantissa. */
unsigned int mantissa1:32;
unsigned int mantissa0:20;
unsigned int exponent:11;
unsigned int negative:1;
} ieee_little_endian;
} ieee;
};
bool
wasm_application_execute_func(WASMModuleInstance *module_inst,
char *name, int argc, char *argv[])
{
WASMFunctionInstance *func;
WASMType *type;
uint32 argc1, *argv1;
int32 i, p;
const char *exception;
wasm_assert(argc >= 0);
func = resolve_function(module_inst, name);
if (!func || func->is_import_func) {
LOG_ERROR("Wasm lookup function %s failed.\n", name);
return false;
}
type = func->u.func->func_type;
if (type->param_count != (uint32)argc) {
LOG_ERROR("Wasm prepare param failed: invalid param count.\n");
return false;
}
argc1 = func->param_cell_num;
argv1 = wasm_malloc(sizeof(uint32) * (argc1 > 2 ? argc1 : 2));
if (argv1 == NULL) {
LOG_ERROR("Wasm prepare param failed: malloc failed.\n");
return false;
}
/* Parse arguments */
for (i = 0, p = 0; i < argc; i++) {
char *endptr;
wasm_assert(argv[i] != NULL);
if (argv[i][0] == '\0') {
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
goto fail;
}
switch (type->types[i]) {
case VALUE_TYPE_I32:
argv1[p++] = strtoul(argv[i], &endptr, 0);
break;
case VALUE_TYPE_I64:
{
union { uint64 val; uint32 parts[2]; } u;
u.val = strtoull(argv[i], &endptr, 0);
argv1[p++] = u.parts[0];
argv1[p++] = u.parts[1];
break;
}
case VALUE_TYPE_F32:
{
float32 f32 = strtof(argv[i], &endptr);
if (isnan(f32)) {
if (argv[i][0] == '-') {
f32 = -f32;
}
if (endptr[0] == ':') {
uint32 sig;
union ieee754_float u;
sig = strtoul(endptr + 1, &endptr, 0);
u.f = f32;
if (is_little_endian)
u.ieee.ieee_little_endian.mantissa = sig;
else
u.ieee.ieee_big_endian.mantissa = sig;
f32 = u.f;
}
}
*(float32*)&argv1[p++] = f32;
break;
}
case VALUE_TYPE_F64:
{
union { float64 val; uint32 parts[2]; } u;
u.val = strtod(argv[i], &endptr);
if (isnan(u.val)) {
if (argv[i][0] == '-') {
u.val = -u.val;
}
if (endptr[0] == ':') {
uint64 sig;
union ieee754_double ud;
sig = strtoull(endptr + 1, &endptr, 0);
ud.d = u.val;
if (is_little_endian) {
ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
ud.ieee.ieee_little_endian.mantissa1 = sig;
}
else {
ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
ud.ieee.ieee_big_endian.mantissa1 = sig;
}
u.val = ud.d;
}
}
argv1[p++] = u.parts[0];
argv1[p++] = u.parts[1];
break;
}
}
if (*endptr != '\0' && *endptr != '_') {
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
goto fail;
}
if (errno != 0) {
LOG_ERROR("Wasm prepare param failed: errno %d.\n", errno);
goto fail;
}
}
wasm_assert(p == (int32)argc1);
wasm_runtime_set_exception(module_inst, NULL);
if (!wasm_runtime_call_wasm(module_inst, NULL, func, argc1, argv1)) {
exception = wasm_runtime_get_exception(module_inst);
wasm_printf("%s\n", exception);
goto fail;
}
/* print return value */
switch (type->types[type->param_count]) {
case VALUE_TYPE_I32:
wasm_printf("0x%x:i32", argv1[0]);
break;
case VALUE_TYPE_I64:
{
union { uint64 val; uint32 parts[2]; } u;
u.parts[0] = argv1[0];
u.parts[1] = argv1[1];
wasm_printf("0x%llx:i64", u.val);
break;
}
case VALUE_TYPE_F32:
wasm_printf("%.7g:f32", *(float32*)argv1);
break;
case VALUE_TYPE_F64:
{
union { float64 val; uint32 parts[2]; } u;
u.parts[0] = argv1[0];
u.parts[1] = argv1[1];
wasm_printf("%.7g:f64", u.val);
break;
}
}
wasm_printf("\n");
wasm_free(argv1);
return true;
fail:
wasm_free(argv1);
return false;
}
static bool
check_type(uint8 type, const char *p)
{
const char *str = "i32";
if (strlen(p) < 3)
return false;
switch (type) {
case VALUE_TYPE_I32:
str = "i32";
break;
case VALUE_TYPE_I64:
str = "i64";
break;
case VALUE_TYPE_F32:
str = "f32";
break;
case VALUE_TYPE_F64:
str = "f64";
break;
}
if (strncmp(p, str, 3))
return false;
return true;
}
static bool
check_function_type(const WASMType *type,
const char *signature)
{
uint32 i;
const char *p = signature;
if (!p || *p++ != '(')
return false;
for (i = 0; i < type->param_count; i++) {
if (!check_type(type->types[i], p))
return false;
p += 3;
}
if (*p++ != ')')
return false;
if (type->result_count) {
if (!check_type(type->types[type->param_count], p))
return false;
p += 3;
}
if (*p != '\0')
return false;
return true;
}
WASMFunctionInstance*
wasm_runtime_lookup_function(const WASMModuleInstance *module_inst,
const char *name,
const char *signature)
{
uint32 i;
for (i = 0; i < module_inst->export_func_count; i++)
if (!strcmp(module_inst->export_functions[i].name, name)
&& check_function_type(
module_inst->export_functions[i].function->u.func->func_type,
signature))
return module_inst->export_functions[i].function;
return NULL;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,79 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_INTERP_H
#define _WASM_INTERP_H
#include "wasm.h"
#ifdef __cplusplus
extern "C" {
#endif
struct WASMFunctionInstance;
typedef struct WASMInterpFrame {
/* The frame of the caller that are calling the current function. */
struct WASMInterpFrame *prev_frame;
/* The current WASM function. */
struct WASMFunctionInstance *function;
/* Instruction pointer of the bytecode array. */
uint8 *ip;
/* Operand stack top pointer of the current frame. The bottom of
the stack is the next cell after the last local variable. */
uint32 *sp_bottom;
uint32 *sp_boundary;
uint32 *sp;
WASMBranchBlock *csp_bottom;
WASMBranchBlock *csp_boundary;
WASMBranchBlock *csp;
/* Frame data, the layout is:
lp: param_cell_count + local_cell_count
sp_bottom to sp_boundary: stack of data
csp_bottom to csp_boundary: stack of block
ref to frame end: data types of local vairables and stack data
*/
uint32 lp[1];
} WASMInterpFrame;
/**
* Calculate the size of interpreter area of frame of a function.
*
* @param all_cell_num number of all cells including local variables
* and the working stack slots
*
* @return the size of interpreter area of the frame
*/
static inline unsigned
wasm_interp_interp_frame_size(unsigned all_cell_num)
{
return align_uint(offsetof(WASMInterpFrame, lp) + all_cell_num * 5, 4);
}
void
wasm_interp_call_wasm(struct WASMFunctionInstance *function,
uint32 argc, uint32 argv[]);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_INTERP_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,92 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_LOADER_H
#define _WASM_LOADER_H
#include "wasm.h"
#include "wasm_hashmap.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Load a WASM module from a specified byte buffer.
*
* @param buf the byte buffer which contains the WASM binary data
* @param size the size of the buffer
* @param error_buf output of the exception info
* @param error_buf_size the size of the exception string
*
* @return return module loaded, NULL if failed
*/
WASMModule*
wasm_loader_load(const uint8 *buf, uint32 size, char *error_buf, uint32 error_buf_size);
/**
* Load a WASM module from a specified WASM section list.
*
* @param section_list the section list which contains each section data
* @param error_buf output of the exception info
* @param error_buf_size the size of the exception string
*
* @return return WASM module loaded, NULL if failed
*/
WASMModule*
wasm_loader_load_from_sections(WASMSection *section_list,
char *error_buf, uint32_t error_buf_size);
/**
* Unload a WASM module.
*
* @param module the module to be unloaded
*/
void
wasm_loader_unload(WASMModule *module);
/**
* Find address of related else opcode and end opcode of opcode block/loop/if
* according to the start address of opcode.
*
* @param branch_set the hashtable to store the else/end adress info of
* block/loop/if opcode. The function will lookup the hashtable firstly,
* if not found, it will then search the code from start_addr, and if success,
* stores the result to the hashtable.
* @param start_addr the next address of opcode block/loop/if
* @param code_end_addr the end address of function code block
* @param block_type the type of block, 0/1/2 denotes block/loop/if
* @param p_else_addr returns the else addr if found
* @param p_end_addr returns the end addr if found
* @param error_buf returns the error log for this function
* @param error_buf_size returns the error log string length
*
* @return true if success, false otherwise
*/
bool
wasm_loader_find_block_addr(HashMap *map,
const uint8 *start_addr,
const uint8 *code_end_addr,
uint8 block_type,
uint8 **p_else_addr,
uint8 **p_end_addr,
char *error_buf,
uint32 error_buf_size);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_LOADER_H */

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_NATIVE_H
#define _WASM_NATIVE_H
#include "wasm.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* Initialize the native module, e.g. sort the function defs
* and the global defs.
*
* @return true if success, false otherwise
*/
bool
wasm_native_init();
/**
* Lookup native function implementation of a given import function.
*
* @param module_name the module name of the import function
* @param func_name the function name of the import function
*
* @return return the native function pointer if success, NULL otherwise
*/
void*
wasm_native_func_lookup(const char *module_name, const char *func_name);
/**
* Lookup global variable of a given import global
*
* @param module_name the module name of the import global
* @param global_name the global name of the import global
* @param global return the global data
*
* @param return true if success, false otherwise
*/
bool
wasm_native_global_lookup(const char *module_name, const char *global_name,
WASMGlobalImport *global);
void* wasm_platform_native_func_lookup(const char *module_name,
const char *func_name);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_NATIVE_H */

View File

@ -0,0 +1,472 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_OPCODE_H
#define _WASM_OPCODE_H
#include "wasm.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef enum WASMOpcode {
/* control instructions */
WASM_OP_UNREACHABLE = 0x00, /* unreachable */
WASM_OP_NOP = 0x01, /* nop */
WASM_OP_BLOCK = 0x02, /* block */
WASM_OP_LOOP = 0x03, /* loop */
WASM_OP_IF = 0x04, /* if */
WASM_OP_ELSE = 0x05, /* else */
WASM_OP_UNUSED_0x06 = 0x06,
WASM_OP_UNUSED_0x07 = 0x07,
WASM_OP_UNUSED_0x08 = 0x08,
WASM_OP_UNUSED_0x09 = 0x09,
WASM_OP_UNUSED_0x0a = 0x0a,
WASM_OP_END = 0x0b, /* end */
WASM_OP_BR = 0x0c, /* br */
WASM_OP_BR_IF = 0x0d, /* br if */
WASM_OP_BR_TABLE = 0x0e, /* br table */
WASM_OP_RETURN = 0x0f, /* return */
WASM_OP_CALL = 0x10, /* call */
WASM_OP_CALL_INDIRECT = 0x11, /* call_indirect */
WASM_OP_UNUSED_0x12 = 0x12,
WASM_OP_UNUSED_0x13 = 0x13,
WASM_OP_UNUSED_0x14 = 0x14,
WASM_OP_UNUSED_0x15 = 0x15,
WASM_OP_UNUSED_0x16 = 0x16,
WASM_OP_UNUSED_0x17 = 0x17,
WASM_OP_UNUSED_0x18 = 0x18,
WASM_OP_UNUSED_0x19 = 0x19,
/* parametric instructions */
WASM_OP_DROP = 0x1a, /* drop */
WASM_OP_SELECT = 0x1b, /* select */
WASM_OP_UNUSED_0x1c = 0x1c,
WASM_OP_UNUSED_0x1d = 0x1d,
WASM_OP_UNUSED_0x1e = 0x1e,
WASM_OP_UNUSED_0x1f = 0x1f,
/* variable instructions */
WASM_OP_GET_LOCAL = 0x20, /* get_local */
WASM_OP_SET_LOCAL = 0x21, /* set_local */
WASM_OP_TEE_LOCAL = 0x22, /* tee_local */
WASM_OP_GET_GLOBAL = 0x23, /* get_global */
WASM_OP_SET_GLOBAL = 0x24, /* set_global */
WASM_OP_UNUSED_0x25 = 0x25,
WASM_OP_UNUSED_0x26 = 0x26,
WASM_OP_UNUSED_0x27 = 0x27,
/* memory instructions */
WASM_OP_I32_LOAD = 0x28, /* i32.load */
WASM_OP_I64_LOAD = 0x29, /* i64.load */
WASM_OP_F32_LOAD = 0x2a, /* f32.load */
WASM_OP_F64_LOAD = 0x2b, /* f64.load */
WASM_OP_I32_LOAD8_S = 0x2c, /* i32.load8_s */
WASM_OP_I32_LOAD8_U = 0x2d, /* i32.load8_u */
WASM_OP_I32_LOAD16_S = 0x2e, /* i32.load16_s */
WASM_OP_I32_LOAD16_U = 0x2f, /* i32.load16_u */
WASM_OP_I64_LOAD8_S = 0x30, /* i64.load8_s */
WASM_OP_I64_LOAD8_U = 0x31, /* i64.load8_u */
WASM_OP_I64_LOAD16_S = 0x32, /* i64.load16_s */
WASM_OP_I64_LOAD16_U = 0x33, /* i64.load16_u */
WASM_OP_I64_LOAD32_S = 0x34, /* i32.load32_s */
WASM_OP_I64_LOAD32_U = 0x35, /* i32.load32_u */
WASM_OP_I32_STORE = 0x36, /* i32.store */
WASM_OP_I64_STORE = 0x37, /* i64.store */
WASM_OP_F32_STORE = 0x38, /* f32.store */
WASM_OP_F64_STORE = 0x39, /* f64.store */
WASM_OP_I32_STORE8 = 0x3a, /* i32.store8 */
WASM_OP_I32_STORE16 = 0x3b, /* i32.store16 */
WASM_OP_I64_STORE8 = 0x3c, /* i64.store8 */
WASM_OP_I64_STORE16 = 0x3d, /* i64.sotre16 */
WASM_OP_I64_STORE32 = 0x3e, /* i64.store32 */
WASM_OP_MEMORY_SIZE = 0x3f, /* memory.size */
WASM_OP_MEMORY_GROW = 0x40, /* memory.grow */
/* constant instructions */
WASM_OP_I32_CONST = 0x41, /* i32.const */
WASM_OP_I64_CONST = 0x42, /* i64.const */
WASM_OP_F32_CONST = 0x43, /* f32.const */
WASM_OP_F64_CONST = 0x44, /* f64.const */
/* comparison instructions */
WASM_OP_I32_EQZ = 0x45, /* i32.eqz */
WASM_OP_I32_EQ = 0x46, /* i32.eq */
WASM_OP_I32_NE = 0x47, /* i32.ne */
WASM_OP_I32_LT_S = 0x48, /* i32.lt_s */
WASM_OP_I32_LT_U = 0x49, /* i32.lt_u */
WASM_OP_I32_GT_S = 0x4a, /* i32.gt_s */
WASM_OP_I32_GT_U = 0x4b, /* i32.gt_u */
WASM_OP_I32_LE_S = 0x4c, /* i32.le_s */
WASM_OP_I32_LE_U = 0x4d, /* i32.le_u */
WASM_OP_I32_GE_S = 0x4e, /* i32.ge_s */
WASM_OP_I32_GE_U = 0x4f, /* i32.ge_u */
WASM_OP_I64_EQZ = 0x50, /* i64.eqz */
WASM_OP_I64_EQ = 0x51, /* i64.eq */
WASM_OP_I64_NE = 0x52, /* i64.ne */
WASM_OP_I64_LT_S = 0x53, /* i64.lt_s */
WASM_OP_I64_LT_U = 0x54, /* i64.lt_u */
WASM_OP_I64_GT_S = 0x55, /* i64.gt_s */
WASM_OP_I64_GT_U = 0x56, /* i64.gt_u */
WASM_OP_I64_LE_S = 0x57, /* i64.le_s */
WASM_OP_I64_LE_U = 0x58, /* i64.le_u */
WASM_OP_I64_GE_S = 0x59, /* i64.ge_s */
WASM_OP_I64_GE_U = 0x5a, /* i64.ge_u */
WASM_OP_F32_EQ = 0x5b, /* f32.eq */
WASM_OP_F32_NE = 0x5c, /* f32.ne */
WASM_OP_F32_LT = 0x5d, /* f32.lt */
WASM_OP_F32_GT = 0x5e, /* f32.gt */
WASM_OP_F32_LE = 0x5f, /* f32.le */
WASM_OP_F32_GE = 0x60, /* f32.ge */
WASM_OP_F64_EQ = 0x61, /* f64.eq */
WASM_OP_F64_NE = 0x62, /* f64.ne */
WASM_OP_F64_LT = 0x63, /* f64.lt */
WASM_OP_F64_GT = 0x64, /* f64.gt */
WASM_OP_F64_LE = 0x65, /* f64.le */
WASM_OP_F64_GE = 0x66, /* f64.ge */
/* numeric operators */
WASM_OP_I32_CLZ = 0x67, /* i32.clz */
WASM_OP_I32_CTZ = 0x68, /* i32.ctz */
WASM_OP_I32_POPCNT = 0x69, /* i32.popcnt */
WASM_OP_I32_ADD = 0x6a, /* i32.add */
WASM_OP_I32_SUB = 0x6b, /* i32.sub */
WASM_OP_I32_MUL = 0x6c, /* i32.mul */
WASM_OP_I32_DIV_S = 0x6d, /* i32.div_s */
WASM_OP_I32_DIV_U = 0x6e, /* i32.div_u */
WASM_OP_I32_REM_S = 0x6f, /* i32.rem_s */
WASM_OP_I32_REM_U = 0x70, /* i32.rem_u */
WASM_OP_I32_AND = 0x71, /* i32.and */
WASM_OP_I32_OR = 0x72, /* i32.or */
WASM_OP_I32_XOR = 0x73, /* i32.xor */
WASM_OP_I32_SHL = 0x74, /* i32.shl */
WASM_OP_I32_SHR_S = 0x75, /* i32.shr_s */
WASM_OP_I32_SHR_U = 0x76, /* i32.shr_u */
WASM_OP_I32_ROTL = 0x77, /* i32.rotl */
WASM_OP_I32_ROTR = 0x78, /* i32.rotr */
WASM_OP_I64_CLZ = 0x79, /* i64.clz */
WASM_OP_I64_CTZ = 0x7a, /* i64.ctz */
WASM_OP_I64_POPCNT = 0x7b, /* i64.popcnt */
WASM_OP_I64_ADD = 0x7c, /* i64.add */
WASM_OP_I64_SUB = 0x7d, /* i64.sub */
WASM_OP_I64_MUL = 0x7e, /* i64.mul */
WASM_OP_I64_DIV_S = 0x7f, /* i64.div_s */
WASM_OP_I64_DIV_U = 0x80, /* i64.div_u */
WASM_OP_I64_REM_S = 0x81, /* i64.rem_s */
WASM_OP_I64_REM_U = 0x82, /* i64.rem_u */
WASM_OP_I64_AND = 0x83, /* i64.and */
WASM_OP_I64_OR = 0x84, /* i64.or */
WASM_OP_I64_XOR = 0x85, /* i64.xor */
WASM_OP_I64_SHL = 0x86, /* i64.shl */
WASM_OP_I64_SHR_S = 0x87, /* i64.shr_s */
WASM_OP_I64_SHR_U = 0x88, /* i64.shr_u */
WASM_OP_I64_ROTL = 0x89, /* i64.rotl */
WASM_OP_I64_ROTR = 0x8a, /* i64.rotr */
WASM_OP_F32_ABS = 0x8b, /* f32.abs */
WASM_OP_F32_NEG = 0x8c, /* f32.neg */
WASM_OP_F32_CEIL = 0x8d, /* f32.ceil */
WASM_OP_F32_FLOOR = 0x8e, /* f32.floor */
WASM_OP_F32_TRUNC = 0x8f, /* f32.trunc */
WASM_OP_F32_NEAREST = 0x90, /* f32.nearest */
WASM_OP_F32_SQRT = 0x91, /* f32.sqrt */
WASM_OP_F32_ADD = 0x92, /* f32.add */
WASM_OP_F32_SUB = 0x93, /* f32.sub */
WASM_OP_F32_MUL = 0x94, /* f32.mul */
WASM_OP_F32_DIV = 0x95, /* f32.div */
WASM_OP_F32_MIN = 0x96, /* f32.min */
WASM_OP_F32_MAX = 0x97, /* f32.max */
WASM_OP_F32_COPYSIGN = 0x98, /* f32.copysign */
WASM_OP_F64_ABS = 0x99, /* f64.abs */
WASM_OP_F64_NEG = 0x9a, /* f64.neg */
WASM_OP_F64_CEIL = 0x9b, /* f64.ceil */
WASM_OP_F64_FLOOR = 0x9c, /* f64.floor */
WASM_OP_F64_TRUNC = 0x9d, /* f64.trunc */
WASM_OP_F64_NEAREST = 0x9e, /* f64.nearest */
WASM_OP_F64_SQRT = 0x9f, /* f64.sqrt */
WASM_OP_F64_ADD = 0xa0, /* f64.add */
WASM_OP_F64_SUB = 0xa1, /* f64.sub */
WASM_OP_F64_MUL = 0xa2, /* f64.mul */
WASM_OP_F64_DIV = 0xa3, /* f64.div */
WASM_OP_F64_MIN = 0xa4, /* f64.min */
WASM_OP_F64_MAX = 0xa5, /* f64.max */
WASM_OP_F64_COPYSIGN = 0xa6, /* f64.copysign */
/* conversions */
WASM_OP_I32_WRAP_I64 = 0xa7, /* i32.wrap/i64 */
WASM_OP_I32_TRUNC_S_F32 = 0xa8, /* i32.trunc_s/f32 */
WASM_OP_I32_TRUNC_U_F32 = 0xa9, /* i32.trunc_u/f32 */
WASM_OP_I32_TRUNC_S_F64 = 0xaa, /* i32.trunc_s/f64 */
WASM_OP_I32_TRUNC_U_F64 = 0xab, /* i32.trunc_u/f64 */
WASM_OP_I64_EXTEND_S_I32 = 0xac, /* i64.extend_s/i32 */
WASM_OP_I64_EXTEND_U_I32 = 0xad, /* i64.extend_u/i32 */
WASM_OP_I64_TRUNC_S_F32 = 0xae, /* i64.trunc_s/f32 */
WASM_OP_I64_TRUNC_U_F32 = 0xaf, /* i64.trunc_u/f32 */
WASM_OP_I64_TRUNC_S_F64 = 0xb0, /* i64.trunc_s/f64 */
WASM_OP_I64_TRUNC_U_F64 = 0xb1, /* i64.trunc_u/f64 */
WASM_OP_F32_CONVERT_S_I32 = 0xb2, /* f32.convert_s/i32 */
WASM_OP_F32_CONVERT_U_I32 = 0xb3, /* f32.convert_u/i32 */
WASM_OP_F32_CONVERT_S_I64 = 0xb4, /* f32.convert_s/i64 */
WASM_OP_F32_CONVERT_U_I64 = 0xb5, /* f32.convert_u/i64 */
WASM_OP_F32_DEMOTE_F64 = 0xb6, /* f32.demote/f64 */
WASM_OP_F64_CONVERT_S_I32 = 0xb7, /* f64.convert_s/i32 */
WASM_OP_F64_CONVERT_U_I32 = 0xb8, /* f64.convert_u/i32 */
WASM_OP_F64_CONVERT_S_I64 = 0xb9, /* f64.convert_s/i64 */
WASM_OP_F64_CONVERT_U_I64 = 0xba, /* f64.convert_u/i64 */
WASM_OP_F64_PROMOTE_F32 = 0xbb, /* f64.promote/f32 */
/* reinterpretations */
WASM_OP_I32_REINTERPRET_F32 = 0xbc, /* i32.reinterpret/f32 */
WASM_OP_I64_REINTERPRET_F64 = 0xbd, /* i64.reinterpret/f64 */
WASM_OP_F32_REINTERPRET_I32 = 0xbe, /* f32.reinterpret/i32 */
WASM_OP_F64_REINTERPRET_I64 = 0xbf, /* f64.reinterpret/i64 */
/* drop/select specified types*/
WASM_OP_DROP_32 = 0xc0,
WASM_OP_DROP_64 = 0xc1,
WASM_OP_SELECT_32 = 0xc2,
WASM_OP_SELECT_64 = 0xc3,
WASM_OP_IMPDEP1 = WASM_OP_SELECT_64 + 1,
WASM_OP_IMPDEP2 = WASM_OP_IMPDEP1 + 1
} WASMOpcode;
#ifdef __cplusplus
}
#endif
/*
* Macro used to generate computed goto tables for the C interpreter.
*/
#define WASM_INSTRUCTION_NUM 256
#define DEFINE_GOTO_TABLE(_name) \
static const void *_name[WASM_INSTRUCTION_NUM] = { \
HANDLE_OPCODE (WASM_OP_UNREACHABLE), /* 0x00 */ \
HANDLE_OPCODE (WASM_OP_NOP), /* 0x01 */ \
HANDLE_OPCODE (WASM_OP_BLOCK), /* 0x02 */ \
HANDLE_OPCODE (WASM_OP_LOOP), /* 0x03 */ \
HANDLE_OPCODE (WASM_OP_IF), /* 0x04 */ \
HANDLE_OPCODE (WASM_OP_ELSE), /* 0x05 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x06), /* 0x06 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x07), /* 0x07 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x08), /* 0x08 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x09), /* 0x09 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x0a), /* 0x0a */ \
HANDLE_OPCODE (WASM_OP_END), /* 0x0b */ \
HANDLE_OPCODE (WASM_OP_BR), /* 0x0c */ \
HANDLE_OPCODE (WASM_OP_BR_IF), /* 0x0d */ \
HANDLE_OPCODE (WASM_OP_BR_TABLE), /* 0x0e */ \
HANDLE_OPCODE (WASM_OP_RETURN), /* 0x0f */ \
HANDLE_OPCODE (WASM_OP_CALL), /* 0x10 */ \
HANDLE_OPCODE (WASM_OP_CALL_INDIRECT), /* 0x11 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x12), /* 0x12 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x13), /* 0x13 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x14), /* 0x14 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x15), /* 0x15 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x16), /* 0x16 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x17), /* 0x17 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x18), /* 0x18 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x19), /* 0x19 */ \
HANDLE_OPCODE (WASM_OP_DROP), /* 0x1a */ \
HANDLE_OPCODE (WASM_OP_SELECT), /* 0x1b */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1c), /* 0x1c */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1d), /* 0x1d */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1e), /* 0x1e */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x1f), /* 0x1f */ \
HANDLE_OPCODE (WASM_OP_GET_LOCAL), /* 0x20 */ \
HANDLE_OPCODE (WASM_OP_SET_LOCAL), /* 0x21 */ \
HANDLE_OPCODE (WASM_OP_TEE_LOCAL), /* 0x22 */ \
HANDLE_OPCODE (WASM_OP_GET_GLOBAL), /* 0x23 */ \
HANDLE_OPCODE (WASM_OP_SET_GLOBAL), /* 0x24 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x25), /* 0x25 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x26), /* 0x26 */ \
HANDLE_OPCODE (WASM_OP_UNUSED_0x27), /* 0x27 */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD), /* 0x28 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD), /* 0x29 */ \
HANDLE_OPCODE (WASM_OP_F32_LOAD), /* 0x2a */ \
HANDLE_OPCODE (WASM_OP_F64_LOAD), /* 0x2b */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD8_S), /* 0x2c */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD8_U), /* 0x2d */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD16_S), /* 0x2e */ \
HANDLE_OPCODE (WASM_OP_I32_LOAD16_U), /* 0x2f */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD8_S), /* 0x30 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD8_U), /* 0x31 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD16_S), /* 0x32 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD16_U), /* 0x33 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD32_S), /* 0x34 */ \
HANDLE_OPCODE (WASM_OP_I64_LOAD32_U), /* 0x35 */ \
HANDLE_OPCODE (WASM_OP_I32_STORE), /* 0x36 */ \
HANDLE_OPCODE (WASM_OP_I64_STORE), /* 0x37 */ \
HANDLE_OPCODE (WASM_OP_F32_STORE), /* 0x38 */ \
HANDLE_OPCODE (WASM_OP_F64_STORE), /* 0x39 */ \
HANDLE_OPCODE (WASM_OP_I32_STORE8), /* 0x3a */ \
HANDLE_OPCODE (WASM_OP_I32_STORE16), /* 0x3b */ \
HANDLE_OPCODE (WASM_OP_I64_STORE8), /* 0x3c */ \
HANDLE_OPCODE (WASM_OP_I64_STORE16), /* 0x3d */ \
HANDLE_OPCODE (WASM_OP_I64_STORE32), /* 0x3e */ \
HANDLE_OPCODE (WASM_OP_MEMORY_SIZE), /* 0x3f */ \
HANDLE_OPCODE (WASM_OP_MEMORY_GROW), /* 0x40 */ \
HANDLE_OPCODE (WASM_OP_I32_CONST), /* 0x41 */ \
HANDLE_OPCODE (WASM_OP_I64_CONST), /* 0x42 */ \
HANDLE_OPCODE (WASM_OP_F32_CONST), /* 0x43 */ \
HANDLE_OPCODE (WASM_OP_F64_CONST), /* 0x44 */ \
HANDLE_OPCODE (WASM_OP_I32_EQZ), /* 0x45 */ \
HANDLE_OPCODE (WASM_OP_I32_EQ), /* 0x46 */ \
HANDLE_OPCODE (WASM_OP_I32_NE), /* 0x47 */ \
HANDLE_OPCODE (WASM_OP_I32_LT_S), /* 0x48 */ \
HANDLE_OPCODE (WASM_OP_I32_LT_U), /* 0x49 */ \
HANDLE_OPCODE (WASM_OP_I32_GT_S), /* 0x4a */ \
HANDLE_OPCODE (WASM_OP_I32_GT_U), /* 0x4b */ \
HANDLE_OPCODE (WASM_OP_I32_LE_S), /* 0x4c */ \
HANDLE_OPCODE (WASM_OP_I32_LE_U), /* 0x4d */ \
HANDLE_OPCODE (WASM_OP_I32_GE_S), /* 0x4e */ \
HANDLE_OPCODE (WASM_OP_I32_GE_U), /* 0x4f */ \
HANDLE_OPCODE (WASM_OP_I64_EQZ), /* 0x50 */ \
HANDLE_OPCODE (WASM_OP_I64_EQ), /* 0x51 */ \
HANDLE_OPCODE (WASM_OP_I64_NE), /* 0x52 */ \
HANDLE_OPCODE (WASM_OP_I64_LT_S), /* 0x53 */ \
HANDLE_OPCODE (WASM_OP_I64_LT_U), /* 0x54 */ \
HANDLE_OPCODE (WASM_OP_I64_GT_S), /* 0x55 */ \
HANDLE_OPCODE (WASM_OP_I64_GT_U), /* 0x56 */ \
HANDLE_OPCODE (WASM_OP_I64_LE_S), /* 0x57 */ \
HANDLE_OPCODE (WASM_OP_I64_LE_U), /* 0x58 */ \
HANDLE_OPCODE (WASM_OP_I64_GE_S), /* 0x59 */ \
HANDLE_OPCODE (WASM_OP_I64_GE_U), /* 0x5a */ \
HANDLE_OPCODE (WASM_OP_F32_EQ), /* 0x5b */ \
HANDLE_OPCODE (WASM_OP_F32_NE), /* 0x5c */ \
HANDLE_OPCODE (WASM_OP_F32_LT), /* 0x5d */ \
HANDLE_OPCODE (WASM_OP_F32_GT), /* 0x5e */ \
HANDLE_OPCODE (WASM_OP_F32_LE), /* 0x5f */ \
HANDLE_OPCODE (WASM_OP_F32_GE), /* 0x60 */ \
HANDLE_OPCODE (WASM_OP_F64_EQ), /* 0x61 */ \
HANDLE_OPCODE (WASM_OP_F64_NE), /* 0x62 */ \
HANDLE_OPCODE (WASM_OP_F64_LT), /* 0x63 */ \
HANDLE_OPCODE (WASM_OP_F64_GT), /* 0x64 */ \
HANDLE_OPCODE (WASM_OP_F64_LE), /* 0x65 */ \
HANDLE_OPCODE (WASM_OP_F64_GE), /* 0x66 */ \
HANDLE_OPCODE (WASM_OP_I32_CLZ), /* 0x67 */ \
HANDLE_OPCODE (WASM_OP_I32_CTZ), /* 0x68 */ \
HANDLE_OPCODE (WASM_OP_I32_POPCNT), /* 0x69 */ \
HANDLE_OPCODE (WASM_OP_I32_ADD), /* 0x6a */ \
HANDLE_OPCODE (WASM_OP_I32_SUB), /* 0x6b */ \
HANDLE_OPCODE (WASM_OP_I32_MUL), /* 0x6c */ \
HANDLE_OPCODE (WASM_OP_I32_DIV_S), /* 0x6d */ \
HANDLE_OPCODE (WASM_OP_I32_DIV_U), /* 0x6e */ \
HANDLE_OPCODE (WASM_OP_I32_REM_S), /* 0x6f */ \
HANDLE_OPCODE (WASM_OP_I32_REM_U), /* 0x70 */ \
HANDLE_OPCODE (WASM_OP_I32_AND), /* 0x71 */ \
HANDLE_OPCODE (WASM_OP_I32_OR), /* 0x72 */ \
HANDLE_OPCODE (WASM_OP_I32_XOR), /* 0x73 */ \
HANDLE_OPCODE (WASM_OP_I32_SHL), /* 0x74 */ \
HANDLE_OPCODE (WASM_OP_I32_SHR_S), /* 0x75 */ \
HANDLE_OPCODE (WASM_OP_I32_SHR_U), /* 0x76 */ \
HANDLE_OPCODE (WASM_OP_I32_ROTL), /* 0x77 */ \
HANDLE_OPCODE (WASM_OP_I32_ROTR), /* 0x78 */ \
HANDLE_OPCODE (WASM_OP_I64_CLZ), /* 0x79 */ \
HANDLE_OPCODE (WASM_OP_I64_CTZ), /* 0x7a */ \
HANDLE_OPCODE (WASM_OP_I64_POPCNT), /* 0x7b */ \
HANDLE_OPCODE (WASM_OP_I64_ADD), /* 0x7c */ \
HANDLE_OPCODE (WASM_OP_I64_SUB), /* 0x7d */ \
HANDLE_OPCODE (WASM_OP_I64_MUL), /* 0x7e */ \
HANDLE_OPCODE (WASM_OP_I64_DIV_S), /* 0x7f */ \
HANDLE_OPCODE (WASM_OP_I64_DIV_U), /* 0x80 */ \
HANDLE_OPCODE (WASM_OP_I64_REM_S), /* 0x81 */ \
HANDLE_OPCODE (WASM_OP_I64_REM_U), /* 0x82 */ \
HANDLE_OPCODE (WASM_OP_I64_AND), /* 0x83 */ \
HANDLE_OPCODE (WASM_OP_I64_OR), /* 0x84 */ \
HANDLE_OPCODE (WASM_OP_I64_XOR), /* 0x85 */ \
HANDLE_OPCODE (WASM_OP_I64_SHL), /* 0x86 */ \
HANDLE_OPCODE (WASM_OP_I64_SHR_S), /* 0x87 */ \
HANDLE_OPCODE (WASM_OP_I64_SHR_U), /* 0x88 */ \
HANDLE_OPCODE (WASM_OP_I64_ROTL), /* 0x89 */ \
HANDLE_OPCODE (WASM_OP_I64_ROTR), /* 0x8a */ \
HANDLE_OPCODE (WASM_OP_F32_ABS), /* 0x8b */ \
HANDLE_OPCODE (WASM_OP_F32_NEG), /* 0x8c */ \
HANDLE_OPCODE (WASM_OP_F32_CEIL), /* 0x8d */ \
HANDLE_OPCODE (WASM_OP_F32_FLOOR), /* 0x8e */ \
HANDLE_OPCODE (WASM_OP_F32_TRUNC), /* 0x8f */ \
HANDLE_OPCODE (WASM_OP_F32_NEAREST), /* 0x90 */ \
HANDLE_OPCODE (WASM_OP_F32_SQRT), /* 0x91 */ \
HANDLE_OPCODE (WASM_OP_F32_ADD), /* 0x92 */ \
HANDLE_OPCODE (WASM_OP_F32_SUB), /* 0x93 */ \
HANDLE_OPCODE (WASM_OP_F32_MUL), /* 0x94 */ \
HANDLE_OPCODE (WASM_OP_F32_DIV), /* 0x95 */ \
HANDLE_OPCODE (WASM_OP_F32_MIN), /* 0x96 */ \
HANDLE_OPCODE (WASM_OP_F32_MAX), /* 0x97 */ \
HANDLE_OPCODE (WASM_OP_F32_COPYSIGN), /* 0x98 */ \
HANDLE_OPCODE (WASM_OP_F64_ABS), /* 0x99 */ \
HANDLE_OPCODE (WASM_OP_F64_NEG), /* 0x9a */ \
HANDLE_OPCODE (WASM_OP_F64_CEIL), /* 0x9b */ \
HANDLE_OPCODE (WASM_OP_F64_FLOOR), /* 0x9c */ \
HANDLE_OPCODE (WASM_OP_F64_TRUNC), /* 0x9d */ \
HANDLE_OPCODE (WASM_OP_F64_NEAREST), /* 0x9e */ \
HANDLE_OPCODE (WASM_OP_F64_SQRT), /* 0x9f */ \
HANDLE_OPCODE (WASM_OP_F64_ADD), /* 0xa0 */ \
HANDLE_OPCODE (WASM_OP_F64_SUB), /* 0xa1 */ \
HANDLE_OPCODE (WASM_OP_F64_MUL), /* 0xa2 */ \
HANDLE_OPCODE (WASM_OP_F64_DIV), /* 0xa3 */ \
HANDLE_OPCODE (WASM_OP_F64_MIN), /* 0xa4 */ \
HANDLE_OPCODE (WASM_OP_F64_MAX), /* 0xa5 */ \
HANDLE_OPCODE (WASM_OP_F64_COPYSIGN), /* 0xa6 */ \
HANDLE_OPCODE (WASM_OP_I32_WRAP_I64), /* 0xa7 */ \
HANDLE_OPCODE (WASM_OP_I32_TRUNC_S_F32), /* 0xa8 */ \
HANDLE_OPCODE (WASM_OP_I32_TRUNC_U_F32), /* 0xa9 */ \
HANDLE_OPCODE (WASM_OP_I32_TRUNC_S_F64), /* 0xaa */ \
HANDLE_OPCODE (WASM_OP_I32_TRUNC_U_F64), /* 0xab */ \
HANDLE_OPCODE (WASM_OP_I64_EXTEND_S_I32), /* 0xac */ \
HANDLE_OPCODE (WASM_OP_I64_EXTEND_U_I32), /* 0xad */ \
HANDLE_OPCODE (WASM_OP_I64_TRUNC_S_F32), /* 0xae */ \
HANDLE_OPCODE (WASM_OP_I64_TRUNC_U_F32), /* 0xaf */ \
HANDLE_OPCODE (WASM_OP_I64_TRUNC_S_F64), /* 0xb0 */ \
HANDLE_OPCODE (WASM_OP_I64_TRUNC_U_F64), /* 0xb1 */ \
HANDLE_OPCODE (WASM_OP_F32_CONVERT_S_I32), /* 0xb2 */ \
HANDLE_OPCODE (WASM_OP_F32_CONVERT_U_I32), /* 0xb3 */ \
HANDLE_OPCODE (WASM_OP_F32_CONVERT_S_I64), /* 0xb4 */ \
HANDLE_OPCODE (WASM_OP_F32_CONVERT_U_I64), /* 0xb5 */ \
HANDLE_OPCODE (WASM_OP_F32_DEMOTE_F64), /* 0xb6 */ \
HANDLE_OPCODE (WASM_OP_F64_CONVERT_S_I32), /* 0xb7 */ \
HANDLE_OPCODE (WASM_OP_F64_CONVERT_U_I32), /* 0xb8 */ \
HANDLE_OPCODE (WASM_OP_F64_CONVERT_S_I64), /* 0xb9 */ \
HANDLE_OPCODE (WASM_OP_F64_CONVERT_U_I64), /* 0xba */ \
HANDLE_OPCODE (WASM_OP_F64_PROMOTE_F32), /* 0xbb */ \
HANDLE_OPCODE (WASM_OP_I32_REINTERPRET_F32), /* 0xbc */ \
HANDLE_OPCODE (WASM_OP_I64_REINTERPRET_F64), /* 0xbd */ \
HANDLE_OPCODE (WASM_OP_F32_REINTERPRET_I32), /* 0xbe */ \
HANDLE_OPCODE (WASM_OP_F64_REINTERPRET_I64), /* 0xbf */ \
HANDLE_OPCODE (WASM_OP_DROP_32), /* 0xc0 */ \
HANDLE_OPCODE (WASM_OP_DROP_64), /* 0xc1 */ \
HANDLE_OPCODE (WASM_OP_SELECT_32), /* 0xc2 */ \
HANDLE_OPCODE (WASM_OP_SELECT_64), /* 0xc3 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP1), /* 0xc4 */ \
HANDLE_OPCODE (WASM_OP_IMPDEP2), /* 0xc5 */ \
}
#endif /* end of _WASM_OPCODE_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,328 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_RUNTIME_H
#define _WASM_RUNTIME_H
#include "wasm.h"
#include "wasm-thread.h"
#include "wasm_hashmap.h"
#ifdef __cplusplus
extern "C" {
#endif
#define DEFAULT_WASM_STACK_SIZE (8 * 1024)
#define DEFAULT_WASM_HEAP_SIZE (8 * 1024)
#define MIN_WASM_HEAP_SIZE (1 * 1024)
typedef struct WASMMemoryInstance {
/* Current page count */
uint32 cur_page_count;
/* Maximum page count */
uint32 max_page_count;
/* Data of import globals with address info, like _stdin/_stdout/_stderr,
stdin/stdout/stderr is stored here, but the actual addr info, or offset
to memory_data is stored in global_data section */
uint8 *addr_data;
/* Size of addr_data */
uint32 addr_data_size;
/* Thunk data of argument strings */
uint8 *thunk_argv_data;
uint32 thunk_argv_data_size;
/* Thunk argument count */
uint32 thunk_argc;
/* Thunk argument offsets */
uint8 *thunk_argv_offsets;
/* Heap data */
uint8 *heap_data;
/* Heap size */
uint32 heap_data_size;
/* The heap created */
void *heap_handle;
/* Memory data */
uint8 *memory_data;
/* Global data of global instances */
uint8 *global_data;
uint32 global_data_size;
/* End address of memory */
uint8 *end_addr;
/* Base address, the layout is:
addr_data + thunk_argv data + thunk arg offsets +
heap data + memory data + global data
memory data init size is: NumBytesPerPage * cur_page_count
addr data size and global data size is calculated in module instantiating
Note: when memory is re-allocated, the addr data, thunk argv data, thunk
argv offsets and memory data must be copied to new memory also.
*/
uint8 base_addr[1];
} WASMMemoryInstance;
typedef struct WASMTableInstance {
/* The element type, TABLE_ELEM_TYPE_ANY_FUNC currently */
uint8 elem_type;
/* Current size */
uint32 cur_size;
/* Maximum size */
uint32 max_size;
/* Base address */
uint8 base_addr[1];
} WASMTableInstance;
typedef struct WASMGlobalInstance {
/* value type, VALUE_TYPE_I32/I64/F32/F64 */
uint8 type;
/* mutable or constant */
bool is_mutable;
bool is_addr;
/* data offset to base_addr of WASMMemoryInstance */
uint32 data_offset;
/* initial value */
WASMValue initial_value;
} WASMGlobalInstance;
typedef struct WASMFunctionInstance {
/* whether it is import function or WASM function */
bool is_import_func;
/* cell num of parameters */
uint16 param_cell_num;
/* cell num of return type */
uint16 ret_cell_num;
/* cell num of local variables, 0 for import function */
uint16 local_cell_num;
uint16 *local_offsets;
union {
WASMFunctionImport *func_import;
WASMFunction *func;
} u;
} WASMFunctionInstance;
typedef struct WASMExportFuncInstance {
char *name;
WASMFunctionInstance *function;
} WASMExportFuncInstance;
/* Package Type */
typedef enum {
Wasm_Module_Bytecode = 0,
Wasm_Module_AoT,
Package_Type_Unknown = 0xFFFF
} PackageType;
typedef struct WASMModuleInstance {
/* Module instance type, for module instance loaded from
WASM bytecode binary, this field is Wasm_Module_Bytecode;
for module instance loaded from AOT package, this field is
Wasm_Module_AoT, and this structure should be treated as
WASMAOTContext structure. */
uint32 module_type;
uint32 memory_count;
uint32 table_count;
uint32 global_count;
uint32 function_count;
uint32 export_func_count;
WASMMemoryInstance **memories;
WASMTableInstance **tables;
WASMGlobalInstance *globals;
WASMFunctionInstance *functions;
WASMExportFuncInstance *export_functions;
WASMMemoryInstance *default_memory;
WASMTableInstance *default_table;
WASMFunctionInstance *start_function;
HashMap *branch_set;
const WASMModule *module;
uint32 DYNAMICTOP_PTR_offset;
uint32 temp_ret;
uint32 llvm_stack;
/* Default WASM stack size of threads of this Module instance. */
uint32 wasm_stack_size;
/* Default WASM stack */
uint8 *wasm_stack;
/* The exception buffer of wasm interpreter for current thread. */
char cur_exception[128];
/* The thread data of the attaching thread */
void *thread_data;
/* Main Thread */
WASMThread main_tlr;
} WASMModuleInstance;
/* Execution environment, e.g. stack info */
typedef struct WASMExecEnv {
uint8_t *stack;
uint32_t stack_size;
} WASMExecEnv;
struct WASMInterpFrame;
typedef struct WASMInterpFrame WASMRuntimeFrame;
/**
* Return the current thread.
*
* @return the current thread
*/
static inline WASMThread*
wasm_runtime_get_self()
{
return (WASMThread*)ws_tls_get();
}
/**
* Set self as the current thread.
*
* @param self the thread to be set as current thread
*/
static inline void
wasm_runtime_set_tlr(WASMThread *self)
{
ws_tls_put(self);
}
/**
* Return the code block of a function.
*
* @param func the WASM function instance
*
* @return the code block of the function
*/
static inline uint8*
wasm_runtime_get_func_code(WASMFunctionInstance *func)
{
return func->is_import_func ? NULL : func->u.func->code;
}
/**
* Return the code block end of a function.
*
* @param func the WASM function instance
*
* @return the code block end of the function
*/
static inline uint8*
wasm_runtime_get_func_code_end(WASMFunctionInstance *func)
{
return func->is_import_func
? NULL : func->u.func->code + func->u.func->code_size;
}
/**
* Call the given WASM function of a WASM module instance with arguments (bytecode and AoT).
*
* @param module_inst the WASM module instance which the function belongs to
* @param exec_env the execution environment to call the function. If the module instance
* is created by AoT mode, it is ignored and just set it to NULL. If the module instance
* is created by bytecode mode and it is NULL, a temporary env object will be created
* @param function the function to be called
* @param argc the number of arguments
* @param argv the arguments. If the function method has return value,
* the first (or first two in case 64-bit return value) element of
* argv stores the return value of the called WASM function after this
* function returns.
*
* @return true if success, false otherwise and exception will be thrown,
* the caller can call wasm_runtime_get_exception to get exception info.
*/
bool
wasm_runtime_call_wasm(WASMModuleInstance *module,
WASMExecEnv *exec_env,
WASMFunctionInstance *function,
unsigned argc, uint32 argv[]);
/**
* Set current exception string to global exception string.
*
* @param module the wasm module instance
*
* @param exception current exception string
*/
void
wasm_runtime_set_exception(WASMModuleInstance *module,
const char *exception);
/**
* Get current exception string.
*
* @param module the wasm module instance
*
* @return return exception string if exception is thrown, NULL otherwise
*/
const char*
wasm_runtime_get_exception(WASMModuleInstance *module);
/**
* Enlarge wasm memory data space.
*
* @param module the wasm module instance
* @param inc_page_count denote the page number to increase
* @return return true if enlarge successfully, false otherwise
*/
bool
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count);
/* See wasm-export.h for description */
WASMModuleInstance *
wasm_runtime_get_current_module_inst();
/* See wasm-export.h for description */
int32_t
wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32_t size);
/* See wasm-export.h for description */
void
wasm_runtime_module_free(WASMModuleInstance *module_inst, int32_t ptr);
/* See wasm-export.h for description */
bool
wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
int32_t app_offset, uint32_t size);
/* See wasm-export.h for description */
bool
wasm_runtime_validate_native_addr(WASMModuleInstance *module_inst,
void *native_ptr, uint32_t size);
/* See wasm-export.h for description */
void *
wasm_runtime_addr_app_to_native(WASMModuleInstance *module_inst,
int32_t app_offset);
/* See wasm-export.h for description */
int32_t
wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
void *native_ptr);
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_RUNTIME_H */

View File

@ -0,0 +1,146 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_RUNTIME_THREAD_H
#define _WASM_RUNTIME_THREAD_H
#include "wasm_assert.h"
#include "wasm_thread.h"
#ifdef __cplusplus
extern "C" {
#endif
struct WASMModuleInstance;
struct WASMInterpFrame;
typedef struct WASMStack {
/* The bottom of the stack, must be 8-bytes align. */
uint8 *bottom;
/* Top cell index which is free. */
uint8 *top;
/* The top boundary of the stack. */
uint8 *top_boundary;
} WASMStack;
typedef struct WASMThread {
/* Previous thread's tlr of an instance. */
struct WASMThread *prev;
/* Next thread's tlr of an instance. */
struct WASMThread *next;
/* The WASM module instance of current thread */
struct WASMModuleInstance *module_inst;
/* Current frame of current thread. */
struct WASMInterpFrame *cur_frame;
/* The boundary of native stack. When interpreter detects that native
frame may overrun this boundary, it will throw a stack overflow
exception. */
void *native_stack_boundary;
/* The WASM stack of current thread. */
WASMStack wasm_stack;
/* The native thread handle of current thread. */
korp_tid handle;
/* Current suspend count of this thread. */
uint32 suspend_count;
} WASMThread;
/**
* Allocate a WASM frame from the WASM stack.
*
* @param tlr the current thread
* @param size size of the WASM frame, it must be a multiple of 4
*
* @return the WASM frame if there is enough space in the stack area
* with a protection area, NULL otherwise
*/
static inline void*
wasm_thread_alloc_wasm_frame(WASMThread *tlr, unsigned size)
{
uint8 *addr = tlr->wasm_stack.top;
wasm_assert(!(size & 3));
/* The outs area size cannot be larger than the frame size, so
multiplying by 2 is enough. */
if (addr + size * 2 > tlr->wasm_stack.top_boundary) {
/* WASM stack overflow. */
/* When throwing SOE, the preserved space must be enough. */
/*wasm_assert(!tlr->throwing_soe);*/
return NULL;
}
tlr->wasm_stack.top += size;
return addr;
}
static inline void
wasm_thread_free_wasm_frame(WASMThread *tlr, void *prev_top)
{
wasm_assert((uint8 *)prev_top >= tlr->wasm_stack.bottom);
tlr->wasm_stack.top = (uint8 *)prev_top;
}
/**
* Get the current WASM stack top pointer.
*
* @param tlr the current thread
*
* @return the current WASM stack top pointer
*/
static inline void*
wasm_thread_wasm_stack_top(WASMThread *tlr)
{
return tlr->wasm_stack.top;
}
/**
* Set the current frame pointer.
*
* @param tlr the current thread
* @param frame the WASM frame to be set for the current thread
*/
static inline void
wasm_thread_set_cur_frame(WASMThread *tlr, struct WASMInterpFrame *frame)
{
tlr->cur_frame = frame;
}
/**
* Get the current frame pointer.
*
* @param tlr the current thread
*
* @return the current frame pointer
*/
static inline struct WASMInterpFrame*
wasm_thread_get_cur_frame(WASMThread *tlr)
{
return tlr->cur_frame;
}
#ifdef __cplusplus
}
#endif
#endif /* end of _WASM_RUNTIME_THREAD_H */

View File

@ -0,0 +1,392 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _WASM_H_
#define _WASM_H_
#include "wasm_platform.h"
#include "wasm_hashmap.h"
#include "wasm_assert.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Value Type */
#define VALUE_TYPE_I32 0x7F
#define VALUE_TYPE_I64 0X7E
#define VALUE_TYPE_F32 0x7D
#define VALUE_TYPE_F64 0x7C
#define VALUE_TYPE_VOID 0x00
/* Table Element Type */
#define TABLE_ELEM_TYPE_ANY_FUNC 0x70
#define MaxMemoryPages 65536
#define MaxTableElems UINT32_MAX
#define NumBytesPerPage 65536
#define NumBytesPerPageLog2 16
#define MaxReturnValues 16
#define INIT_EXPR_TYPE_I32_CONST 0x41
#define INIT_EXPR_TYPE_I64_CONST 0x42
#define INIT_EXPR_TYPE_F32_CONST 0x43
#define INIT_EXPR_TYPE_F64_CONST 0x44
#define INIT_EXPR_TYPE_GET_GLOBAL 0x23
#define INIT_EXPR_TYPE_ERROR 0xff
#define WASM_MAGIC_NUMBER 0x6d736100
#define WASM_CURRENT_VERSION 1
#define SECTION_TYPE_USER 0
#define SECTION_TYPE_TYPE 1
#define SECTION_TYPE_IMPORT 2
#define SECTION_TYPE_FUNC 3
#define SECTION_TYPE_TABLE 4
#define SECTION_TYPE_MEMORY 5
#define SECTION_TYPE_GLOBAL 6
#define SECTION_TYPE_EXPORT 7
#define SECTION_TYPE_START 8
#define SECTION_TYPE_ELEM 9
#define SECTION_TYPE_CODE 10
#define SECTION_TYPE_DATA 11
#define IMPORT_KIND_FUNC 0
#define IMPORT_KIND_TABLE 1
#define IMPORT_KIND_MEMORY 2
#define IMPORT_KIND_GLOBAL 3
#define EXPORT_KIND_FUNC 0
#define EXPORT_KIND_TABLE 1
#define EXPORT_KIND_MEMORY 2
#define EXPORT_KIND_GLOBAL 3
#define BLOCK_TYPE_BLOCK 0
#define BLOCK_TYPE_LOOP 1
#define BLOCK_TYPE_IF 2
#define BLOCK_TYPE_FUNCTION 3
#define CALL_TYPE_WRAPPER 0
#define CALL_TYPE_C_INTRINSIC 1
typedef union WASMValue {
int32 i32;
uint32 u32;
int64 i64;
uint64 u64;
float32 f32;
float64 f64;
uintptr_t addr;
} WASMValue;
typedef struct InitializerExpression {
/* type of INIT_EXPR_TYPE_XXX */
uint8 init_expr_type;
union {
int32 i32;
int64 i64;
float32 f32;
float64 f64;
uint32 global_index;
} u;
} InitializerExpression;
typedef struct WASMType {
uint32 param_count;
/* only one result is supported currently */
uint32 result_count;
/* types of params and results */
uint8 types[1];
} WASMType;
typedef struct WASMTable {
uint8 elem_type;
uint32 flags;
uint32 init_size;
/* specified if (flags & 1), else it is 0x10000 */
uint32 max_size;
} WASMTable;
typedef struct WASMMemory {
uint32 flags;
/* 64 kbytes one page by default */
uint32 init_page_count;
uint32 max_page_count;
} WASMMemory;
typedef struct WASMTableImport {
char *module_name;
char *field_name;
uint8 elem_type;
uint32 flags;
uint32 init_size;
/* specified if (flags & 1), else it is 0x10000 */
uint32 max_size;
} WASMTableImport;
typedef struct WASMMemoryImport {
char *module_name;
char *field_name;
uint32 flags;
/* 64 kbytes one page by default */
uint32 init_page_count;
uint32 max_page_count;
} WASMMemoryImport;
typedef struct WASMFunctionImport {
char *module_name;
char *field_name;
/* function type */
WASMType *func_type;
/* c intrinsic function or wrapper function */
uint32 call_type;
/* function pointer after linked */
void *func_ptr_linked;
} WASMFunctionImport;
typedef struct WASMGlobalImport {
char *module_name;
char *field_name;
uint8 type;
bool is_mutable;
bool is_addr;
/* global data after linked */
WASMValue global_data_linked;
} WASMGlobalImport;
typedef struct WASMImport {
uint8 kind;
union {
WASMFunctionImport function;
WASMTableImport table;
WASMMemoryImport memory;
WASMGlobalImport global;
struct {
char *module_name;
char *field_name;
} names;
} u;
} WASMImport;
typedef struct WASMFunction {
/* the type of function */
WASMType *func_type;
uint32 local_count;
uint8 *local_types;
uint32 max_stack_cell_num;
uint32 max_block_num;
uint32 code_size;
uint8 *code;
} WASMFunction;
typedef struct WASMGlobal {
uint8 type;
bool is_mutable;
bool is_addr;
InitializerExpression init_expr;
} WASMGlobal;
typedef struct WASMExport {
char *name;
uint8 kind;
uint32 index;
} WASMExport;
typedef struct WASMTableSeg {
uint32 table_index;
InitializerExpression base_offset;
uint32 function_count;
uint32 *func_indexes;
} WASMTableSeg;
typedef struct WASMDataSeg {
uint32 memory_index;
InitializerExpression base_offset;
uint32 data_length;
uint8 *data;
} WASMDataSeg;
typedef struct WASMModule {
uint32 type_count;
uint32 import_count;
uint32 function_count;
uint32 table_count;
uint32 memory_count;
uint32 global_count;
uint32 export_count;
uint32 table_seg_count;
uint32 data_seg_count;
uint32 import_function_count;
uint32 import_table_count;
uint32 import_memory_count;
uint32 import_global_count;
WASMImport *import_functions;
WASMImport *import_tables;
WASMImport *import_memories;
WASMImport *import_globals;
WASMType **types;
WASMImport *imports;
WASMFunction **functions;
WASMTable *tables;
WASMMemory *memories;
WASMGlobal *globals;
WASMExport *exports;
WASMTableSeg *table_segments;
WASMDataSeg **data_segments;
uint32 start_function;
HashMap *const_str_set;
HashMap *branch_set;
} WASMModule;
typedef struct WASMBranchBlock {
uint8 block_type;
uint8 return_type;
uint8 *start_addr;
uint8 *else_addr;
uint8 *end_addr;
uint32 *frame_sp;
uint8 *frame_ref;
} WASMBranchBlock;
typedef struct WASMSection {
struct WASMSection *next;
/* section type */
int section_type;
/* section body, not include type and size */
const uint8_t *section_body;
/* section body size */
uint32_t section_body_size;
} WASMSection;
/* Execution environment, e.g. stack info */
/**
* Align an unsigned value on a alignment boundary.
*
* @param v the value to be aligned
* @param b the alignment boundary (2, 4, 8, ...)
*
* @return the aligned value
*/
inline static unsigned
align_uint (unsigned v, unsigned b)
{
unsigned m = b - 1;
return (v + m) & ~m;
}
/**
* Return the hash value of c string.
*/
inline static uint32
wasm_string_hash(const char *str)
{
unsigned h = strlen(str);
const uint8 *p = (uint8*)str;
const uint8 *end = p + h;
while (p != end)
h = ((h << 5) - h) + *p++;
return h;
}
/**
* Whether two c strings are equal.
*/
inline static bool
wasm_string_equal(const char *s1, const char *s2)
{
return strcmp(s1, s2) == 0 ? true : false;
}
/**
* Return the byte size of value type.
*
*/
inline static uint32
wasm_value_type_size(uint8 value_type)
{
switch (value_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
return sizeof(int32);
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
return sizeof(int64);
default:
wasm_assert(0);
}
return 0;
}
inline static uint16
wasm_value_type_cell_num(uint8 value_type)
{
switch (value_type) {
case VALUE_TYPE_I32:
case VALUE_TYPE_F32:
return 1;
case VALUE_TYPE_I64:
case VALUE_TYPE_F64:
return 2;
default:
wasm_assert(0);
}
return 0;
}
inline static uint16
wasm_get_cell_num(const uint8 *types, uint32 type_count)
{
uint16 cell_num = 0;
uint32 i;
for (i = 0; i < type_count; i++)
cell_num += wasm_value_type_cell_num(types[i]);
return cell_num;
}
inline static uint16
wasm_type_param_cell_num(const WASMType *type)
{
return wasm_get_cell_num(type->types, type->param_count);
}
inline static uint16
wasm_type_return_cell_num(const WASMType *type)
{
return wasm_get_cell_num(type->types + type->param_count,
type->result_count);
}
inline static bool
wasm_type_equal(const WASMType *type1, const WASMType *type2)
{
return (type1->param_count == type2->param_count
&& type1->result_count == type2->result_count
&& memcmp(type1->types, type2->types,
type1->param_count + type1->result_count) == 0)
? true : false;
}
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* end of _WASM_H_ */