Enable WASI feature, enhance security and add SGX sample (#142)
Change emcc to clang Refine interpreter to improve perforamnce
This commit is contained in:
@ -24,10 +24,6 @@ extern "C" {
|
||||
#define app_manager_printf printk
|
||||
#endif
|
||||
|
||||
#define ID_HOST -3
|
||||
#define ID_APP_MGR -2
|
||||
#define ID_NONE (uint32)-1
|
||||
|
||||
#define SEND_ERR_RESPONSE(mid, err_msg) do { \
|
||||
app_manager_printf("%s\n", err_msg); \
|
||||
send_error_response_to_host(mid, INTERNAL_SERVER_ERROR_5_00, err_msg); \
|
||||
|
||||
@ -121,8 +121,9 @@ module_data_list_lookup_id(unsigned int module_id)
|
||||
module_data *
|
||||
app_manager_get_module_data(uint32 module_type, void *module_inst)
|
||||
{
|
||||
if (g_module_interfaces[module_type]
|
||||
&& g_module_interfaces[module_type]->module_get_module_data)
|
||||
if (module_type < Module_Max
|
||||
&& g_module_interfaces[module_type]
|
||||
&& g_module_interfaces[module_type]->module_get_module_data)
|
||||
return g_module_interfaces[module_type]->module_get_module_data(module_inst);
|
||||
return NULL;
|
||||
}
|
||||
@ -130,24 +131,28 @@ app_manager_get_module_data(uint32 module_type, void *module_inst)
|
||||
void*
|
||||
app_manager_get_module_queue(uint32 module_type, void *module_inst)
|
||||
{
|
||||
return app_manager_get_module_data(module_type, module_inst)->queue;
|
||||
module_data *m_data = app_manager_get_module_data(module_type, module_inst);
|
||||
return m_data ? m_data->queue : NULL;
|
||||
}
|
||||
|
||||
const char*
|
||||
app_manager_get_module_name(uint32 module_type, void *module_inst)
|
||||
{
|
||||
return app_manager_get_module_data(module_type, module_inst)->module_name;
|
||||
module_data *m_data = app_manager_get_module_data(module_type, module_inst);
|
||||
return m_data ? m_data->module_name : NULL;
|
||||
}
|
||||
|
||||
unsigned int app_manager_get_module_id(uint32 module_type, void *module_inst)
|
||||
{
|
||||
return app_manager_get_module_data(module_type, module_inst)->id;
|
||||
module_data *m_data = app_manager_get_module_data(module_type, module_inst);
|
||||
return m_data ? m_data->id : ID_NONE;
|
||||
}
|
||||
|
||||
void*
|
||||
app_manager_get_module_heap(uint32 module_type, void *module_inst)
|
||||
{
|
||||
return app_manager_get_module_data(module_type, module_inst)->heap;
|
||||
module_data *m_data = app_manager_get_module_data(module_type, module_inst);
|
||||
return m_data ? m_data->heap : NULL;
|
||||
}
|
||||
|
||||
module_data*
|
||||
@ -170,7 +175,8 @@ void app_manager_del_module_data(module_data *m_data)
|
||||
|
||||
bool app_manager_is_interrupting_module(uint32 module_type, void *module_inst)
|
||||
{
|
||||
return app_manager_get_module_data(module_type, module_inst)->wd_timer.is_interrupting;
|
||||
module_data *m_data = app_manager_get_module_data(module_type, module_inst);
|
||||
return m_data ? m_data->wd_timer.is_interrupting : false;
|
||||
}
|
||||
|
||||
extern void destroy_module_timer_ctx(unsigned int module_id);
|
||||
|
||||
@ -17,12 +17,20 @@
|
||||
#include "runtime_lib.h"
|
||||
|
||||
/* Wasm app 4 magic bytes */
|
||||
static unsigned char wasm_app_magics[] = { (unsigned char) 0x00,
|
||||
(unsigned char) 0x61, (unsigned char) 0x73, (unsigned char) 0x6d };
|
||||
static unsigned char wasm_app_magics[] = {
|
||||
(unsigned char) 0x00,
|
||||
(unsigned char) 0x61,
|
||||
(unsigned char) 0x73,
|
||||
(unsigned char) 0x6d
|
||||
};
|
||||
|
||||
/* Wasm app 4 version bytes */
|
||||
static unsigned char wasm_app_version[] = { (unsigned char) 0x01,
|
||||
(unsigned char) 0x00, (unsigned char) 0x00, (unsigned char) 0x00 };
|
||||
static unsigned char wasm_app_version[] = {
|
||||
(unsigned char) 0x01,
|
||||
(unsigned char) 0x00,
|
||||
(unsigned char) 0x00,
|
||||
(unsigned char) 0x00
|
||||
};
|
||||
|
||||
/* Wasm App Install Request Receiving Phase */
|
||||
typedef enum wasm_app_install_req_recv_phase_t {
|
||||
@ -73,7 +81,7 @@ static bool wasm_app_module_handle_host_url(void *queue_msg);
|
||||
static module_data *wasm_app_module_get_module_data(void *inst);
|
||||
static bool
|
||||
wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
|
||||
int *received_size);
|
||||
int *received_size);
|
||||
|
||||
static bool module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message);
|
||||
static void destroy_wasm_sections_list(wasm_section_t *sections);
|
||||
@ -84,14 +92,18 @@ int g_msg_type[Max_Msg_Callback] = { 0 };
|
||||
message_type_handler_t g_msg_callbacks[Max_Msg_Callback] = { 0 };
|
||||
|
||||
#define Max_Cleanup_Callback 10
|
||||
static resource_cleanup_handler_t g_cleanup_callbacks[Max_Cleanup_Callback] = {
|
||||
0 };
|
||||
static resource_cleanup_handler_t
|
||||
g_cleanup_callbacks[Max_Cleanup_Callback] = { 0 };
|
||||
|
||||
module_interface wasm_app_module_interface = { wasm_app_module_init,
|
||||
wasm_app_module_install, wasm_app_module_uninstall,
|
||||
wasm_app_module_watchdog_kill, wasm_app_module_handle_host_url,
|
||||
wasm_app_module_get_module_data,
|
||||
wasm_app_module_on_install_request_byte_arrive };
|
||||
module_interface wasm_app_module_interface = {
|
||||
wasm_app_module_init,
|
||||
wasm_app_module_install,
|
||||
wasm_app_module_uninstall,
|
||||
wasm_app_module_watchdog_kill,
|
||||
wasm_app_module_handle_host_url,
|
||||
wasm_app_module_get_module_data,
|
||||
wasm_app_module_on_install_request_byte_arrive
|
||||
};
|
||||
|
||||
static unsigned align_uint(unsigned v, unsigned b)
|
||||
{
|
||||
@ -99,6 +111,19 @@ static unsigned align_uint(unsigned v, unsigned b)
|
||||
return (v + m) & ~m;
|
||||
}
|
||||
|
||||
static wasm_function_inst_t
|
||||
app_manager_lookup_function(const wasm_module_inst_t module_inst,
|
||||
const char *name, const char *signature)
|
||||
{
|
||||
wasm_function_inst_t func;
|
||||
|
||||
func = wasm_runtime_lookup_function(module_inst, name, signature);
|
||||
if (!func && name[0] == '_')
|
||||
func = wasm_runtime_lookup_function(module_inst, name + 1, signature);
|
||||
return func;
|
||||
}
|
||||
|
||||
|
||||
static void app_instance_queue_callback(void *queue_msg, void *arg)
|
||||
{
|
||||
uint32 argv[2];
|
||||
@ -108,133 +133,157 @@ static void app_instance_queue_callback(void *queue_msg, void *arg)
|
||||
module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst);
|
||||
int message_type = bh_message_type(queue_msg);
|
||||
|
||||
switch (message_type) {
|
||||
case RESTFUL_REQUEST: {
|
||||
request_t *request = (request_t *) bh_message_payload(queue_msg);
|
||||
int size;
|
||||
char *buffer;
|
||||
int32 buffer_offset;
|
||||
bh_assert(m_data);
|
||||
|
||||
app_manager_printf("App %s got request, url %s, action %d\n",
|
||||
m_data->module_name, request->url, request->action);
|
||||
if (message_type < BASE_EVENT_MAX) {
|
||||
switch (message_type) {
|
||||
case RESTFUL_REQUEST: {
|
||||
request_t *request = (request_t *)bh_message_payload(queue_msg);
|
||||
int size;
|
||||
char *buffer;
|
||||
int32 buffer_offset;
|
||||
|
||||
func_onRequest = wasm_runtime_lookup_function(inst, "_on_request",
|
||||
"(i32i32)");
|
||||
if (!func_onRequest) {
|
||||
app_manager_printf("Cannot find function onRequest\n");
|
||||
break;
|
||||
}
|
||||
app_manager_printf("App %s got request, url %s, action %d\n",
|
||||
m_data->module_name,
|
||||
request->url,
|
||||
request->action);
|
||||
|
||||
buffer = pack_request(request, &size);
|
||||
if (buffer == NULL)
|
||||
break;
|
||||
func_onRequest = app_manager_lookup_function(inst,
|
||||
"_on_request",
|
||||
"(i32i32)");
|
||||
if (!func_onRequest) {
|
||||
app_manager_printf("Cannot find function onRequest\n");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
|
||||
if (buffer_offset == 0) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
free_req_resp_packet(buffer);
|
||||
break;
|
||||
}
|
||||
buffer = pack_request(request, &size);
|
||||
if (buffer == NULL)
|
||||
break;
|
||||
|
||||
free_req_resp_packet(buffer);
|
||||
buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
|
||||
if (buffer_offset == 0) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
free_req_resp_packet(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
argv[0] = (uint32) buffer_offset;
|
||||
argv[1] = (uint32) size;
|
||||
free_req_resp_packet(buffer);
|
||||
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onRequest, 2, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
break;
|
||||
}
|
||||
argv[0] = (uint32) buffer_offset;
|
||||
argv[1] = (uint32) size;
|
||||
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
app_manager_printf("Wasm app process request success.\n");
|
||||
break;
|
||||
}
|
||||
case RESTFUL_RESPONSE: {
|
||||
response_t *response = (response_t *) bh_message_payload(queue_msg);
|
||||
int size;
|
||||
char *buffer;
|
||||
int32 buffer_offset;
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onRequest, 2, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
app_manager_printf("App %s got response_t,status %d\n",
|
||||
m_data->module_name, response->status);
|
||||
|
||||
wasm_function_inst_t func_onResponse = wasm_runtime_lookup_function(
|
||||
inst, "_on_response", "(i32i32)");
|
||||
if (!func_onResponse) {
|
||||
app_manager_printf("Cannot find function on_response\n");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = pack_response(response, &size);
|
||||
if (buffer == NULL)
|
||||
break;
|
||||
|
||||
buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
|
||||
if (buffer_offset == 0) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
free_req_resp_packet(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
free_req_resp_packet(buffer);
|
||||
|
||||
argv[0] = (uint32) buffer_offset;
|
||||
argv[1] = (uint32) size;
|
||||
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onResponse, 2, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
app_manager_printf("Wasm app process response success.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
case TIMER_EVENT_WASM: {
|
||||
if (bh_message_payload(queue_msg)) {
|
||||
/* Call Timer.callOnTimer() method */
|
||||
func_onTimer = wasm_runtime_lookup_function(inst,
|
||||
"_on_timer_callback", "(i32)");
|
||||
|
||||
if (!func_onTimer) {
|
||||
app_manager_printf("Cannot find function _on_timer_callback\n");
|
||||
break;
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
app_manager_printf("Wasm app process request success.\n");
|
||||
break;
|
||||
}
|
||||
unsigned int timer_id = (unsigned int)(uintptr_t)
|
||||
bh_message_payload(queue_msg);
|
||||
argv[0] = timer_id;
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
case RESTFUL_RESPONSE: {
|
||||
wasm_function_inst_t func_onResponse;
|
||||
response_t *response = (response_t *) bh_message_payload(queue_msg);
|
||||
int size;
|
||||
char *buffer;
|
||||
int32 buffer_offset;
|
||||
|
||||
app_manager_printf("App %s got response_t,status %d\n",
|
||||
m_data->module_name, response->status);
|
||||
|
||||
func_onResponse =
|
||||
app_manager_lookup_function(inst, "_on_response", "(i32i32)");
|
||||
if (!func_onResponse) {
|
||||
app_manager_printf("Cannot find function on_response\n");
|
||||
break;
|
||||
}
|
||||
|
||||
buffer = pack_response(response, &size);
|
||||
if (buffer == NULL)
|
||||
break;
|
||||
|
||||
buffer_offset = wasm_runtime_module_dup_data(inst, buffer, size);
|
||||
if (buffer_offset == 0) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
free_req_resp_packet(buffer);
|
||||
break;
|
||||
}
|
||||
|
||||
free_req_resp_packet(buffer);
|
||||
|
||||
argv[0] = (uint32) buffer_offset;
|
||||
argv[1] = (uint32) size;
|
||||
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onResponse, 2, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
break;
|
||||
}
|
||||
|
||||
wasm_runtime_module_free(inst, buffer_offset);
|
||||
app_manager_printf("Wasm app process response success.\n");
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
for (int i = 0; i < Max_Msg_Callback; i++) {
|
||||
if (g_msg_type[i] == message_type) {
|
||||
g_msg_callbacks[i](m_data, queue_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
app_manager_printf("Invalid message type of WASM app queue message.\n");
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else {
|
||||
switch (message_type) {
|
||||
case TIMER_EVENT_WASM: {
|
||||
unsigned int timer_id;
|
||||
if (bh_message_payload(queue_msg)) {
|
||||
/* Call Timer.callOnTimer() method */
|
||||
func_onTimer =
|
||||
app_manager_lookup_function(inst,
|
||||
"_on_timer_callback",
|
||||
"(i32)");
|
||||
|
||||
default: {
|
||||
for (int i = 0; i < Max_Msg_Callback; i++) {
|
||||
if (g_msg_type[i] == message_type) {
|
||||
g_msg_callbacks[i](m_data, queue_msg);
|
||||
return;
|
||||
if (!func_onTimer) {
|
||||
app_manager_printf("Cannot find function _on_timer_callback\n");
|
||||
break;
|
||||
}
|
||||
timer_id =
|
||||
(unsigned int)(uintptr_t)bh_message_payload(queue_msg);
|
||||
argv[0] = timer_id;
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
|
||||
app_manager_printf("Got exception running wasm code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
for (int i = 0; i < Max_Msg_Callback; i++) {
|
||||
if (g_msg_type[i] == message_type) {
|
||||
g_msg_callbacks[i](m_data, queue_msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
app_manager_printf("Invalid message type of WASM app queue message.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
app_manager_printf("Invalid message type of WASM app queue message.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,7 +305,7 @@ wasm_app_routine(void *arg)
|
||||
app_manager_printf("WASM app '%s' started\n", m_data->module_name);
|
||||
|
||||
/* Call app's onInit() method */
|
||||
func_onInit = wasm_runtime_lookup_function(inst, "_on_init", "()");
|
||||
func_onInit = app_manager_lookup_function(inst, "_on_init", "()");
|
||||
if (!func_onInit) {
|
||||
app_manager_printf("Cannot find function on_init().\n");
|
||||
goto fail1;
|
||||
@ -264,7 +313,7 @@ wasm_app_routine(void *arg)
|
||||
|
||||
if (!wasm_runtime_call_wasm(inst, NULL, func_onInit, 0, NULL)) {
|
||||
printf("Got exception running WASM code: %s\n",
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_get_exception(inst));
|
||||
wasm_runtime_clear_exception(inst);
|
||||
/* call on_destroy() in case some resources are opened in on_init()
|
||||
* and then exception thrown */
|
||||
@ -278,7 +327,7 @@ wasm_app_routine(void *arg)
|
||||
|
||||
fail2:
|
||||
/* Call WASM app onDestroy() method if there is */
|
||||
func_onDestroy = wasm_runtime_lookup_function(inst, "_on_destroy", "()");
|
||||
func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()");
|
||||
if (func_onDestroy)
|
||||
wasm_runtime_call_wasm(inst, NULL, func_onDestroy, 0, NULL);
|
||||
|
||||
@ -341,8 +390,8 @@ static bool wasm_app_module_init(void)
|
||||
|
||||
static bool wasm_app_module_install(request_t * msg)
|
||||
{
|
||||
unsigned int m_data_size, wasm_app_aot_file_len, heap_size, timeout, timers,
|
||||
err_size;
|
||||
unsigned int m_data_size, wasm_app_aot_file_len, heap_size;
|
||||
unsigned int timeout, timers, err_size;
|
||||
char *properties;
|
||||
int properties_offset, i;
|
||||
uint8 *wasm_app_aot_file;
|
||||
@ -352,22 +401,25 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
module_data *m_data;
|
||||
wasm_module_t module = NULL;
|
||||
wasm_module_inst_t inst = NULL;
|
||||
char m_name[APP_NAME_MAX_LEN] = { 0 }, timeout_str[MAX_INT_STR_LEN] = { 0 },
|
||||
heap_size_str[MAX_INT_STR_LEN] = { 0 },
|
||||
timers_str[MAX_INT_STR_LEN] = { 0 }, err[256];
|
||||
char m_name[APP_NAME_MAX_LEN] = { 0 };
|
||||
char timeout_str[MAX_INT_STR_LEN] = { 0 };
|
||||
char heap_size_str[MAX_INT_STR_LEN] = { 0 };
|
||||
char timers_str[MAX_INT_STR_LEN] = { 0 }, err[256];
|
||||
/* Useless sections after load */
|
||||
uint8 sections1[] = { SECTION_TYPE_USER,
|
||||
SECTION_TYPE_TYPE,
|
||||
SECTION_TYPE_IMPORT,
|
||||
SECTION_TYPE_FUNC,
|
||||
SECTION_TYPE_TABLE,
|
||||
SECTION_TYPE_MEMORY,
|
||||
SECTION_TYPE_GLOBAL,
|
||||
SECTION_TYPE_EXPORT,
|
||||
SECTION_TYPE_START,
|
||||
SECTION_TYPE_ELEM,
|
||||
/*SECTION_TYPE_CODE,*/
|
||||
/*SECTION_TYPE_DATA*/};
|
||||
uint8 sections1[] = {
|
||||
SECTION_TYPE_USER,
|
||||
SECTION_TYPE_TYPE,
|
||||
SECTION_TYPE_IMPORT,
|
||||
SECTION_TYPE_FUNC,
|
||||
SECTION_TYPE_TABLE,
|
||||
SECTION_TYPE_MEMORY,
|
||||
SECTION_TYPE_GLOBAL,
|
||||
SECTION_TYPE_EXPORT,
|
||||
SECTION_TYPE_START,
|
||||
SECTION_TYPE_ELEM,
|
||||
/*SECTION_TYPE_CODE,*/
|
||||
/*SECTION_TYPE_DATA*/
|
||||
};
|
||||
/* Useless sections after instantiate */
|
||||
uint8 sections2[] = { SECTION_TYPE_DATA };
|
||||
|
||||
@ -375,8 +427,7 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
|
||||
/* Check payload */
|
||||
if (!msg->payload || msg->payload_len == 0) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: invalid wasm file.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: invalid wasm file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -387,24 +438,22 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
return false;
|
||||
properties = msg->url + properties_offset;
|
||||
find_key_value(properties, strlen(properties), "name", m_name,
|
||||
sizeof(m_name) - 1, '&');
|
||||
sizeof(m_name) - 1, '&');
|
||||
|
||||
if (strlen(m_name) == 0) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: invalid app name.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: invalid app name.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (app_manager_lookup_module_data(m_name)) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: app already installed.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: app already installed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parse heap size */
|
||||
heap_size = APP_HEAP_SIZE_DEFAULT;
|
||||
find_key_value(properties, strlen(properties), "heap", heap_size_str,
|
||||
sizeof(heap_size_str) - 1, '&');
|
||||
sizeof(heap_size_str) - 1, '&');
|
||||
if (strlen(heap_size_str) > 0) {
|
||||
heap_size = atoi(heap_size_str);
|
||||
if (heap_size < APP_HEAP_SIZE_MIN)
|
||||
@ -421,19 +470,20 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
wasm_app_aot_file = (uint8 *) msg->payload;
|
||||
wasm_app_aot_file_len = msg->payload_len;
|
||||
inst = wasm_runtime_load_aot(wasm_app_aot_file, wasm_app_aot_file_len,
|
||||
heap_size, err, err_size);
|
||||
heap_size, err, err_size);
|
||||
if (!inst) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: load wasm aot binary failed.");
|
||||
"Install WASM app failed: load wasm aot binary failed.");
|
||||
return false;
|
||||
}
|
||||
} else if (package_type == Wasm_Module_Bytecode) {
|
||||
}
|
||||
else if (package_type == Wasm_Module_Bytecode) {
|
||||
wasm_app_file = (wasm_app_file_t *) msg->payload;
|
||||
module = wasm_runtime_load_from_sections(wasm_app_file->sections, err,
|
||||
err_size);
|
||||
err_size);
|
||||
if (!module) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: load WASM file failed.");
|
||||
"Install WASM app failed: load WASM file failed.");
|
||||
printf("error: %s\n", err);
|
||||
destroy_wasm_sections_list(wasm_app_file->sections);
|
||||
return false;
|
||||
@ -442,7 +492,7 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
/* Destroy useless sections from list after load */
|
||||
for (i = 0; i < sizeof(sections1); i++)
|
||||
destroy_wasm_section_from_list(&wasm_app_file->sections,
|
||||
sections1[i]);
|
||||
sections1[i]);
|
||||
|
||||
inst = wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
|
||||
if (!inst) {
|
||||
@ -457,11 +507,12 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
/* Destroy useless sections from list after instantiate */
|
||||
for (i = 0; i < sizeof(sections2); i++)
|
||||
destroy_wasm_section_from_list(&wasm_app_file->sections,
|
||||
sections2[i]);
|
||||
sections2[i]);
|
||||
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: invalid wasm package type.");
|
||||
"Install WASM app failed: invalid wasm package type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -470,8 +521,7 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
m_data_size = align_uint(m_data_size, 4);
|
||||
m_data = bh_malloc(m_data_size + sizeof(wasm_data));
|
||||
if (!m_data) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: allocate memory failed.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
memset(m_data, 0, m_data_size + sizeof(wasm_data));
|
||||
@ -490,7 +540,7 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
/* Set module data - execution timeout */
|
||||
timeout = DEFAULT_WATCHDOG_INTERVAL;
|
||||
find_key_value(properties, strlen(properties), "wd", timeout_str,
|
||||
sizeof(timeout_str) - 1, '&');
|
||||
sizeof(timeout_str) - 1, '&');
|
||||
if (strlen(timeout_str) > 0)
|
||||
timeout = atoi(timeout_str);
|
||||
m_data->timeout = timeout;
|
||||
@ -498,8 +548,7 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
/* Set module data - create queue */
|
||||
m_data->queue = bh_queue_create();
|
||||
if (!m_data->queue) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: create app queue failed.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Install WASM app failed: create app queue failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -522,24 +571,23 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
m_data->timer_ctx = create_wasm_timer_ctx(m_data->id, timers);
|
||||
if (!m_data->timer_ctx) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: create app timers failed.");
|
||||
"Install WASM app failed: create app timers failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Initialize watchdog timer */
|
||||
if (!watchdog_timer_init(m_data)) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: create app watchdog timer failed.");
|
||||
"Install WASM app failed: create app watchdog timer failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Create WASM app thread. */
|
||||
if (vm_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
|
||||
(void*) m_data, APP_THREAD_STACK_SIZE_DEFAULT) != 0) {
|
||||
(void*) m_data, APP_THREAD_STACK_SIZE_DEFAULT) != 0) {
|
||||
module_data_list_remove(m_data);
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Install WASM app failed: create app threadf failed.");
|
||||
|
||||
"Install WASM app failed: create app threadf failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -551,7 +599,8 @@ static bool wasm_app_module_install(request_t * msg)
|
||||
|
||||
return true;
|
||||
|
||||
fail: if (m_data)
|
||||
fail:
|
||||
if (m_data)
|
||||
release_module(m_data);
|
||||
|
||||
wasm_runtime_deinstantiate(inst);
|
||||
@ -580,11 +629,10 @@ static bool wasm_app_module_uninstall(request_t *msg)
|
||||
return false;
|
||||
properties = msg->url + properties_offset;
|
||||
find_key_value(properties, strlen(properties), "name", m_name,
|
||||
sizeof(m_name) - 1, '&');
|
||||
sizeof(m_name) - 1, '&');
|
||||
|
||||
if (strlen(m_name) == 0) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Uninstall WASM app failed: invalid app name.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: invalid app name.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -595,14 +643,13 @@ static bool wasm_app_module_uninstall(request_t *msg)
|
||||
}
|
||||
|
||||
if (m_data->module_type != Module_WASM_App) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Uninstall WASM app failed: invalid module type.");
|
||||
SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: invalid module type.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_data->wd_timer.is_interrupting) {
|
||||
SEND_ERR_RESPONSE(msg->mid,
|
||||
"Uninstall WASM app failed: app is being interrupted by watchdog.");
|
||||
"Uninstall WASM app failed: app is being interrupted by watchdog.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -646,7 +693,7 @@ static void wasm_app_module_watchdog_kill(module_data *m_data)
|
||||
}
|
||||
|
||||
bool wasm_register_msg_callback(int message_type,
|
||||
message_type_handler_t message_handler)
|
||||
message_type_handler_t message_handler)
|
||||
{
|
||||
int i;
|
||||
int freeslot = -1;
|
||||
@ -684,26 +731,27 @@ bool wasm_register_cleanup_callback(resource_cleanup_handler_t handler)
|
||||
return false;
|
||||
}
|
||||
|
||||
#define RECV_INTEGER(value, next_phase) do{ \
|
||||
unsigned char *p = (unsigned char *)&value; \
|
||||
p[recv_ctx.size_in_phase++] = ch; \
|
||||
if (recv_ctx.size_in_phase == sizeof(value)) { \
|
||||
if (sizeof(value) == 4) \
|
||||
value = ntohl(value); \
|
||||
else if (sizeof(value) == 2) \
|
||||
value = ntohs(value); \
|
||||
recv_ctx.phase = next_phase; \
|
||||
recv_ctx.size_in_phase = 0; \
|
||||
} \
|
||||
} while(0)
|
||||
#define RECV_INTEGER(value, next_phase) do { \
|
||||
unsigned char *p = (unsigned char *)&value; \
|
||||
p[recv_ctx.size_in_phase++] = ch; \
|
||||
if (recv_ctx.size_in_phase == sizeof(value)) { \
|
||||
if (sizeof(value) == 4) \
|
||||
value = ntohl(value); \
|
||||
else if (sizeof(value) == 2) \
|
||||
value = ntohs(value); \
|
||||
recv_ctx.phase = next_phase; \
|
||||
recv_ctx.size_in_phase = 0; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* return:
|
||||
* 1: whole wasm app arrived
|
||||
* 0: one valid byte arrived
|
||||
* -1: fail to process the byte arrived, e.g. allocate memory fail
|
||||
*/
|
||||
static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
int request_total_size, int *received_size)
|
||||
static bool
|
||||
wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
|
||||
int *received_size)
|
||||
{
|
||||
if (recv_ctx.phase == Phase_Req_Ver) {
|
||||
recv_ctx.phase = Phase_Req_Ver;
|
||||
@ -719,49 +767,57 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
return false;
|
||||
recv_ctx.phase = Phase_Req_Action;
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Action) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Action) {
|
||||
recv_ctx.message.request_action = ch;
|
||||
recv_ctx.phase = Phase_Req_Fmt;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Fmt) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Fmt) {
|
||||
RECV_INTEGER(recv_ctx.message.request_fmt, Phase_Req_Mid);
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Mid) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Mid) {
|
||||
RECV_INTEGER(recv_ctx.message.request_mid, Phase_Req_Sender);
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Sender) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Sender) {
|
||||
RECV_INTEGER(recv_ctx.message.request_sender, Phase_Req_Url_Len);
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Url_Len) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Url_Len) {
|
||||
unsigned char *p = (unsigned char *) &recv_ctx.message.request_url_len;
|
||||
|
||||
p[recv_ctx.size_in_phase++] = ch;
|
||||
if (recv_ctx.size_in_phase
|
||||
== sizeof(recv_ctx.message.request_url_len)) {
|
||||
recv_ctx.message.request_url_len = ntohs(
|
||||
recv_ctx.message.request_url_len);
|
||||
recv_ctx.message.request_url = bh_malloc(
|
||||
recv_ctx.message.request_url_len + 1);
|
||||
if (recv_ctx.size_in_phase ==
|
||||
sizeof(recv_ctx.message.request_url_len)) {
|
||||
recv_ctx.message.request_url_len =
|
||||
ntohs(recv_ctx.message.request_url_len);
|
||||
recv_ctx.message.request_url =
|
||||
bh_malloc(recv_ctx.message.request_url_len + 1);
|
||||
if (NULL == recv_ctx.message.request_url)
|
||||
goto fail;
|
||||
memset(recv_ctx.message.request_url, 0,
|
||||
recv_ctx.message.request_url_len + 1);
|
||||
recv_ctx.message.request_url_len + 1);
|
||||
recv_ctx.phase = Phase_Req_Payload_Len;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
}
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Payload_Len) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Payload_Len) {
|
||||
RECV_INTEGER(recv_ctx.message.wasm_app_size, Phase_Req_Url);
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Req_Url) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Req_Url) {
|
||||
recv_ctx.message.request_url[recv_ctx.size_in_phase++] = ch;
|
||||
if (recv_ctx.size_in_phase == recv_ctx.message.request_url_len) {
|
||||
recv_ctx.phase = Phase_Wasm_Magic;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
}
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Wasm_Magic) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Wasm_Magic) {
|
||||
/* start to receive wasm app binary */
|
||||
unsigned char *p =
|
||||
(unsigned char *) &recv_ctx.message.wasm_app_binary.magic;
|
||||
@ -771,14 +827,14 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
else
|
||||
goto fail;
|
||||
|
||||
if (recv_ctx.size_in_phase
|
||||
== sizeof(recv_ctx.message.wasm_app_binary.magic)) {
|
||||
if (recv_ctx.size_in_phase ==
|
||||
sizeof(recv_ctx.message.wasm_app_binary.magic)) {
|
||||
recv_ctx.phase = Phase_Wasm_Version;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Wasm_Version) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Wasm_Version) {
|
||||
unsigned char *p =
|
||||
(unsigned char *) &recv_ctx.message.wasm_app_binary.version;
|
||||
|
||||
@ -787,14 +843,14 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
else
|
||||
goto fail;
|
||||
|
||||
if (recv_ctx.size_in_phase
|
||||
== sizeof(recv_ctx.message.wasm_app_binary.version)) {
|
||||
if (recv_ctx.size_in_phase ==
|
||||
sizeof(recv_ctx.message.wasm_app_binary.version)) {
|
||||
recv_ctx.phase = Phase_Wasm_Section_Type;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Wasm_Section_Type) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Wasm_Section_Type) {
|
||||
wasm_section_t *new_section;
|
||||
|
||||
if (!(new_section = (wasm_section_t *) bh_malloc(sizeof(wasm_section_t))))
|
||||
@ -808,7 +864,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
if (NULL == recv_ctx.message.wasm_app_binary.sections) {
|
||||
recv_ctx.message.wasm_app_binary.sections = new_section;
|
||||
recv_ctx.message.wasm_app_binary.section_end = new_section;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
recv_ctx.message.wasm_app_binary.section_end->next = new_section;
|
||||
recv_ctx.message.wasm_app_binary.section_end = new_section;
|
||||
}
|
||||
@ -817,7 +874,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
recv_ctx.size_in_phase = 0;
|
||||
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
|
||||
/* the last section is the current receiving one */
|
||||
wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end;
|
||||
uint32 byte;
|
||||
@ -830,8 +888,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
<< recv_ctx.size_in_phase * 7);
|
||||
recv_ctx.size_in_phase++;
|
||||
/* check leab128 overflow for uint32 value */
|
||||
if (recv_ctx.size_in_phase
|
||||
> (sizeof(section->section_body_size) * 8 + 7 - 1) / 7) {
|
||||
if (recv_ctx.size_in_phase >
|
||||
(sizeof(section->section_body_size) * 8 + 7 - 1) / 7) {
|
||||
app_manager_printf(" LEB overflow when parsing section size\n");
|
||||
goto fail;
|
||||
}
|
||||
@ -845,7 +903,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (recv_ctx.phase == Phase_Wasm_Section_Content) {
|
||||
}
|
||||
else if (recv_ctx.phase == Phase_Wasm_Section_Content) {
|
||||
/* the last section is the current receiving one */
|
||||
wasm_section_t *section = recv_ctx.message.wasm_app_binary.section_end;
|
||||
|
||||
@ -861,9 +920,11 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
recv_ctx.message.request_url = NULL;
|
||||
memset(&recv_ctx, 0, sizeof(recv_ctx));
|
||||
return true;
|
||||
} else
|
||||
}
|
||||
else
|
||||
goto fail;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
recv_ctx.phase = Phase_Wasm_Section_Type;
|
||||
recv_ctx.size_in_phase = 0;
|
||||
return true;
|
||||
@ -873,7 +934,8 @@ static bool wasm_app_module_on_install_request_byte_arrive(uint8 ch,
|
||||
return true;
|
||||
}
|
||||
|
||||
fail: if (recv_ctx.message.wasm_app_binary.sections != NULL) {
|
||||
fail:
|
||||
if (recv_ctx.message.wasm_app_binary.sections != NULL) {
|
||||
destroy_wasm_sections_list(recv_ctx.message.wasm_app_binary.sections);
|
||||
recv_ctx.message.wasm_app_binary.sections = NULL;
|
||||
}
|
||||
@ -915,13 +977,14 @@ static bool module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message)
|
||||
|
||||
/* Request payload is set to wasm_app_file_t struct,
|
||||
* but not whole app buffer */
|
||||
memcpy(request->payload, &message->wasm_app_binary, request->payload_len);
|
||||
bh_memcpy_s(request->payload, request->payload_len,
|
||||
&message->wasm_app_binary, request->payload_len);
|
||||
|
||||
/* Since it's a wasm app install request, so directly post to app-mgr's
|
||||
* queue. The benefit is that section list can be freed when the msg
|
||||
* failed to post to app-mgr's queue. The defect is missing url check. */
|
||||
if (!(msg = bh_new_msg(RESTFUL_REQUEST, request, sizeof(*request),
|
||||
request_cleaner))) {
|
||||
request_cleaner))) {
|
||||
request_cleaner(request);
|
||||
return false;
|
||||
}
|
||||
@ -970,9 +1033,11 @@ static void destroy_wasm_section_from_list(wasm_section_t **sections, int type)
|
||||
bh_free(cur->section_body);
|
||||
bh_free(cur);
|
||||
break;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
prev = cur;
|
||||
}
|
||||
cur = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -16,6 +16,12 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Special module IDs */
|
||||
#define ID_HOST -3
|
||||
#define ID_APP_MGR -2
|
||||
/* Invalid module ID */
|
||||
#define ID_NONE (uint32)-1
|
||||
|
||||
struct attr_container_t;
|
||||
|
||||
/* Queue message type */
|
||||
@ -56,6 +62,7 @@ typedef struct watchdog_timer {
|
||||
typedef struct module_data {
|
||||
struct module_data *next;
|
||||
|
||||
/* ID of the module */
|
||||
uint32 id;
|
||||
|
||||
/* Type of the module */
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
emcc -g -O3 *.c -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \
|
||||
-s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 -o test.wasm
|
||||
clang-8 --target=wasm32 -O3 \
|
||||
-z stack-size=4096 -Wl,--initial-memory=65536 \
|
||||
-Wl,--allow-undefined, \
|
||||
-Wl,--export=main, \
|
||||
-Wl,--no-threads,--strip-all,--no-entry \
|
||||
-nostdlib -o test.wasm *.c
|
||||
#./jeffdump -o test_wasm.h -n wasm_test_file test.wasm
|
||||
|
||||
@ -20,7 +20,7 @@ int main(int argc, char **argv)
|
||||
|
||||
printf("buf ptr: %p\n", buf);
|
||||
|
||||
sprintf(buf, "%s", "1234\n");
|
||||
snprintf(buf, 1024, "%s", "1234\n");
|
||||
printf("buf: %s", buf);
|
||||
|
||||
free(buf);
|
||||
|
||||
@ -1,6 +1,10 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
emcc -g -O3 *.c -s WASM=1 -s SIDE_MODULE=1 -s ASSERTIONS=1 -s STACK_OVERFLOW_CHECK=2 \
|
||||
-s TOTAL_MEMORY=65536 -s TOTAL_STACK=4096 -o test.wasm
|
||||
clang-8 --target=wasm32 -O3 \
|
||||
-z stack-size=4096 -Wl,--initial-memory=65536 \
|
||||
-Wl,--allow-undefined, \
|
||||
-Wl,--export=main, \
|
||||
-Wl,--no-threads,--strip-all,--no-entry \
|
||||
-nostdlib -o test.wasm *.c
|
||||
#./jeffdump -o ../test_wasm.h -n wasm_test_file test.wasm
|
||||
|
||||
@ -180,7 +180,8 @@ request_t *clone_request(request_t *request)
|
||||
|
||||
return req;
|
||||
|
||||
fail: request_cleaner(req);
|
||||
fail:
|
||||
request_cleaner(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -225,7 +226,8 @@ response_t * clone_response(response_t * response)
|
||||
}
|
||||
return clone;
|
||||
|
||||
fail: response_cleaner(clone);
|
||||
fail:
|
||||
response_cleaner(clone);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
#include "app_manager_export.h"
|
||||
#include "coap_ext.h"
|
||||
#include "wasm_export.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
extern void module_request_handler(request_t *request, void *user_data);
|
||||
|
||||
@ -47,6 +48,7 @@ wasm_register_resource(wasm_module_inst_t module_inst, int32 url_offset)
|
||||
if (url != NULL) {
|
||||
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
am_register_resource(url, module_request_handler, mod_id);
|
||||
}
|
||||
}
|
||||
@ -73,6 +75,7 @@ wasm_post_request(wasm_module_inst_t module_inst,
|
||||
// set sender to help dispatch the response to the sender ap
|
||||
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
req->sender = mod_id;
|
||||
|
||||
if (req->action == COAP_EVENT) {
|
||||
@ -98,6 +101,7 @@ wasm_sub_event(wasm_module_inst_t module_inst, int32 url_offset)
|
||||
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
am_register_event(url, mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -143,27 +143,34 @@ timer_id_t
|
||||
wasm_create_timer(wasm_module_inst_t module_inst,
|
||||
int interval, bool is_period, bool auto_start)
|
||||
{
|
||||
return sys_create_timer(get_wasm_timer_ctx(module_inst), interval, is_period,
|
||||
auto_start);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
return sys_create_timer(timer_ctx, interval, is_period, auto_start);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_destroy(wasm_module_inst_t module_inst, timer_id_t timer_id)
|
||||
{
|
||||
sys_timer_destroy(get_wasm_timer_ctx(module_inst), timer_id);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_destroy(timer_ctx, timer_id);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_cancel(wasm_module_inst_t module_inst, timer_id_t timer_id)
|
||||
{
|
||||
sys_timer_cancel(get_wasm_timer_ctx(module_inst), timer_id);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_cancel(timer_ctx, timer_id);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_restart(wasm_module_inst_t module_inst,
|
||||
timer_id_t timer_id, int interval)
|
||||
{
|
||||
sys_timer_restart(get_wasm_timer_ctx(module_inst), timer_id, interval);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_restart(timer_ctx, timer_id, interval);
|
||||
}
|
||||
|
||||
extern uint32 get_sys_tick_ms();
|
||||
|
||||
@ -60,7 +60,7 @@ int uart_open(char* device, int baudrate)
|
||||
|
||||
uart_fd = open(device, O_RDWR | O_NOCTTY);
|
||||
|
||||
if (uart_fd <= 0)
|
||||
if (uart_fd < 0)
|
||||
return -1;
|
||||
|
||||
memset(&uart_term, 0, sizeof(uart_term));
|
||||
|
||||
@ -26,8 +26,10 @@ int udp_open(uint16 port)
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
ret = bind(sock, (struct sockaddr*)&addr, sizeof(addr));
|
||||
if (ret == -1)
|
||||
if (ret == -1) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put the socket in non-blocking mode */
|
||||
if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) {
|
||||
|
||||
@ -17,6 +17,8 @@
|
||||
#include "conn_tcp.h"
|
||||
#include "conn_udp.h"
|
||||
#include "conn_uart.h"
|
||||
#include "bh_common.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/epoll.h>
|
||||
@ -214,6 +216,7 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
|
||||
struct epoll_event ev;
|
||||
uint32 module_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
bh_assert(module_id != ID_NONE);
|
||||
|
||||
if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP)
|
||||
return -1;
|
||||
@ -242,7 +245,7 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
|
||||
port = attr_container_get_as_uint16(args, "port");
|
||||
|
||||
/* Connect to TCP server */
|
||||
if ((fd = tcp_open(address, port)) == -1)
|
||||
if (!address || (fd = tcp_open(address, port)) == -1)
|
||||
goto fail;
|
||||
|
||||
} else if (conn->type == CONN_TYPE_UDP) {
|
||||
@ -269,9 +272,10 @@ static uint32 _conn_open(wasm_module_inst_t module_inst,
|
||||
baud = attr_container_get_as_int(args, "baudrate");
|
||||
|
||||
/* Open device */
|
||||
if ((fd = uart_open(device, baud)) == -1)
|
||||
if (!device || (fd = uart_open(device, baud)) == -1)
|
||||
goto fail;
|
||||
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
conn->fd = fd;
|
||||
@ -345,7 +349,8 @@ static bool _conn_config(uint32 handle, attr_container_t *cfg)
|
||||
if (!attr_container_contain_key(cfg, "address") ||
|
||||
!attr_container_contain_key(cfg, "port"))
|
||||
return false;
|
||||
address = attr_container_get_as_string(cfg, "address");
|
||||
if (!(address = attr_container_get_as_string(cfg, "address")))
|
||||
return false;
|
||||
port = attr_container_get_as_uint16(cfg, "port");
|
||||
|
||||
if (conn->arg == NULL) {
|
||||
@ -409,7 +414,7 @@ static void post_msg_to_module(sys_connection_t *conn,
|
||||
bh_free(conn_data_event);
|
||||
return;
|
||||
}
|
||||
memcpy(data_copy, data, len);
|
||||
bh_memcpy_s(data_copy, len, data, len);
|
||||
}
|
||||
|
||||
memset(conn_data_event, 0, sizeof(*conn_data_event));
|
||||
|
||||
@ -0,0 +1,13 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_LIB_CONN_MGR_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c)
|
||||
|
||||
set (WASM_LIB_CONN_MGR_SOURCE ${source_all})
|
||||
|
||||
|
||||
@ -5,7 +5,10 @@ set (WASM_LIB_GUI_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
set (THIRD_PARTY_DIR ${WASM_LIB_GUI_DIR}/../../../3rdparty)
|
||||
|
||||
include_directories(${WASM_LIB_GUI_DIR} ${THIRD_PARTY_DIR} ${THIRD_PARTY_DIR}/lvgl)
|
||||
include_directories(${WASM_LIB_GUI_DIR}
|
||||
${THIRD_PARTY_DIR}
|
||||
${THIRD_PARTY_DIR}/lvgl
|
||||
${THIRD_PARTY_DIR}/lvgl/src)
|
||||
|
||||
file (GLOB_RECURSE lvgl_source ${THIRD_PARTY_DIR}/lvgl/*.c)
|
||||
file (GLOB_RECURSE wrapper_source ${WASM_LIB_GUI_DIR}/*.c)
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
#include "lvgl.h"
|
||||
#include "module_wasm_app.h"
|
||||
#include "wgl_native_utils.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
/* -------------------------------------------------------------------------
|
||||
* List widget native function wrappers
|
||||
@ -24,16 +25,17 @@ lv_list_add_btn_wrapper(wasm_module_inst_t module_inst,
|
||||
{
|
||||
uint32 btn_obj_id;
|
||||
lv_obj_t *btn;
|
||||
uint32 mod_id;
|
||||
|
||||
btn = lv_list_add_btn(list, NULL, text);
|
||||
|
||||
if (btn == NULL)
|
||||
return 0;
|
||||
|
||||
if (wgl_native_add_object(btn,
|
||||
app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst),
|
||||
&btn_obj_id))
|
||||
mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
if (wgl_native_add_object(btn, mod_id, &btn_obj_id))
|
||||
return btn_obj_id; /* success return */
|
||||
|
||||
return 0;
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
#include "lvgl.h"
|
||||
#include "module_wasm_app.h"
|
||||
#include "wasm_export.h"
|
||||
#include "wasm_assert.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -17,7 +17,8 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
|
||||
wasm_module_inst_t module_inst)
|
||||
{
|
||||
uint32 obj_id;
|
||||
lv_obj_t *wigdet;
|
||||
lv_obj_t *wigdet = NULL;
|
||||
uint32 mod_id;
|
||||
|
||||
//TODO: limit total widget number
|
||||
|
||||
@ -38,10 +39,10 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
|
||||
if (wigdet == NULL)
|
||||
return 0;
|
||||
|
||||
if (wgl_native_add_object(wigdet,
|
||||
app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst),
|
||||
&obj_id))
|
||||
mod_id = app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
if (wgl_native_add_object(wigdet, mod_id, &obj_id))
|
||||
return obj_id; /* success return */
|
||||
|
||||
return 0;
|
||||
@ -49,7 +50,7 @@ uint32 wgl_native_wigdet_create(int8 widget_type, lv_obj_t *par, lv_obj_t *copy,
|
||||
|
||||
static void invokeNative(intptr_t argv[], uint32 argc, void (*native_code)())
|
||||
{
|
||||
wasm_assert(argc >= 1);
|
||||
bh_assert(argc >= 1);
|
||||
|
||||
switch(argc) {
|
||||
case 1:
|
||||
|
||||
@ -50,7 +50,10 @@ static void app_mgr_object_event_callback(module_data *m_data, bh_message_t msg)
|
||||
return;
|
||||
|
||||
func_on_object_event = wasm_runtime_lookup_function(inst, "_on_widget_event",
|
||||
"(i32i32)");
|
||||
"(i32i32)");
|
||||
if (!func_on_object_event)
|
||||
func_on_object_event = wasm_runtime_lookup_function(inst, "on_widget_event",
|
||||
"(i32i32)");
|
||||
if (!func_on_object_event) {
|
||||
printf("Cannot find function _on_object_event\n");
|
||||
return;
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#include "module_wasm_app.h"
|
||||
#include "bh_thread.h"
|
||||
#include "bh_time.h"
|
||||
#include "bh_common.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
static sys_sensor_t * g_sys_sensors = NULL;
|
||||
static int g_sensor_id_max = 0;
|
||||
@ -59,7 +61,8 @@ wasm_sensor_callback(void *client, uint32 sensor_id, void *user_data)
|
||||
return;
|
||||
|
||||
/* multiple sensor clients may use/free the sensor data, so make a copy */
|
||||
memcpy(sensor_data_clone, sensor_data, sensor_data_len);
|
||||
bh_memcpy_s(sensor_data_clone, sensor_data_len,
|
||||
sensor_data, sensor_data_len);
|
||||
|
||||
sensor_event = (sensor_event_data_t *)bh_malloc(sizeof(*sensor_event));
|
||||
if (sensor_event == NULL) {
|
||||
@ -97,6 +100,7 @@ wasm_sensor_config(wasm_module_inst_t module_inst,
|
||||
|
||||
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
vm_mutex_lock(&s->lock);
|
||||
|
||||
@ -147,6 +151,7 @@ wasm_sensor_open(wasm_module_inst_t module_inst,
|
||||
|
||||
unsigned int mod_id = app_manager_get_module_id(Module_WASM_App,
|
||||
module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
vm_mutex_lock(&s->lock);
|
||||
|
||||
@ -219,6 +224,8 @@ wasm_sensor_close(wasm_module_inst_t module_inst, uint32 sensor)
|
||||
sensor_obj_t s = find_sys_sensor_id(sensor);
|
||||
sensor_client_t *c;
|
||||
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
|
||||
@ -7,6 +7,10 @@
|
||||
#include "wasm_export.h"
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_platform_log.h"
|
||||
#include "bh_common.h"
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
#include "wasi_wrapper.h"
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_runtime_set_exception(wasm_module_inst_t module, const char *exception);
|
||||
@ -52,7 +56,7 @@ enum pad_type {
|
||||
|
||||
typedef char *_va_list;
|
||||
#define _INTSIZEOF(n) \
|
||||
((sizeof(n) + 3) & ~3)
|
||||
(((uint32)sizeof(n) + 3) & (uint32)~3)
|
||||
#define _va_arg(ap, t) \
|
||||
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
|
||||
|
||||
@ -86,7 +90,7 @@ _printf_hex_uint(out_func_t out, void *ctx,
|
||||
|
||||
if (nibble || found_largest_digit || size == 1) {
|
||||
found_largest_digit = 1;
|
||||
nibble += nibble > 9 ? 87 : 48;
|
||||
nibble = (char)(nibble + (nibble > 9 ? 87 : 48));
|
||||
out((int) nibble, ctx);
|
||||
digits++;
|
||||
continue;
|
||||
@ -250,7 +254,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
|
||||
d = -d;
|
||||
min_width--;
|
||||
}
|
||||
_printf_dec_uint(out, ctx, d, padding, min_width);
|
||||
_printf_dec_uint(out, ctx, (uint32)d, padding, min_width);
|
||||
break;
|
||||
}
|
||||
case 'u': {
|
||||
@ -301,8 +305,8 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
|
||||
char *start;
|
||||
int32 s_offset;
|
||||
|
||||
CHECK_VA_ARG(ap, uint32);
|
||||
s_offset = _va_arg(ap, uint32);
|
||||
CHECK_VA_ARG(ap, int32);
|
||||
s_offset = _va_arg(ap, int32);
|
||||
|
||||
if (!validate_app_str_addr(s_offset)) {
|
||||
return false;
|
||||
@ -314,7 +318,7 @@ _vprintf_wa(out_func_t out, void *ctx, const char *fmt, _va_list ap,
|
||||
out((int) (*s++), ctx);
|
||||
|
||||
if (padding == PAD_SPACE_AFTER) {
|
||||
int remaining = min_width - (s - start);
|
||||
int remaining = min_width - (int32)(s - start);
|
||||
while (remaining-- > 0) {
|
||||
out(' ', ctx);
|
||||
}
|
||||
@ -356,8 +360,8 @@ fail:
|
||||
|
||||
struct str_context {
|
||||
char *str;
|
||||
int max;
|
||||
int count;
|
||||
uint32 max;
|
||||
uint32 count;
|
||||
};
|
||||
|
||||
static int
|
||||
@ -371,7 +375,7 @@ sprintf_out(int c, struct str_context *ctx)
|
||||
if (ctx->count == ctx->max - 1) {
|
||||
ctx->str[ctx->count++] = '\0';
|
||||
} else {
|
||||
ctx->str[ctx->count++] = c;
|
||||
ctx->str[ctx->count++] = (char)c;
|
||||
}
|
||||
|
||||
return c;
|
||||
@ -432,7 +436,7 @@ _printf_wrapper(wasm_module_inst_t module_inst,
|
||||
|
||||
if (!_vprintf_wa((out_func_t)printf_out, &ctx, fmt, va_args, module_inst))
|
||||
return 0;
|
||||
return ctx.count;
|
||||
return (int)ctx.count;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -457,7 +461,7 @@ _sprintf_wrapper(wasm_module_inst_t module_inst,
|
||||
return 0;
|
||||
|
||||
ctx.str = str;
|
||||
ctx.max = app_end_offset - str_offset;
|
||||
ctx.max = (uint32)(app_end_offset - str_offset);
|
||||
ctx.count = 0;
|
||||
|
||||
if (!_vprintf_wa((out_func_t)sprintf_out, &ctx, fmt, va_args, module_inst))
|
||||
@ -467,12 +471,12 @@ _sprintf_wrapper(wasm_module_inst_t module_inst,
|
||||
str[ctx.count] = '\0';
|
||||
}
|
||||
|
||||
return ctx.count;
|
||||
return (int)ctx.count;
|
||||
}
|
||||
|
||||
static int
|
||||
_snprintf_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 str_offset, int32 size, int32 fmt_offset,
|
||||
int32 str_offset, uint32 size, int32 fmt_offset,
|
||||
int32 va_list_offset)
|
||||
{
|
||||
struct str_context ctx;
|
||||
@ -499,7 +503,7 @@ _snprintf_wrapper(wasm_module_inst_t module_inst,
|
||||
str[ctx.count] = '\0';
|
||||
}
|
||||
|
||||
return ctx.count;
|
||||
return (int)ctx.count;
|
||||
}
|
||||
|
||||
static int
|
||||
@ -536,21 +540,28 @@ _strdup_wrapper(wasm_module_inst_t module_inst,
|
||||
str = addr_app_to_native(str_offset);
|
||||
|
||||
if (str) {
|
||||
len = strlen(str) + 1;
|
||||
len = (uint32)strlen(str) + 1;
|
||||
|
||||
str_ret_offset = module_malloc(len);
|
||||
if (str_ret_offset) {
|
||||
str_ret = addr_app_to_native(str_ret_offset);
|
||||
memcpy(str_ret, str, len);
|
||||
bh_memcpy_s(str_ret, len, str, len);
|
||||
}
|
||||
}
|
||||
|
||||
return str_ret_offset;
|
||||
}
|
||||
|
||||
static int32
|
||||
__strdup_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 str_offset)
|
||||
{
|
||||
return _strdup_wrapper(module_inst, str_offset);
|
||||
}
|
||||
|
||||
static int32
|
||||
_memcmp_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s1_offset, int32 s2_offset, int32 size)
|
||||
int32 s1_offset, int32 s2_offset, uint32 size)
|
||||
{
|
||||
void *s1, *s2;
|
||||
|
||||
@ -565,7 +576,7 @@ _memcmp_wrapper(wasm_module_inst_t module_inst,
|
||||
|
||||
static int32
|
||||
_memcpy_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 dst_offset, int32 src_offset, int32 size)
|
||||
int32 dst_offset, int32 src_offset, uint32 size)
|
||||
{
|
||||
void *dst, *src;
|
||||
|
||||
@ -578,13 +589,13 @@ _memcpy_wrapper(wasm_module_inst_t module_inst,
|
||||
|
||||
dst = addr_app_to_native(dst_offset);
|
||||
src = addr_app_to_native(src_offset);
|
||||
memcpy(dst, src, size);
|
||||
bh_memcpy_s(dst, size, src, size);
|
||||
return dst_offset;
|
||||
}
|
||||
|
||||
static int32
|
||||
_memmove_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 dst_offset, int32 src_offset, int32 size)
|
||||
int32 dst_offset, int32 src_offset, uint32 size)
|
||||
{
|
||||
void *dst, *src;
|
||||
|
||||
@ -600,7 +611,7 @@ _memmove_wrapper(wasm_module_inst_t module_inst,
|
||||
|
||||
static int32
|
||||
_memset_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset, int32 c, int32 size)
|
||||
int32 s_offset, int32 c, uint32 size)
|
||||
{
|
||||
void *s;
|
||||
|
||||
@ -668,7 +679,7 @@ _strcpy_wrapper(wasm_module_inst_t module_inst,
|
||||
return 0;
|
||||
|
||||
src = addr_app_to_native(src_offset);
|
||||
len = strlen(src);
|
||||
len = (uint32)strlen(src);
|
||||
|
||||
if (!validate_app_addr(dst_offset, len + 1))
|
||||
return 0;
|
||||
@ -704,7 +715,7 @@ _strlen_wrapper(wasm_module_inst_t module_inst,
|
||||
return 0;
|
||||
|
||||
s = addr_app_to_native(s_offset);
|
||||
return strlen(s);
|
||||
return (uint32)strlen(s);
|
||||
}
|
||||
|
||||
static int32
|
||||
@ -719,13 +730,13 @@ _calloc_wrapper(wasm_module_inst_t module_inst,
|
||||
uint32 nmemb, uint32 size)
|
||||
{
|
||||
uint64 total_size = (uint64) nmemb * (uint64) size;
|
||||
uint32 ret_offset = 0;
|
||||
int32 ret_offset = 0;
|
||||
uint8 *ret_ptr;
|
||||
|
||||
if (total_size > UINT32_MAX)
|
||||
total_size = UINT32_MAX;
|
||||
if (total_size >= UINT32_MAX)
|
||||
return 0;
|
||||
|
||||
ret_offset = module_malloc((uint32 )total_size);
|
||||
ret_offset = module_malloc((uint32)total_size);
|
||||
if (ret_offset) {
|
||||
ret_ptr = addr_app_to_native(ret_offset);
|
||||
memset(ret_ptr, 0, (uint32) total_size);
|
||||
@ -743,6 +754,245 @@ _free_wrapper(wasm_module_inst_t module_inst,
|
||||
return module_free(ptr_offset);
|
||||
}
|
||||
|
||||
static int32
|
||||
_atoi_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset)
|
||||
{
|
||||
char *str;
|
||||
|
||||
if (!validate_app_str_addr(s_offset))
|
||||
return 0;
|
||||
|
||||
str = addr_app_to_native(s_offset);
|
||||
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
static int32
|
||||
_bsearch_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 key_offset, /* const void * */
|
||||
int32 array_offset, /* const void * */
|
||||
uint32 count,
|
||||
uint32 size,
|
||||
int32 cmp_index)
|
||||
{
|
||||
wasm_runtime_set_exception(module_inst, "bsearch not implemented.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
_exit_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 status)
|
||||
{
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "env.exit(%i)", status);
|
||||
wasm_runtime_set_exception(module_inst, buf);
|
||||
}
|
||||
|
||||
static int32
|
||||
_strtol_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 nptr_offset, /* const char * */
|
||||
int32 endptr_offset, /* char ** */
|
||||
int32 base)
|
||||
{
|
||||
char *nptr, **endptr;
|
||||
int32 num = 0;
|
||||
|
||||
if (!validate_app_str_addr(nptr_offset)
|
||||
|| !validate_app_addr(endptr_offset, sizeof(int32)))
|
||||
return 0;
|
||||
|
||||
nptr = addr_app_to_native(nptr_offset);
|
||||
endptr = addr_app_to_native(endptr_offset);
|
||||
|
||||
num = (int32)strtol(nptr, endptr, base);
|
||||
*(int32 *)endptr = addr_native_to_app(*endptr);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static uint32
|
||||
_strtoul_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 nptr_offset, /* const char * */
|
||||
int32 endptr_offset, /* char ** */
|
||||
int32 base)
|
||||
{
|
||||
char *nptr, **endptr;
|
||||
uint32 num = 0;
|
||||
|
||||
if (!validate_app_str_addr(nptr_offset)
|
||||
|| !validate_app_addr(endptr_offset, sizeof(int32)))
|
||||
return 0;
|
||||
|
||||
nptr = addr_app_to_native(nptr_offset);
|
||||
endptr = addr_app_to_native(endptr_offset);
|
||||
|
||||
num = (uint32)strtoul(nptr, endptr, base);
|
||||
*(int32 *)endptr = addr_native_to_app(*endptr);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static int32
|
||||
_memchr_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset, /* const void * */
|
||||
int32 c,
|
||||
uint32 n)
|
||||
{
|
||||
void *s, *res;
|
||||
|
||||
if (!validate_app_addr(s_offset, n))
|
||||
return 0;
|
||||
|
||||
s = (void*)addr_app_to_native(s_offset);
|
||||
|
||||
res = memchr(s, c, n);
|
||||
|
||||
return addr_native_to_app(res);
|
||||
}
|
||||
|
||||
static int32
|
||||
_strncasecmp_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s1_offset, /* const char * */
|
||||
int32 s2_offset, /* const char * */
|
||||
uint32 n)
|
||||
{
|
||||
char *s1, *s2;
|
||||
|
||||
if (!validate_app_str_addr(s1_offset)
|
||||
|| !validate_app_str_addr(s2_offset))
|
||||
return 0;
|
||||
|
||||
s1 = addr_app_to_native(s1_offset);
|
||||
s2 = addr_app_to_native(s2_offset);
|
||||
|
||||
return strncasecmp(s1, s2, n);
|
||||
}
|
||||
|
||||
static uint32
|
||||
_strspn_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset, /* const char * */
|
||||
int32 accept_offset) /* const char * */
|
||||
{
|
||||
char *s, *accept;
|
||||
|
||||
if (!validate_app_str_addr(s_offset)
|
||||
|| !validate_app_str_addr(accept_offset))
|
||||
return 0;
|
||||
|
||||
s = addr_app_to_native(s_offset);
|
||||
accept = addr_app_to_native(accept_offset);
|
||||
|
||||
return (uint32)strspn(s, accept);
|
||||
}
|
||||
|
||||
static uint32
|
||||
_strcspn_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset, /* const char * */
|
||||
int32 reject_offset) /* const char * */
|
||||
{
|
||||
char *s, *reject;
|
||||
|
||||
if (!validate_app_str_addr(s_offset)
|
||||
|| !validate_app_str_addr(reject_offset))
|
||||
return 0;
|
||||
|
||||
s = addr_app_to_native(s_offset);
|
||||
reject = addr_app_to_native(reject_offset);
|
||||
|
||||
return (uint32)strcspn(s, reject);
|
||||
}
|
||||
|
||||
static int32
|
||||
_strstr_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 s_offset, /* const char * */
|
||||
int32 find_offset) /* const char * */
|
||||
{
|
||||
char *s, *find, *res;
|
||||
|
||||
if (!validate_app_str_addr(s_offset)
|
||||
|| !validate_app_str_addr(find_offset))
|
||||
return 0;
|
||||
|
||||
s = addr_app_to_native(s_offset);
|
||||
find = addr_app_to_native(find_offset);
|
||||
|
||||
res = strstr(s, find);
|
||||
|
||||
return addr_native_to_app(res);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isupper_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isupper(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isalpha_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isalpha(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isspace_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isspace(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isgraph_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isgraph(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isprint_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isprint(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isdigit_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isdigit(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isxdigit_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isxdigit(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_tolower_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return tolower(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_toupper_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return toupper(c);
|
||||
}
|
||||
|
||||
static int32
|
||||
_isalnum_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 c)
|
||||
{
|
||||
return isalnum(c);
|
||||
}
|
||||
|
||||
static void
|
||||
setTempRet0_wrapper(wasm_module_inst_t module_inst,
|
||||
uint32 temp_ret)
|
||||
@ -842,7 +1092,7 @@ _emscripten_memcpy_big_wrapper(wasm_module_inst_t module_inst,
|
||||
dst = addr_app_to_native(dst_offset);
|
||||
src = addr_app_to_native(src_offset);
|
||||
|
||||
memcpy(dst, src, size);
|
||||
bh_memcpy_s(dst, size, src, size);
|
||||
return dst_offset;
|
||||
}
|
||||
|
||||
@ -873,6 +1123,36 @@ nullFunc_X_wrapper(wasm_module_inst_t module_inst,
|
||||
wasm_runtime_set_exception(module_inst, buf);
|
||||
}
|
||||
|
||||
static int32
|
||||
__cxa_allocate_exception_wrapper(wasm_module_inst_t module_inst,
|
||||
uint32 thrown_size)
|
||||
{
|
||||
int32 exception = module_malloc(thrown_size);
|
||||
if (!exception)
|
||||
return 0;
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
static void
|
||||
__cxa_begin_catch_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 exception_object_offset)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
__cxa_throw_wrapper(wasm_module_inst_t module_inst,
|
||||
int32 thrown_exception_offset,
|
||||
int32 tinfo_offset,
|
||||
uint32 table_elem_idx)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s", "exception thrown by stdc++");
|
||||
wasm_runtime_set_exception(module_inst, buf);
|
||||
}
|
||||
|
||||
/*#define ENABLE_SPEC_TEST 1*/
|
||||
|
||||
#ifdef ENABLE_SPEC_TEST
|
||||
@ -922,7 +1202,29 @@ static WASMNativeFuncDef native_func_defs[] = {
|
||||
REG_NATIVE_FUNC(env, _malloc),
|
||||
REG_NATIVE_FUNC(env, _calloc),
|
||||
REG_NATIVE_FUNC(env, _strdup),
|
||||
/* clang may introduce __strdup */
|
||||
REG_NATIVE_FUNC(env, __strdup),
|
||||
REG_NATIVE_FUNC(env, _free),
|
||||
REG_NATIVE_FUNC(env, _atoi),
|
||||
REG_NATIVE_FUNC(env, _bsearch),
|
||||
REG_NATIVE_FUNC(env, _exit),
|
||||
REG_NATIVE_FUNC(env, _strtol),
|
||||
REG_NATIVE_FUNC(env, _strtoul),
|
||||
REG_NATIVE_FUNC(env, _memchr),
|
||||
REG_NATIVE_FUNC(env, _strncasecmp),
|
||||
REG_NATIVE_FUNC(env, _strspn),
|
||||
REG_NATIVE_FUNC(env, _strcspn),
|
||||
REG_NATIVE_FUNC(env, _strstr),
|
||||
REG_NATIVE_FUNC(env, _isupper),
|
||||
REG_NATIVE_FUNC(env, _isalpha),
|
||||
REG_NATIVE_FUNC(env, _isspace),
|
||||
REG_NATIVE_FUNC(env, _isgraph),
|
||||
REG_NATIVE_FUNC(env, _isprint),
|
||||
REG_NATIVE_FUNC(env, _isdigit),
|
||||
REG_NATIVE_FUNC(env, _isxdigit),
|
||||
REG_NATIVE_FUNC(env, _tolower),
|
||||
REG_NATIVE_FUNC(env, _toupper),
|
||||
REG_NATIVE_FUNC(env, _isalnum),
|
||||
REG_NATIVE_FUNC(env, setTempRet0),
|
||||
REG_NATIVE_FUNC(env, getTempRet0),
|
||||
REG_NATIVE_FUNC(env, _llvm_bswap_i16),
|
||||
@ -934,7 +1236,10 @@ static WASMNativeFuncDef native_func_defs[] = {
|
||||
REG_NATIVE_FUNC(env, _emscripten_memcpy_big),
|
||||
REG_NATIVE_FUNC(env, abort),
|
||||
REG_NATIVE_FUNC(env, abortStackOverflow),
|
||||
REG_NATIVE_FUNC(env, nullFunc_X)
|
||||
REG_NATIVE_FUNC(env, nullFunc_X),
|
||||
REG_NATIVE_FUNC(env, __cxa_allocate_exception),
|
||||
REG_NATIVE_FUNC(env, __cxa_begin_catch),
|
||||
REG_NATIVE_FUNC(env, __cxa_throw)
|
||||
};
|
||||
|
||||
void*
|
||||
@ -960,6 +1265,11 @@ wasm_native_func_lookup(const char *module_name, const char *func_name)
|
||||
if ((ret = wasm_platform_native_func_lookup(module_name, func_name)))
|
||||
return ret;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
if ((ret = wasi_native_func_lookup(module_name, func_name)))
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
1289
core/iwasm/lib/native/libc/wasi_wrapper.c
Normal file
1289
core/iwasm/lib/native/libc/wasi_wrapper.c
Normal file
File diff suppressed because it is too large
Load Diff
54
core/iwasm/lib/native/libc/wasi_wrapper.h
Normal file
54
core/iwasm/lib/native/libc/wasi_wrapper.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WASI_WRAPPER_H
|
||||
#define _WASI_WRAPPER_H
|
||||
|
||||
#include "wasmtime_ssp.h"
|
||||
#include "posix.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef __wasi_errno_t wasi_errno_t;
|
||||
typedef __wasi_fd_t wasi_fd_t;
|
||||
typedef __wasi_clockid_t wasi_clockid_t;
|
||||
typedef __wasi_timestamp_t wasi_timestamp_t;
|
||||
typedef __wasi_prestat_t wasi_prestat_t;
|
||||
typedef __wasi_iovec_t wasi_iovec_t;
|
||||
typedef __wasi_ciovec_t wasi_ciovec_t;
|
||||
typedef __wasi_filetype_t wasi_filetype_t;
|
||||
typedef __wasi_filesize_t wasi_filesize_t;
|
||||
typedef __wasi_filedelta_t wasi_filedelta_t;
|
||||
typedef __wasi_whence_t wasi_whence_t;
|
||||
typedef __wasi_fdstat_t wasi_fdstat_t;
|
||||
typedef __wasi_fdflags_t wasi_fdflags_t;
|
||||
typedef __wasi_rights_t wasi_rights_t;
|
||||
typedef __wasi_advice_t wasi_advice_t;
|
||||
typedef __wasi_lookupflags_t wasi_lookupflags_t;
|
||||
typedef __wasi_oflags_t wasi_oflags_t;
|
||||
typedef __wasi_dircookie_t wasi_dircookie_t;
|
||||
typedef __wasi_filestat_t wasi_filestat_t;
|
||||
typedef __wasi_fstflags_t wasi_fstflags_t;
|
||||
typedef __wasi_subscription_t wasi_subscription_t;
|
||||
typedef __wasi_event_t wasi_event_t;
|
||||
typedef __wasi_exitcode_t wasi_exitcode_t;
|
||||
typedef __wasi_signal_t wasi_signal_t;
|
||||
typedef __wasi_riflags_t wasi_riflags_t;
|
||||
typedef __wasi_roflags_t wasi_roflags_t;
|
||||
typedef __wasi_siflags_t wasi_siflags_t;
|
||||
typedef __wasi_sdflags_t wasi_sdflags_t;
|
||||
typedef __wasi_dircookie_t wasi_dircookie_t;
|
||||
typedef __wasi_preopentype_t wasi_preopentype_t;
|
||||
|
||||
void*
|
||||
wasi_native_func_lookup(const char *module_name, const char *func_name);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASI_WRAPPER_H */
|
||||
@ -26,6 +26,7 @@ $(NAME)_SOURCES := ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c \
|
||||
${IWASM_ROOT}/lib/native/libc/libc_wrapper.c \
|
||||
${IWASM_ROOT}/lib/native/base/base_lib_export.c \
|
||||
${SHARED_LIB_ROOT}/platform/alios/bh_platform.c \
|
||||
${SHARED_LIB_ROOT}/platform/alios/bh_definition.c \
|
||||
${SHARED_LIB_ROOT}/platform/alios/bh_assert.c \
|
||||
${SHARED_LIB_ROOT}/platform/alios/bh_thread.c \
|
||||
${SHARED_LIB_ROOT}/platform/alios/bh_math.c \
|
||||
|
||||
@ -48,7 +48,7 @@ static char global_heap_buf[256 * 1024] = { 0 };
|
||||
void iwasm_main(void *arg1)
|
||||
{
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
uint32 wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
|
||||
@ -3,6 +3,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/**
|
||||
* The byte array buffer is the file content of a test wasm binary file,
|
||||
* which is compiled by emcc or clang toolchain from C source file of:
|
||||
* core/iwasm/app-samples/hello-world/main.c.
|
||||
*/
|
||||
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
|
||||
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,
|
||||
|
||||
@ -17,7 +17,7 @@ endif ()
|
||||
|
||||
# Set BUILD_TARGET, currently values supported:
|
||||
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
|
||||
if (NOT BUILD_TARGET)
|
||||
if (NOT DEFINED BUILD_TARGET)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
set (BUILD_TARGET "X86_64")
|
||||
@ -60,6 +60,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WASM_ENABLE_WASI)
|
||||
# Enable wasi support by default
|
||||
set (WASM_ENABLE_WASI 1)
|
||||
endif ()
|
||||
|
||||
if (WASM_ENABLE_WASI EQUAL 1)
|
||||
add_definitions(-DWASM_ENABLE_WASI=1)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
message ("-- WASI enabled")
|
||||
else ()
|
||||
message ("-- WASI disabled")
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
@ -82,6 +95,7 @@ enable_language (ASM)
|
||||
include (../../runtime/platform/${PLATFORM}/platform.cmake)
|
||||
include (../../runtime/utils/utils.cmake)
|
||||
include (../../runtime/vmcore-wasm/vmcore.cmake)
|
||||
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
|
||||
include (../../lib/native/base/wasm_lib_base.cmake)
|
||||
include (../../lib/native/libc/wasm_libc.cmake)
|
||||
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
|
||||
@ -92,6 +106,7 @@ add_library (vmlib
|
||||
${WASM_PLATFORM_LIB_SOURCE}
|
||||
${WASM_UTILS_LIB_SOURCE}
|
||||
${VMCORE_LIB_SOURCE}
|
||||
${WASI_LIB_SOURCE}
|
||||
${WASM_LIB_BASE_DIR}/base_lib_export.c
|
||||
${WASM_LIBC_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
|
||||
@ -34,6 +34,15 @@ static int print_help()
|
||||
#endif
|
||||
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
||||
" that runs commands in the form of `FUNC ARG...`\n");
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
|
||||
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -49,7 +58,7 @@ app_instance_main(wasm_module_inst_t module_inst)
|
||||
}
|
||||
|
||||
static void*
|
||||
app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
|
||||
app_instance_func(wasm_module_inst_t module_inst, char *func_name)
|
||||
{
|
||||
const char *exception;
|
||||
|
||||
@ -77,7 +86,7 @@ split_string(char *str, int *count)
|
||||
do {
|
||||
p = strtok(str, " ");
|
||||
str = NULL;
|
||||
res = (char**) realloc(res, sizeof(char*) * (idx + 1));
|
||||
res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -120,6 +129,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_env_str(char *env)
|
||||
{
|
||||
char *p = env;
|
||||
int key_len = 0;
|
||||
|
||||
while (*p != '\0' && *p != '=') {
|
||||
key_len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '=' || key_len == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define USE_GLOBAL_HEAP_BUF 0
|
||||
|
||||
#if USE_GLOBAL_HEAP_BUF != 0
|
||||
@ -129,9 +155,9 @@ static char global_heap_buf[10 * 1024 * 1024] = { 0 };
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char *wasm_file = NULL;
|
||||
const char *func_name = NULL;
|
||||
char *func_name = NULL;
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
uint32 wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
@ -139,6 +165,12 @@ int main(int argc, char *argv[])
|
||||
int log_verbose_level = 1;
|
||||
#endif
|
||||
bool is_repl_mode = false;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
const char *dir_list[8] = { NULL };
|
||||
uint32 dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32 env_list_size = 0;
|
||||
#endif
|
||||
|
||||
/* Process options. */
|
||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||
@ -159,6 +191,37 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
else if (!strcmp(argv[0], "--repl"))
|
||||
is_repl_mode = true;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
else if (!strncmp(argv[0], "--dir=", 6)) {
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max dir number %d\n",
|
||||
(int)(sizeof(dir_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
dir_list[dir_list_size++] = argv[0] + 6;
|
||||
}
|
||||
else if (!strncmp(argv[0], "--env=", 6)) {
|
||||
char *tmp_env;
|
||||
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max env number %d\n",
|
||||
(int)(sizeof(env_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
tmp_env = argv[0] + 6;
|
||||
if (validate_env_str(tmp_env))
|
||||
env_list[env_list_size++] = tmp_env;
|
||||
else {
|
||||
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
|
||||
tmp_env);
|
||||
return print_help();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return print_help();
|
||||
}
|
||||
@ -201,6 +264,14 @@ int main(int argc, char *argv[])
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_runtime_set_wasi_args(wasm_module,
|
||||
dir_list, dir_list_size,
|
||||
NULL, 0,
|
||||
env_list, env_list_size,
|
||||
argv, argc);
|
||||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
|
||||
64 * 1024, /* stack size */
|
||||
|
||||
@ -22,7 +22,7 @@ if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
|
||||
endif ()
|
||||
|
||||
# Set BUILD_TARGET, currently values supported:
|
||||
if (NOT BUILD_TARGET)
|
||||
if (NOT DEFINED BUILD_TARGET)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
set (BUILD_TARGET "X86_64")
|
||||
@ -62,6 +62,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WASM_ENABLE_WASI)
|
||||
# Disable wasi support by default
|
||||
set (WASM_ENABLE_WASI 0)
|
||||
endif ()
|
||||
|
||||
if (WASM_ENABLE_WASI EQUAL 1)
|
||||
add_definitions(-DWASM_ENABLE_WASI=1)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
message ("-- WASI enabled")
|
||||
else ()
|
||||
message ("-- WASI disabled")
|
||||
endif ()
|
||||
|
||||
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--gc-sections")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
|
||||
|
||||
@ -78,6 +91,7 @@ enable_language (ASM)
|
||||
include (../../runtime/platform/${PLATFORM}/platform.cmake)
|
||||
include (../../runtime/utils/utils.cmake)
|
||||
include (../../runtime/vmcore-wasm/vmcore.cmake)
|
||||
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
|
||||
include (../../lib/native/base/wasm_lib_base.cmake)
|
||||
include (../../lib/native/libc/wasm_libc.cmake)
|
||||
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
|
||||
@ -88,6 +102,7 @@ add_library (vmlib
|
||||
${WASM_PLATFORM_LIB_SOURCE}
|
||||
${WASM_UTILS_LIB_SOURCE}
|
||||
${VMCORE_LIB_SOURCE}
|
||||
${WASI_LIB_SOURCE}
|
||||
${WASM_LIB_BASE_DIR}/base_lib_export.c
|
||||
${WASM_LIBC_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
@ -95,3 +110,7 @@ add_library (vmlib
|
||||
${UTILS_SHARED_SOURCE})
|
||||
|
||||
add_library (extlib ext_lib_export.c)
|
||||
|
||||
set (copy_libs_cmd cp -a libvmlib.a libextlib.a ../enclave-sample/)
|
||||
add_custom_target (copy_libs_to_enclave ALL COMMAND ${copy_libs_cmd} DEPENDS vmlib extlib)
|
||||
|
||||
|
||||
130
core/iwasm/products/linux-sgx/enclave-sample/App/App.cpp
Normal file
130
core/iwasm/products/linux-sgx/enclave-sample/App/App.cpp
Normal file
@ -0,0 +1,130 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include "Enclave_u.h"
|
||||
#include "sgx_urts.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define TOKEN_FILENAME "enclave.token"
|
||||
#define ENCLAVE_FILENAME "enclave.signed.so"
|
||||
#define MAX_PATH FILENAME_MAX
|
||||
|
||||
sgx_enclave_id_t g_eid = 0;
|
||||
|
||||
void
|
||||
ocall_print(const char* str)
|
||||
{
|
||||
printf("%s", str);
|
||||
}
|
||||
|
||||
static void
|
||||
print_error_message(sgx_status_t ret)
|
||||
{
|
||||
printf("SGX error code: %d\n", ret);
|
||||
}
|
||||
|
||||
/* Initialize the enclave:
|
||||
* Step 1: try to retrieve the launch token saved by last transaction
|
||||
* Step 2: call sgx_create_enclave to initialize an enclave instance
|
||||
* Step 3: save the launch token if it is updated
|
||||
*/
|
||||
static int
|
||||
enclave_init(sgx_enclave_id_t *p_eid)
|
||||
|
||||
{
|
||||
char token_path[MAX_PATH] = {'\0'};
|
||||
sgx_launch_token_t token = {0};
|
||||
sgx_status_t ret = SGX_ERROR_UNEXPECTED;
|
||||
int updated = 0;
|
||||
|
||||
/* Step 1: try to retrieve the launch token saved by last transaction
|
||||
* if there is no token, then create a new one.
|
||||
*/
|
||||
/* try to get the token saved in $HOME */
|
||||
const char *home_dir = getpwuid(getuid())->pw_dir;
|
||||
|
||||
if (home_dir != NULL &&
|
||||
(strlen(home_dir) + strlen("/") + sizeof(TOKEN_FILENAME) + 1) <= MAX_PATH) {
|
||||
/* compose the token path */
|
||||
strncpy(token_path, home_dir, strlen(home_dir));
|
||||
strncat(token_path, "/", strlen("/"));
|
||||
strncat(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME) + 1);
|
||||
}
|
||||
else {
|
||||
/* if token path is too long or $HOME is NULL */
|
||||
strncpy(token_path, TOKEN_FILENAME, sizeof(TOKEN_FILENAME));
|
||||
}
|
||||
|
||||
FILE *fp = fopen(token_path, "rb");
|
||||
if (fp == NULL && (fp = fopen(token_path, "wb")) == NULL) {
|
||||
printf("Warning: Failed to create/open the launch token file \"%s\".\n", token_path);
|
||||
}
|
||||
|
||||
if (fp != NULL) {
|
||||
/* read the token from saved file */
|
||||
size_t read_num = fread(token, 1, sizeof(sgx_launch_token_t), fp);
|
||||
if (read_num != 0 && read_num != sizeof(sgx_launch_token_t)) {
|
||||
/* if token is invalid, clear the buffer */
|
||||
memset(&token, 0x0, sizeof(sgx_launch_token_t));
|
||||
printf("Warning: Invalid launch token read from \"%s\".\n", token_path);
|
||||
}
|
||||
}
|
||||
|
||||
/* Step 2: call sgx_create_enclave to initialize an enclave instance */
|
||||
/* Debug Support: set 2nd parameter to 1 */
|
||||
ret = sgx_create_enclave(ENCLAVE_FILENAME, SGX_DEBUG_FLAG, &token, &updated, p_eid, NULL);
|
||||
if (ret != SGX_SUCCESS) {
|
||||
print_error_message(ret);
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Step 3: save the launch token if it is updated */
|
||||
if (updated == FALSE || fp == NULL) {
|
||||
/* if the token is not updated, or file handler is invalid, do not perform saving */
|
||||
if (fp != NULL) fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reopen the file with write capablity */
|
||||
fp = freopen(token_path, "wb", fp);
|
||||
if (fp == NULL)
|
||||
return 0;
|
||||
|
||||
size_t write_num = fwrite(token, 1, sizeof(sgx_launch_token_t), fp);
|
||||
if (write_num != sizeof(sgx_launch_token_t))
|
||||
printf("Warning: Failed to save launch token to \"%s\".\n", token_path);
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char const *argv[])
|
||||
{
|
||||
if (enclave_init(&g_eid) < 0) {
|
||||
std::cout << "Fail to initialize enclave." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ecall_iwasm_main(g_eid);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
<!-- Please refer to User's Guide for the explanation of each field -->
|
||||
<EnclaveConfiguration>
|
||||
<ProdID>0</ProdID>
|
||||
<ISVSVN>0</ISVSVN>
|
||||
<StackMaxSize>0x40000</StackMaxSize>
|
||||
<HeapMaxSize>0x100000</HeapMaxSize>
|
||||
<TCSNum>10</TCSNum>
|
||||
<TCSPolicy>1</TCSPolicy>
|
||||
<DisableDebug>0</DisableDebug>
|
||||
<MiscSelect>0</MiscSelect>
|
||||
<MiscMask>0xFFFFFFFF</MiscMask>
|
||||
</EnclaveConfiguration>
|
||||
106
core/iwasm/products/linux-sgx/enclave-sample/Enclave/Enclave.cpp
Normal file
106
core/iwasm/products/linux-sgx/enclave-sample/Enclave/Enclave.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "Enclave_t.h"
|
||||
#include "test_wasm.h"
|
||||
#include "bh_memory.h"
|
||||
#include "wasm_export.h"
|
||||
#include "wasm_application.h"
|
||||
|
||||
static char global_heap_buf[512 * 1024] = { 0 };
|
||||
|
||||
static int app_argc;
|
||||
static char **app_argv;
|
||||
|
||||
static void*
|
||||
app_instance_main(wasm_module_inst_t module_inst)
|
||||
{
|
||||
const char *exception;
|
||||
|
||||
wasm_application_execute_main(module_inst, app_argc, app_argv);
|
||||
if ((exception = wasm_runtime_get_exception(module_inst))) {
|
||||
ocall_print(exception);
|
||||
ocall_print("\n");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
int bh_printf(const char *message, ...);
|
||||
|
||||
typedef void (*bh_print_function_t)(const char* message);
|
||||
extern void bh_set_print_function(bh_print_function_t pf);
|
||||
|
||||
void enclave_print(const char *message)
|
||||
{
|
||||
ocall_print(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ecall_iwasm_main()
|
||||
{
|
||||
bh_set_print_function(enclave_print);
|
||||
|
||||
uint8_t *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
|
||||
if (bh_memory_init_with_pool(global_heap_buf,
|
||||
sizeof(global_heap_buf)) != 0) {
|
||||
ocall_print("Init global heap failed.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* initialize runtime environment */
|
||||
if (!wasm_runtime_init())
|
||||
goto fail1;
|
||||
|
||||
/* load WASM byte buffer from byte buffer of include file */
|
||||
wasm_file_buf = (uint8_t*) wasm_test_file;
|
||||
wasm_file_size = sizeof(wasm_test_file);
|
||||
|
||||
/* load WASM module */
|
||||
if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
|
||||
error_buf, sizeof(error_buf)))) {
|
||||
ocall_print(error_buf);
|
||||
ocall_print("\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
|
||||
16 * 1024,
|
||||
16 * 1024,
|
||||
error_buf,
|
||||
sizeof(error_buf)))) {
|
||||
ocall_print(error_buf);
|
||||
ocall_print("\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
/* execute the main function of wasm app */
|
||||
app_instance_main(wasm_module_inst);
|
||||
|
||||
/* destroy the module instance */
|
||||
wasm_runtime_deinstantiate(wasm_module_inst);
|
||||
|
||||
fail3:
|
||||
/* unload the module */
|
||||
wasm_runtime_unload(wasm_module);
|
||||
|
||||
fail2:
|
||||
/* destroy runtime environment */
|
||||
wasm_runtime_destroy();
|
||||
|
||||
fail1:
|
||||
bh_memory_destroy();
|
||||
}
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
enclave {
|
||||
trusted {
|
||||
/* define ECALLs here. */
|
||||
public void ecall_iwasm_main(void);
|
||||
};
|
||||
|
||||
untrusted {
|
||||
/* define OCALLs here. */
|
||||
void ocall_print([in, string]const char* str);
|
||||
};
|
||||
};
|
||||
@ -0,0 +1,39 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIG4gIBAAKCAYEAroOogvsj/fZDZY8XFdkl6dJmky0lRvnWMmpeH41Bla6U1qLZ
|
||||
AmZuyIF+mQC/cgojIsrBMzBxb1kKqzATF4+XwPwgKz7fmiddmHyYz2WDJfAjIveJ
|
||||
ZjdMjM4+EytGlkkJ52T8V8ds0/L2qKexJ+NBLxkeQLfV8n1mIk7zX7jguwbCG1Pr
|
||||
nEMdJ3Sew20vnje+RsngAzdPChoJpVsWi/K7cettX/tbnre1DL02GXc5qJoQYk7b
|
||||
3zkmhz31TgFrd9VVtmUGyFXAysuSAb3EN+5VnHGr0xKkeg8utErea2FNtNIgua8H
|
||||
ONfm9Eiyaav1SVKzPHlyqLtcdxH3I8Wg7yqMsaprZ1n5A1v/levxnL8+It02KseD
|
||||
5HqV4rf/cImSlCt3lpRg8U5E1pyFQ2IVEC/XTDMiI3c+AR+w2jSRB3Bwn9zJtFlW
|
||||
KHG3m1xGI4ck+Lci1JvWWLXQagQSPtZTsubxTQNx1gsgZhgv1JHVZMdbVlAbbRMC
|
||||
1nSuJNl7KPAS/VfzAgEDAoIBgHRXxaynbVP5gkO0ug6Qw/E27wzIw4SmjsxG6Wpe
|
||||
K7kfDeRskKxESdsA/xCrKkwGwhcx1iIgS5+Qscd1Yg+1D9X9asd/P7waPmWoZd+Z
|
||||
AhlKwhdPsO7PiF3e1AzHhGQwsUTt/Y/aSI1MpHBvy2/s1h9mFCslOUxTmWw0oj/Q
|
||||
ldIEgWeNR72CE2+jFIJIyml6ftnb6qzPiga8Bm48ubKh0kvySOqnkmnPzgh+JBD6
|
||||
JnBmtZbfPT97bwTT+N6rnPqOOApvfHPf15kWI8yDbprG1l4OCUaIUH1AszxLd826
|
||||
5IPM+8gINLRDP1MA6azECPjTyHXhtnSIBZCyWSVkc05vYmNXYUNiXWMajcxW9M02
|
||||
wKzFELO8NCEAkaTPxwo4SCyIjUxiK1LbQ9h8PSy4c1+gGP4LAMR8xqP4QKg6zdu9
|
||||
osUGG/xRe/uufgTBFkcjqBHtK5L5VI0jeNIUAgW/6iNbYXjBMJ0GfauLs+g1VsOm
|
||||
WfdgXzsb9DYdMa0OXXHypmV4GwKBwQDUwQj8RKJ6c8cT4vcWCoJvJF00+RFL+P3i
|
||||
Gx2DLERxRrDa8AVGfqaCjsR+3vLgG8V/py+z+dxZYSqeB80Qeo6PDITcRKoeAYh9
|
||||
xlT3LJOS+k1cJcEmlbbO2IjLkTmzSwa80fWexKu8/Xv6vv15gpqYl1ngYoqJM3pd
|
||||
vzmTIOi7MKSZ0WmEQavrZj8zK4endE3v0eAEeQ55j1GImbypSf7Idh7wOXtjZ7WD
|
||||
Dg6yWDrri+AP/L3gClMj8wsAxMV4ZR8CgcEA0fzDHkFa6raVOxWnObmRoDhAtE0a
|
||||
cjUj976NM5yyfdf2MrKy4/RhdTiPZ6b08/lBC/+xRfV3xKVGzacm6QjqjZrUpgHC
|
||||
0LKiZaMtccCJjLtPwQd0jGQEnKfMFaPsnhOc5y8qVkCzVOSthY5qhz0XNotHHFmJ
|
||||
gffVgB0iqrMTvSL7IA2yqqpOqNRlhaYhNl8TiFP3gIeMtVa9rZy31JPgT2uJ+kfo
|
||||
gV7sdTPEjPWZd7OshGxWpT6QfVDj/T9T7L6tAoHBAI3WBf2DFvxNL2KXT2QHAZ9t
|
||||
k3imC4f7U+wSE6zILaDZyzygA4RUbwG0gv8/TJVn2P/Eynf76DuWHGlaiLWnCbSz
|
||||
Az2DHBQBBaku409zDQym3j1ugMRjzzSQWzJg0SIyBH3hTmnYcn3+Uqcp/lEBvGW6
|
||||
O+rsXFt3pukqJmIV8HzLGGaLm62BHUeZf3dyWm+i3p/hQAL7Xvu04QW70xuGqdr5
|
||||
afV7p5eaeQIJXyGQJ0eylV/90+qxjMKiB1XYg6WYvwKBwQCL/ddpgOdHJGN8uRom
|
||||
e7Zq0Csi3hGheMKlKbN3vcxT5U7MdyHtTZZOJbTvxKNNUNYH/8uD+PqDGNneb29G
|
||||
BfGzvI3EASyLIcGZF3OhKwZd0jUrWk2y7Vhob91jwp2+t73vdMbkKyI4mHOuXvGv
|
||||
fg95si9oO7EBT+Oqvhccd2J+F1IVXncccYnF4u5ZGWt5lLewN/pVr7MjjykeaHqN
|
||||
t+rfnQam2psA6fL4zS2zTmZPzR2tnY8Y1GBTi0Ko1OKd1HMCgcAb5cB/7/AQlhP9
|
||||
yQa04PLH9ygQkKKptZp7dy5WcWRx0K/hAHRoi2aw1wZqfm7VBNu2SLcs90kCCCxp
|
||||
6C5sfJi6b8NpNbIPC+sc9wsFr7pGo9SFzQ78UlcWYK2Gu2FxlMjonhka5hvo4zvg
|
||||
WxlpXKEkaFt3gLd92m/dMqBrHfafH7VwOJY2zT3WIpjwuk0ZzmRg5p0pG/svVQEH
|
||||
NZmwRwlopysbR69B/n1nefJ84UO50fLh5s5Zr3gBRwbWNZyzhXk=
|
||||
-----END RSA PRIVATE KEY-----
|
||||
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/**
|
||||
* The byte array buffer is the file content of a test wasm binary file,
|
||||
* which is compiled by emcc or clang toolchain from C source file of:
|
||||
* core/iwasm/app-samples/hello-world/main.c.
|
||||
*/
|
||||
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
|
||||
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,
|
||||
0x01, 0x7F, 0x01, 0x7F, 0x60, 0x02, 0x7F, 0x7F, 0x01, 0x7F, 0x60, 0x00,
|
||||
0x00, 0x02, 0x58, 0x06, 0x03, 0x65, 0x6E, 0x76, 0x05, 0x5F, 0x66, 0x72,
|
||||
0x65, 0x65, 0x00, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F, 0x6D, 0x61,
|
||||
0x6C, 0x6C, 0x6F, 0x63, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76, 0x07, 0x5F,
|
||||
0x70, 0x72, 0x69, 0x6E, 0x74, 0x66, 0x00, 0x02, 0x03, 0x65, 0x6E, 0x76,
|
||||
0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x00, 0x01, 0x03, 0x65, 0x6E, 0x76,
|
||||
0x0D, 0x5F, 0x5F, 0x6D, 0x65, 0x6D, 0x6F, 0x72, 0x79, 0x5F, 0x62, 0x61,
|
||||
0x73, 0x65, 0x03, 0x7F, 0x00, 0x03, 0x65, 0x6E, 0x76, 0x06, 0x6D, 0x65,
|
||||
0x6D, 0x6F, 0x72, 0x79, 0x02, 0x00, 0x01, 0x03, 0x04, 0x03, 0x02, 0x03,
|
||||
0x03, 0x06, 0x10, 0x03, 0x7F, 0x01, 0x41, 0x00, 0x0B, 0x7F, 0x01, 0x41,
|
||||
0x00, 0x0B, 0x7F, 0x00, 0x41, 0x1B, 0x0B, 0x07, 0x33, 0x04, 0x12, 0x5F,
|
||||
0x5F, 0x70, 0x6F, 0x73, 0x74, 0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E,
|
||||
0x74, 0x69, 0x61, 0x74, 0x65, 0x00, 0x06, 0x05, 0x5F, 0x6D, 0x61, 0x69,
|
||||
0x6E, 0x00, 0x04, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74, 0x53,
|
||||
0x65, 0x74, 0x73, 0x00, 0x05, 0x04, 0x5F, 0x73, 0x74, 0x72, 0x03, 0x03,
|
||||
0x0A, 0xBA, 0x01, 0x03, 0x9E, 0x01, 0x01, 0x01, 0x7F, 0x23, 0x01, 0x21,
|
||||
0x00, 0x23, 0x01, 0x41, 0x10, 0x6A, 0x24, 0x01, 0x20, 0x00, 0x41, 0x08,
|
||||
0x6A, 0x21, 0x02, 0x23, 0x00, 0x41, 0x1B, 0x6A, 0x10, 0x03, 0x1A, 0x41,
|
||||
0x80, 0x08, 0x10, 0x01, 0x21, 0x01, 0x20, 0x01, 0x04, 0x7F, 0x20, 0x00,
|
||||
0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x20, 0x00, 0x10, 0x02, 0x1A,
|
||||
0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x0D, 0x3A, 0x00, 0x00, 0x20, 0x01,
|
||||
0x23, 0x00, 0x2C, 0x00, 0x0E, 0x3A, 0x00, 0x01, 0x20, 0x01, 0x23, 0x00,
|
||||
0x2C, 0x00, 0x0F, 0x3A, 0x00, 0x02, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00,
|
||||
0x10, 0x3A, 0x00, 0x03, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x11, 0x3A,
|
||||
0x00, 0x04, 0x20, 0x01, 0x23, 0x00, 0x2C, 0x00, 0x12, 0x3A, 0x00, 0x05,
|
||||
0x20, 0x02, 0x20, 0x01, 0x36, 0x02, 0x00, 0x23, 0x00, 0x41, 0x13, 0x6A,
|
||||
0x20, 0x02, 0x10, 0x02, 0x1A, 0x20, 0x01, 0x10, 0x00, 0x20, 0x00, 0x24,
|
||||
0x01, 0x41, 0x00, 0x05, 0x23, 0x00, 0x41, 0x28, 0x6A, 0x10, 0x03, 0x1A,
|
||||
0x20, 0x00, 0x24, 0x01, 0x41, 0x7F, 0x0B, 0x0B, 0x03, 0x00, 0x01, 0x0B,
|
||||
0x14, 0x00, 0x23, 0x00, 0x41, 0x40, 0x6B, 0x24, 0x01, 0x23, 0x01, 0x41,
|
||||
0x80, 0x80, 0x04, 0x6A, 0x24, 0x02, 0x10, 0x05, 0x0B, 0x0B, 0x3F, 0x01,
|
||||
0x00, 0x23, 0x00, 0x0B, 0x39, 0x62, 0x75, 0x66, 0x20, 0x70, 0x74, 0x72,
|
||||
0x3A, 0x20, 0x25, 0x70, 0x0A, 0x00, 0x31, 0x32, 0x33, 0x34, 0x0A, 0x00,
|
||||
0x62, 0x75, 0x66, 0x3A, 0x20, 0x25, 0x73, 0x00, 0x48, 0x65, 0x6C, 0x6C,
|
||||
0x6F, 0x20, 0x77, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x00, 0x6D, 0x61, 0x6C,
|
||||
0x6C, 0x6F, 0x63, 0x20, 0x62, 0x75, 0x66, 0x20, 0x66, 0x61, 0x69, 0x6C,
|
||||
0x65, 0x64, 0x00, 0x50, 0x04, 0x6E, 0x61, 0x6D, 0x65, 0x01, 0x49, 0x07,
|
||||
0x00, 0x05, 0x5F, 0x66, 0x72, 0x65, 0x65, 0x01, 0x07, 0x5F, 0x6D, 0x61,
|
||||
0x6C, 0x6C, 0x6F, 0x63, 0x02, 0x07, 0x5F, 0x70, 0x72, 0x69, 0x6E, 0x74,
|
||||
0x66, 0x03, 0x05, 0x5F, 0x70, 0x75, 0x74, 0x73, 0x04, 0x05, 0x5F, 0x6D,
|
||||
0x61, 0x69, 0x6E, 0x05, 0x0B, 0x72, 0x75, 0x6E, 0x50, 0x6F, 0x73, 0x74,
|
||||
0x53, 0x65, 0x74, 0x73, 0x06, 0x12, 0x5F, 0x5F, 0x70, 0x6F, 0x73, 0x74,
|
||||
0x5F, 0x69, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74, 0x69, 0x61, 0x74, 0x65,
|
||||
0x00, 0x20, 0x10, 0x73, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x4D, 0x61, 0x70,
|
||||
0x70, 0x69, 0x6E, 0x67, 0x55, 0x52, 0x4C, 0x0E, 0x61, 0x2E, 0x6F, 0x75,
|
||||
0x74, 0x2E, 0x77, 0x61, 0x73, 0x6D, 0x2E, 0x6D, 0x61, 0x70 };
|
||||
184
core/iwasm/products/linux-sgx/enclave-sample/Makefile
Normal file
184
core/iwasm/products/linux-sgx/enclave-sample/Makefile
Normal file
@ -0,0 +1,184 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
######## SGX SDK Settings ########
|
||||
|
||||
SGX_SDK ?= /opt/intel/sgxsdk
|
||||
SGX_MODE ?= SIM
|
||||
SGX_ARCH ?= x64
|
||||
|
||||
ifeq ($(shell getconf LONG_BIT), 32)
|
||||
SGX_ARCH := x86
|
||||
else ifeq ($(findstring -m32, $(CXXFLAGS)), -m32)
|
||||
SGX_ARCH := x86
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_ARCH), x86)
|
||||
SGX_COMMON_CFLAGS := -m32
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x86/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x86/sgx_edger8r
|
||||
else
|
||||
SGX_COMMON_CFLAGS := -m64
|
||||
SGX_LIBRARY_PATH := $(SGX_SDK)/lib64
|
||||
SGX_ENCLAVE_SIGNER := $(SGX_SDK)/bin/x64/sgx_sign
|
||||
SGX_EDGER8R := $(SGX_SDK)/bin/x64/sgx_edger8r
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
ifeq ($(SGX_PRERELEASE), 1)
|
||||
$(error Cannot set SGX_DEBUG and SGX_PRERELEASE at the same time!!)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
SGX_COMMON_CFLAGS += -O0 -g
|
||||
else
|
||||
SGX_COMMON_CFLAGS += -O2
|
||||
endif
|
||||
|
||||
######## App Settings ########
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
Urts_Library_Name := sgx_urts_sim
|
||||
else
|
||||
Urts_Library_Name := sgx_urts
|
||||
endif
|
||||
|
||||
App_Cpp_Files := App/App.cpp
|
||||
App_Include_Paths := -IApp -I$(SGX_SDK)/include
|
||||
|
||||
App_C_Flags := $(SGX_COMMON_CFLAGS) -fPIC -Wno-attributes $(App_Include_Paths)
|
||||
|
||||
# Three configuration modes - Debug, prerelease, release
|
||||
# Debug - Macro DEBUG enabled.
|
||||
# Prerelease - Macro NDEBUG and EDEBUG enabled.
|
||||
# Release - Macro NDEBUG enabled.
|
||||
ifeq ($(SGX_DEBUG), 1)
|
||||
App_C_Flags += -DDEBUG -UNDEBUG -UEDEBUG
|
||||
else ifeq ($(SGX_PRERELEASE), 1)
|
||||
App_C_Flags += -DNDEBUG -DEDEBUG -UDEBUG
|
||||
else
|
||||
App_C_Flags += -DNDEBUG -UEDEBUG -UDEBUG
|
||||
endif
|
||||
|
||||
App_Cpp_Flags := $(App_C_Flags) -std=c++11
|
||||
App_Link_Flags := $(SGX_COMMON_CFLAGS) -L$(SGX_LIBRARY_PATH) -l$(Urts_Library_Name) -lpthread
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
App_Link_Flags += -lsgx_uae_service_sim
|
||||
else
|
||||
App_Link_Flags += -lsgx_uae_service
|
||||
endif
|
||||
|
||||
App_Cpp_Objects := $(App_Cpp_Files:.cpp=.o)
|
||||
|
||||
App_Name := app
|
||||
|
||||
######## Enclave Settings ########
|
||||
|
||||
ifneq ($(SGX_MODE), HW)
|
||||
Trts_Library_Name := sgx_trts_sim
|
||||
Service_Library_Name := sgx_tservice_sim
|
||||
else
|
||||
Trts_Library_Name := sgx_trts
|
||||
Service_Library_Name := sgx_tservice
|
||||
endif
|
||||
Crypto_Library_Name := sgx_tcrypto
|
||||
|
||||
WAMR_ROOT := $(CURDIR)/../../../../../
|
||||
|
||||
Enclave_Cpp_Files := Enclave/Enclave.cpp
|
||||
Enclave_Include_Paths := -IEnclave -I$(WAMR_ROOT)/core/iwasm/runtime/include \
|
||||
-I$(SGX_SDK)/include -I$(SGX_SDK)/include/tlibc -I$(SGX_SDK)/include/stlport
|
||||
|
||||
Enclave_C_Flags := $(SGX_COMMON_CFLAGS) -nostdinc -fvisibility=hidden -fpie -fstack-protector $(Enclave_Include_Paths)
|
||||
Enclave_Cpp_Flags := $(Enclave_C_Flags) -std=c++03 -nostdinc++
|
||||
Enclave_Link_Flags := $(SGX_COMMON_CFLAGS) -Wl,--no-undefined -nostdlib -nodefaultlibs -nostartfiles -L$(SGX_LIBRARY_PATH) \
|
||||
-Wl,--whole-archive -l$(Trts_Library_Name) -Wl,--no-whole-archive \
|
||||
libvmlib.a libextlib.a \
|
||||
-Wl,--start-group -lsgx_tstdc -lsgx_tcxx -l$(Crypto_Library_Name) -l$(Service_Library_Name) -Wl,--end-group \
|
||||
-Wl,-Bstatic -Wl,-Bsymbolic -Wl,--no-undefined \
|
||||
-Wl,-pie,-eenclave_entry -Wl,--export-dynamic \
|
||||
-Wl,--defsym,__ImageBase=0
|
||||
|
||||
Enclave_Cpp_Objects := $(Enclave_Cpp_Files:.cpp=.o)
|
||||
|
||||
Enclave_Name := enclave.so
|
||||
Signed_Enclave_Name := enclave.signed.so
|
||||
Enclave_Config_File := Enclave/Enclave.config.xml
|
||||
|
||||
ifeq ($(SGX_MODE), HW)
|
||||
ifneq ($(SGX_DEBUG), 1)
|
||||
ifneq ($(SGX_PRERELEASE), 1)
|
||||
Build_Mode = HW_RELEASE
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: all run
|
||||
|
||||
ifeq ($(Build_Mode), HW_RELEASE)
|
||||
all: $(App_Name) $(Enclave_Name)
|
||||
@echo "The project has been built in release hardware mode."
|
||||
@echo "Please sign the $(Enclave_Name) first with your signing key before you run the $(App_Name) to launch and access the enclave."
|
||||
@echo "To sign the enclave use the command:"
|
||||
@echo " $(SGX_ENCLAVE_SIGNER) sign -key <your key> -enclave $(Enclave_Name) -out <$(Signed_Enclave_Name)> -config $(Enclave_Config_File)"
|
||||
@echo "You can also sign the enclave using an external signing tool. See User's Guide for more details."
|
||||
@echo "To build the project in simulation mode set SGX_MODE=SIM. To build the project in prerelease mode set SGX_PRERELEASE=1 and SGX_MODE=HW."
|
||||
else
|
||||
all: $(App_Name) $(Signed_Enclave_Name)
|
||||
endif
|
||||
|
||||
run: all
|
||||
ifneq ($(Build_Mode), HW_RELEASE)
|
||||
@$(CURDIR)/$(App_Name)
|
||||
@echo "RUN => $(App_Name) [$(SGX_MODE)|$(SGX_ARCH), OK]"
|
||||
endif
|
||||
|
||||
######## App Objects ########
|
||||
|
||||
App/Enclave_u.c: $(SGX_EDGER8R) Enclave/Enclave.edl
|
||||
@cd App && $(SGX_EDGER8R) --untrusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
|
||||
@echo "GEN => $@"
|
||||
|
||||
App/Enclave_u.o: App/Enclave_u.c
|
||||
@$(CC) $(App_C_Flags) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
App/%.o: App/%.cpp
|
||||
@$(CXX) $(App_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
$(App_Name): App/Enclave_u.o $(App_Cpp_Objects)
|
||||
@$(CXX) $^ -o $@ $(App_Link_Flags)
|
||||
@echo "LINK => $@"
|
||||
|
||||
|
||||
######## Enclave Objects ########
|
||||
|
||||
Enclave/Enclave_t.c: $(SGX_EDGER8R) Enclave/Enclave.edl
|
||||
@cd Enclave && $(SGX_EDGER8R) --trusted ../Enclave/Enclave.edl --search-path ../Enclave --search-path $(SGX_SDK)/include
|
||||
@echo "GEN => $@"
|
||||
|
||||
Enclave/Enclave_t.o: Enclave/Enclave_t.c
|
||||
@$(CC) $(Enclave_C_Flags) -c $< -o $@
|
||||
@echo "CC <= $<"
|
||||
|
||||
Enclave/%.o: Enclave/%.cpp
|
||||
@$(CXX) $(Enclave_Cpp_Flags) -c $< -o $@
|
||||
@echo "CXX <= $<"
|
||||
|
||||
$(Enclave_Name): Enclave/Enclave_t.o $(Enclave_Cpp_Objects)
|
||||
@$(CXX) $^ -o $@ $(Enclave_Link_Flags)
|
||||
@echo "LINK => $@"
|
||||
|
||||
$(Signed_Enclave_Name): $(Enclave_Name)
|
||||
@$(SGX_ENCLAVE_SIGNER) sign -key Enclave/Enclave_private.pem -enclave $(Enclave_Name) -out $@ -config $(Enclave_Config_File)
|
||||
@echo "SIGN => $@"
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
@rm -f $(App_Name) $(Enclave_Name) $(Signed_Enclave_Name) $(App_Cpp_Objects) App/Enclave_u.* $(Enclave_Cpp_Objects) Enclave/Enclave_t.*
|
||||
@ -17,7 +17,7 @@ endif ()
|
||||
|
||||
# Set BUILD_TARGET, currently values supported:
|
||||
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32"
|
||||
if (NOT BUILD_TARGET)
|
||||
if (NOT DEFINED BUILD_TARGET)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
set (BUILD_TARGET "X86_64")
|
||||
@ -60,6 +60,18 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WASM_ENABLE_WASI)
|
||||
# Enable wasi support by default
|
||||
set (WASM_ENABLE_WASI 1)
|
||||
endif ()
|
||||
|
||||
if (WASM_ENABLE_WASI EQUAL 1)
|
||||
add_definitions(-DWASM_ENABLE_WASI=1)
|
||||
message ("-- WASI enabled")
|
||||
else ()
|
||||
message ("-- WASI disabled")
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
@ -80,16 +92,26 @@ enable_language (ASM)
|
||||
include (../../runtime/platform/${PLATFORM}/platform.cmake)
|
||||
include (../../runtime/utils/utils.cmake)
|
||||
include (../../runtime/vmcore-wasm/vmcore.cmake)
|
||||
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
|
||||
include (../../lib/native/base/wasm_lib_base.cmake)
|
||||
include (../../lib/native/libc/wasm_libc.cmake)
|
||||
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
|
||||
include (${SHARED_LIB_DIR}/mem-alloc/mem_alloc.cmake)
|
||||
include (${SHARED_LIB_DIR}/utils/shared_utils.cmake)
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wformat -Wformat-security")
|
||||
#set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wconversion -Wsign-conversion")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mindirect-branch=thunk -mfunction-return=thunk -mindirect-branch-register")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector-strong --param ssp-buffer-size=4")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pie -fPIE -ftrapv -D_FORTIFY_SOURCE=2")
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wl,-z,noexecstack,-z,relro,-z,now")
|
||||
#message ("-- CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
|
||||
|
||||
add_library (vmlib
|
||||
${WASM_PLATFORM_LIB_SOURCE}
|
||||
${WASM_UTILS_LIB_SOURCE}
|
||||
${VMCORE_LIB_SOURCE}
|
||||
${WASI_LIB_SOURCE}
|
||||
${WASM_LIB_BASE_DIR}/base_lib_export.c
|
||||
${WASM_LIBC_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
|
||||
@ -32,6 +32,15 @@ static int print_help()
|
||||
#endif
|
||||
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
||||
" that runs commands in the form of `FUNC ARG...`\n");
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
|
||||
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -104,7 +113,7 @@ split_string(char *str, int *count)
|
||||
do {
|
||||
p = strtok(str, " ");
|
||||
str = NULL;
|
||||
res = (char**) realloc(res, sizeof(char*) * (idx + 1));
|
||||
res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -147,6 +156,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_env_str(char *env)
|
||||
{
|
||||
char *p = env;
|
||||
int key_len = 0;
|
||||
|
||||
while (*p != '\0' && *p != '=') {
|
||||
key_len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '=' || key_len == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define USE_GLOBAL_HEAP_BUF 0
|
||||
|
||||
#if USE_GLOBAL_HEAP_BUF != 0
|
||||
@ -158,7 +184,7 @@ int main(int argc, char *argv[])
|
||||
char *wasm_file = NULL;
|
||||
const char *func_name = NULL;
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
uint32 wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
@ -166,6 +192,12 @@ int main(int argc, char *argv[])
|
||||
int log_verbose_level = 1;
|
||||
#endif
|
||||
bool is_repl_mode = false;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
const char *dir_list[8] = { NULL };
|
||||
uint32 dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32 env_list_size = 0;
|
||||
#endif
|
||||
|
||||
/* Process options. */
|
||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||
@ -186,6 +218,37 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
else if (!strcmp(argv[0], "--repl"))
|
||||
is_repl_mode = true;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
else if (!strncmp(argv[0], "--dir=", 6)) {
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max dir number %d\n",
|
||||
(int)(sizeof(dir_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
dir_list[dir_list_size++] = argv[0] + 6;
|
||||
}
|
||||
else if (!strncmp(argv[0], "--env=", 6)) {
|
||||
char *tmp_env;
|
||||
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max env number %d\n",
|
||||
(int)(sizeof(env_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
tmp_env = argv[0] + 6;
|
||||
if (validate_env_str(tmp_env))
|
||||
env_list[env_list_size++] = tmp_env;
|
||||
else {
|
||||
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
|
||||
tmp_env);
|
||||
return print_help();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return print_help();
|
||||
}
|
||||
@ -228,6 +291,14 @@ int main(int argc, char *argv[])
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_runtime_set_wasi_args(wasm_module,
|
||||
dir_list, dir_list_size,
|
||||
NULL, 0,
|
||||
env_list, env_list_size,
|
||||
argv, argc);
|
||||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
|
||||
64 * 1024, /* stack size */
|
||||
|
||||
@ -24,7 +24,7 @@ endif ()
|
||||
# "X86_64", "AMD_64", "X86_32", "ARM_32", "MIPS_32", "XTENSA_32", "GENERAL"
|
||||
#set (BUILD_TARGET "X86_64")
|
||||
|
||||
if (NOT BUILD_TARGET)
|
||||
if (NOT DEFINED BUILD_TARGET)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
# if BUILD_TARGET isn't set
|
||||
@ -77,6 +77,19 @@ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WASM_ENABLE_WASI)
|
||||
# Enable wasi support by default
|
||||
set (WASM_ENABLE_WASI 1)
|
||||
endif ()
|
||||
|
||||
if (WASM_ENABLE_WASI EQUAL 1)
|
||||
add_definitions(-DWASM_ENABLE_WASI=1)
|
||||
add_definitions(-D_GNU_SOURCE)
|
||||
message ("-- WASI enabled")
|
||||
else ()
|
||||
message ("-- WASI disabled")
|
||||
endif ()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif (NOT CMAKE_BUILD_TYPE)
|
||||
@ -97,6 +110,7 @@ enable_language (ASM)
|
||||
include (../../runtime/platform/${PLATFORM}/platform.cmake)
|
||||
include (../../runtime/utils/utils.cmake)
|
||||
include (../../runtime/vmcore-wasm/vmcore.cmake)
|
||||
include (../../runtime/wasmtime-wasi-c/wasi.cmake)
|
||||
include (../../lib/native/base/wasm_lib_base.cmake)
|
||||
include (../../lib/native/libc/wasm_libc.cmake)
|
||||
include (${SHARED_LIB_DIR}/platform/${PLATFORM}/shared_platform.cmake)
|
||||
@ -107,6 +121,7 @@ add_library (vmlib
|
||||
${WASM_PLATFORM_LIB_SOURCE}
|
||||
${WASM_UTILS_LIB_SOURCE}
|
||||
${VMCORE_LIB_SOURCE}
|
||||
${WASI_LIB_SOURCE}
|
||||
${WASM_LIB_BASE_DIR}/base_lib_export.c
|
||||
${WASM_LIBC_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
|
||||
@ -32,6 +32,15 @@ static int print_help()
|
||||
#endif
|
||||
wasm_printf(" --repl Start a very simple REPL (read-eval-print-loop) mode\n"
|
||||
" that runs commands in the form of `FUNC ARG...`\n");
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_printf(" --env=<env> Pass wasi environment variables with \"key=value\"\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --env=\"key1=value1\" --env=\"key2=value2\"\n");
|
||||
wasm_printf(" --dir=<dir> Grant wasi access to the given host directories\n");
|
||||
wasm_printf(" to the program, for example:\n");
|
||||
wasm_printf(" --dir=<dir1> --dir=<dir2>\n");
|
||||
#endif
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -104,7 +113,7 @@ split_string(char *str, int *count)
|
||||
do {
|
||||
p = strtok(str, " ");
|
||||
str = NULL;
|
||||
res = (char**) realloc(res, sizeof(char*) * (idx + 1));
|
||||
res = (char**) realloc(res, sizeof(char*) * (uint32)(idx + 1));
|
||||
if (res == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@ -147,6 +156,23 @@ app_instance_repl(wasm_module_inst_t module_inst)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool
|
||||
validate_env_str(char *env)
|
||||
{
|
||||
char *p = env;
|
||||
int key_len = 0;
|
||||
|
||||
while (*p != '\0' && *p != '=') {
|
||||
key_len++;
|
||||
p++;
|
||||
}
|
||||
|
||||
if (*p != '=' || key_len == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static char global_heap_buf[512 * 1024] = { 0 };
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
@ -154,7 +180,7 @@ int main(int argc, char *argv[])
|
||||
char *wasm_file = NULL;
|
||||
const char *func_name = NULL;
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
uint32 wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
@ -162,6 +188,12 @@ int main(int argc, char *argv[])
|
||||
int log_verbose_level = 1;
|
||||
#endif
|
||||
bool is_repl_mode = false;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
const char *dir_list[8] = { NULL };
|
||||
uint32 dir_list_size = 0;
|
||||
const char *env_list[8] = { NULL };
|
||||
uint32 env_list_size = 0;
|
||||
#endif
|
||||
|
||||
/* Process options. */
|
||||
for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
|
||||
@ -182,6 +214,37 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
else if (!strcmp(argv[0], "--repl"))
|
||||
is_repl_mode = true;
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
else if (!strncmp(argv[0], "--dir=", 6)) {
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (dir_list_size >= sizeof(dir_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max dir number %d\n",
|
||||
(int)(sizeof(dir_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
dir_list[dir_list_size++] = argv[0] + 6;
|
||||
}
|
||||
else if (!strncmp(argv[0], "--env=", 6)) {
|
||||
char *tmp_env;
|
||||
|
||||
if (argv[0][6] == '\0')
|
||||
return print_help();
|
||||
if (env_list_size >= sizeof(env_list) / sizeof(char*)) {
|
||||
wasm_printf("Only allow max env number %d\n",
|
||||
(int)(sizeof(env_list) / sizeof(char*)));
|
||||
return -1;
|
||||
}
|
||||
tmp_env = argv[0] + 6;
|
||||
if (validate_env_str(tmp_env))
|
||||
env_list[env_list_size++] = tmp_env;
|
||||
else {
|
||||
wasm_printf("Wasm parse env string failed: expect \"key=value\", got \"%s\"\n",
|
||||
tmp_env);
|
||||
return print_help();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
return print_help();
|
||||
}
|
||||
@ -217,6 +280,14 @@ int main(int argc, char *argv[])
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_runtime_set_wasi_args(wasm_module,
|
||||
dir_list, dir_list_size,
|
||||
NULL, 0,
|
||||
env_list, env_list_size,
|
||||
argv, argc);
|
||||
#endif
|
||||
|
||||
/* instantiate the module */
|
||||
if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
|
||||
16 * 1024, /* stack size */
|
||||
|
||||
@ -8,11 +8,13 @@ project(NONE)
|
||||
|
||||
enable_language (ASM)
|
||||
|
||||
set (PLATFORM "zephyr")
|
||||
|
||||
add_definitions (-DNVALGRIND)
|
||||
|
||||
# Build as X86_32 by default, change to "ARM_32", "MIPS_32" or "XTENSA_32"
|
||||
# if we want to support arm, mips or xtensa
|
||||
if (NOT BUILD_TARGET)
|
||||
if (NOT DEFINED BUILD_TARGET)
|
||||
set (BUILD_TARGET "X86_32")
|
||||
endif ()
|
||||
|
||||
@ -35,33 +37,29 @@ message ("-- Build as target ${BUILD_TARGET}")
|
||||
set (IWASM_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/iwasm)
|
||||
set (SHARED_LIB_ROOT ${IWASM_ROOT}/../shared-lib)
|
||||
|
||||
include_directories (${IWASM_ROOT}/runtime/include
|
||||
${IWASM_ROOT}/runtime/platform/include
|
||||
${IWASM_ROOT}/runtime/platform/zephyr
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm
|
||||
${SHARED_LIB_ROOT}/include
|
||||
${SHARED_LIB_ROOT}/platform/include
|
||||
${SHARED_LIB_ROOT}/platform/zephyr)
|
||||
include (${IWASM_ROOT}/runtime/platform/${PLATFORM}/platform.cmake)
|
||||
include (${IWASM_ROOT}/runtime/utils/utils.cmake)
|
||||
include (${IWASM_ROOT}/runtime/vmcore-wasm/vmcore.cmake)
|
||||
include (${IWASM_ROOT}/runtime/wasmtime-wasi-c/wasi.cmake)
|
||||
include (${IWASM_ROOT}/lib/native/base/wasm_lib_base.cmake)
|
||||
include (${IWASM_ROOT}/lib/native/libc/wasm_libc.cmake)
|
||||
include (${SHARED_LIB_ROOT}/platform/${PLATFORM}/shared_platform.cmake)
|
||||
include (${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.cmake)
|
||||
include (${SHARED_LIB_ROOT}/utils/shared_utils.cmake)
|
||||
|
||||
set (IWASM_SRCS ${IWASM_ROOT}/runtime/utils/wasm_hashmap.c
|
||||
${IWASM_ROOT}/runtime/utils/wasm_log.c
|
||||
${IWASM_ROOT}/runtime/utils/wasm_dlfcn.c
|
||||
${IWASM_ROOT}/runtime/platform/zephyr/wasm_native.c
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_application.c
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_interp.c
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_loader.c
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm/wasm_runtime.c
|
||||
${IWASM_ROOT}/runtime/vmcore-wasm/invokeNative_general.c
|
||||
${IWASM_ROOT}/lib/native/libc/libc_wrapper.c
|
||||
${IWASM_ROOT}/lib/native/base/base_lib_export.c
|
||||
${SHARED_LIB_ROOT}/platform/zephyr/bh_platform.c
|
||||
${SHARED_LIB_ROOT}/platform/zephyr/bh_assert.c
|
||||
${SHARED_LIB_ROOT}/platform/zephyr/bh_thread.c
|
||||
${SHARED_LIB_ROOT}/platform/zephyr/bh_math.c
|
||||
${SHARED_LIB_ROOT}/mem-alloc/bh_memory.c
|
||||
${SHARED_LIB_ROOT}/mem-alloc/mem_alloc.c
|
||||
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_kfc.c
|
||||
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_alloc.c
|
||||
${SHARED_LIB_ROOT}/mem-alloc/ems/ems_hmu.c)
|
||||
set (VM_LIB_SRCS
|
||||
${WASM_PLATFORM_LIB_SOURCE}
|
||||
${WASM_UTILS_LIB_SOURCE}
|
||||
${VMCORE_LIB_SOURCE}
|
||||
${WASI_LIB_SOURCE}
|
||||
${WASM_LIB_BASE_DIR}/base_lib_export.c
|
||||
${WASM_LIBC_SOURCE}
|
||||
${PLATFORM_SHARED_SOURCE}
|
||||
${MEM_ALLOC_SHARED_SOURCE}
|
||||
${UTILS_SHARED_SOURCE})
|
||||
|
||||
target_sources(app PRIVATE
|
||||
${VM_LIB_SRCS}
|
||||
src/main.c
|
||||
src/ext_lib_export.c)
|
||||
|
||||
target_sources(app PRIVATE ${IWASM_SRCS} src/main.c src/ext_lib_export.c)
|
||||
|
||||
@ -53,7 +53,7 @@ static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
|
||||
void iwasm_main(void *arg1, void *arg2, void *arg3)
|
||||
{
|
||||
uint8 *wasm_file_buf = NULL;
|
||||
int wasm_file_size;
|
||||
uint32 wasm_file_size;
|
||||
wasm_module_t wasm_module = NULL;
|
||||
wasm_module_inst_t wasm_module_inst = NULL;
|
||||
char error_buf[128];
|
||||
|
||||
@ -3,6 +3,11 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/**
|
||||
* The byte array buffer is the file content of a test wasm binary file,
|
||||
* which is compiled by emcc or clang toolchain from C source file of:
|
||||
* core/iwasm/app-samples/hello-world/main.c.
|
||||
*/
|
||||
unsigned char wasm_test_file[] = { 0x00, 0x61, 0x73, 0x6D, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x0D, 0x06, 0x64, 0x79, 0x6C, 0x69, 0x6E, 0x6B, 0xC0, 0x80,
|
||||
0x04, 0x04, 0x00, 0x00, 0x01, 0x13, 0x04, 0x60, 0x01, 0x7F, 0x00, 0x60,
|
||||
|
||||
@ -45,7 +45,7 @@ void bh_memory_destroy();
|
||||
* Get the pool size of memory, if memory is initialized with allocator,
|
||||
* return 1GB by default.
|
||||
*/
|
||||
int bh_memory_pool_size();
|
||||
unsigned bh_memory_pool_size();
|
||||
|
||||
#if BEIHAI_ENABLE_MEMORY_PROFILING == 0
|
||||
|
||||
|
||||
@ -110,6 +110,15 @@ wasm_runtime_load_from_sections(wasm_section_list_t section_list,
|
||||
void
|
||||
wasm_runtime_unload(wasm_module_t module);
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
void
|
||||
wasm_runtime_set_wasi_args(wasm_module_t module,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count,
|
||||
char *argv[], int argc);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instantiate a WASM module.
|
||||
*
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_platform_log.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
@ -91,7 +92,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
|
||||
uint32 iov_len;
|
||||
} *vec;
|
||||
int32 vec_offset = arg2, str_offset;
|
||||
uint32 iov_count = arg3, i;
|
||||
uint32 iov_count = (uint32)arg3, i;
|
||||
int32 count = 0;
|
||||
char *iov_base, *str;
|
||||
|
||||
@ -110,7 +111,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
|
||||
|
||||
str = addr_app_to_native(str_offset);
|
||||
|
||||
memcpy(str, iov_base, vec->iov_len);
|
||||
bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
|
||||
str[vec->iov_len] = '\0';
|
||||
count += wasm_printf("%s", str);
|
||||
|
||||
@ -219,7 +220,7 @@ EMCC_SYSCALL_WRAPPER3(221)
|
||||
|
||||
EMCC_SYSCALL_WRAPPER5(140)
|
||||
|
||||
static int32
|
||||
static uint32
|
||||
getTotalMemory_wrapper(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L)
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
|
||||
|
||||
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_platform_log.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/uio.h>
|
||||
@ -92,7 +93,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
|
||||
return 0;
|
||||
|
||||
wsz = (struct winsize*)addr_app_to_native(arg3);
|
||||
return syscall(54, arg1, arg2, wsz);
|
||||
return (int32)syscall(54, arg1, arg2, wsz);
|
||||
}
|
||||
|
||||
case 146: /* writev */
|
||||
@ -104,7 +105,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
|
||||
uint32 iov_len;
|
||||
} *vec;
|
||||
int32 vec_offset = arg2, str_offset;
|
||||
uint32 iov_count = arg3, i;
|
||||
uint32 iov_count = (uint32)arg3, i;
|
||||
int32 count = 0;
|
||||
char *iov_base, *str;
|
||||
|
||||
@ -123,7 +124,7 @@ __syscall3_wrapper(WASMModuleInstance *module_inst,
|
||||
|
||||
str = addr_app_to_native(str_offset);
|
||||
|
||||
memcpy(str, iov_base, vec->iov_len);
|
||||
bh_memcpy_s(str, vec->iov_len + 1, iov_base, vec->iov_len);
|
||||
str[vec->iov_len] = '\0';
|
||||
count += wasm_printf("%s", str);
|
||||
|
||||
@ -232,7 +233,7 @@ EMCC_SYSCALL_WRAPPER3(221)
|
||||
|
||||
EMCC_SYSCALL_WRAPPER5(140)
|
||||
|
||||
static int32
|
||||
static uint32
|
||||
getTotalMemory_wrapper(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L)
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
|
||||
|
||||
set (PLATFORM_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
|
||||
14
core/iwasm/runtime/platform/zephyr/platform.cmake
Normal file
14
core/iwasm/runtime/platform/zephyr/platform.cmake
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
|
||||
|
||||
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})
|
||||
|
||||
@ -37,7 +37,7 @@ wasm_hash_map_create(uint32 size, bool use_lock,
|
||||
ValueDestroyFunc value_destroy_func)
|
||||
{
|
||||
HashMap *map;
|
||||
uint32 total_size;
|
||||
uint64 total_size;
|
||||
|
||||
if (size > HASH_MAP_MAX_SIZE) {
|
||||
LOG_ERROR("HashMap create failed: size is too large.\n");
|
||||
@ -51,19 +51,21 @@ wasm_hash_map_create(uint32 size, bool use_lock,
|
||||
}
|
||||
|
||||
total_size = offsetof(HashMap, elements) +
|
||||
sizeof(HashMapElem) * size +
|
||||
sizeof(HashMapElem) * (uint64)size +
|
||||
(use_lock ? sizeof(korp_mutex) : 0);
|
||||
|
||||
if (!(map = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(map = wasm_malloc((uint32)total_size))) {
|
||||
LOG_ERROR("HashMap create failed: alloc memory failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(map, 0, total_size);
|
||||
memset(map, 0, (uint32)total_size);
|
||||
|
||||
if (use_lock) {
|
||||
map->lock = (korp_mutex*)
|
||||
((uint8*)map + offsetof(HashMap, elements) + sizeof(HashMapElem) * size);
|
||||
((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);
|
||||
|
||||
@ -217,6 +217,19 @@ typedef struct BlockAddr {
|
||||
#define BLOCK_ADDR_CACHE_SIZE 64
|
||||
#define BLOCK_ADDR_CONFLICT_SIZE 4
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
typedef struct WASIArguments {
|
||||
const char **dir_list;
|
||||
uint32 dir_count;
|
||||
const char **map_dir_list;
|
||||
uint32 map_dir_count;
|
||||
const char **env;
|
||||
uint32 env_count;
|
||||
const char **argv;
|
||||
uint32 argc;
|
||||
} WASIArguments;
|
||||
#endif
|
||||
|
||||
typedef struct WASMModule {
|
||||
uint32 type_count;
|
||||
uint32 import_count;
|
||||
@ -255,16 +268,19 @@ typedef struct WASMModule {
|
||||
#else
|
||||
BlockAddr block_addr_cache[BLOCK_ADDR_CACHE_SIZE][BLOCK_ADDR_CONFLICT_SIZE];
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
WASIArguments wasi_args;
|
||||
bool is_wasi_module;
|
||||
#endif
|
||||
} 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 {
|
||||
@ -299,7 +315,7 @@ align_uint (unsigned v, unsigned b)
|
||||
inline static uint32
|
||||
wasm_string_hash(const char *str)
|
||||
{
|
||||
unsigned h = strlen(str);
|
||||
unsigned h = (unsigned)strlen(str);
|
||||
const uint8 *p = (uint8*)str;
|
||||
const uint8 *end = p + h;
|
||||
|
||||
@ -356,11 +372,11 @@ wasm_value_type_cell_num(uint8 value_type)
|
||||
inline static uint16
|
||||
wasm_get_cell_num(const uint8 *types, uint32 type_count)
|
||||
{
|
||||
uint16 cell_num = 0;
|
||||
uint32 cell_num = 0;
|
||||
uint32 i;
|
||||
for (i = 0; i < type_count; i++)
|
||||
cell_num += wasm_value_type_cell_num(types[i]);
|
||||
return cell_num;
|
||||
return (uint16)cell_num;
|
||||
}
|
||||
|
||||
inline static uint16
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_platform_log.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
|
||||
static WASMFunctionInstance*
|
||||
@ -55,17 +56,55 @@ check_main_func_type(const WASMType *type)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
static WASMFunctionInstance *
|
||||
lookup_wasi_start_function(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASMFunctionInstance *func = NULL;
|
||||
uint32 i;
|
||||
for (i = 0; i < module_inst->export_func_count; i++) {
|
||||
if (!strcmp(module_inst->export_functions[i].name, "_start")) {
|
||||
func = module_inst->export_functions[i].function;
|
||||
if (func->u.func->func_type->param_count != 0
|
||||
|| func->u.func->func_type->result_count != 0) {
|
||||
LOG_ERROR("Lookup wasi _start function failed: "
|
||||
"invalid function type.\n");
|
||||
return NULL;
|
||||
}
|
||||
return func;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_application_execute_main(WASMModuleInstance *module_inst,
|
||||
int argc, char *argv[])
|
||||
{
|
||||
WASMFunctionInstance *func = resolve_main_function(module_inst);
|
||||
WASMFunctionInstance *func;
|
||||
uint32 argc1 = 0, argv1[2] = { 0 };
|
||||
uint32 total_argv_size = 0, total_size;
|
||||
uint32 total_argv_size = 0;
|
||||
uint64 total_size;
|
||||
int32 argv_buf_offset, i;
|
||||
char *argv_buf, *p;
|
||||
char *argv_buf, *p, *p_end;
|
||||
int32 *argv_offsets;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
if (module_inst->module->is_wasi_module) {
|
||||
/* In wasi mode, we should call function named "_start"
|
||||
which initializes the wasi envrionment and then calls
|
||||
the actual main function. Directly call main function
|
||||
may cause exception thrown. */
|
||||
if ((func = lookup_wasi_start_function(module_inst)))
|
||||
return wasm_runtime_call_wasm(module_inst, NULL,
|
||||
func, 0, NULL);
|
||||
/* if no start function is found, we execute
|
||||
the main function as normal */
|
||||
}
|
||||
#endif
|
||||
|
||||
func = resolve_main_function(module_inst);
|
||||
if (!func || func->is_import_func)
|
||||
return false;
|
||||
|
||||
@ -74,25 +113,28 @@ wasm_application_execute_main(WASMModuleInstance *module_inst,
|
||||
|
||||
if (func->u.func->func_type->param_count) {
|
||||
for (i = 0; i < argc; i++)
|
||||
total_argv_size += strlen(argv[i]) + 1;
|
||||
total_argv_size += (uint32)(strlen(argv[i]) + 1);
|
||||
total_argv_size = align_uint(total_argv_size, 4);
|
||||
|
||||
total_size = total_argv_size + sizeof(int32) * argc;
|
||||
total_size = (uint64)total_argv_size + sizeof(int32) * (uint64)argc;
|
||||
|
||||
if (!(argv_buf_offset = wasm_runtime_module_malloc(module_inst, total_size)))
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(argv_buf_offset =
|
||||
wasm_runtime_module_malloc(module_inst, (uint32)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);
|
||||
p_end = p + total_size;
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
memcpy(p, argv[i], strlen(argv[i]) + 1);
|
||||
argv_offsets[i] = argv_buf_offset + (p - argv_buf);
|
||||
bh_memcpy_s(p, (uint32)(p_end - p), argv[i], (uint32)(strlen(argv[i]) + 1));
|
||||
argv_offsets[i] = argv_buf_offset + (int32)(p - argv_buf);
|
||||
p += strlen(argv[i]) + 1;
|
||||
}
|
||||
|
||||
argc1 = 2;
|
||||
argv1[0] = argc;
|
||||
argv1[0] = (uint32)argc;
|
||||
argv1[1] = (uint32)wasm_runtime_addr_native_to_app(module_inst, argv_offsets);
|
||||
}
|
||||
|
||||
@ -165,6 +207,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
WASMType *type;
|
||||
uint32 argc1, *argv1;
|
||||
int32 i, p;
|
||||
uint64 total_size;
|
||||
const char *exception;
|
||||
|
||||
wasm_assert(argc >= 0);
|
||||
@ -181,15 +224,16 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
}
|
||||
|
||||
argc1 = func->param_cell_num;
|
||||
argv1 = wasm_malloc(sizeof(uint32) * (argc1 > 2 ? argc1 : 2));
|
||||
if (argv1 == NULL) {
|
||||
total_size = sizeof(uint32) * (uint64)(argc1 > 2 ? argc1 : 2);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| (!(argv1 = wasm_malloc((uint32)total_size)))) {
|
||||
LOG_ERROR("Wasm prepare param failed: malloc failed.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Parse arguments */
|
||||
for (i = 0, p = 0; i < argc; i++) {
|
||||
char *endptr;
|
||||
char *endptr = NULL;
|
||||
wasm_assert(argv[i] != NULL);
|
||||
if (argv[i][0] == '\0') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
@ -197,7 +241,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
}
|
||||
switch (type->types[i]) {
|
||||
case VALUE_TYPE_I32:
|
||||
argv1[p++] = strtoul(argv[i], &endptr, 0);
|
||||
argv1[p++] = (uint32)strtoul(argv[i], &endptr, 0);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
{
|
||||
@ -217,7 +261,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
if (endptr[0] == ':') {
|
||||
uint32 sig;
|
||||
union ieee754_float u;
|
||||
sig = strtoul(endptr + 1, &endptr, 0);
|
||||
sig = (uint32)strtoul(endptr + 1, &endptr, 0);
|
||||
u.f = f32;
|
||||
if (is_little_endian())
|
||||
u.ieee.ieee_little_endian.mantissa = sig;
|
||||
@ -244,11 +288,11 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
ud.d = u.val;
|
||||
if (is_little_endian()) {
|
||||
ud.ieee.ieee_little_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_little_endian.mantissa1 = sig;
|
||||
ud.ieee.ieee_little_endian.mantissa1 = (uint32)sig;
|
||||
}
|
||||
else {
|
||||
ud.ieee.ieee_big_endian.mantissa0 = sig >> 32;
|
||||
ud.ieee.ieee_big_endian.mantissa1 = sig;
|
||||
ud.ieee.ieee_big_endian.mantissa1 = (uint32)sig;
|
||||
}
|
||||
u.val = ud.d;
|
||||
}
|
||||
@ -258,7 +302,7 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*endptr != '\0' && *endptr != '_') {
|
||||
if (endptr && *endptr != '\0' && *endptr != '_') {
|
||||
LOG_ERROR("Wasm prepare param failed: invalid num (%s).\n", argv[i]);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ typedef float64 CellType_F64;
|
||||
#else /* WASM_CPU_SUPPORTS_UNALIGNED_64BIT_ACCESS != 0 */
|
||||
#define PUT_I64_TO_ADDR(addr, value) do { \
|
||||
union { int64 val; uint32 parts[2]; } u; \
|
||||
u.val = (value); \
|
||||
u.val = (int64)(value); \
|
||||
(addr)[0] = u.parts[0]; \
|
||||
(addr)[1] = u.parts[1]; \
|
||||
} while (0)
|
||||
@ -110,36 +110,36 @@ GET_F64_FROM_ADDR (uint32 *addr)
|
||||
} while (0)
|
||||
|
||||
static inline uint32
|
||||
rotl32(uint32 n, unsigned int c)
|
||||
rotl32(uint32 n, uint32 c)
|
||||
{
|
||||
const unsigned int mask = (31);
|
||||
const uint32 mask = (31);
|
||||
c = c % 32;
|
||||
c &= mask;
|
||||
return (n<<c) | (n>>( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint32
|
||||
rotr32(uint32 n, unsigned int c)
|
||||
rotr32(uint32 n, uint32 c)
|
||||
{
|
||||
const unsigned int mask = (31);
|
||||
const uint32 mask = (31);
|
||||
c = c % 32;
|
||||
c &= mask;
|
||||
return (n>>c) | (n<<( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint64
|
||||
rotl64(uint64 n, unsigned int c)
|
||||
rotl64(uint64 n, uint64 c)
|
||||
{
|
||||
const unsigned int mask = (63);
|
||||
const uint64 mask = (63);
|
||||
c = c % 64;
|
||||
c &= mask;
|
||||
return (n<<c) | (n>>( (-c)&mask ));
|
||||
}
|
||||
|
||||
static inline uint64
|
||||
rotr64(uint64 n, unsigned int c)
|
||||
rotr64(uint64 n, uint64 c)
|
||||
{
|
||||
const unsigned int mask = (63);
|
||||
const uint64 mask = (63);
|
||||
c = c % 64;
|
||||
c &= mask;
|
||||
return (n>>c) | (n<<( (-c)&mask ));
|
||||
@ -237,21 +237,6 @@ popcount64(uint64 u)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline WASMGlobalInstance*
|
||||
get_global(const WASMModuleInstance *module, uint32 global_idx)
|
||||
{
|
||||
if (global_idx >= module->global_count)
|
||||
return NULL;
|
||||
|
||||
return module->globals + global_idx;
|
||||
}
|
||||
|
||||
static inline uint8*
|
||||
get_global_addr(WASMMemoryInstance *memory, WASMGlobalInstance *global)
|
||||
{
|
||||
return memory->global_data + global->data_offset;
|
||||
}
|
||||
|
||||
static uint64
|
||||
read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
{
|
||||
@ -300,7 +285,6 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
frame_csp->block_type = type; \
|
||||
frame_csp->return_type = ret_type; \
|
||||
frame_csp->start_addr = start; \
|
||||
frame_csp->else_addr = else_; \
|
||||
frame_csp->end_addr = end; \
|
||||
frame_csp->frame_sp = frame_sp; \
|
||||
frame_csp++; \
|
||||
@ -315,7 +299,7 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define POP_F64() (frame_sp -= 2, GET_F64_FROM_ADDR(frame_sp))
|
||||
|
||||
#define POP_CSP_CHECK_OVERFLOW(n) do { \
|
||||
wasm_assert(frame_csp - n >= frame->csp_bottom); \
|
||||
wasm_assert(frame_csp - n >= frame->csp_bottom); \
|
||||
} while (0)
|
||||
|
||||
#define POP_CSP() do { \
|
||||
@ -355,28 +339,28 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define LOCAL_I32(n) (*(int32*)(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_I32(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
*(int32*)(local_off(n)) = (int32)(val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_F32(n) (*(float32*)(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_F32(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
*(float32*)(local_off(n)) = (float32)(val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_I64(n) (GET_I64_FROM_ADDR(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_I64(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
PUT_I64_TO_ADDR(local_off(n), val); \
|
||||
} while (0)
|
||||
|
||||
#define LOCAL_F64(n) (GET_F64_FROM_ADDR(local_off(n)))
|
||||
|
||||
#define SET_LOCAL_F64(N, val) do { \
|
||||
int n = (N); \
|
||||
uint32 n = (N); \
|
||||
PUT_F64_TO_ADDR(local_off(n), val); \
|
||||
} while (0)
|
||||
|
||||
@ -428,15 +412,15 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
p += _off; \
|
||||
} while (0)
|
||||
|
||||
#define RECOVER_CONTEXT(new_frame) do { \
|
||||
frame = (new_frame); \
|
||||
cur_func = frame->function; \
|
||||
prev_frame = frame->prev_frame; \
|
||||
frame_ip = frame->ip; \
|
||||
frame_ip_end = wasm_runtime_get_func_code_end(cur_func); \
|
||||
frame_lp = frame->lp; \
|
||||
frame_sp = frame->sp; \
|
||||
frame_csp = frame->csp; \
|
||||
#define RECOVER_CONTEXT(new_frame) do { \
|
||||
frame = (new_frame); \
|
||||
cur_func = frame->function; \
|
||||
prev_frame = frame->prev_frame; \
|
||||
frame_ip = frame->ip; \
|
||||
frame_ip_end = wasm_runtime_get_func_code_end(cur_func); \
|
||||
frame_lp = frame->lp; \
|
||||
frame_sp = frame->sp; \
|
||||
frame_csp = frame->csp; \
|
||||
} while (0)
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
@ -445,56 +429,56 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
#define GET_OPCODE() (void)0
|
||||
#endif
|
||||
|
||||
#define DEF_OP_LOAD(operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
#define DEF_OP_LOAD(operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_STORE(sval_type, sval_op_type, operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
sval_type sval; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
sval = POP_##sval_op_type(); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
#define DEF_OP_STORE(sval_type, sval_op_type, operation) do { \
|
||||
uint32 offset, flags, addr; \
|
||||
sval_type sval; \
|
||||
GET_OPCODE(); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags); \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset); \
|
||||
sval = POP_##sval_op_type(); \
|
||||
addr = POP_I32(); \
|
||||
CHECK_MEMORY_OVERFLOW(); \
|
||||
operation; \
|
||||
(void)flags; \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_I_CONST(ctype, src_op_type) do { \
|
||||
ctype cval; \
|
||||
read_leb_##ctype(frame_ip, frame_ip_end, cval); \
|
||||
PUSH_##src_op_type(cval); \
|
||||
#define DEF_OP_I_CONST(ctype, src_op_type) do { \
|
||||
ctype cval; \
|
||||
read_leb_##ctype(frame_ip, frame_ip_end, cval); \
|
||||
PUSH_##src_op_type(cval); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_EQZ(src_op_type) do { \
|
||||
uint32 val; \
|
||||
val = POP_##src_op_type() == 0; \
|
||||
PUSH_I32(val); \
|
||||
#define DEF_OP_EQZ(src_op_type) do { \
|
||||
int32 val; \
|
||||
val = POP_##src_op_type() == 0; \
|
||||
PUSH_I32(val); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_CMP(src_type, src_op_type, cond) do { \
|
||||
uint32 res; \
|
||||
src_type val1, val2; \
|
||||
val2 = POP_##src_op_type(); \
|
||||
val1 = POP_##src_op_type(); \
|
||||
res = val1 cond val2; \
|
||||
PUSH_I32(res); \
|
||||
#define DEF_OP_CMP(src_type, src_op_type, cond) do { \
|
||||
uint32 res; \
|
||||
src_type val1, val2; \
|
||||
val2 = (src_type)POP_##src_op_type(); \
|
||||
val1 = (src_type)POP_##src_op_type(); \
|
||||
res = val1 cond val2; \
|
||||
PUSH_I32(res); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
|
||||
src_type val1, val2; \
|
||||
val1 = POP_##src_op_type(); \
|
||||
val2 = operation(val1); \
|
||||
PUSH_##src_op_type(val2); \
|
||||
#define DEF_OP_BIT_COUNT(src_type, src_op_type, operation) do { \
|
||||
src_type val1, val2; \
|
||||
val1 = (src_type)POP_##src_op_type(); \
|
||||
val2 = (src_type)operation(val1); \
|
||||
PUSH_##src_op_type(val2); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_NUMERIC(src_type1, src_type2, src_op_type, operation) do { \
|
||||
@ -503,50 +487,48 @@ read_leb(const uint8 *buf, uint32 *p_offset, uint32 maxbits, bool sign)
|
||||
*(src_type2*)(frame_sp); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_MATH(src_type, src_op_type, method) do { \
|
||||
src_type val; \
|
||||
val = POP_##src_op_type(); \
|
||||
PUSH_##src_op_type(method(val)); \
|
||||
#define DEF_OP_MATH(src_type, src_op_type, method) do { \
|
||||
src_type val; \
|
||||
val = POP_##src_op_type(); \
|
||||
PUSH_##src_op_type(method(val)); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
|
||||
min_cond, max_cond) do { \
|
||||
src_type value = POP_##src_op_type(); \
|
||||
if (isnan(value)) { \
|
||||
wasm_runtime_set_exception(module, \
|
||||
"invalid conversion to integer"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
else if (value min_cond || value max_cond) { \
|
||||
wasm_runtime_set_exception(module, "integer overflow"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
PUSH_##dst_op_type(((dst_type)value)); \
|
||||
#define DEF_OP_TRUNC(dst_type, dst_op_type, src_type, src_op_type, \
|
||||
min_cond, max_cond) do { \
|
||||
src_type value = POP_##src_op_type(); \
|
||||
if (isnan(value)) { \
|
||||
wasm_runtime_set_exception(module, \
|
||||
"invalid conversion to integer"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
else if (value min_cond || value max_cond) { \
|
||||
wasm_runtime_set_exception(module, "integer overflow"); \
|
||||
goto got_exception; \
|
||||
} \
|
||||
PUSH_##dst_op_type(((dst_type)value)); \
|
||||
} while (0)
|
||||
|
||||
#define DEF_OP_CONVERT(dst_type, dst_op_type, \
|
||||
src_type, src_op_type) do { \
|
||||
dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
|
||||
PUSH_##dst_op_type(value); \
|
||||
#define DEF_OP_CONVERT(dst_type, dst_op_type, \
|
||||
src_type, src_op_type) do { \
|
||||
dst_type value = (dst_type)(src_type)POP_##src_op_type(); \
|
||||
PUSH_##dst_op_type(value); \
|
||||
} while (0)
|
||||
|
||||
#define GET_LOCAL_INDEX_AND_TYPE() do { \
|
||||
param_count = cur_func->u.func->func_type->param_count; \
|
||||
local_count = cur_func->u.func->local_count; \
|
||||
uint32 param_count = cur_func->param_count; \
|
||||
read_leb_uint32(frame_ip, frame_ip_end, local_idx); \
|
||||
wasm_assert(local_idx < param_count + local_count); \
|
||||
wasm_assert(local_idx < param_count + cur_func->local_count); \
|
||||
if (local_idx < param_count) \
|
||||
local_type = cur_func->u.func->func_type->types[local_idx]; \
|
||||
local_type = cur_func->param_types[local_idx]; \
|
||||
else \
|
||||
local_type = \
|
||||
cur_func->u.func->local_types[local_idx - param_count]; \
|
||||
local_type = cur_func->local_types[local_idx - param_count]; \
|
||||
} while (0)
|
||||
|
||||
static inline int32
|
||||
sign_ext_8_32(int8 val)
|
||||
{
|
||||
if (val & 0x80)
|
||||
return val | 0xffffff00;
|
||||
return (int32)val | (int32)0xffffff00;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -554,7 +536,7 @@ static inline int32
|
||||
sign_ext_16_32(int16 val)
|
||||
{
|
||||
if (val & 0x8000)
|
||||
return val | 0xffff0000;
|
||||
return (int32)val | (int32)0xffff0000;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -562,7 +544,7 @@ static inline int64
|
||||
sign_ext_8_64(int8 val)
|
||||
{
|
||||
if (val & 0x80)
|
||||
return val | 0xffffffffffffff00;
|
||||
return (int64)val | (int64)0xffffffffffffff00;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -570,15 +552,15 @@ static inline int64
|
||||
sign_ext_16_64(int16 val)
|
||||
{
|
||||
if (val & 0x8000)
|
||||
return val | 0xffffffffffff0000;
|
||||
return (int64)val | (int64)0xffffffffffff0000;
|
||||
return val;
|
||||
}
|
||||
|
||||
static inline int64
|
||||
sign_ext_32_64(int32 val)
|
||||
{
|
||||
if (val & 0x80000000)
|
||||
return val | 0xffffffff00000000;
|
||||
if (val & (int32)0x80000000)
|
||||
return (int64)val | (int64)0xffffffff00000000;
|
||||
return val;
|
||||
}
|
||||
|
||||
@ -674,10 +656,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
uint32 memory_data_size = memory
|
||||
? NumBytesPerPage * memory->cur_page_count : 0;
|
||||
uint32 heap_base_offset = memory ? memory->heap_base_offset : 0;
|
||||
uint32 heap_base_offset = memory ? (uint32)memory->heap_base_offset : 0;
|
||||
uint32 heap_data_size = memory
|
||||
? memory->heap_data_end - memory->heap_data : 0;
|
||||
? (uint32)(memory->heap_data_end - memory->heap_data) : 0;
|
||||
WASMTableInstance *table = module->default_table;
|
||||
WASMGlobalInstance *globals = module->globals;
|
||||
uint8 *global_data = memory ? memory->global_data : NULL;
|
||||
uint8 opcode_IMPDEP2 = WASM_OP_IMPDEP2;
|
||||
WASMInterpFrame *frame = NULL;
|
||||
/* Points to this special opcode so as to jump to the
|
||||
@ -690,10 +674,10 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
uint8 opcode, block_ret_type;
|
||||
uint32 *depths = NULL;
|
||||
uint32 depth_buf[BR_TABLE_TMP_BUF_LEN];
|
||||
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0;
|
||||
uint32 i, depth, cond, count, fidx, tidx, frame_size = 0;
|
||||
uint64 all_cell_num = 0;
|
||||
int32 didx, val;
|
||||
uint8 *else_addr, *end_addr;
|
||||
uint8 *maddr = NULL;
|
||||
uint8 *else_addr, *end_addr, *maddr = NULL;
|
||||
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
#define HANDLE_OPCODE(op) &&HANDLE_##op
|
||||
@ -723,7 +707,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_BLOCK):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -738,7 +722,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_LOOP):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -753,7 +737,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
HANDLE_OP_END ();
|
||||
|
||||
HANDLE_OP (WASM_OP_IF):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, block_ret_type);
|
||||
read_leb_uint8(frame_ip, frame_ip_end, block_ret_type);
|
||||
|
||||
if (!wasm_loader_find_block_addr(module->module,
|
||||
frame_ip, frame_ip_end,
|
||||
@ -764,7 +748,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
|
||||
PUSH_CSP(BLOCK_TYPE_IF, block_ret_type, frame_ip, else_addr, end_addr);
|
||||
|
||||
@ -806,7 +790,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_BR_IF):
|
||||
read_leb_uint32(frame_ip, frame_ip_end, depth);
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
if (cond)
|
||||
POP_CSP_N(depth);
|
||||
HANDLE_OP_END ();
|
||||
@ -816,7 +800,9 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
if (count <= BR_TABLE_TMP_BUF_LEN)
|
||||
depths = depth_buf;
|
||||
else {
|
||||
if (!(depths = wasm_malloc(sizeof(uint32) * count))) {
|
||||
uint64 total_size = sizeof(uint32) * (uint64)count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(depths = wasm_malloc((uint32)total_size))) {
|
||||
wasm_runtime_set_exception(module,
|
||||
"WASM interp failed: "
|
||||
"allocate memory failed.");
|
||||
@ -916,7 +902,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_SELECT_32):
|
||||
{
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
frame_sp--;
|
||||
if (!cond)
|
||||
*(frame_sp - 1) = *frame_sp;
|
||||
@ -925,7 +911,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
HANDLE_OP (WASM_OP_SELECT_64):
|
||||
{
|
||||
cond = POP_I32();
|
||||
cond = (uint32)POP_I32();
|
||||
frame_sp -= 2;
|
||||
if (!cond) {
|
||||
*(frame_sp - 2) = *frame_sp;
|
||||
@ -937,7 +923,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
/* variable instructions */
|
||||
HANDLE_OP (WASM_OP_GET_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -960,13 +946,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
"invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
HANDLE_OP (WASM_OP_SET_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -989,13 +974,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
"invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
HANDLE_OP (WASM_OP_TEE_LOCAL):
|
||||
{
|
||||
uint32 local_idx, param_count, local_count;
|
||||
uint32 local_idx;
|
||||
uint8 local_type;
|
||||
|
||||
GET_LOCAL_INDEX_AND_TYPE();
|
||||
@ -1017,7 +1001,6 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
wasm_runtime_set_exception(module, "invalid local type");
|
||||
goto got_exception;
|
||||
}
|
||||
(void)local_count;
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
|
||||
@ -1025,24 +1008,26 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
WASMGlobalInstance *global;
|
||||
uint32 global_idx;
|
||||
uint8 *global_addr;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
|
||||
|
||||
global = get_global(module, global_idx);
|
||||
wasm_assert(global && global_idx < module->global_count);
|
||||
wasm_assert(global_idx < module->global_count);
|
||||
global = globals + global_idx;
|
||||
global_addr = global_data + global->data_offset;
|
||||
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
PUSH_I32(*(uint32*)get_global_addr(memory, global));
|
||||
PUSH_I32(*(uint32*)global_addr);
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
PUSH_F32(*(float32*)get_global_addr(memory, global));
|
||||
PUSH_F32(*(float32*)global_addr);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUSH_I64(*(uint64*)get_global_addr(memory, global));
|
||||
PUSH_I64(GET_I64_FROM_ADDR((uint32*)global_addr));
|
||||
break;
|
||||
case VALUE_TYPE_F64:
|
||||
PUSH_F64(*(float64*)get_global_addr(memory, global));
|
||||
PUSH_F64(GET_F64_FROM_ADDR((uint32*)global_addr));
|
||||
break;
|
||||
default:
|
||||
wasm_runtime_set_exception(module, "invalid global type");
|
||||
@ -1059,13 +1044,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, global_idx);
|
||||
|
||||
global = get_global(module, global_idx);
|
||||
wasm_assert(global && global_idx < module->global_count);
|
||||
wasm_assert(global_idx < module->global_count);
|
||||
global = globals + global_idx;
|
||||
global_addr = global_data + global->data_offset;
|
||||
|
||||
global_addr = get_global_addr(memory, global);
|
||||
switch (global->type) {
|
||||
case VALUE_TYPE_I32:
|
||||
*(uint32*)global_addr = POP_I32();
|
||||
*(int32*)global_addr = POP_I32();
|
||||
break;
|
||||
case VALUE_TYPE_F32:
|
||||
*(float32*)global_addr = POP_F32();
|
||||
@ -1103,7 +1088,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
#if WASM_ENABLE_LABELS_AS_VALUES != 0
|
||||
static const void *handle_load_table[] = {
|
||||
@ -1184,7 +1169,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
frame_sp--;
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
*(uint32*)maddr = frame_sp[1];
|
||||
(void)flags;
|
||||
@ -1198,7 +1183,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
frame_sp -= 2;
|
||||
addr = POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
*(uint32*)maddr = frame_sp[1];
|
||||
*((uint32*)maddr + 1) = frame_sp[2];
|
||||
@ -1215,12 +1200,12 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
sval = POP_I32();
|
||||
addr = POP_I32();
|
||||
sval = (uint32)POP_I32();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
switch (opcode) {
|
||||
case WASM_OP_I32_STORE:
|
||||
*(int32*)maddr = sval;
|
||||
*(uint32*)maddr = sval;
|
||||
break;
|
||||
case WASM_OP_I32_STORE8:
|
||||
*(uint8*)maddr = (uint8)sval;
|
||||
@ -1243,8 +1228,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
GET_OPCODE();
|
||||
read_leb_uint32(frame_ip, frame_ip_end, flags);
|
||||
read_leb_uint32(frame_ip, frame_ip_end, offset);
|
||||
sval = POP_I64();
|
||||
addr = POP_I32();
|
||||
sval = (uint64)POP_I64();
|
||||
addr = (uint32)POP_I32();
|
||||
CHECK_MEMORY_OVERFLOW();
|
||||
switch (opcode) {
|
||||
case WASM_OP_I64_STORE:
|
||||
@ -1279,13 +1264,13 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
uint32 reserved, delta, prev_page_count = memory->cur_page_count;
|
||||
|
||||
read_leb_uint32(frame_ip, frame_ip_end, reserved);
|
||||
delta = POP_I32();
|
||||
delta = (uint32)POP_I32();
|
||||
|
||||
if (!wasm_runtime_enlarge_memory(module, delta)) {
|
||||
/* fail to memory.grow, return -1 */
|
||||
PUSH_I32(-1);
|
||||
if (wasm_runtime_get_exception(module)) {
|
||||
printf("%s\n", wasm_runtime_get_exception(module));
|
||||
bh_printf("%s\n", wasm_runtime_get_exception(module));
|
||||
wasm_runtime_set_exception(module, NULL);
|
||||
}
|
||||
}
|
||||
@ -1295,6 +1280,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
/* update the memory instance ptr */
|
||||
memory = module->default_memory;
|
||||
memory_data_size = NumBytesPerPage * memory->cur_page_count;
|
||||
global_data = memory->global_data;
|
||||
}
|
||||
|
||||
(void)reserved;
|
||||
@ -1514,8 +1500,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1546,8 +1532,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1584,8 +1570,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
PUSH_I32(rotl32(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1594,8 +1580,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint32 a, b;
|
||||
|
||||
b = POP_I32();
|
||||
a = POP_I32();
|
||||
b = (uint32)POP_I32();
|
||||
a = (uint32)POP_I32();
|
||||
PUSH_I32(rotr32(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1647,8 +1633,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1679,8 +1665,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
if (b == 0) {
|
||||
wasm_runtime_set_exception(module, "integer divide by zero");
|
||||
goto got_exception;
|
||||
@ -1717,8 +1703,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
PUSH_I64(rotl64(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -1727,8 +1713,8 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
{
|
||||
uint64 a, b;
|
||||
|
||||
b = POP_I64();
|
||||
a = POP_I64();
|
||||
b = (uint64)POP_I64();
|
||||
a = (uint64)POP_I64();
|
||||
PUSH_I64(rotr64(a, b));
|
||||
HANDLE_OP_END ();
|
||||
}
|
||||
@ -2092,14 +2078,23 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
goto got_exception;
|
||||
}
|
||||
else {
|
||||
WASMFunction *cur_wasm_func = cur_func->u.func;
|
||||
WASMType *func_type;
|
||||
uint8 ret_type;
|
||||
|
||||
all_cell_num = cur_func->param_cell_num + cur_func->local_cell_num
|
||||
+ cur_func->u.func->max_stack_cell_num
|
||||
+ cur_func->u.func->max_block_num * sizeof(WASMBranchBlock) / 4;
|
||||
frame_size = wasm_interp_interp_frame_size(all_cell_num);
|
||||
func_type = cur_wasm_func->func_type;
|
||||
|
||||
all_cell_num = (uint64)cur_func->param_cell_num
|
||||
+ (uint64)cur_func->local_cell_num
|
||||
+ (uint64)cur_wasm_func->max_stack_cell_num
|
||||
+ ((uint64)cur_wasm_func->max_block_num) * sizeof(WASMBranchBlock) / 4;
|
||||
if (all_cell_num >= UINT32_MAX) {
|
||||
wasm_runtime_set_exception(self->module_inst,
|
||||
"WASM interp failed: stack overflow.");
|
||||
goto got_exception;
|
||||
}
|
||||
|
||||
frame_size = wasm_interp_interp_frame_size((uint32)all_cell_num);
|
||||
if (!(frame = ALLOC_FRAME(self, frame_size, prev_frame))) {
|
||||
frame = prev_frame;
|
||||
goto got_exception;
|
||||
@ -2113,19 +2108,18 @@ wasm_interp_call_func_bytecode(WASMThread *self,
|
||||
|
||||
frame_sp = frame->sp_bottom = frame_lp + cur_func->param_cell_num
|
||||
+ cur_func->local_cell_num;
|
||||
frame->sp_boundary = frame->sp_bottom + cur_func->u.func->max_stack_cell_num;
|
||||
frame->sp_boundary = frame->sp_bottom + cur_wasm_func->max_stack_cell_num;
|
||||
|
||||
frame_csp = frame->csp_bottom = (WASMBranchBlock*)frame->sp_boundary;
|
||||
frame->csp_boundary = frame->csp_bottom + cur_func->u.func->max_block_num;
|
||||
frame->csp_boundary = frame->csp_bottom + cur_wasm_func->max_block_num;
|
||||
|
||||
/* Initialize the local varialbes */
|
||||
memset(frame_lp + cur_func->param_cell_num, 0,
|
||||
cur_func->local_cell_num * 4);
|
||||
(uint32)(cur_func->local_cell_num * 4));
|
||||
|
||||
/* Push function block as first block */
|
||||
func_type = cur_func->u.func->func_type;
|
||||
ret_type = func_type->result_count
|
||||
? func_type->types[func_type->param_count]
|
||||
? cur_func->param_types[func_type->param_count]
|
||||
: VALUE_TYPE_VOID;
|
||||
PUSH_CSP(BLOCK_TYPE_FUNCTION, ret_type,
|
||||
frame_ip, NULL, frame_ip_end - 1);
|
||||
|
||||
@ -55,7 +55,8 @@ typedef struct WASMInterpFrame {
|
||||
static inline unsigned
|
||||
wasm_interp_interp_frame_size(unsigned all_cell_num)
|
||||
{
|
||||
return align_uint(offsetof(WASMInterpFrame, lp) + all_cell_num * 5, 4);
|
||||
return align_uint((uint32)offsetof(WASMInterpFrame, lp)
|
||||
+ all_cell_num * 5, 4);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include "wasm_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "wasm_dlfcn.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
/* Read a value of given type from the address pointed to by the given
|
||||
pointer and increase the pointer to the position just after the
|
||||
@ -108,7 +109,7 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (uint32)res64; \
|
||||
res = (int32)res64; \
|
||||
} while (0)
|
||||
|
||||
#define read_leb_uint8(p, p_end, res) do { \
|
||||
@ -118,11 +119,11 @@ read_leb(const uint8 *buf, const uint8 *buf_end,
|
||||
error_buf, error_buf_size)) \
|
||||
return false; \
|
||||
p += off; \
|
||||
res = (uint32)res64; \
|
||||
res = (uint8)res64; \
|
||||
} while (0)
|
||||
|
||||
static char*
|
||||
const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
|
||||
const_str_set_insert(const uint8 *str, uint32 len, WASMModule *module,
|
||||
char* error_buf, uint32 error_buf_size)
|
||||
{
|
||||
HashMap *set = module->const_str_set;
|
||||
@ -135,7 +136,7 @@ const_str_set_insert(const uint8 *str, int32 len, WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(c_str, str, len);
|
||||
bh_memcpy_s(c_str, len + 1, str, len);
|
||||
c_str[len] = '\0';
|
||||
|
||||
if ((value = wasm_hash_map_find(set, c_str))) {
|
||||
@ -215,6 +216,7 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end, *p_org;
|
||||
uint32 type_count, param_count, result_count, i, j;
|
||||
uint64 total_size;
|
||||
uint8 flag;
|
||||
WASMType *type;
|
||||
|
||||
@ -222,13 +224,15 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
if (type_count) {
|
||||
module->type_count = type_count;
|
||||
if (!(module->types = wasm_malloc(sizeof(WASMType*) * type_count))) {
|
||||
total_size = sizeof(WASMType*) * (uint64)type_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->types = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load type section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->types, 0, sizeof(WASMType*) * type_count);
|
||||
memset(module->types, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < type_count; i++) {
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -254,8 +258,10 @@ load_type_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
CHECK_BUF(p, p_end, result_count);
|
||||
p = p_org;
|
||||
|
||||
if (!(type = module->types[i] = wasm_malloc(offsetof(WASMType, types) +
|
||||
sizeof(uint8) * (param_count + result_count)))) {
|
||||
total_size = offsetof(WASMType, types) +
|
||||
sizeof(uint8) * (uint64)(param_count + result_count);
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(type = module->types[i] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load type section failed: allocate memory failed.");
|
||||
return false;
|
||||
@ -398,6 +404,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end, *p_old;
|
||||
uint32 import_count, name_len, type_index, i, u32, flags;
|
||||
uint64 total_size;
|
||||
WASMImport *import;
|
||||
WASMImport *import_functions = NULL, *import_tables = NULL;
|
||||
WASMImport *import_memories = NULL, *import_globals = NULL;
|
||||
@ -408,13 +415,15 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
|
||||
if (import_count) {
|
||||
module->import_count = import_count;
|
||||
if (!(module->imports = wasm_malloc(sizeof(WASMImport) * import_count))) {
|
||||
total_size = sizeof(WASMImport) * (uint64)import_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->imports = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load import section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->imports, 0, sizeof(WASMImport) * import_count);
|
||||
memset(module->imports, 0, (uint32)total_size);
|
||||
|
||||
p_old = p;
|
||||
|
||||
@ -514,6 +523,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
read_leb_uint8(p, p_end, kind);
|
||||
switch (kind) {
|
||||
case IMPORT_KIND_FUNC: /* import function */
|
||||
wasm_assert(import_functions);
|
||||
import = import_functions++;
|
||||
read_leb_uint32(p, p_end, type_index);
|
||||
if (type_index >= module->type_count) {
|
||||
@ -543,6 +553,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_TABLE: /* import table */
|
||||
wasm_assert(import_tables);
|
||||
import = import_tables++;
|
||||
if (!load_table_import(&p, p_end, &import->u.table,
|
||||
error_buf, error_buf_size))
|
||||
@ -554,6 +565,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_MEMORY: /* import memory */
|
||||
wasm_assert(import_memories);
|
||||
import = import_memories++;
|
||||
if (!load_memory_import(&p, p_end, &import->u.memory,
|
||||
error_buf, error_buf_size))
|
||||
@ -565,6 +577,7 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
break;
|
||||
|
||||
case IMPORT_KIND_GLOBAL: /* import global */
|
||||
wasm_assert(import_globals);
|
||||
import = import_globals++;
|
||||
read_leb_uint8(p, p_end, import->u.global.type);
|
||||
read_leb_uint8(p, p_end, mutable);
|
||||
@ -590,6 +603,16 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
import->u.names.module_name = module_name;
|
||||
import->u.names.field_name = field_name;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
import = module->import_functions;
|
||||
for (i = 0; i < module->import_function_count; i++, import++) {
|
||||
if (!strcmp(import->u.names.module_name, "wasi_unstable")) {
|
||||
module->is_wasi_module = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (p != p_end) {
|
||||
@ -613,7 +636,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
const uint8 *p_code = buf_code, *p_code_end, *p_code_save;
|
||||
uint32 func_count, total_size;
|
||||
uint32 func_count;
|
||||
uint64 total_size;
|
||||
uint32 code_count = 0, code_size, type_index, i, j, k, local_type_index;
|
||||
uint32 local_count, local_set_count, sub_local_count;
|
||||
uint8 type;
|
||||
@ -632,13 +656,15 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
|
||||
if (func_count) {
|
||||
module->function_count = func_count;
|
||||
if (!(module->functions = wasm_malloc(sizeof(WASMFunction*) * func_count))) {
|
||||
total_size = sizeof(WASMFunction*) * (uint64)func_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->functions = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load function section failed: allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->functions, 0, sizeof(WASMFunction*) * func_count);
|
||||
memset(module->functions, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < func_count; i++) {
|
||||
/* Resolve function type */
|
||||
@ -678,10 +704,11 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
}
|
||||
|
||||
/* Alloc memory, layout: function structure + local types */
|
||||
code_size = p_code_end - p_code;
|
||||
total_size = sizeof(WASMFunction) + local_count;
|
||||
code_size = (uint32)(p_code_end - p_code);
|
||||
|
||||
if (!(func = module->functions[i] = wasm_malloc(total_size))) {
|
||||
total_size = sizeof(WASMFunction) + (uint64)local_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(func = module->functions[i] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load function section failed: "
|
||||
"allocate memory failed.");
|
||||
@ -689,7 +716,7 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
|
||||
}
|
||||
|
||||
/* Set function type, local count, code size and code body */
|
||||
memset(func, 0, total_size);
|
||||
memset(func, 0, (uint32)total_size);
|
||||
func->func_type = module->types[type_index];
|
||||
func->local_count = local_count;
|
||||
if (local_count > 0)
|
||||
@ -741,6 +768,7 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 table_count, i;
|
||||
uint64 total_size;
|
||||
WASMTable *table;
|
||||
|
||||
read_leb_uint32(p, p_end, table_count);
|
||||
@ -752,14 +780,16 @@ load_table_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
return false;
|
||||
}
|
||||
module->table_count = table_count;
|
||||
if (!(module->tables = wasm_malloc(sizeof(WASMTable) * table_count))) {
|
||||
total_size = sizeof(WASMTable) * (uint64)table_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->tables = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->tables, 0, sizeof(WASMTable) * table_count);
|
||||
memset(module->tables, 0, (uint32)total_size);
|
||||
|
||||
/* load each table */
|
||||
table = module->tables;
|
||||
@ -784,6 +814,7 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 memory_count, i;
|
||||
uint64 total_size;
|
||||
WASMMemory *memory;
|
||||
|
||||
read_leb_uint32(p, p_end, memory_count);
|
||||
@ -795,14 +826,16 @@ load_memory_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
return false;
|
||||
}
|
||||
module->memory_count = memory_count;
|
||||
if (!(module->memories = wasm_malloc(sizeof(WASMMemory) * memory_count))) {
|
||||
total_size = sizeof(WASMMemory) * (uint64)memory_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->memories = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load memory section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->memories, 0, sizeof(WASMMemory) * memory_count);
|
||||
memset(module->memories, 0, (uint32)total_size);
|
||||
|
||||
/* load each memory */
|
||||
memory = module->memories;
|
||||
@ -827,20 +860,23 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 global_count, i;
|
||||
uint64 total_size;
|
||||
WASMGlobal *global;
|
||||
|
||||
read_leb_uint32(p, p_end, global_count);
|
||||
|
||||
if (global_count) {
|
||||
module->global_count = global_count;
|
||||
if (!(module->globals = wasm_malloc(sizeof(WASMGlobal) * global_count))) {
|
||||
total_size = sizeof(WASMGlobal) * (uint64)global_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->globals = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load global section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->globals, 0, sizeof(WASMGlobal) * global_count);
|
||||
memset(module->globals, 0, (uint32)total_size);
|
||||
|
||||
global = module->globals;
|
||||
|
||||
@ -872,21 +908,24 @@ load_export_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 export_count, i, index;
|
||||
uint8 str_len;
|
||||
uint64 total_size;
|
||||
uint32 str_len;
|
||||
WASMExport *export;
|
||||
|
||||
read_leb_uint32(p, p_end, export_count);
|
||||
|
||||
if (export_count) {
|
||||
module->export_count = export_count;
|
||||
if (!(module->exports = wasm_malloc(sizeof(WASMExport) * export_count))) {
|
||||
total_size = sizeof(WASMExport) * (uint64)export_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->exports = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load export section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->exports, 0, sizeof(WASMExport) * export_count);
|
||||
memset(module->exports, 0, (uint32)total_size);
|
||||
|
||||
export = module->exports;
|
||||
for (i = 0; i < export_count; i++, export++) {
|
||||
@ -965,21 +1004,23 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 table_segment_count, i, j, table_index, function_count, function_index;
|
||||
uint64 total_size;
|
||||
WASMTableSeg *table_segment;
|
||||
|
||||
read_leb_uint32(p, p_end, table_segment_count);
|
||||
|
||||
if (table_segment_count) {
|
||||
module->table_seg_count = table_segment_count;
|
||||
if (!(module->table_segments = wasm_malloc
|
||||
(sizeof(WASMTableSeg) * table_segment_count))) {
|
||||
total_size = sizeof(WASMTableSeg) * (uint64)table_segment_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->table_segments = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->table_segments, 0, sizeof(WASMTableSeg) * table_segment_count);
|
||||
memset(module->table_segments, 0, (uint32)total_size);
|
||||
|
||||
table_segment = module->table_segments;
|
||||
for (i = 0; i < table_segment_count; i++, table_segment++) {
|
||||
@ -993,8 +1034,10 @@ load_table_segment_section(const uint8 *buf, const uint8 *buf_end, WASMModule *m
|
||||
|
||||
read_leb_uint32(p, p_end, function_count);
|
||||
table_segment->function_count = function_count;
|
||||
if (!(table_segment->func_indexes = (uint32 *)
|
||||
wasm_malloc(sizeof(uint32) * function_count))) {
|
||||
total_size = sizeof(uint32) * (uint64)function_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table_segment->func_indexes = (uint32 *)
|
||||
wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load table segment section failed: "
|
||||
"allocate memory failed.");
|
||||
@ -1025,6 +1068,7 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
{
|
||||
const uint8 *p = buf, *p_end = buf_end;
|
||||
uint32 data_seg_count, i, mem_index, data_seg_len;
|
||||
uint64 total_size;
|
||||
WASMDataSeg *dataseg;
|
||||
InitializerExpression init_expr;
|
||||
|
||||
@ -1032,15 +1076,16 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
|
||||
if (data_seg_count) {
|
||||
module->data_seg_count = data_seg_count;
|
||||
if (!(module->data_segments =
|
||||
wasm_malloc(sizeof(WASMDataSeg*) * data_seg_count))) {
|
||||
total_size = sizeof(WASMDataSeg*) * (uint64)data_seg_count;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(module->data_segments = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load data segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(module->data_segments, 0, sizeof(WASMDataSeg*) * data_seg_count);
|
||||
memset(module->data_segments, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < data_seg_count; i++) {
|
||||
read_leb_uint32(p, p_end, mem_index);
|
||||
@ -1051,14 +1096,15 @@ load_data_segment_section(const uint8 *buf, const uint8 *buf_end,
|
||||
read_leb_uint32(p, p_end, data_seg_len);
|
||||
|
||||
if (!(dataseg = module->data_segments[i] =
|
||||
wasm_malloc(sizeof(WASMDataSeg)))) {
|
||||
wasm_malloc((uint32)sizeof(WASMDataSeg)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Load data segment section failed: "
|
||||
"allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(&dataseg->base_offset, &init_expr, sizeof(init_expr));
|
||||
bh_memcpy_s(&dataseg->base_offset, sizeof(InitializerExpression),
|
||||
&init_expr, sizeof(InitializerExpression));
|
||||
|
||||
dataseg->memory_index = mem_index;
|
||||
dataseg->data_length = data_seg_len;
|
||||
@ -1343,6 +1389,8 @@ create_sections(const uint8 *buf, uint32 size,
|
||||
uint8 section_type;
|
||||
uint32 section_size;
|
||||
|
||||
wasm_assert(!*p_section_list);
|
||||
|
||||
p += 8;
|
||||
while (p < p_end) {
|
||||
CHECK_BUF(p, p_end, 1);
|
||||
@ -1548,6 +1596,25 @@ wasm_loader_unload(WASMModule *module)
|
||||
wasm_free(module);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
void
|
||||
wasm_runtime_set_wasi_args(WASMModule *module,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env_list[], uint32 env_count,
|
||||
const char *argv[], uint32 argc)
|
||||
{
|
||||
module->wasi_args.dir_list = dir_list;
|
||||
module->wasi_args.dir_count = dir_count;
|
||||
module->wasi_args.map_dir_list = map_dir_list;
|
||||
module->wasi_args.map_dir_count = map_dir_count;
|
||||
module->wasi_args.env = env_list;
|
||||
module->wasi_args.env_count = env_count;
|
||||
module->wasi_args.argv = argv;
|
||||
module->wasi_args.argc = argc;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
|
||||
typedef struct block_addr {
|
||||
uint8 block_type;
|
||||
@ -1568,7 +1635,8 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
{
|
||||
const uint8 *p = start_addr, *p_end = code_end_addr;
|
||||
uint8 *else_addr = NULL;
|
||||
uint32 block_nested_depth = 1, count, i, u32, u64;
|
||||
uint32 block_nested_depth = 1, count, i, u32;
|
||||
uint64 u64;
|
||||
uint8 opcode, u8;
|
||||
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR != 0
|
||||
@ -1586,7 +1654,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
BlockAddr block_stack[16] = { 0 }, *block;
|
||||
uint32 j, t;
|
||||
|
||||
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16);
|
||||
i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
|
||||
i = i % BLOCK_ADDR_CACHE_SIZE;
|
||||
block = module->block_addr_cache[i];
|
||||
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++) {
|
||||
@ -1613,7 +1681,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
case WASM_OP_BLOCK:
|
||||
case WASM_OP_LOOP:
|
||||
case WASM_OP_IF:
|
||||
read_leb_uint32(p, p_end, u32); /* blocktype */
|
||||
read_leb_uint8(p, p_end, u8); /* blocktype */
|
||||
#if WASM_ENABLE_HASH_BLOCK_ADDR == 0
|
||||
if (block_nested_depth < sizeof(block_stack)/sizeof(BlockAddr)) {
|
||||
block_stack[block_nested_depth].start_addr = p;
|
||||
@ -1658,7 +1726,7 @@ wasm_loader_find_block_addr(WASMModule *module,
|
||||
for (t = 0; t < sizeof(block_stack)/sizeof(BlockAddr); t++) {
|
||||
start_addr = block_stack[t].start_addr;
|
||||
if (start_addr) {
|
||||
i = ((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16);
|
||||
i = (uint32)(((uintptr_t)start_addr) ^ ((uintptr_t)start_addr >> 16));
|
||||
i = i % BLOCK_ADDR_CACHE_SIZE;
|
||||
block = module->block_addr_cache[i];
|
||||
for (j = 0; j < BLOCK_ADDR_CONFLICT_SIZE; j++)
|
||||
@ -1937,7 +2005,7 @@ memory_realloc(void *mem_old, uint32 size_old, uint32 size_new)
|
||||
uint8 *mem_new;
|
||||
wasm_assert(size_new > size_old);
|
||||
if ((mem_new = wasm_malloc(size_new))) {
|
||||
memcpy(mem_new, mem_old, size_old);
|
||||
bh_memcpy_s(mem_new, size_new, mem_old, size_old);
|
||||
memset(mem_new + size_old, 0, size_new - size_old);
|
||||
wasm_free(mem_old);
|
||||
}
|
||||
@ -2171,8 +2239,9 @@ pop_type(uint8 type, uint8 **p_frame_ref, uint32 *p_stack_cell_num,
|
||||
#define CHECK_CSP_PUSH() do { \
|
||||
if (frame_csp >= frame_csp_boundary) { \
|
||||
MEM_REALLOC(frame_csp_bottom, frame_csp_size, \
|
||||
frame_csp_size + 8 * sizeof(BranchBlock));\
|
||||
frame_csp_size += 8 * sizeof(BranchBlock); \
|
||||
(uint32)(frame_csp_size \
|
||||
+ 8 * sizeof(BranchBlock))); \
|
||||
frame_csp_size += (uint32)(8 * sizeof(BranchBlock)); \
|
||||
frame_csp_boundary = frame_csp_bottom + \
|
||||
frame_csp_size / sizeof(BranchBlock); \
|
||||
frame_csp = frame_csp_bottom + csp_num; \
|
||||
@ -2281,10 +2350,10 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
uint32 stack_cell_num = 0, csp_num = 0;
|
||||
uint32 frame_ref_size, frame_csp_size;
|
||||
uint8 *param_types, ret_type, *local_types, local_type, global_type;
|
||||
uint32 count, i, local_idx, global_idx, block_return_type, depth, u32;
|
||||
uint32 count, i, local_idx, global_idx, depth, u32;
|
||||
int32 i32, i32_const = 0;
|
||||
int64 i64;
|
||||
uint8 opcode, u8;
|
||||
uint8 opcode, u8, block_return_type;
|
||||
bool return_value = false, is_i32_const = false;
|
||||
|
||||
global_count = module->import_global_count + module->global_count;
|
||||
@ -2332,18 +2401,18 @@ wasm_loader_prepare_bytecode(WASMModule *module, WASMFunction *func,
|
||||
break;
|
||||
|
||||
case WASM_OP_BLOCK:
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_BLOCK, block_return_type, p);
|
||||
break;
|
||||
|
||||
case WASM_OP_LOOP:
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_LOOP, block_return_type, p);
|
||||
break;
|
||||
|
||||
case WASM_OP_IF:
|
||||
POP_I32();
|
||||
read_leb_uint32(p, p_end, block_return_type);
|
||||
read_leb_uint8(p, p_end, block_return_type);
|
||||
PUSH_CSP(BLOCK_TYPE_IF, block_return_type, p);
|
||||
if (!is_i32_const)
|
||||
(frame_csp - 1)->jumped_by_br = true;
|
||||
@ -2535,8 +2604,10 @@ handle_op_br:
|
||||
func_type =
|
||||
module->functions[func_idx - module->import_function_count]->func_type;
|
||||
|
||||
for (idx = func_type->param_count - 1; idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
if (func_type->param_count > 0) {
|
||||
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
}
|
||||
|
||||
if (func_type->result_count)
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
@ -2575,8 +2646,10 @@ handle_op_br:
|
||||
|
||||
func_type = module->types[type_idx];
|
||||
|
||||
for (idx = func_type->param_count - 1; idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
if (func_type->param_count > 0) {
|
||||
for (idx = (int32)(func_type->param_count - 1); idx >= 0; idx--)
|
||||
POP_TYPE(func_type->types[idx]);
|
||||
}
|
||||
|
||||
PUSH_TYPE(func_type->types[func_type->param_count]);
|
||||
break;
|
||||
|
||||
@ -12,6 +12,7 @@
|
||||
#include "wasm_platform_log.h"
|
||||
#include "wasm_memory.h"
|
||||
#include "mem_alloc.h"
|
||||
#include "bh_common.h"
|
||||
|
||||
|
||||
static void
|
||||
@ -77,9 +78,9 @@ wasm_runtime_call_wasm(WASMModuleInstance *module_inst,
|
||||
uint32 stack_size;
|
||||
|
||||
/* Set to 8 bytes align */
|
||||
stack = (stack + 7) & ~7;
|
||||
stack_size = exec_env->stack_size
|
||||
- (stack - (uintptr_t)exec_env->stack);
|
||||
stack = (stack + 7) & (uintptr_t)~7;
|
||||
stack_size = (uint32)(exec_env->stack_size
|
||||
- (stack - (uintptr_t)exec_env->stack));
|
||||
|
||||
if (!exec_env->stack || exec_env->stack_size <= 0
|
||||
|| exec_env->stack_size < stack - (uintptr_t)exec_env->stack) {
|
||||
@ -171,18 +172,19 @@ memory_instantiate(uint32 init_page_count, uint32 max_page_count,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
WASMMemoryInstance *memory;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
NumBytesPerPage * init_page_count +
|
||||
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
NumBytesPerPage * (uint64)init_page_count +
|
||||
addr_data_size + global_data_size;
|
||||
|
||||
/* Allocate memory space, addr data and global data */
|
||||
if (!(memory = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(memory = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(memory, 0, total_size);
|
||||
memset(memory, 0, (uint32)total_size);
|
||||
memory->cur_page_count = init_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
|
||||
@ -238,23 +240,23 @@ memories_instantiate(const WASMModule *module, uint32 addr_data_size,
|
||||
WASMImport *import;
|
||||
uint32 mem_index = 0, i, memory_count =
|
||||
module->import_memory_count + module->memory_count;
|
||||
uint32 total_size;
|
||||
uint64 total_size;
|
||||
WASMMemoryInstance **memories, *memory;
|
||||
|
||||
if (memory_count == 0 && global_data_size > 0)
|
||||
memory_count = 1;
|
||||
|
||||
total_size = sizeof(WASMMemoryInstance*) * memory_count;
|
||||
memories = wasm_malloc(total_size);
|
||||
total_size = sizeof(WASMMemoryInstance*) * (uint64)memory_count;
|
||||
|
||||
if (!memories) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(memories = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate memory failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(memories, 0, total_size);
|
||||
memset(memories, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate memories from import section */
|
||||
import = module->import_memories;
|
||||
@ -329,24 +331,26 @@ tables_instantiate(const WASMModule *module,
|
||||
WASMImport *import;
|
||||
uint32 table_index = 0, i, table_count =
|
||||
module->import_table_count + module->table_count;
|
||||
uint32 total_size = sizeof(WASMTableInstance*) * table_count;
|
||||
WASMTableInstance **tables = wasm_malloc(total_size), *table;
|
||||
uint64 total_size = sizeof(WASMTableInstance*) * (uint64)table_count;
|
||||
WASMTableInstance **tables, *table;
|
||||
|
||||
if (!tables) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(tables = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(tables, 0, total_size);
|
||||
memset(tables, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate tables from import section */
|
||||
import = module->import_tables;
|
||||
for (i = 0; i < module->import_table_count; i++, import++) {
|
||||
total_size = offsetof(WASMTableInstance, base_addr) +
|
||||
sizeof(uint32) * import->u.table.init_size;
|
||||
if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
|
||||
sizeof(uint32) * (uint64)import->u.table.init_size;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
@ -354,7 +358,7 @@ tables_instantiate(const WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(table, 0, total_size);
|
||||
memset(table, 0, (uint32)total_size);
|
||||
table->cur_size = import->u.table.init_size;
|
||||
table->max_size = import->u.table.max_size;
|
||||
}
|
||||
@ -362,8 +366,9 @@ tables_instantiate(const WASMModule *module,
|
||||
/* instantiate tables from table section */
|
||||
for (i = 0; i < module->table_count; i++) {
|
||||
total_size = offsetof(WASMTableInstance, base_addr) +
|
||||
sizeof(uint32) * module->tables[i].init_size;
|
||||
if (!(table = tables[table_index++] = wasm_malloc(total_size))) {
|
||||
sizeof(uint32) * (uint64)module->tables[i].init_size;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(table = tables[table_index++] = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate table failed: "
|
||||
"allocate memory failed.");
|
||||
@ -371,7 +376,7 @@ tables_instantiate(const WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(table, 0, total_size);
|
||||
memset(table, 0, (uint32)total_size);
|
||||
table->cur_size = module->tables[i].init_size;
|
||||
table->max_size = module->tables[i].max_size;
|
||||
}
|
||||
@ -399,24 +404,26 @@ functions_deinstantiate(WASMFunctionInstance *functions, uint32 count)
|
||||
static bool
|
||||
function_init_local_offsets(WASMFunctionInstance *func)
|
||||
{
|
||||
uint16 local_offset = 0;
|
||||
uint32 local_offset = 0;
|
||||
WASMType *param_type = func->u.func->func_type;
|
||||
uint32 param_count = param_type->param_count;
|
||||
uint8 *param_types = param_type->types;
|
||||
uint32 local_count = func->u.func->local_count;
|
||||
uint8 *local_types = func->u.func->local_types;
|
||||
uint32 i, total_size = (param_count + local_count) * sizeof(uint16);
|
||||
uint32 i;
|
||||
uint64 total_size = sizeof(uint16) * (uint64)(param_count + local_count);
|
||||
|
||||
if (!(func->local_offsets = wasm_malloc(total_size)))
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(func->local_offsets = wasm_malloc((uint32)total_size)))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < param_count; i++) {
|
||||
func->local_offsets[i] = local_offset;
|
||||
func->local_offsets[i] = (uint16)local_offset;
|
||||
local_offset += wasm_value_type_cell_num(param_types[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < local_count; i++) {
|
||||
func->local_offsets[param_count + i] = local_offset;
|
||||
func->local_offsets[param_count + i] = (uint16)local_offset;
|
||||
local_offset += wasm_value_type_cell_num(local_types[i]);
|
||||
}
|
||||
|
||||
@ -434,17 +441,18 @@ functions_instantiate(const WASMModule *module,
|
||||
WASMImport *import;
|
||||
uint32 i, function_count =
|
||||
module->import_function_count + module->function_count;
|
||||
uint32 total_size = sizeof(WASMFunctionInstance) * function_count;
|
||||
WASMFunctionInstance *functions = wasm_malloc(total_size), *function;
|
||||
uint64 total_size = sizeof(WASMFunctionInstance) * (uint64)function_count;
|
||||
WASMFunctionInstance *functions, *function;
|
||||
|
||||
if (!functions) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(functions = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate function failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(functions, 0, total_size);
|
||||
memset(functions, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate functions from import section */
|
||||
function = functions;
|
||||
@ -459,6 +467,12 @@ functions_instantiate(const WASMModule *module,
|
||||
wasm_type_return_cell_num(import->u.function.func_type);
|
||||
function->local_cell_num = 0;
|
||||
|
||||
function->param_count =
|
||||
(uint16)function->u.func_import->func_type->param_count;
|
||||
function->local_count = 0;
|
||||
function->param_types = function->u.func_import->func_type->types;
|
||||
function->local_types = NULL;
|
||||
|
||||
function++;
|
||||
}
|
||||
|
||||
@ -475,6 +489,11 @@ functions_instantiate(const WASMModule *module,
|
||||
wasm_get_cell_num(function->u.func->local_types,
|
||||
function->u.func->local_count);
|
||||
|
||||
function->param_count = (uint16)function->u.func->func_type->param_count;
|
||||
function->local_count = (uint16)function->u.func->local_count;
|
||||
function->param_types = function->u.func->func_type->types;
|
||||
function->local_types = function->u.func->local_types;
|
||||
|
||||
if (!function_init_local_offsets(function)) {
|
||||
functions_deinstantiate(functions, function_count);
|
||||
return NULL;
|
||||
@ -510,17 +529,18 @@ globals_instantiate(const WASMModule *module,
|
||||
uint32 addr_data_offset = 0, global_data_offset = 0;
|
||||
uint32 i, global_count =
|
||||
module->import_global_count + module->global_count;
|
||||
uint32 total_size = sizeof(WASMGlobalInstance) * global_count;
|
||||
WASMGlobalInstance *globals = wasm_malloc(total_size), *global;
|
||||
uint64 total_size = sizeof(WASMGlobalInstance) * (uint64)global_count;
|
||||
WASMGlobalInstance *globals, *global;
|
||||
|
||||
if (!globals) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(globals = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate global failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(globals, 0, total_size);
|
||||
memset(globals, 0, (uint32)total_size);
|
||||
|
||||
/* instantiate globals from import section */
|
||||
global = globals;
|
||||
@ -535,7 +555,7 @@ globals_instantiate(const WASMModule *module,
|
||||
global_data_offset += wasm_value_type_size(global->type);
|
||||
|
||||
if (global->is_addr)
|
||||
addr_data_offset += sizeof(uint32);
|
||||
addr_data_offset += (uint32)sizeof(uint32);
|
||||
|
||||
global++;
|
||||
}
|
||||
@ -550,7 +570,7 @@ globals_instantiate(const WASMModule *module,
|
||||
global_data_offset += wasm_value_type_size(global->type);
|
||||
|
||||
if (global->is_addr)
|
||||
addr_data_offset += sizeof(uint32);
|
||||
addr_data_offset += (uint32)sizeof(uint32);
|
||||
|
||||
global++;
|
||||
}
|
||||
@ -583,7 +603,7 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
|
||||
}
|
||||
else if (!strcmp(import->u.names.field_name, "DYNAMICTOP_PTR")) {
|
||||
global->initial_value.i32 =
|
||||
NumBytesPerPage * module_inst->default_memory->cur_page_count;
|
||||
(int32)(NumBytesPerPage * module_inst->default_memory->cur_page_count);
|
||||
module_inst->DYNAMICTOP_PTR_offset = global->data_offset;
|
||||
}
|
||||
else if (!strcmp(import->u.names.field_name, "STACKTOP")) {
|
||||
@ -604,7 +624,8 @@ globals_instantiate_fix(WASMGlobalInstance *globals,
|
||||
global->initial_value = globals[init_expr->u.global_index].initial_value;
|
||||
}
|
||||
else {
|
||||
memcpy(&global->initial_value, &init_expr->u, sizeof(int64));
|
||||
bh_memcpy_s(&global->initial_value, sizeof(WASMValue),
|
||||
&init_expr->u, sizeof(init_expr->u));
|
||||
}
|
||||
global++;
|
||||
}
|
||||
@ -647,16 +668,18 @@ export_functions_instantiate(const WASMModule *module,
|
||||
{
|
||||
WASMExportFuncInstance *export_funcs, *export_func;
|
||||
WASMExport *export = module->exports;
|
||||
uint32 i, total_size = sizeof(WASMExportFuncInstance) * export_func_count;
|
||||
uint32 i;
|
||||
uint64 total_size = sizeof(WASMExportFuncInstance) * (uint64)export_func_count;
|
||||
|
||||
if (!(export_func = export_funcs = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(export_func = export_funcs = wasm_malloc((uint32)total_size))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate export function failed: "
|
||||
"allocate memory failed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(export_funcs, 0, total_size);
|
||||
memset(export_funcs, 0, (uint32)total_size);
|
||||
|
||||
for (i = 0; i < module->export_count; i++, export++)
|
||||
if (export->kind == EXPORT_KIND_FUNC) {
|
||||
@ -710,11 +733,209 @@ execute_start_function(WASMModuleInstance *module_inst)
|
||||
return true;
|
||||
|
||||
wasm_assert(!func->is_import_func && func->param_cell_num == 0
|
||||
&& func->ret_cell_num == 0);
|
||||
&& func->ret_cell_num == 0);
|
||||
|
||||
return wasm_runtime_call_wasm(module_inst, NULL, func, 0, NULL);
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
static bool
|
||||
wasm_runtime_init_wasi(WASMModuleInstance *module_inst,
|
||||
const char *dir_list[], uint32 dir_count,
|
||||
const char *map_dir_list[], uint32 map_dir_count,
|
||||
const char *env[], uint32 env_count,
|
||||
const char *argv[], uint32 argc,
|
||||
char *error_buf, uint32 error_buf_size)
|
||||
{
|
||||
size_t *argv_offsets = NULL;
|
||||
char *argv_buf = NULL;
|
||||
size_t *env_offsets = NULL;
|
||||
char *env_buf = NULL;
|
||||
uint64 argv_buf_len = 0, env_buf_len = 0;
|
||||
uint32 argv_buf_offset = 0, env_buf_offset = 0;
|
||||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
int32 offset_argv_offsets = 0, offset_env_offsets = 0;
|
||||
int32 offset_argv_buf = 0, offset_env_buf = 0;
|
||||
int32 offset_curfds = 0;
|
||||
int32 offset_prestats = 0;
|
||||
int32 offset_argv_environ = 0;
|
||||
__wasi_fd_t wasm_fd = 3;
|
||||
int32 raw_fd;
|
||||
char *path, resolved_path[PATH_MAX];
|
||||
uint64 total_size;
|
||||
uint32 i;
|
||||
|
||||
if (!module_inst->default_memory) {
|
||||
argv_environ = module_inst->wasi_ctx.argv_environ = NULL;
|
||||
prestats = module_inst->wasi_ctx.prestats = NULL;
|
||||
curfds = module_inst->wasi_ctx.curfds = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* process argv[0], trip the path and suffix, only keep the program name */
|
||||
for (i = 0; i < argc; i++)
|
||||
argv_buf_len += strlen(argv[i]) + 1;
|
||||
|
||||
total_size = sizeof(size_t) * (uint64)argc;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(offset_argv_offsets = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)total_size))
|
||||
|| argv_buf_len >= UINT32_MAX
|
||||
|| !(offset_argv_buf = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)argv_buf_len))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
argv_offsets = (size_t*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_argv_offsets);
|
||||
argv_buf = (char*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_argv_buf);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
argv_offsets[i] = argv_buf_offset;
|
||||
bh_strcpy_s(argv_buf + argv_buf_offset,
|
||||
(uint32)argv_buf_len - argv_buf_offset, argv[i]);
|
||||
argv_buf_offset += (uint32)(strlen(argv[i]) + 1);
|
||||
}
|
||||
|
||||
for (i = 0; i < env_count; i++)
|
||||
env_buf_len += strlen(env[i]) + 1;
|
||||
|
||||
total_size = sizeof(size_t) * (uint64)argc;
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(offset_env_offsets = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)total_size))
|
||||
|| env_buf_len >= UINT32_MAX
|
||||
|| !(offset_env_buf = wasm_runtime_module_malloc
|
||||
(module_inst, (uint32)env_buf_len))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
env_offsets = (size_t*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_env_offsets);
|
||||
env_buf = (char*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_env_buf);
|
||||
|
||||
for (i = 0; i < env_count; i++) {
|
||||
env_offsets[i] = env_buf_offset;
|
||||
bh_strcpy_s(env_buf + env_buf_offset,
|
||||
(uint32)env_buf_len - env_buf_offset, env[i]);
|
||||
env_buf_offset += (uint32)(strlen(env[i]) + 1);
|
||||
}
|
||||
|
||||
if (!(offset_curfds = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct fd_table)))
|
||||
|| !(offset_prestats = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct fd_prestats)))
|
||||
|| !(offset_argv_environ = wasm_runtime_module_malloc
|
||||
(module_inst, sizeof(struct argv_environ_values)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: allocate memory failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
curfds = module_inst->wasi_ctx.curfds = (struct fd_table*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_curfds);
|
||||
prestats = module_inst->wasi_ctx.prestats = (struct fd_prestats*)
|
||||
wasm_runtime_addr_app_to_native(module_inst, offset_prestats);
|
||||
argv_environ = module_inst->wasi_ctx.argv_environ =
|
||||
(struct argv_environ_values*)wasm_runtime_addr_app_to_native
|
||||
(module_inst, offset_argv_environ);
|
||||
|
||||
fd_table_init(curfds);
|
||||
fd_prestats_init(prestats);
|
||||
|
||||
if (!argv_environ_init(argv_environ,
|
||||
argv_offsets, argc,
|
||||
argv_buf, argv_buf_len,
|
||||
env_offsets, env_count,
|
||||
env_buf, env_buf_len)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: "
|
||||
"init argument environment failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Prepopulate curfds with stdin, stdout, and stderr file descriptors. */
|
||||
if (!fd_table_insert_existing(curfds, 0, 0)
|
||||
|| !fd_table_insert_existing(curfds, 1, 1)
|
||||
|| !fd_table_insert_existing(curfds, 2, 2)) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Init wasi environment failed: init fd table failed.");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
wasm_fd = 3;
|
||||
for (i = 0; i < dir_count; i++, wasm_fd++) {
|
||||
path = realpath(dir_list[i], resolved_path);
|
||||
if (!path) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening directory %s: %d\n",
|
||||
dir_list[i], errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
raw_fd = open(path, O_RDONLY | O_DIRECTORY, 0);
|
||||
if (raw_fd == -1) {
|
||||
if (error_buf)
|
||||
snprintf(error_buf, error_buf_size,
|
||||
"error while pre-opening directory %s: %d\n",
|
||||
dir_list[i], errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fd_table_insert_existing(curfds, wasm_fd, raw_fd);
|
||||
fd_prestats_insert(prestats, dir_list[i], wasm_fd);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
if (offset_curfds != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_curfds);
|
||||
if (offset_prestats != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_prestats);
|
||||
if (offset_argv_environ != 0)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_environ);
|
||||
if (offset_argv_buf)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_buf);
|
||||
if (offset_argv_offsets)
|
||||
wasm_runtime_module_free(module_inst, offset_argv_offsets);
|
||||
if (offset_env_buf)
|
||||
wasm_runtime_module_free(module_inst, offset_env_buf);
|
||||
if (offset_env_offsets)
|
||||
wasm_runtime_module_free(module_inst, offset_env_offsets);
|
||||
return false;
|
||||
}
|
||||
|
||||
static void
|
||||
wasm_runtime_destroy_wasi(WASMModuleInstance *module_inst)
|
||||
{
|
||||
WASIContext *wasi_ctx = &module_inst->wasi_ctx;
|
||||
|
||||
if (wasi_ctx->argv_environ)
|
||||
argv_environ_destroy(wasi_ctx->argv_environ);
|
||||
if (wasi_ctx->curfds)
|
||||
fd_table_destroy(wasi_ctx->curfds);
|
||||
if (wasi_ctx->prestats)
|
||||
fd_prestats_destroy(wasi_ctx->prestats);
|
||||
}
|
||||
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstance *module_inst)
|
||||
{
|
||||
return &module_inst->wasi_ctx;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Instantiate module
|
||||
*/
|
||||
@ -754,14 +975,14 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
|
||||
/* Allocate the memory */
|
||||
if (!(module_inst = wasm_malloc(sizeof(WASMModuleInstance)))) {
|
||||
if (!(module_inst = wasm_malloc((uint32)sizeof(WASMModuleInstance)))) {
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate module failed: allocate memory failed.");
|
||||
globals_deinstantiate(globals);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(module_inst, 0, sizeof(WASMModuleInstance));
|
||||
memset(module_inst, 0, (uint32)sizeof(WASMModuleInstance));
|
||||
module_inst->global_count = global_count;
|
||||
module_inst->globals = globals;
|
||||
|
||||
@ -818,7 +1039,7 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
else {
|
||||
*(int32*)addr_data = global->initial_value.i32;
|
||||
/* Store the offset to memory data for global of addr */
|
||||
*(int32*)global_data = addr_data - memory_data;
|
||||
*(int32*)global_data = (int32)(addr_data - memory_data);
|
||||
addr_data += sizeof(int32);
|
||||
}
|
||||
global_data += sizeof(int32);
|
||||
@ -826,7 +1047,8 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
case VALUE_TYPE_I64:
|
||||
case VALUE_TYPE_F64:
|
||||
wasm_assert(!global->is_addr);
|
||||
memcpy(global_data, &global->initial_value.i64, sizeof(int64));
|
||||
bh_memcpy_s(global_data, (uint32)(global_data_end - global_data),
|
||||
&global->initial_value.i64, sizeof(int64));
|
||||
global_data += sizeof(int64);
|
||||
break;
|
||||
default:
|
||||
@ -880,7 +1102,8 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(memory_data + base_offset, data_seg->data, length);
|
||||
bh_memcpy_s(memory_data + base_offset, memory_size - base_offset,
|
||||
data_seg->data, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -909,10 +1132,10 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
if ((uint32)table_seg->base_offset.u.i32 <
|
||||
module_inst->default_table->cur_size) {
|
||||
length = table_seg->function_count;
|
||||
if (table_seg->base_offset.u.i32 + length >
|
||||
if ((uint32)table_seg->base_offset.u.i32 + length >
|
||||
module_inst->default_table->cur_size)
|
||||
length = module_inst->default_table->cur_size
|
||||
- table_seg->base_offset.u.i32;
|
||||
- (uint32)table_seg->base_offset.u.i32;
|
||||
/* Check function index */
|
||||
for (j = 0; j < length; j++) {
|
||||
if (table_seg->func_indexes[j] >= module_inst->function_count) {
|
||||
@ -922,12 +1145,31 @@ wasm_runtime_instantiate(WASMModule *module,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
memcpy(table_data + table_seg->base_offset.u.i32,
|
||||
table_seg->func_indexes, length * sizeof(uint32));
|
||||
bh_memcpy_s(table_data + table_seg->base_offset.u.i32,
|
||||
(uint32)((module_inst->default_table->cur_size
|
||||
- (uint32)table_seg->base_offset.u.i32)
|
||||
* sizeof(uint32)),
|
||||
table_seg->func_indexes, (uint32)(length * sizeof(uint32)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
if (!wasm_runtime_init_wasi(module_inst,
|
||||
module->wasi_args.dir_list,
|
||||
module->wasi_args.dir_count,
|
||||
module->wasi_args.map_dir_list,
|
||||
module->wasi_args.map_dir_count,
|
||||
module->wasi_args.env,
|
||||
module->wasi_args.env_count,
|
||||
module->wasi_args.argv,
|
||||
module->wasi_args.argc,
|
||||
error_buf, error_buf_size)) {
|
||||
wasm_runtime_deinstantiate(module_inst);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (module->start_function != (uint32)-1) {
|
||||
wasm_assert(module->start_function >= module->import_function_count);
|
||||
module_inst->start_function =
|
||||
@ -968,6 +1210,10 @@ wasm_runtime_deinstantiate(WASMModuleInstance *module_inst)
|
||||
if (!module_inst)
|
||||
return;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
wasm_runtime_destroy_wasi(module_inst);
|
||||
#endif
|
||||
|
||||
if (module_inst->memory_count > 0)
|
||||
memories_deinstantiate(module_inst->memories, module_inst->memory_count);
|
||||
else if (module_inst->memories != NULL && module_inst->global_count > 0)
|
||||
@ -1018,15 +1264,15 @@ wasm_runtime_set_ext_memory(WASMModuleInstance *module_inst,
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
{
|
||||
#if WASM_ENABLE_MEMORY_GROW != 0
|
||||
WASMMemoryInstance *memory = module->default_memory;
|
||||
WASMMemoryInstance *new_memory;
|
||||
uint32 total_page_count = inc_page_count + memory->cur_page_count;
|
||||
uint32 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
uint64 total_size = offsetof(WASMMemoryInstance, base_addr) +
|
||||
memory->addr_data_size +
|
||||
NumBytesPerPage * total_page_count +
|
||||
NumBytesPerPage * (uint64)total_page_count +
|
||||
memory->global_data_size;
|
||||
|
||||
if (inc_page_count <= 0)
|
||||
@ -1039,7 +1285,8 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(new_memory = wasm_malloc(total_size))) {
|
||||
if (total_size >= UINT32_MAX
|
||||
|| !(new_memory = wasm_malloc((uint32)total_size))) {
|
||||
wasm_runtime_set_exception(module, "fail to enlarge memory.");
|
||||
return false;
|
||||
}
|
||||
@ -1059,11 +1306,13 @@ wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count)
|
||||
new_memory->end_addr = new_memory->global_data + memory->global_data_size;
|
||||
|
||||
/* Copy addr data and memory data */
|
||||
memcpy(new_memory->addr_data, memory->addr_data,
|
||||
memory->global_data - memory->addr_data);
|
||||
bh_memcpy_s(new_memory->addr_data,
|
||||
(uint32)(memory->global_data - memory->addr_data),
|
||||
memory->addr_data,
|
||||
(uint32)(memory->global_data - memory->addr_data));
|
||||
/* Copy global data */
|
||||
memcpy(new_memory->global_data, memory->global_data,
|
||||
memory->global_data_size);
|
||||
bh_memcpy_s(new_memory->global_data, new_memory->global_data_size,
|
||||
memory->global_data, memory->global_data_size);
|
||||
/* Init free space of new memory */
|
||||
memset(new_memory->memory_data + NumBytesPerPage * memory->cur_page_count,
|
||||
0, NumBytesPerPage * (total_page_count - memory->cur_page_count));
|
||||
@ -1097,7 +1346,7 @@ get_package_type(const uint8 *buf, uint32 size)
|
||||
WASMExecEnv*
|
||||
wasm_runtime_create_exec_env(uint32 stack_size)
|
||||
{
|
||||
WASMExecEnv *exec_env = wasm_malloc(sizeof(WASMExecEnv));
|
||||
WASMExecEnv *exec_env = wasm_malloc((uint32)sizeof(WASMExecEnv));
|
||||
if (exec_env) {
|
||||
if (!(exec_env->stack = wasm_malloc(stack_size))) {
|
||||
wasm_free(exec_env);
|
||||
@ -1139,7 +1388,7 @@ wasm_runtime_module_malloc(WASMModuleInstance *module_inst, uint32 size)
|
||||
wasm_runtime_set_exception(module_inst, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
return memory->heap_base_offset + (addr - memory->heap_data);
|
||||
return memory->heap_base_offset + (int32)(addr - memory->heap_data);
|
||||
}
|
||||
|
||||
void
|
||||
@ -1161,7 +1410,7 @@ wasm_runtime_module_dup_data(WASMModuleInstance *module_inst,
|
||||
if (buffer_offset != 0) {
|
||||
char *buffer;
|
||||
buffer = wasm_runtime_addr_app_to_native(module_inst, buffer_offset);
|
||||
memcpy(buffer, src, size);
|
||||
bh_memcpy_s(buffer, size, src, size);
|
||||
}
|
||||
return buffer_offset;
|
||||
}
|
||||
@ -1174,7 +1423,7 @@ wasm_runtime_validate_app_addr(WASMModuleInstance *module_inst,
|
||||
uint8 *addr;
|
||||
|
||||
/* integer overflow check */
|
||||
if(app_offset + size < app_offset) {
|
||||
if(app_offset + (int32)size < app_offset) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@ -1294,11 +1543,11 @@ wasm_runtime_addr_native_to_app(WASMModuleInstance *module_inst,
|
||||
WASMMemoryInstance *memory = module_inst->default_memory;
|
||||
if (memory->base_addr <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < memory->end_addr)
|
||||
return (uint8*)native_ptr - memory->memory_data;
|
||||
return (int32)((uint8*)native_ptr - memory->memory_data);
|
||||
else if (memory->heap_data <= (uint8*)native_ptr
|
||||
&& (uint8*)native_ptr < memory->heap_data_end)
|
||||
return memory->heap_base_offset
|
||||
+ ((uint8*)native_ptr - memory->heap_data);
|
||||
+ (int32)((uint8*)native_ptr - memory->heap_data);
|
||||
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0
|
||||
else if (module_inst->ext_mem_data
|
||||
&& module_inst->ext_mem_data <= (uint8*)native_ptr
|
||||
@ -1321,14 +1570,14 @@ wasm_runtime_get_app_addr_range(WASMModuleInstance *module_inst,
|
||||
|
||||
if (0 <= app_offset && app_offset < memory->heap_base_offset) {
|
||||
app_start_offset = 0;
|
||||
app_end_offset = NumBytesPerPage * memory->cur_page_count;
|
||||
app_end_offset = (int32)(NumBytesPerPage * memory->cur_page_count);
|
||||
}
|
||||
else if (memory->heap_base_offset < app_offset
|
||||
&& app_offset < memory->heap_base_offset
|
||||
+ (memory->heap_data_end - memory->heap_data)) {
|
||||
app_start_offset = memory->heap_base_offset;
|
||||
app_end_offset = memory->heap_base_offset
|
||||
+ (memory->heap_data_end - memory->heap_data);
|
||||
+ (int32)(memory->heap_data_end - memory->heap_data);
|
||||
}
|
||||
#if WASM_ENABLE_EXT_MEMORY_SPACE != 0
|
||||
else if (module_inst->ext_mem_data
|
||||
@ -1479,7 +1728,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
#endif
|
||||
|
||||
if (argc1 > sizeof(argv_buf) / sizeof(uint32)) {
|
||||
size = ((uint64)sizeof(uint32)) * argc1;
|
||||
size = sizeof(uint32) * (uint64)argc1;
|
||||
if (size >= UINT_MAX
|
||||
|| !(argv1 = wasm_malloc((uint32)size))) {
|
||||
wasm_runtime_set_exception(module_inst, "allocate memory failed.");
|
||||
@ -1524,7 +1773,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
else {
|
||||
switch (func_type->types[func_type->param_count]) {
|
||||
case VALUE_TYPE_I32:
|
||||
ret[0] = invokeNative_Int32(func_ptr, argv1, argc1);
|
||||
ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, argc1);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, argc1));
|
||||
@ -1587,9 +1836,9 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
|
||||
argc1 = 1 + MAX_REG_FLOATS + func_type->param_count + 2;
|
||||
if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
|
||||
size = sizeof(uint64) * argc1;
|
||||
size = sizeof(uint64) * (uint64)argc1;
|
||||
if (size >= UINT32_MAX
|
||||
|| !(argv1 = wasm_malloc(size))) {
|
||||
|| !(argv1 = wasm_malloc((uint32)size))) {
|
||||
wasm_runtime_set_exception(module_inst, "allocate memory failed.");
|
||||
return false;
|
||||
}
|
||||
@ -1641,7 +1890,7 @@ wasm_runtime_invoke_native(void *func_ptr, WASMType *func_type,
|
||||
else {
|
||||
switch (func_type->types[func_type->param_count]) {
|
||||
case VALUE_TYPE_I32:
|
||||
ret[0] = invokeNative_Int32(func_ptr, argv1, n_stacks);
|
||||
ret[0] = (uint32)invokeNative_Int32(func_ptr, argv1, n_stacks);
|
||||
break;
|
||||
case VALUE_TYPE_I64:
|
||||
PUT_I64_TO_ADDR(ret, invokeNative_Int64(func_ptr, argv1, n_stacks));
|
||||
|
||||
@ -9,6 +9,10 @@
|
||||
#include "wasm.h"
|
||||
#include "wasm_thread.h"
|
||||
#include "wasm_hashmap.h"
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
#include "wasmtime_ssp.h"
|
||||
#include "posix.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -81,6 +85,10 @@ typedef struct WASMGlobalInstance {
|
||||
typedef struct WASMFunctionInstance {
|
||||
/* whether it is import function or WASM function */
|
||||
bool is_import_func;
|
||||
/* parameter count */
|
||||
uint16 param_count;
|
||||
/* local variable count, 0 for import function */
|
||||
uint16 local_count;
|
||||
/* cell num of parameters */
|
||||
uint16 param_cell_num;
|
||||
/* cell num of return type */
|
||||
@ -88,6 +96,10 @@ typedef struct WASMFunctionInstance {
|
||||
/* cell num of local variables, 0 for import function */
|
||||
uint16 local_cell_num;
|
||||
uint16 *local_offsets;
|
||||
/* parameter types */
|
||||
uint8 *param_types;
|
||||
/* local types, NULL for import function */
|
||||
uint8 *local_types;
|
||||
union {
|
||||
WASMFunctionImport *func_import;
|
||||
WASMFunction *func;
|
||||
@ -106,6 +118,14 @@ typedef enum {
|
||||
Package_Type_Unknown = 0xFFFF
|
||||
} PackageType;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
typedef struct WASIContext {
|
||||
struct fd_table *curfds;
|
||||
struct fd_prestats *prestats;
|
||||
struct argv_environ_values *argv_environ;
|
||||
} WASIContext;
|
||||
#endif
|
||||
|
||||
typedef struct WASMModuleInstance {
|
||||
/* Module instance type, for module instance loaded from
|
||||
WASM bytecode binary, this field is Wasm_Module_Bytecode;
|
||||
@ -133,6 +153,10 @@ typedef struct WASMModuleInstance {
|
||||
|
||||
WASMModule *module;
|
||||
|
||||
#if WASM_ENABLE_WASI != 0
|
||||
WASIContext wasi_ctx;
|
||||
#endif
|
||||
|
||||
uint32 DYNAMICTOP_PTR_offset;
|
||||
uint32 temp_ret;
|
||||
uint32 llvm_stack;
|
||||
@ -271,7 +295,7 @@ wasm_runtime_get_exception(WASMModuleInstance *module);
|
||||
* @return return true if enlarge successfully, false otherwise
|
||||
*/
|
||||
bool
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, int inc_page_count);
|
||||
wasm_runtime_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASMModuleInstance *
|
||||
|
||||
220
core/iwasm/runtime/wasmtime-wasi-c/LICENSE
Normal file
220
core/iwasm/runtime/wasmtime-wasi-c/LICENSE
Normal file
@ -0,0 +1,220 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
||||
|
||||
|
||||
--- LLVM Exceptions to the Apache 2.0 License ----
|
||||
|
||||
As an exception, if, as a result of your compiling your source code, portions
|
||||
of this Software are embedded into an Object form of such source code, you
|
||||
may redistribute such embedded portions in such Object form without complying
|
||||
with the conditions of Sections 4(a), 4(b) and 4(d) of the License.
|
||||
|
||||
In addition, if you combine or link compiled forms of this Software with
|
||||
software that is licensed under the GPLv2 ("Combined Software") and if a
|
||||
court of competent jurisdiction determines that the patent provision (Section
|
||||
3), the indemnity provision (Section 9) or other Section of the License
|
||||
conflicts with the conditions of the GPLv2, you may retroactively and
|
||||
prospectively choose to deem waived or otherwise exclude such Section(s) of
|
||||
the License, but only in their entirety and only with respect to the Combined
|
||||
Software.
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
Please see the LICENSE file in each top-level directory for the terms applicable to that directory and its relative sub-directories.
|
||||
|
||||
The relevant directories and licenses are:
|
||||
|
||||
src/ - BSD-2-Clause; see src/LICENSE for details
|
||||
include/ - CC0 1.0 Universal (CC0 1.0) Public Domain Dedication
|
||||
polyfill/clang/ - MIT; see the header of polyfill/clang/stdatomic.h for details
|
||||
@ -0,0 +1,121 @@
|
||||
Creative Commons Legal Code
|
||||
|
||||
CC0 1.0 Universal
|
||||
|
||||
CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE
|
||||
LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN
|
||||
ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS
|
||||
INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES
|
||||
REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS
|
||||
PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM
|
||||
THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED
|
||||
HEREUNDER.
|
||||
|
||||
Statement of Purpose
|
||||
|
||||
The laws of most jurisdictions throughout the world automatically confer
|
||||
exclusive Copyright and Related Rights (defined below) upon the creator
|
||||
and subsequent owner(s) (each and all, an "owner") of an original work of
|
||||
authorship and/or a database (each, a "Work").
|
||||
|
||||
Certain owners wish to permanently relinquish those rights to a Work for
|
||||
the purpose of contributing to a commons of creative, cultural and
|
||||
scientific works ("Commons") that the public can reliably and without fear
|
||||
of later claims of infringement build upon, modify, incorporate in other
|
||||
works, reuse and redistribute as freely as possible in any form whatsoever
|
||||
and for any purposes, including without limitation commercial purposes.
|
||||
These owners may contribute to the Commons to promote the ideal of a free
|
||||
culture and the further production of creative, cultural and scientific
|
||||
works, or to gain reputation or greater distribution for their Work in
|
||||
part through the use and efforts of others.
|
||||
|
||||
For these and/or other purposes and motivations, and without any
|
||||
expectation of additional consideration or compensation, the person
|
||||
associating CC0 with a Work (the "Affirmer"), to the extent that he or she
|
||||
is an owner of Copyright and Related Rights in the Work, voluntarily
|
||||
elects to apply CC0 to the Work and publicly distribute the Work under its
|
||||
terms, with knowledge of his or her Copyright and Related Rights in the
|
||||
Work and the meaning and intended legal effect of CC0 on those rights.
|
||||
|
||||
1. Copyright and Related Rights. A Work made available under CC0 may be
|
||||
protected by copyright and related or neighboring rights ("Copyright and
|
||||
Related Rights"). Copyright and Related Rights include, but are not
|
||||
limited to, the following:
|
||||
|
||||
i. the right to reproduce, adapt, distribute, perform, display,
|
||||
communicate, and translate a Work;
|
||||
ii. moral rights retained by the original author(s) and/or performer(s);
|
||||
iii. publicity and privacy rights pertaining to a person's image or
|
||||
likeness depicted in a Work;
|
||||
iv. rights protecting against unfair competition in regards to a Work,
|
||||
subject to the limitations in paragraph 4(a), below;
|
||||
v. rights protecting the extraction, dissemination, use and reuse of data
|
||||
in a Work;
|
||||
vi. database rights (such as those arising under Directive 96/9/EC of the
|
||||
European Parliament and of the Council of 11 March 1996 on the legal
|
||||
protection of databases, and under any national implementation
|
||||
thereof, including any amended or successor version of such
|
||||
directive); and
|
||||
vii. other similar, equivalent or corresponding rights throughout the
|
||||
world based on applicable law or treaty, and any national
|
||||
implementations thereof.
|
||||
|
||||
2. Waiver. To the greatest extent permitted by, but not in contravention
|
||||
of, applicable law, Affirmer hereby overtly, fully, permanently,
|
||||
irrevocably and unconditionally waives, abandons, and surrenders all of
|
||||
Affirmer's Copyright and Related Rights and associated claims and causes
|
||||
of action, whether now known or unknown (including existing as well as
|
||||
future claims and causes of action), in the Work (i) in all territories
|
||||
worldwide, (ii) for the maximum duration provided by applicable law or
|
||||
treaty (including future time extensions), (iii) in any current or future
|
||||
medium and for any number of copies, and (iv) for any purpose whatsoever,
|
||||
including without limitation commercial, advertising or promotional
|
||||
purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each
|
||||
member of the public at large and to the detriment of Affirmer's heirs and
|
||||
successors, fully intending that such Waiver shall not be subject to
|
||||
revocation, rescission, cancellation, termination, or any other legal or
|
||||
equitable action to disrupt the quiet enjoyment of the Work by the public
|
||||
as contemplated by Affirmer's express Statement of Purpose.
|
||||
|
||||
3. Public License Fallback. Should any part of the Waiver for any reason
|
||||
be judged legally invalid or ineffective under applicable law, then the
|
||||
Waiver shall be preserved to the maximum extent permitted taking into
|
||||
account Affirmer's express Statement of Purpose. In addition, to the
|
||||
extent the Waiver is so judged Affirmer hereby grants to each affected
|
||||
person a royalty-free, non transferable, non sublicensable, non exclusive,
|
||||
irrevocable and unconditional license to exercise Affirmer's Copyright and
|
||||
Related Rights in the Work (i) in all territories worldwide, (ii) for the
|
||||
maximum duration provided by applicable law or treaty (including future
|
||||
time extensions), (iii) in any current or future medium and for any number
|
||||
of copies, and (iv) for any purpose whatsoever, including without
|
||||
limitation commercial, advertising or promotional purposes (the
|
||||
"License"). The License shall be deemed effective as of the date CC0 was
|
||||
applied by Affirmer to the Work. Should any part of the License for any
|
||||
reason be judged legally invalid or ineffective under applicable law, such
|
||||
partial invalidity or ineffectiveness shall not invalidate the remainder
|
||||
of the License, and in such case Affirmer hereby affirms that he or she
|
||||
will not (i) exercise any of his or her remaining Copyright and Related
|
||||
Rights in the Work or (ii) assert any associated claims and causes of
|
||||
action with respect to the Work, in either case contrary to Affirmer's
|
||||
express Statement of Purpose.
|
||||
|
||||
4. Limitations and Disclaimers.
|
||||
|
||||
a. No trademark or patent rights held by Affirmer are waived, abandoned,
|
||||
surrendered, licensed or otherwise affected by this document.
|
||||
b. Affirmer offers the Work as-is and makes no representations or
|
||||
warranties of any kind concerning the Work, express, implied,
|
||||
statutory or otherwise, including without limitation warranties of
|
||||
title, merchantability, fitness for a particular purpose, non
|
||||
infringement, or the absence of latent or other defects, accuracy, or
|
||||
the present or absence of errors, whether or not discoverable, all to
|
||||
the greatest extent permissible under applicable law.
|
||||
c. Affirmer disclaims responsibility for clearing rights of other persons
|
||||
that may apply to the Work or any use thereof, including without
|
||||
limitation any person's Copyright and Related Rights in the Work.
|
||||
Further, Affirmer disclaims responsibility for obtaining any necessary
|
||||
consents, permissions or other rights required for any use of the
|
||||
Work.
|
||||
d. Affirmer understands and acknowledges that Creative Commons is not a
|
||||
party to this document and has no duty or obligation with respect to
|
||||
this CC0 or use of the Work.
|
||||
@ -0,0 +1,866 @@
|
||||
/*
|
||||
* Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
* See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
*
|
||||
* This file declares an interface similar to WASI, but augmented to expose
|
||||
* some implementation details such as the curfds arguments that we pass
|
||||
* around to avoid storing them in TLS.
|
||||
*/
|
||||
|
||||
#ifndef WASMTIME_SSP_H
|
||||
#define WASMTIME_SSP_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
_Static_assert(_Alignof(int8_t) == 1, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(uint8_t) == 1, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(int16_t) == 2, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(uint16_t) == 2, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(int32_t) == 4, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(uint32_t) == 4, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(int64_t) == 8, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(uint64_t) == 8, "non-wasi data layout");
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t __wasi_advice_t;
|
||||
#define __WASI_ADVICE_NORMAL (0)
|
||||
#define __WASI_ADVICE_SEQUENTIAL (1)
|
||||
#define __WASI_ADVICE_RANDOM (2)
|
||||
#define __WASI_ADVICE_WILLNEED (3)
|
||||
#define __WASI_ADVICE_DONTNEED (4)
|
||||
#define __WASI_ADVICE_NOREUSE (5)
|
||||
|
||||
typedef uint32_t __wasi_clockid_t;
|
||||
#define __WASI_CLOCK_REALTIME (0)
|
||||
#define __WASI_CLOCK_MONOTONIC (1)
|
||||
#define __WASI_CLOCK_PROCESS_CPUTIME_ID (2)
|
||||
#define __WASI_CLOCK_THREAD_CPUTIME_ID (3)
|
||||
|
||||
typedef uint64_t __wasi_device_t;
|
||||
|
||||
typedef uint64_t __wasi_dircookie_t;
|
||||
#define __WASI_DIRCOOKIE_START (0)
|
||||
|
||||
typedef uint16_t __wasi_errno_t;
|
||||
#define __WASI_ESUCCESS (0)
|
||||
#define __WASI_E2BIG (1)
|
||||
#define __WASI_EACCES (2)
|
||||
#define __WASI_EADDRINUSE (3)
|
||||
#define __WASI_EADDRNOTAVAIL (4)
|
||||
#define __WASI_EAFNOSUPPORT (5)
|
||||
#define __WASI_EAGAIN (6)
|
||||
#define __WASI_EALREADY (7)
|
||||
#define __WASI_EBADF (8)
|
||||
#define __WASI_EBADMSG (9)
|
||||
#define __WASI_EBUSY (10)
|
||||
#define __WASI_ECANCELED (11)
|
||||
#define __WASI_ECHILD (12)
|
||||
#define __WASI_ECONNABORTED (13)
|
||||
#define __WASI_ECONNREFUSED (14)
|
||||
#define __WASI_ECONNRESET (15)
|
||||
#define __WASI_EDEADLK (16)
|
||||
#define __WASI_EDESTADDRREQ (17)
|
||||
#define __WASI_EDOM (18)
|
||||
#define __WASI_EDQUOT (19)
|
||||
#define __WASI_EEXIST (20)
|
||||
#define __WASI_EFAULT (21)
|
||||
#define __WASI_EFBIG (22)
|
||||
#define __WASI_EHOSTUNREACH (23)
|
||||
#define __WASI_EIDRM (24)
|
||||
#define __WASI_EILSEQ (25)
|
||||
#define __WASI_EINPROGRESS (26)
|
||||
#define __WASI_EINTR (27)
|
||||
#define __WASI_EINVAL (28)
|
||||
#define __WASI_EIO (29)
|
||||
#define __WASI_EISCONN (30)
|
||||
#define __WASI_EISDIR (31)
|
||||
#define __WASI_ELOOP (32)
|
||||
#define __WASI_EMFILE (33)
|
||||
#define __WASI_EMLINK (34)
|
||||
#define __WASI_EMSGSIZE (35)
|
||||
#define __WASI_EMULTIHOP (36)
|
||||
#define __WASI_ENAMETOOLONG (37)
|
||||
#define __WASI_ENETDOWN (38)
|
||||
#define __WASI_ENETRESET (39)
|
||||
#define __WASI_ENETUNREACH (40)
|
||||
#define __WASI_ENFILE (41)
|
||||
#define __WASI_ENOBUFS (42)
|
||||
#define __WASI_ENODEV (43)
|
||||
#define __WASI_ENOENT (44)
|
||||
#define __WASI_ENOEXEC (45)
|
||||
#define __WASI_ENOLCK (46)
|
||||
#define __WASI_ENOLINK (47)
|
||||
#define __WASI_ENOMEM (48)
|
||||
#define __WASI_ENOMSG (49)
|
||||
#define __WASI_ENOPROTOOPT (50)
|
||||
#define __WASI_ENOSPC (51)
|
||||
#define __WASI_ENOSYS (52)
|
||||
#define __WASI_ENOTCONN (53)
|
||||
#define __WASI_ENOTDIR (54)
|
||||
#define __WASI_ENOTEMPTY (55)
|
||||
#define __WASI_ENOTRECOVERABLE (56)
|
||||
#define __WASI_ENOTSOCK (57)
|
||||
#define __WASI_ENOTSUP (58)
|
||||
#define __WASI_ENOTTY (59)
|
||||
#define __WASI_ENXIO (60)
|
||||
#define __WASI_EOVERFLOW (61)
|
||||
#define __WASI_EOWNERDEAD (62)
|
||||
#define __WASI_EPERM (63)
|
||||
#define __WASI_EPIPE (64)
|
||||
#define __WASI_EPROTO (65)
|
||||
#define __WASI_EPROTONOSUPPORT (66)
|
||||
#define __WASI_EPROTOTYPE (67)
|
||||
#define __WASI_ERANGE (68)
|
||||
#define __WASI_EROFS (69)
|
||||
#define __WASI_ESPIPE (70)
|
||||
#define __WASI_ESRCH (71)
|
||||
#define __WASI_ESTALE (72)
|
||||
#define __WASI_ETIMEDOUT (73)
|
||||
#define __WASI_ETXTBSY (74)
|
||||
#define __WASI_EXDEV (75)
|
||||
#define __WASI_ENOTCAPABLE (76)
|
||||
|
||||
typedef uint16_t __wasi_eventrwflags_t;
|
||||
#define __WASI_EVENT_FD_READWRITE_HANGUP (0x0001)
|
||||
|
||||
typedef uint8_t __wasi_eventtype_t;
|
||||
#define __WASI_EVENTTYPE_CLOCK (0)
|
||||
#define __WASI_EVENTTYPE_FD_READ (1)
|
||||
#define __WASI_EVENTTYPE_FD_WRITE (2)
|
||||
|
||||
typedef uint32_t __wasi_exitcode_t;
|
||||
|
||||
typedef uint32_t __wasi_fd_t;
|
||||
|
||||
typedef uint16_t __wasi_fdflags_t;
|
||||
#define __WASI_FDFLAG_APPEND (0x0001)
|
||||
#define __WASI_FDFLAG_DSYNC (0x0002)
|
||||
#define __WASI_FDFLAG_NONBLOCK (0x0004)
|
||||
#define __WASI_FDFLAG_RSYNC (0x0008)
|
||||
#define __WASI_FDFLAG_SYNC (0x0010)
|
||||
|
||||
typedef int64_t __wasi_filedelta_t;
|
||||
|
||||
typedef uint64_t __wasi_filesize_t;
|
||||
|
||||
typedef uint8_t __wasi_filetype_t;
|
||||
#define __WASI_FILETYPE_UNKNOWN (0)
|
||||
#define __WASI_FILETYPE_BLOCK_DEVICE (1)
|
||||
#define __WASI_FILETYPE_CHARACTER_DEVICE (2)
|
||||
#define __WASI_FILETYPE_DIRECTORY (3)
|
||||
#define __WASI_FILETYPE_REGULAR_FILE (4)
|
||||
#define __WASI_FILETYPE_SOCKET_DGRAM (5)
|
||||
#define __WASI_FILETYPE_SOCKET_STREAM (6)
|
||||
#define __WASI_FILETYPE_SYMBOLIC_LINK (7)
|
||||
|
||||
typedef uint16_t __wasi_fstflags_t;
|
||||
#define __WASI_FILESTAT_SET_ATIM (0x0001)
|
||||
#define __WASI_FILESTAT_SET_ATIM_NOW (0x0002)
|
||||
#define __WASI_FILESTAT_SET_MTIM (0x0004)
|
||||
#define __WASI_FILESTAT_SET_MTIM_NOW (0x0008)
|
||||
|
||||
typedef uint64_t __wasi_inode_t;
|
||||
|
||||
typedef uint32_t __wasi_linkcount_t;
|
||||
|
||||
typedef uint32_t __wasi_lookupflags_t;
|
||||
#define __WASI_LOOKUP_SYMLINK_FOLLOW (0x00000001)
|
||||
|
||||
typedef uint16_t __wasi_oflags_t;
|
||||
#define __WASI_O_CREAT (0x0001)
|
||||
#define __WASI_O_DIRECTORY (0x0002)
|
||||
#define __WASI_O_EXCL (0x0004)
|
||||
#define __WASI_O_TRUNC (0x0008)
|
||||
|
||||
typedef uint16_t __wasi_riflags_t;
|
||||
#define __WASI_SOCK_RECV_PEEK (0x0001)
|
||||
#define __WASI_SOCK_RECV_WAITALL (0x0002)
|
||||
|
||||
typedef uint64_t __wasi_rights_t;
|
||||
#define __WASI_RIGHT_FD_DATASYNC (0x0000000000000001)
|
||||
#define __WASI_RIGHT_FD_READ (0x0000000000000002)
|
||||
#define __WASI_RIGHT_FD_SEEK (0x0000000000000004)
|
||||
#define __WASI_RIGHT_FD_FDSTAT_SET_FLAGS (0x0000000000000008)
|
||||
#define __WASI_RIGHT_FD_SYNC (0x0000000000000010)
|
||||
#define __WASI_RIGHT_FD_TELL (0x0000000000000020)
|
||||
#define __WASI_RIGHT_FD_WRITE (0x0000000000000040)
|
||||
#define __WASI_RIGHT_FD_ADVISE (0x0000000000000080)
|
||||
#define __WASI_RIGHT_FD_ALLOCATE (0x0000000000000100)
|
||||
#define __WASI_RIGHT_PATH_CREATE_DIRECTORY (0x0000000000000200)
|
||||
#define __WASI_RIGHT_PATH_CREATE_FILE (0x0000000000000400)
|
||||
#define __WASI_RIGHT_PATH_LINK_SOURCE (0x0000000000000800)
|
||||
#define __WASI_RIGHT_PATH_LINK_TARGET (0x0000000000001000)
|
||||
#define __WASI_RIGHT_PATH_OPEN (0x0000000000002000)
|
||||
#define __WASI_RIGHT_FD_READDIR (0x0000000000004000)
|
||||
#define __WASI_RIGHT_PATH_READLINK (0x0000000000008000)
|
||||
#define __WASI_RIGHT_PATH_RENAME_SOURCE (0x0000000000010000)
|
||||
#define __WASI_RIGHT_PATH_RENAME_TARGET (0x0000000000020000)
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_GET (0x0000000000040000)
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_SIZE (0x0000000000080000)
|
||||
#define __WASI_RIGHT_PATH_FILESTAT_SET_TIMES (0x0000000000100000)
|
||||
#define __WASI_RIGHT_FD_FILESTAT_GET (0x0000000000200000)
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_SIZE (0x0000000000400000)
|
||||
#define __WASI_RIGHT_FD_FILESTAT_SET_TIMES (0x0000000000800000)
|
||||
#define __WASI_RIGHT_PATH_SYMLINK (0x0000000001000000)
|
||||
#define __WASI_RIGHT_PATH_REMOVE_DIRECTORY (0x0000000002000000)
|
||||
#define __WASI_RIGHT_PATH_UNLINK_FILE (0x0000000004000000)
|
||||
#define __WASI_RIGHT_POLL_FD_READWRITE (0x0000000008000000)
|
||||
#define __WASI_RIGHT_SOCK_SHUTDOWN (0x0000000010000000)
|
||||
|
||||
typedef uint16_t __wasi_roflags_t;
|
||||
#define __WASI_SOCK_RECV_DATA_TRUNCATED (0x0001)
|
||||
|
||||
typedef uint8_t __wasi_sdflags_t;
|
||||
#define __WASI_SHUT_RD (0x01)
|
||||
#define __WASI_SHUT_WR (0x02)
|
||||
|
||||
typedef uint16_t __wasi_siflags_t;
|
||||
|
||||
typedef uint8_t __wasi_signal_t;
|
||||
// 0 is reserved; POSIX has special semantics for kill(pid, 0).
|
||||
#define __WASI_SIGHUP (1)
|
||||
#define __WASI_SIGINT (2)
|
||||
#define __WASI_SIGQUIT (3)
|
||||
#define __WASI_SIGILL (4)
|
||||
#define __WASI_SIGTRAP (5)
|
||||
#define __WASI_SIGABRT (6)
|
||||
#define __WASI_SIGBUS (7)
|
||||
#define __WASI_SIGFPE (8)
|
||||
#define __WASI_SIGKILL (9)
|
||||
#define __WASI_SIGUSR1 (10)
|
||||
#define __WASI_SIGSEGV (11)
|
||||
#define __WASI_SIGUSR2 (12)
|
||||
#define __WASI_SIGPIPE (13)
|
||||
#define __WASI_SIGALRM (14)
|
||||
#define __WASI_SIGTERM (15)
|
||||
#define __WASI_SIGCHLD (16)
|
||||
#define __WASI_SIGCONT (17)
|
||||
#define __WASI_SIGSTOP (18)
|
||||
#define __WASI_SIGTSTP (19)
|
||||
#define __WASI_SIGTTIN (20)
|
||||
#define __WASI_SIGTTOU (21)
|
||||
#define __WASI_SIGURG (22)
|
||||
#define __WASI_SIGXCPU (23)
|
||||
#define __WASI_SIGXFSZ (24)
|
||||
#define __WASI_SIGVTALRM (25)
|
||||
#define __WASI_SIGPROF (26)
|
||||
#define __WASI_SIGWINCH (27)
|
||||
#define __WASI_SIGPOLL (28)
|
||||
#define __WASI_SIGPWR (29)
|
||||
#define __WASI_SIGSYS (30)
|
||||
|
||||
typedef uint16_t __wasi_subclockflags_t;
|
||||
#define __WASI_SUBSCRIPTION_CLOCK_ABSTIME (0x0001)
|
||||
|
||||
typedef uint64_t __wasi_timestamp_t;
|
||||
|
||||
typedef uint64_t __wasi_userdata_t;
|
||||
|
||||
typedef uint8_t __wasi_whence_t;
|
||||
#define __WASI_WHENCE_CUR (0)
|
||||
#define __WASI_WHENCE_END (1)
|
||||
#define __WASI_WHENCE_SET (2)
|
||||
|
||||
typedef uint8_t __wasi_preopentype_t;
|
||||
#define __WASI_PREOPENTYPE_DIR (0)
|
||||
|
||||
struct fd_table;
|
||||
struct fd_prestats;
|
||||
struct argv_environ_values;
|
||||
|
||||
typedef struct __wasi_dirent_t {
|
||||
__wasi_dircookie_t d_next;
|
||||
__wasi_inode_t d_ino;
|
||||
uint32_t d_namlen;
|
||||
__wasi_filetype_t d_type;
|
||||
} __wasi_dirent_t;
|
||||
_Static_assert(offsetof(__wasi_dirent_t, d_next) == 0, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_dirent_t, d_ino) == 8, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_dirent_t, d_namlen) == 16, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_dirent_t, d_type) == 20, "non-wasi data layout");
|
||||
_Static_assert(sizeof(__wasi_dirent_t) == 24, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(__wasi_dirent_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_event_t {
|
||||
__wasi_userdata_t userdata;
|
||||
__wasi_errno_t error;
|
||||
__wasi_eventtype_t type;
|
||||
union __wasi_event_u {
|
||||
struct __wasi_event_u_fd_readwrite_t {
|
||||
__wasi_filesize_t nbytes;
|
||||
__wasi_eventrwflags_t flags;
|
||||
} fd_readwrite;
|
||||
} u;
|
||||
} __wasi_event_t;
|
||||
_Static_assert(offsetof(__wasi_event_t, userdata) == 0, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_event_t, error) == 8, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_event_t, type) == 10, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_event_t, u.fd_readwrite.nbytes) == 16, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_event_t, u.fd_readwrite.flags) == 24, "non-wasi data layout");
|
||||
_Static_assert(sizeof(__wasi_event_t) == 32, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(__wasi_event_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_prestat_t {
|
||||
__wasi_preopentype_t pr_type;
|
||||
union __wasi_prestat_u {
|
||||
struct __wasi_prestat_u_dir_t {
|
||||
size_t pr_name_len;
|
||||
} dir;
|
||||
} u;
|
||||
} __wasi_prestat_t;
|
||||
_Static_assert(offsetof(__wasi_prestat_t, pr_type) == 0, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_prestat_t, u.dir.pr_name_len) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_prestat_t) == 16, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_prestat_t) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_prestat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_fdstat_t {
|
||||
__wasi_filetype_t fs_filetype;
|
||||
__wasi_fdflags_t fs_flags;
|
||||
__wasi_rights_t fs_rights_base;
|
||||
__wasi_rights_t fs_rights_inheriting;
|
||||
} __wasi_fdstat_t;
|
||||
_Static_assert(
|
||||
offsetof(__wasi_fdstat_t, fs_filetype) == 0, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_fdstat_t, fs_flags) == 2, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_fdstat_t, fs_rights_base) == 8, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_fdstat_t, fs_rights_inheriting) == 16,
|
||||
"non-wasi data layout");
|
||||
_Static_assert(sizeof(__wasi_fdstat_t) == 24, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(__wasi_fdstat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_filestat_t {
|
||||
__wasi_device_t st_dev;
|
||||
__wasi_inode_t st_ino;
|
||||
__wasi_filetype_t st_filetype;
|
||||
__wasi_linkcount_t st_nlink;
|
||||
__wasi_filesize_t st_size;
|
||||
__wasi_timestamp_t st_atim;
|
||||
__wasi_timestamp_t st_mtim;
|
||||
__wasi_timestamp_t st_ctim;
|
||||
} __wasi_filestat_t;
|
||||
_Static_assert(offsetof(__wasi_filestat_t, st_dev) == 0, "non-wasi data layout");
|
||||
_Static_assert(offsetof(__wasi_filestat_t, st_ino) == 8, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_filetype) == 16, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_nlink) == 20, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_size) == 24, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_atim) == 32, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_mtim) == 40, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_filestat_t, st_ctim) == 48, "non-wasi data layout");
|
||||
_Static_assert(sizeof(__wasi_filestat_t) == 56, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(__wasi_filestat_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_ciovec_t {
|
||||
const void *buf;
|
||||
size_t buf_len;
|
||||
} __wasi_ciovec_t;
|
||||
_Static_assert(offsetof(__wasi_ciovec_t, buf) == 0, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_ciovec_t, buf_len) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_ciovec_t, buf_len) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_ciovec_t) == 16, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_ciovec_t) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_ciovec_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_iovec_t {
|
||||
void *buf;
|
||||
size_t buf_len;
|
||||
} __wasi_iovec_t;
|
||||
_Static_assert(offsetof(__wasi_iovec_t, buf) == 0, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
offsetof(__wasi_iovec_t, buf_len) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
offsetof(__wasi_iovec_t, buf_len) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
sizeof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
sizeof(__wasi_iovec_t) == 16, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 4 ||
|
||||
_Alignof(__wasi_iovec_t) == 4, "non-wasi data layout");
|
||||
_Static_assert(sizeof(void *) != 8 ||
|
||||
_Alignof(__wasi_iovec_t) == 8, "non-wasi data layout");
|
||||
|
||||
typedef struct __wasi_subscription_t {
|
||||
__wasi_userdata_t userdata;
|
||||
__wasi_eventtype_t type;
|
||||
union __wasi_subscription_u {
|
||||
struct __wasi_subscription_u_clock_t {
|
||||
__wasi_userdata_t identifier;
|
||||
__wasi_clockid_t clock_id;
|
||||
__wasi_timestamp_t timeout;
|
||||
__wasi_timestamp_t precision;
|
||||
__wasi_subclockflags_t flags;
|
||||
} clock;
|
||||
struct __wasi_subscription_u_fd_readwrite_t {
|
||||
__wasi_fd_t fd;
|
||||
} fd_readwrite;
|
||||
} u;
|
||||
} __wasi_subscription_t;
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, userdata) == 0, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, type) == 8, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.clock.identifier) == 16,
|
||||
"non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.clock.clock_id) == 24,
|
||||
"non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.clock.timeout) == 32, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.clock.precision) == 40,
|
||||
"non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.clock.flags) == 48, "non-wasi data layout");
|
||||
_Static_assert(
|
||||
offsetof(__wasi_subscription_t, u.fd_readwrite.fd) == 16,
|
||||
"non-wasi data layout");
|
||||
_Static_assert(sizeof(__wasi_subscription_t) == 56, "non-wasi data layout");
|
||||
_Static_assert(_Alignof(__wasi_subscription_t) == 8, "non-wasi data layout");
|
||||
|
||||
#if defined(WASMTIME_SSP_WASI_API)
|
||||
#define WASMTIME_SSP_SYSCALL_NAME(name) \
|
||||
asm("__wasi_" #name)
|
||||
#else
|
||||
#define WASMTIME_SSP_SYSCALL_NAME(name)
|
||||
#endif
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_args_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct argv_environ_values *arg_environ,
|
||||
#endif
|
||||
char **argv,
|
||||
char *argv_buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(args_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_args_sizes_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct argv_environ_values *arg_environ,
|
||||
#endif
|
||||
size_t *argc,
|
||||
size_t *argv_buf_size
|
||||
) WASMTIME_SSP_SYSCALL_NAME(args_sizes_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_clock_res_get(
|
||||
__wasi_clockid_t clock_id,
|
||||
__wasi_timestamp_t *resolution
|
||||
) WASMTIME_SSP_SYSCALL_NAME(clock_res_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_clock_time_get(
|
||||
__wasi_clockid_t clock_id,
|
||||
__wasi_timestamp_t precision,
|
||||
__wasi_timestamp_t *time
|
||||
) WASMTIME_SSP_SYSCALL_NAME(clock_time_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_environ_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct argv_environ_values *arg_environ,
|
||||
#endif
|
||||
char **environ,
|
||||
char *environ_buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(environ_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_environ_sizes_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct argv_environ_values *arg_environ,
|
||||
#endif
|
||||
size_t *environ_count,
|
||||
size_t *environ_buf_size
|
||||
) WASMTIME_SSP_SYSCALL_NAME(environ_sizes_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_prestat_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_prestats *prestats,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_prestat_t *buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_prestat_dir_name(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_prestats *prestats,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
char *path,
|
||||
size_t path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_prestat_dir_name) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_close(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
struct fd_prestats *prestats,
|
||||
#endif
|
||||
__wasi_fd_t fd
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_close) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_datasync(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_datasync) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_pread(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const __wasi_iovec_t *iovs,
|
||||
size_t iovs_len,
|
||||
__wasi_filesize_t offset,
|
||||
size_t *nread
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_pread) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_pwrite(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const __wasi_ciovec_t *iovs,
|
||||
size_t iovs_len,
|
||||
__wasi_filesize_t offset,
|
||||
size_t *nwritten
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_pwrite) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_read(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const __wasi_iovec_t *iovs,
|
||||
size_t iovs_len,
|
||||
size_t *nread
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_read) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_renumber(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
struct fd_prestats *prestats,
|
||||
#endif
|
||||
__wasi_fd_t from,
|
||||
__wasi_fd_t to
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_renumber) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_seek(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filedelta_t offset,
|
||||
__wasi_whence_t whence,
|
||||
__wasi_filesize_t *newoffset
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_seek) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_tell(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filesize_t *newoffset
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_tell) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_fdstat_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_fdstat_t *buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_flags(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_fdflags_t flags
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_flags) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_fdstat_set_rights(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_rights_t fs_rights_base,
|
||||
__wasi_rights_t fs_rights_inheriting
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_fdstat_set_rights) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_sync(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_sync) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_write(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const __wasi_ciovec_t *iovs,
|
||||
size_t iovs_len,
|
||||
size_t *nwritten
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_write) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_advise(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filesize_t offset,
|
||||
__wasi_filesize_t len,
|
||||
__wasi_advice_t advice
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_advise) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_allocate(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filesize_t offset,
|
||||
__wasi_filesize_t len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_allocate) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_create_directory(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const char *path,
|
||||
size_t path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_create_directory) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_link(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t old_fd,
|
||||
__wasi_lookupflags_t old_flags,
|
||||
const char *old_path,
|
||||
size_t old_path_len,
|
||||
__wasi_fd_t new_fd,
|
||||
const char *new_path,
|
||||
size_t new_path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_link) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_open(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t dirfd,
|
||||
__wasi_lookupflags_t dirflags,
|
||||
const char *path,
|
||||
size_t path_len,
|
||||
__wasi_oflags_t oflags,
|
||||
__wasi_rights_t fs_rights_base,
|
||||
__wasi_rights_t fs_rights_inheriting,
|
||||
__wasi_fdflags_t fs_flags,
|
||||
__wasi_fd_t *fd
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_open) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_readdir(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
void *buf,
|
||||
size_t buf_len,
|
||||
__wasi_dircookie_t cookie,
|
||||
size_t *bufused
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_readdir) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_readlink(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const char *path,
|
||||
size_t path_len,
|
||||
char *buf,
|
||||
size_t buf_len,
|
||||
size_t *bufused
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_readlink) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_rename(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t old_fd,
|
||||
const char *old_path,
|
||||
size_t old_path_len,
|
||||
__wasi_fd_t new_fd,
|
||||
const char *new_path,
|
||||
size_t new_path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_rename) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_filestat_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filestat_t *buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_filestat_set_times(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_timestamp_t st_atim,
|
||||
__wasi_timestamp_t st_mtim,
|
||||
__wasi_fstflags_t fstflags
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_times) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_fd_filestat_set_size(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_filesize_t st_size
|
||||
) WASMTIME_SSP_SYSCALL_NAME(fd_filestat_set_size) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_filestat_get(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_lookupflags_t flags,
|
||||
const char *path,
|
||||
size_t path_len,
|
||||
__wasi_filestat_t *buf
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_filestat_set_times(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
__wasi_lookupflags_t flags,
|
||||
const char *path,
|
||||
size_t path_len,
|
||||
__wasi_timestamp_t st_atim,
|
||||
__wasi_timestamp_t st_mtim,
|
||||
__wasi_fstflags_t fstflags
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_filestat_set_times) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_symlink(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
const char *old_path,
|
||||
size_t old_path_len,
|
||||
__wasi_fd_t fd,
|
||||
const char *new_path,
|
||||
size_t new_path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_symlink) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_unlink_file(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const char *path,
|
||||
size_t path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_unlink_file) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_path_remove_directory(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t fd,
|
||||
const char *path,
|
||||
size_t path_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(path_remove_directory) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_poll_oneoff(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
const __wasi_subscription_t *in,
|
||||
__wasi_event_t *out,
|
||||
size_t nsubscriptions,
|
||||
size_t *nevents
|
||||
) WASMTIME_SSP_SYSCALL_NAME(poll_oneoff) __attribute__((__warn_unused_result__));
|
||||
|
||||
_Noreturn void wasmtime_ssp_proc_exit(
|
||||
__wasi_exitcode_t rval
|
||||
) WASMTIME_SSP_SYSCALL_NAME(proc_exit);
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_proc_raise(
|
||||
__wasi_signal_t sig
|
||||
) WASMTIME_SSP_SYSCALL_NAME(proc_raise) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_random_get(
|
||||
void *buf,
|
||||
size_t buf_len
|
||||
) WASMTIME_SSP_SYSCALL_NAME(random_get) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_recv(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
const __wasi_iovec_t *ri_data,
|
||||
size_t ri_data_len,
|
||||
__wasi_riflags_t ri_flags,
|
||||
size_t *ro_datalen,
|
||||
__wasi_roflags_t *ro_flags
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_recv) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_send(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
const __wasi_ciovec_t *si_data,
|
||||
size_t si_data_len,
|
||||
__wasi_siflags_t si_flags,
|
||||
size_t *so_datalen
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_send) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sock_shutdown(
|
||||
#if !defined(WASMTIME_SSP_STATIC_CURFDS)
|
||||
struct fd_table *curfds,
|
||||
#endif
|
||||
__wasi_fd_t sock,
|
||||
__wasi_sdflags_t how
|
||||
) WASMTIME_SSP_SYSCALL_NAME(sock_shutdown) __attribute__((__warn_unused_result__));
|
||||
|
||||
__wasi_errno_t wasmtime_ssp_sched_yield(void)
|
||||
WASMTIME_SSP_SYSCALL_NAME(sched_yield) __attribute__((__warn_unused_result__));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef WASMTIME_SSP_SYSCALL_NAME
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,24 @@
|
||||
All code is distributed under the following license:
|
||||
|
||||
Copyright (c) 2015 Nuxi, https://nuxi.nl/
|
||||
|
||||
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.
|
||||
@ -0,0 +1,14 @@
|
||||
This directory consists of selected files copied from the [libemulator]
|
||||
directory in the [cloudabi-utils] repository, with minor modifications,
|
||||
along with the accompanying LICENSE file from that repository.
|
||||
|
||||
The modifications are marked with `WASMTIME_*` preprocessor macros.
|
||||
|
||||
The files were copied at git revision
|
||||
223dadc53248552db43e012c67ed08cf416a2b12
|
||||
which is dated
|
||||
Tue Jun 25 17:22:07 2019 -0700
|
||||
.
|
||||
|
||||
[libemulator]: https://github.com/NuxiNL/cloudabi-utils/tree/master/src/libemulator
|
||||
[cloudabi-utils]: https://github.com/NuxiNL/cloudabi-utils
|
||||
@ -0,0 +1,100 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef CONFIG_H
|
||||
#define CONFIG_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#define CONFIG_HAS_ARC4RANDOM_BUF 1
|
||||
#else
|
||||
#define CONFIG_HAS_ARC4RANDOM_BUF 0
|
||||
#endif
|
||||
|
||||
// On Linux, prefer to use getrandom, though it isn't available in
|
||||
// GLIBC before 2.25.
|
||||
#if defined(__linux__) && \
|
||||
(!defined(__GLIBC__) || \
|
||||
__GLIBC__ > 2 || \
|
||||
(__GLIBC__ == 2 && __GLIBC_MINOR__ >= 25))
|
||||
#define CONFIG_HAS_GETRANDOM 1
|
||||
#else
|
||||
#define CONFIG_HAS_GETRANDOM 0
|
||||
#endif
|
||||
|
||||
#if defined(__CloudABI__)
|
||||
#define CONFIG_HAS_CAP_ENTER 1
|
||||
#else
|
||||
#define CONFIG_HAS_CAP_ENTER 0
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__EMSCRIPTEN__)
|
||||
#define CONFIG_HAS_CLOCK_NANOSLEEP 1
|
||||
#else
|
||||
#define CONFIG_HAS_CLOCK_NANOSLEEP 0
|
||||
#endif
|
||||
|
||||
#if !defined(__APPLE__) && !defined(__FreeBSD__)
|
||||
#define CONFIG_HAS_FDATASYNC 1
|
||||
#else
|
||||
#define CONFIG_HAS_FDATASYNC 0
|
||||
#endif
|
||||
|
||||
#ifndef __CloudABI__
|
||||
#define CONFIG_HAS_ISATTY 1
|
||||
#else
|
||||
#define CONFIG_HAS_ISATTY 0
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#define CONFIG_HAS_POSIX_FALLOCATE 1
|
||||
#else
|
||||
#define CONFIG_HAS_POSIX_FALLOCATE 0
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#define CONFIG_HAS_PREADV 1
|
||||
#else
|
||||
#define CONFIG_HAS_PREADV 0
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) || defined(__CloudABI__)
|
||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 1
|
||||
#else
|
||||
#define CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP 0
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 1
|
||||
#else
|
||||
#define CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK 0
|
||||
#endif
|
||||
|
||||
#ifndef __APPLE__
|
||||
#define CONFIG_HAS_PWRITEV 1
|
||||
#else
|
||||
#define CONFIG_HAS_PWRITEV 0
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define st_atimespec st_atim
|
||||
#define st_mtimespec st_mtim
|
||||
#define st_ctimespec st_ctim
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define CONFIG_TLS_USE_GSBASE 1
|
||||
#else
|
||||
#define CONFIG_TLS_USE_GSBASE 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,215 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef LOCKING_H
|
||||
#define LOCKING_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
|
||||
#ifndef __has_extension
|
||||
#define __has_extension(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_extension(c_thread_safety_attributes)
|
||||
#define LOCK_ANNOTATE(x) __attribute__((x))
|
||||
#else
|
||||
#define LOCK_ANNOTATE(x)
|
||||
#endif
|
||||
|
||||
// Lock annotation macros.
|
||||
|
||||
#define LOCKABLE LOCK_ANNOTATE(lockable)
|
||||
|
||||
#define LOCKS_EXCLUSIVE(...) LOCK_ANNOTATE(exclusive_lock_function(__VA_ARGS__))
|
||||
#define LOCKS_SHARED(...) LOCK_ANNOTATE(shared_lock_function(__VA_ARGS__))
|
||||
|
||||
#define TRYLOCKS_EXCLUSIVE(...) \
|
||||
LOCK_ANNOTATE(exclusive_trylock_function(__VA_ARGS__))
|
||||
#define TRYLOCKS_SHARED(...) LOCK_ANNOTATE(shared_trylock_function(__VA_ARGS__))
|
||||
|
||||
#define UNLOCKS(...) LOCK_ANNOTATE(unlock_function(__VA_ARGS__))
|
||||
|
||||
#define REQUIRES_EXCLUSIVE(...) \
|
||||
LOCK_ANNOTATE(exclusive_locks_required(__VA_ARGS__))
|
||||
#define REQUIRES_SHARED(...) LOCK_ANNOTATE(shared_locks_required(__VA_ARGS__))
|
||||
#define REQUIRES_UNLOCKED(...) LOCK_ANNOTATE(locks_excluded(__VA_ARGS__))
|
||||
|
||||
#define NO_LOCK_ANALYSIS LOCK_ANNOTATE(no_thread_safety_analysis)
|
||||
|
||||
// Mutex that uses the lock annotations.
|
||||
|
||||
struct LOCKABLE mutex {
|
||||
pthread_mutex_t object;
|
||||
};
|
||||
|
||||
#define MUTEX_INITIALIZER \
|
||||
{ PTHREAD_MUTEX_INITIALIZER }
|
||||
|
||||
static inline void mutex_init(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
|
||||
pthread_mutex_init(&lock->object, NULL);
|
||||
}
|
||||
|
||||
static inline void mutex_destroy(struct mutex *lock) REQUIRES_UNLOCKED(*lock) {
|
||||
pthread_mutex_destroy(&lock->object);
|
||||
}
|
||||
|
||||
static inline void mutex_lock(struct mutex *lock)
|
||||
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_mutex_lock(&lock->object);
|
||||
}
|
||||
|
||||
static inline void mutex_unlock(struct mutex *lock)
|
||||
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_mutex_unlock(&lock->object);
|
||||
}
|
||||
|
||||
// Read-write lock that uses the lock annotations.
|
||||
|
||||
struct LOCKABLE rwlock {
|
||||
pthread_rwlock_t object;
|
||||
};
|
||||
|
||||
static inline void rwlock_init(struct rwlock *lock) REQUIRES_UNLOCKED(*lock) {
|
||||
pthread_rwlock_init(&lock->object, NULL);
|
||||
}
|
||||
|
||||
static inline void rwlock_rdlock(struct rwlock *lock)
|
||||
LOCKS_SHARED(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_rwlock_rdlock(&lock->object);
|
||||
}
|
||||
|
||||
static inline void rwlock_wrlock(struct rwlock *lock)
|
||||
LOCKS_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_rwlock_wrlock(&lock->object);
|
||||
}
|
||||
|
||||
static inline void rwlock_unlock(struct rwlock *lock)
|
||||
UNLOCKS(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_rwlock_unlock(&lock->object);
|
||||
}
|
||||
|
||||
// Condition variable that uses the lock annotations.
|
||||
|
||||
struct LOCKABLE cond {
|
||||
pthread_cond_t object;
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
clockid_t clock;
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline void cond_init_monotonic(struct cond *cond) {
|
||||
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
|
||||
pthread_condattr_t attr;
|
||||
pthread_condattr_init(&attr);
|
||||
pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
|
||||
pthread_cond_init(&cond->object, &attr);
|
||||
pthread_condattr_destroy(&attr);
|
||||
#else
|
||||
pthread_cond_init(&cond->object, NULL);
|
||||
#endif
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
cond->clock = CLOCK_MONOTONIC;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void cond_init_realtime(struct cond *cond) {
|
||||
pthread_cond_init(&cond->object, NULL);
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK || \
|
||||
!CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
cond->clock = CLOCK_REALTIME;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void cond_destroy(struct cond *cond) {
|
||||
pthread_cond_destroy(&cond->object);
|
||||
}
|
||||
|
||||
static inline void cond_signal(struct cond *cond) {
|
||||
pthread_cond_signal(&cond->object);
|
||||
}
|
||||
|
||||
static inline bool cond_timedwait(struct cond *cond, struct mutex *lock,
|
||||
uint64_t timeout, bool abstime)
|
||||
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
|
||||
struct timespec ts = {
|
||||
.tv_sec = (time_t)(timeout / 1000000000),
|
||||
.tv_nsec = (long)(timeout % 1000000000),
|
||||
};
|
||||
|
||||
if (abstime) {
|
||||
#if !CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
|
||||
// No native support for sleeping on monotonic clocks. Convert the
|
||||
// timeout to a relative value and then to an absolute value for the
|
||||
// realtime clock.
|
||||
if (cond->clock != CLOCK_REALTIME) {
|
||||
struct timespec ts_monotonic;
|
||||
clock_gettime(cond->clock, &ts_monotonic);
|
||||
ts.tv_sec -= ts_monotonic.tv_sec;
|
||||
ts.tv_nsec -= ts_monotonic.tv_nsec;
|
||||
if (ts.tv_nsec < 0) {
|
||||
ts.tv_nsec += 1000000000;
|
||||
--ts.tv_sec;
|
||||
}
|
||||
|
||||
struct timespec ts_realtime;
|
||||
clock_gettime(CLOCK_REALTIME, &ts_realtime);
|
||||
ts.tv_sec += ts_realtime.tv_sec;
|
||||
ts.tv_nsec += ts_realtime.tv_nsec;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
++ts.tv_sec;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
#if CONFIG_HAS_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP
|
||||
// Implementation supports relative timeouts.
|
||||
int ret =
|
||||
pthread_cond_timedwait_relative_np(&cond->object, &lock->object, &ts);
|
||||
assert((ret == 0 || ret == ETIMEDOUT) &&
|
||||
"pthread_cond_timedwait_relative_np() failed");
|
||||
return ret == ETIMEDOUT;
|
||||
#else
|
||||
// Convert to absolute timeout.
|
||||
struct timespec ts_now;
|
||||
#if CONFIG_HAS_PTHREAD_CONDATTR_SETCLOCK
|
||||
clock_gettime(cond->clock, &ts_now);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME, &ts_now);
|
||||
#endif
|
||||
ts.tv_sec += ts_now.tv_sec;
|
||||
ts.tv_nsec += ts_now.tv_nsec;
|
||||
if (ts.tv_nsec >= 1000000000) {
|
||||
ts.tv_nsec -= 1000000000;
|
||||
++ts.tv_sec;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int ret = pthread_cond_timedwait(&cond->object, &lock->object, &ts);
|
||||
assert((ret == 0 || ret == ETIMEDOUT) && "pthread_cond_timedwait() failed");
|
||||
return ret == ETIMEDOUT;
|
||||
}
|
||||
|
||||
static inline void cond_wait(struct cond *cond, struct mutex *lock)
|
||||
REQUIRES_EXCLUSIVE(*lock) NO_LOCK_ANALYSIS {
|
||||
pthread_cond_wait(&cond->object, &lock->object);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,42 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2015 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef COMMON_LIMITS_H
|
||||
#define COMMON_LIMITS_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#define NUMERIC_MIN(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MIN, signed char \
|
||||
: SCHAR_MIN, unsigned char : 0, short \
|
||||
: SHRT_MIN, unsigned short : 0, int \
|
||||
: INT_MIN, unsigned int : 0, long \
|
||||
: LONG_MIN, unsigned long : 0, long long \
|
||||
: LLONG_MIN, unsigned long long : 0, default \
|
||||
: (void)0)
|
||||
|
||||
#define NUMERIC_MAX(t) \
|
||||
_Generic((t)0, char \
|
||||
: CHAR_MAX, signed char \
|
||||
: SCHAR_MAX, unsigned char \
|
||||
: UCHAR_MAX, short \
|
||||
: SHRT_MAX, unsigned short \
|
||||
: USHRT_MAX, int \
|
||||
: INT_MAX, unsigned int \
|
||||
: UINT_MAX, long \
|
||||
: LONG_MAX, unsigned long \
|
||||
: ULONG_MAX, long long \
|
||||
: LLONG_MAX, unsigned long long \
|
||||
: ULLONG_MAX, default \
|
||||
: (void)0)
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,62 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016-2018 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef POSIX_H
|
||||
#define POSIX_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "locking.h"
|
||||
|
||||
struct fd_entry;
|
||||
struct fd_prestat;
|
||||
struct syscalls;
|
||||
|
||||
struct fd_table {
|
||||
struct rwlock lock;
|
||||
struct fd_entry *entries;
|
||||
size_t size;
|
||||
size_t used;
|
||||
};
|
||||
|
||||
struct fd_prestats {
|
||||
struct rwlock lock;
|
||||
struct fd_prestat *prestats;
|
||||
size_t size;
|
||||
size_t used;
|
||||
};
|
||||
|
||||
struct argv_environ_values {
|
||||
size_t argc;
|
||||
size_t argv_buf_size;
|
||||
char **argv;
|
||||
char *argv_buf;
|
||||
size_t environ_count;
|
||||
size_t environ_buf_size;
|
||||
char **environ;
|
||||
char *environ_buf;
|
||||
};
|
||||
|
||||
void fd_table_init(struct fd_table *);
|
||||
bool fd_table_insert_existing(struct fd_table *, __wasi_fd_t, int);
|
||||
void fd_prestats_init(struct fd_prestats *);
|
||||
bool fd_prestats_insert(struct fd_prestats *, const char *, __wasi_fd_t);
|
||||
bool argv_environ_init(struct argv_environ_values *,
|
||||
const size_t *argv_offsets, size_t argv_offsets_len,
|
||||
const char *argv_buf, size_t argv_buf_len,
|
||||
const size_t *environ_offsets, size_t environ_offsets_len,
|
||||
const char *environ_buf, size_t environ_buf_len);
|
||||
void argv_environ_destroy(struct argv_environ_values *argv_environ);
|
||||
void fd_table_destroy(struct fd_table *ft);
|
||||
void fd_prestats_destroy(struct fd_prestats *pt);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,92 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef QUEUE_H
|
||||
#define QUEUE_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// LIST: Double-linked list.
|
||||
|
||||
#define LIST_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *l_first; \
|
||||
}
|
||||
#define LIST_HEAD_INITIALIZER(head) \
|
||||
{ NULL }
|
||||
|
||||
#define LIST_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *l_next; \
|
||||
struct type **l_prev; \
|
||||
}
|
||||
|
||||
#define LIST_FOREACH(var, head, field) \
|
||||
for ((var) = (head)->l_first; (var) != NULL; (var) = (var)->field.l_next)
|
||||
#define LIST_INIT(head) \
|
||||
do { \
|
||||
(head)->l_first = NULL; \
|
||||
} while (0)
|
||||
#define LIST_INSERT_HEAD(head, element, field) \
|
||||
do { \
|
||||
(element)->field.l_next = (head)->l_first; \
|
||||
if ((head)->l_first != NULL) \
|
||||
(head)->l_first->field.l_prev = &(element)->field.l_next; \
|
||||
(head)->l_first = (element); \
|
||||
(element)->field.l_prev = &(head)->l_first; \
|
||||
} while (0)
|
||||
#define LIST_REMOVE(element, field) \
|
||||
do { \
|
||||
if ((element)->field.l_next != NULL) \
|
||||
(element)->field.l_next->field.l_prev = (element)->field.l_prev; \
|
||||
*(element)->field.l_prev = (element)->field.l_next; \
|
||||
} while (0)
|
||||
|
||||
// TAILQ: Double-linked list with tail pointer.
|
||||
|
||||
#define TAILQ_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *t_first; \
|
||||
struct type **t_last; \
|
||||
}
|
||||
|
||||
#define TAILQ_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *t_next; \
|
||||
struct type **t_prev; \
|
||||
}
|
||||
|
||||
#define TAILQ_EMPTY(head) ((head)->t_first == NULL)
|
||||
#define TAILQ_FIRST(head) ((head)->t_first)
|
||||
#define TAILQ_FOREACH(var, head, field) \
|
||||
for ((var) = (head)->t_first; (var) != NULL; (var) = (var)->field.t_next)
|
||||
#define TAILQ_INIT(head) \
|
||||
do { \
|
||||
(head)->t_first = NULL; \
|
||||
(head)->t_last = &(head)->t_first; \
|
||||
} while (0)
|
||||
#define TAILQ_INSERT_TAIL(head, elm, field) \
|
||||
do { \
|
||||
(elm)->field.t_next = NULL; \
|
||||
(elm)->field.t_prev = (head)->t_last; \
|
||||
*(head)->t_last = (elm); \
|
||||
(head)->t_last = &(elm)->field.t_next; \
|
||||
} while (0)
|
||||
#define TAILQ_REMOVE(head, element, field) \
|
||||
do { \
|
||||
if ((element)->field.t_next != NULL) \
|
||||
(element)->field.t_next->field.t_prev = (element)->field.t_prev; \
|
||||
else \
|
||||
(head)->t_last = (element)->field.t_prev; \
|
||||
*(element)->field.t_prev = (element)->field.t_next; \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,92 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "random.h"
|
||||
|
||||
#if CONFIG_HAS_ARC4RANDOM_BUF
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
arc4random_buf(buf, len);
|
||||
}
|
||||
|
||||
#elif CONFIG_HAS_GETRANDOM
|
||||
|
||||
#include <sys/random.h>
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
for (;;) {
|
||||
ssize_t x = getrandom(buf, len, 0);
|
||||
if (x < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
fprintf(stderr, "getrandom failed: %s", strerror(errno));
|
||||
abort();
|
||||
}
|
||||
if (x == len)
|
||||
return;
|
||||
buf = (void *)((unsigned char *)buf + x);
|
||||
len -= x;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static int urandom;
|
||||
|
||||
static void open_urandom(void) {
|
||||
urandom = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom < 0) {
|
||||
fputs("Failed to open /dev/urandom\n", stderr);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
void random_buf(void *buf, size_t len) {
|
||||
static pthread_once_t open_once = PTHREAD_ONCE_INIT;
|
||||
pthread_once(&open_once, open_urandom);
|
||||
|
||||
if ((size_t)read(urandom, buf, len) != len) {
|
||||
fputs("Short read on /dev/urandom\n", stderr);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Calculates a random number within the range [0, upper - 1] without
|
||||
// any modulo bias.
|
||||
//
|
||||
// The function below repeatedly obtains a random number from
|
||||
// arc4random() until it lies within the range [2^k % upper, 2^k). As
|
||||
// this range has length k * upper, we can safely obtain a number
|
||||
// without any modulo bias.
|
||||
uintmax_t random_uniform(uintmax_t upper) {
|
||||
// Compute 2^k % upper
|
||||
// == (2^k - upper) % upper
|
||||
// == -upper % upper.
|
||||
uintmax_t lower = -upper % upper;
|
||||
for (;;) {
|
||||
uintmax_t value;
|
||||
random_buf(&value, sizeof(value));
|
||||
if (value >= lower)
|
||||
return value % upper;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef RANDOM_H
|
||||
#define RANDOM_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
void random_buf(void *, size_t);
|
||||
uintmax_t random_uniform(uintmax_t);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,47 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef REFCOUNT_H
|
||||
#define REFCOUNT_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdatomic.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "locking.h"
|
||||
|
||||
// Simple reference counter.
|
||||
struct LOCKABLE refcount {
|
||||
atomic_uint count;
|
||||
};
|
||||
|
||||
#define PRODUCES(...) LOCKS_SHARED(__VA_ARGS__) NO_LOCK_ANALYSIS
|
||||
#define CONSUMES(...) UNLOCKS(__VA_ARGS__) NO_LOCK_ANALYSIS
|
||||
|
||||
// Initialize the reference counter.
|
||||
static void refcount_init(struct refcount *r, unsigned int count) PRODUCES(*r) {
|
||||
atomic_init(&r->count, count);
|
||||
}
|
||||
|
||||
// Increment the reference counter.
|
||||
static inline void refcount_acquire(struct refcount *r) PRODUCES(*r) {
|
||||
atomic_fetch_add_explicit(&r->count, 1, memory_order_acquire);
|
||||
}
|
||||
|
||||
// Decrement the reference counter, returning whether the reference
|
||||
// dropped to zero.
|
||||
static inline bool refcount_release(struct refcount *r) CONSUMES(*r) {
|
||||
int old = (int)atomic_fetch_sub_explicit(&r->count, 1, memory_order_release);
|
||||
assert(old != 0 && "Reference count becoming negative");
|
||||
return old == 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,83 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef RIGHTS_H
|
||||
#define RIGHTS_H
|
||||
|
||||
#define RIGHTS_ALL \
|
||||
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
|
||||
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
|
||||
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
|
||||
__WASI_RIGHT_PATH_CREATE_DIRECTORY | __WASI_RIGHT_PATH_CREATE_FILE | \
|
||||
__WASI_RIGHT_PATH_LINK_SOURCE | __WASI_RIGHT_PATH_LINK_TARGET | \
|
||||
__WASI_RIGHT_PATH_OPEN | __WASI_RIGHT_FD_READDIR | \
|
||||
__WASI_RIGHT_PATH_READLINK | __WASI_RIGHT_PATH_RENAME_SOURCE | \
|
||||
__WASI_RIGHT_PATH_RENAME_TARGET | __WASI_RIGHT_PATH_FILESTAT_GET | \
|
||||
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
|
||||
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
|
||||
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
|
||||
__WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
|
||||
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
|
||||
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
|
||||
|
||||
// Block and character device interaction is outside the scope of
|
||||
// CloudABI. Simply allow everything.
|
||||
#define RIGHTS_BLOCK_DEVICE_BASE RIGHTS_ALL
|
||||
#define RIGHTS_BLOCK_DEVICE_INHERITING RIGHTS_ALL
|
||||
#define RIGHTS_CHARACTER_DEVICE_BASE RIGHTS_ALL
|
||||
#define RIGHTS_CHARACTER_DEVICE_INHERITING RIGHTS_ALL
|
||||
|
||||
// Only allow directory operations on directories. Directories can only
|
||||
// yield file descriptors to other directories and files.
|
||||
#define RIGHTS_DIRECTORY_BASE \
|
||||
(__WASI_RIGHT_FD_FDSTAT_SET_FLAGS | __WASI_RIGHT_FD_SYNC | \
|
||||
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_PATH_CREATE_DIRECTORY | \
|
||||
__WASI_RIGHT_PATH_CREATE_FILE | __WASI_RIGHT_PATH_LINK_SOURCE | \
|
||||
__WASI_RIGHT_PATH_LINK_TARGET | __WASI_RIGHT_PATH_OPEN | \
|
||||
__WASI_RIGHT_FD_READDIR | __WASI_RIGHT_PATH_READLINK | \
|
||||
__WASI_RIGHT_PATH_RENAME_SOURCE | __WASI_RIGHT_PATH_RENAME_TARGET | \
|
||||
__WASI_RIGHT_PATH_FILESTAT_GET | \
|
||||
__WASI_RIGHT_PATH_FILESTAT_SET_SIZE | \
|
||||
__WASI_RIGHT_PATH_FILESTAT_SET_TIMES | \
|
||||
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_TIMES | \
|
||||
__WASI_RIGHT_PATH_SYMLINK | __WASI_RIGHT_PATH_UNLINK_FILE | \
|
||||
__WASI_RIGHT_PATH_REMOVE_DIRECTORY | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE)
|
||||
#define RIGHTS_DIRECTORY_INHERITING \
|
||||
(RIGHTS_DIRECTORY_BASE | RIGHTS_REGULAR_FILE_BASE)
|
||||
|
||||
// Operations that apply to regular files.
|
||||
#define RIGHTS_REGULAR_FILE_BASE \
|
||||
(__WASI_RIGHT_FD_DATASYNC | __WASI_RIGHT_FD_READ | \
|
||||
__WASI_RIGHT_FD_SEEK | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_SYNC | __WASI_RIGHT_FD_TELL | __WASI_RIGHT_FD_WRITE | \
|
||||
__WASI_RIGHT_FD_ADVISE | __WASI_RIGHT_FD_ALLOCATE | \
|
||||
__WASI_RIGHT_FD_FILESTAT_GET | __WASI_RIGHT_FD_FILESTAT_SET_SIZE | \
|
||||
__WASI_RIGHT_FD_FILESTAT_SET_TIMES | __WASI_RIGHT_POLL_FD_READWRITE)
|
||||
#define RIGHTS_REGULAR_FILE_INHERITING 0
|
||||
|
||||
// Operations that apply to sockets and socket pairs.
|
||||
#define RIGHTS_SOCKET_BASE \
|
||||
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE | __WASI_RIGHT_SOCK_SHUTDOWN)
|
||||
#define RIGHTS_SOCKET_INHERITING RIGHTS_ALL
|
||||
|
||||
// Operations that apply to TTYs.
|
||||
#define RIGHTS_TTY_BASE \
|
||||
(__WASI_RIGHT_FD_READ | __WASI_RIGHT_FD_FDSTAT_SET_FLAGS | \
|
||||
__WASI_RIGHT_FD_WRITE | __WASI_RIGHT_FD_FILESTAT_GET | \
|
||||
__WASI_RIGHT_POLL_FD_READWRITE)
|
||||
#define RIGHTS_TTY_INHERITING 0
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,17 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef SIGNALS_H
|
||||
#define SIGNALS_H
|
||||
|
||||
void signals_init(void);
|
||||
|
||||
#endif
|
||||
@ -0,0 +1,33 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "str.h"
|
||||
|
||||
char *str_nullterminate(const char *s, size_t len) {
|
||||
// Copy string.
|
||||
char *ret = strndup(s, len);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
|
||||
// Ensure that it contains no null bytes within.
|
||||
if (strlen(ret) != len) {
|
||||
free(ret);
|
||||
errno = EILSEQ;
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -0,0 +1,19 @@
|
||||
// Part of the Wasmtime Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://github.com/CraneStation/wasmtime/blob/master/LICENSE for license information.
|
||||
//
|
||||
// Significant parts of this file are derived from cloudabi-utils. See
|
||||
// https://github.com/CraneStation/wasmtime/blob/master/lib/wasi/sandboxed-system-primitives/src/LICENSE
|
||||
// for license information.
|
||||
//
|
||||
// The upstream file contains the following copyright notice:
|
||||
//
|
||||
// Copyright (c) 2016 Nuxi, https://nuxi.nl/
|
||||
|
||||
#ifndef STR_H
|
||||
#define STR_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
char *str_nullterminate(const char *, size_t);
|
||||
|
||||
#endif
|
||||
12
core/iwasm/runtime/wasmtime-wasi-c/wasi.cmake
Normal file
12
core/iwasm/runtime/wasmtime-wasi-c/wasi.cmake
Normal file
@ -0,0 +1,12 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASI_LIB_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
if (WASM_ENABLE_WASI EQUAL 1)
|
||||
include_directories(${WASI_LIB_DIR}/sandboxed-system-primitives/include
|
||||
${WASI_LIB_DIR}/sandboxed-system-primitives/src
|
||||
)
|
||||
file (GLOB_RECURSE source_all ${WASI_LIB_DIR}/sandboxed-system-primitives/*.c )
|
||||
set (WASI_LIB_SOURCE ${source_all})
|
||||
endif ()
|
||||
@ -1,38 +0,0 @@
|
||||
Contiki is licensed under the 3-clause BSD license. This license gives
|
||||
everyone the right to use and distribute the code, either in binary or
|
||||
source code format, as long as the copyright license is retained in
|
||||
the source code.
|
||||
|
||||
The copyright for different parts of the code is held by different
|
||||
people and organizations, but the code is licensed under the same type
|
||||
of license. The license text is:
|
||||
|
||||
* Copyright (c) (Year), (Name of copyright holder)
|
||||
* 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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
|
||||
* COPYRIGHT HOLDER 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.
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
COAP_ROOT=${ZEPHYR_BASE}/subsys/aee/Beihai/runtime/utils/coap
|
||||
subdir-ccflags-y += -I${COAP_ROOT}/er-coap -I${COAP_ROOT}/extension
|
||||
|
||||
obj-y += er-coap/
|
||||
obj-y += extension/
|
||||
30
core/shared-lib/coap/er-coap/LICENSE.md
Normal file
30
core/shared-lib/coap/er-coap/LICENSE.md
Normal file
@ -0,0 +1,30 @@
|
||||
Copyright (c) (Year), (Name of copyright holder)
|
||||
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. Neither the name of the copyright holder 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 COPYRIGHT HOLDERS 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
|
||||
COPYRIGHT HOLDER 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.
|
||||
@ -1,4 +0,0 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
obj-y += er-coap.o
|
||||
192
core/shared-lib/coap/er-coap/coap-constants.h
Normal file
192
core/shared-lib/coap/er-coap/coap-constants.h
Normal file
@ -0,0 +1,192 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Collection of constants specified in the CoAP standard.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup coap
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifndef COAP_CONSTANTS_H_
|
||||
#define COAP_CONSTANTS_H_
|
||||
|
||||
#define COAP_DEFAULT_PORT 5683
|
||||
#define COAP_DEFAULT_SECURE_PORT 5684
|
||||
|
||||
#define COAP_DEFAULT_MAX_AGE 60
|
||||
#define COAP_RESPONSE_TIMEOUT 3
|
||||
#define COAP_RESPONSE_RANDOM_FACTOR 1.5
|
||||
#define COAP_MAX_RETRANSMIT 4
|
||||
|
||||
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
|
||||
#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
|
||||
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
|
||||
|
||||
#define COAP_HEADER_VERSION_MASK 0xC0
|
||||
#define COAP_HEADER_VERSION_POSITION 6
|
||||
#define COAP_HEADER_TYPE_MASK 0x30
|
||||
#define COAP_HEADER_TYPE_POSITION 4
|
||||
#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
|
||||
#define COAP_HEADER_TOKEN_LEN_POSITION 0
|
||||
|
||||
#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
|
||||
#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
|
||||
|
||||
/* CoAP message types */
|
||||
typedef enum {
|
||||
COAP_TYPE_CON, /* confirmables */
|
||||
COAP_TYPE_NON, /* non-confirmables */
|
||||
COAP_TYPE_ACK, /* acknowledgements */
|
||||
COAP_TYPE_RST /* reset */
|
||||
} coap_message_type_t;
|
||||
|
||||
/* CoAP request method codes */
|
||||
typedef enum {
|
||||
COAP_GET = 1,
|
||||
COAP_POST,
|
||||
COAP_PUT,
|
||||
COAP_DELETE
|
||||
} coap_method_t;
|
||||
|
||||
/* CoAP response codes */
|
||||
typedef enum {
|
||||
NO_ERROR = 0,
|
||||
|
||||
CREATED_2_01 = 65, /* CREATED */
|
||||
DELETED_2_02 = 66, /* DELETED */
|
||||
VALID_2_03 = 67, /* NOT_MODIFIED */
|
||||
CHANGED_2_04 = 68, /* CHANGED */
|
||||
CONTENT_2_05 = 69, /* OK */
|
||||
CONTINUE_2_31 = 95, /* CONTINUE */
|
||||
|
||||
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
|
||||
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
|
||||
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
|
||||
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
|
||||
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
|
||||
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
|
||||
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
|
||||
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
|
||||
|
||||
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
|
||||
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
|
||||
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
|
||||
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
|
||||
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
|
||||
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
|
||||
|
||||
/* Erbium errors */
|
||||
MEMORY_ALLOCATION_ERROR = 192,
|
||||
PACKET_SERIALIZATION_ERROR,
|
||||
|
||||
/* Erbium hooks */
|
||||
MANUAL_RESPONSE,
|
||||
PING_RESPONSE
|
||||
} coap_status_t;
|
||||
|
||||
/* CoAP header option numbers */
|
||||
typedef enum {
|
||||
COAP_OPTION_IF_MATCH = 1, /* 0-8 B */
|
||||
COAP_OPTION_URI_HOST = 3, /* 1-255 B */
|
||||
COAP_OPTION_ETAG = 4, /* 1-8 B */
|
||||
COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */
|
||||
COAP_OPTION_OBSERVE = 6, /* 0-3 B */
|
||||
COAP_OPTION_URI_PORT = 7, /* 0-2 B */
|
||||
COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */
|
||||
COAP_OPTION_URI_PATH = 11, /* 0-255 B */
|
||||
COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
|
||||
COAP_OPTION_MAX_AGE = 14, /* 0-4 B */
|
||||
COAP_OPTION_URI_QUERY = 15, /* 0-255 B */
|
||||
COAP_OPTION_ACCEPT = 17, /* 0-2 B */
|
||||
COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
|
||||
COAP_OPTION_BLOCK2 = 23, /* 1-3 B */
|
||||
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
|
||||
COAP_OPTION_SIZE2 = 28, /* 0-4 B */
|
||||
COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */
|
||||
COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */
|
||||
COAP_OPTION_SIZE1 = 60, /* 0-4 B */
|
||||
} coap_option_t;
|
||||
|
||||
/* CoAP Content-Formats */
|
||||
typedef enum {
|
||||
TEXT_PLAIN = 0,
|
||||
TEXT_XML = 1,
|
||||
TEXT_CSV = 2,
|
||||
TEXT_HTML = 3,
|
||||
IMAGE_GIF = 21,
|
||||
IMAGE_JPEG = 22,
|
||||
IMAGE_PNG = 23,
|
||||
IMAGE_TIFF = 24,
|
||||
AUDIO_RAW = 25,
|
||||
VIDEO_RAW = 26,
|
||||
APPLICATION_LINK_FORMAT = 40,
|
||||
APPLICATION_XML = 41,
|
||||
APPLICATION_OCTET_STREAM = 42,
|
||||
APPLICATION_RDF_XML = 43,
|
||||
APPLICATION_SOAP_XML = 44,
|
||||
APPLICATION_ATOM_XML = 45,
|
||||
APPLICATION_XMPP_XML = 46,
|
||||
APPLICATION_EXI = 47,
|
||||
APPLICATION_FASTINFOSET = 48,
|
||||
APPLICATION_SOAP_FASTINFOSET = 49,
|
||||
APPLICATION_JSON = 50,
|
||||
APPLICATION_X_OBIX_BINARY = 51
|
||||
} coap_content_format_t;
|
||||
|
||||
/**
|
||||
* Resource flags for allowed methods and special functionalities.
|
||||
*/
|
||||
typedef enum {
|
||||
NO_FLAGS = 0,
|
||||
|
||||
/* methods to handle */
|
||||
METHOD_GET = (1 << 0),
|
||||
METHOD_POST = (1 << 1),
|
||||
METHOD_PUT = (1 << 2),
|
||||
METHOD_DELETE = (1 << 3),
|
||||
|
||||
/* special flags */
|
||||
HAS_SUB_RESOURCES = (1 << 4),
|
||||
IS_SEPARATE = (1 << 5),
|
||||
IS_OBSERVABLE = (1 << 6),
|
||||
IS_PERIODIC = (1 << 7)
|
||||
} coap_resource_flags_t;
|
||||
|
||||
#endif /* COAP_CONSTANTS_H_ */
|
||||
/** @} */
|
||||
@ -1,75 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Collection of default configuration values.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_CONF_H_
|
||||
#define ER_COAP_CONF_H_
|
||||
|
||||
/* Features that can be disabled to achieve smaller memory footprint */
|
||||
#define COAP_LINK_FORMAT_FILTERING 0
|
||||
#define COAP_PROXY_OPTION_PROCESSING 0
|
||||
|
||||
/* Listening port for the CoAP REST Engine */
|
||||
#ifndef COAP_SERVER_PORT
|
||||
#define COAP_SERVER_PORT COAP_DEFAULT_PORT
|
||||
#endif
|
||||
|
||||
/* The number of concurrent messages that can be stored for retransmission in the transaction layer. */
|
||||
#ifndef COAP_MAX_OPEN_TRANSACTIONS
|
||||
#define COAP_MAX_OPEN_TRANSACTIONS 4
|
||||
#endif /* COAP_MAX_OPEN_TRANSACTIONS */
|
||||
|
||||
/* Maximum number of failed request attempts before action */
|
||||
#ifndef COAP_MAX_ATTEMPTS
|
||||
#define COAP_MAX_ATTEMPTS 4
|
||||
#endif /* COAP_MAX_ATTEMPTS */
|
||||
|
||||
/* Conservative size limit, as not all options have to be set at the same time. Check when Proxy-Uri option is used */
|
||||
#ifndef COAP_MAX_HEADER_SIZE /* Hdr CoF If-Match Obs Blo strings */
|
||||
#define COAP_MAX_HEADER_SIZE 512
|
||||
//(4 + COAP_TOKEN_LEN + 3 + 1 + COAP_ETAG_LEN + 4 + 4 + 30) /* 65 */
|
||||
#endif /* COAP_MAX_HEADER_SIZE */
|
||||
|
||||
/* Number of observer slots (each takes abot xxx bytes) */
|
||||
#ifndef COAP_MAX_OBSERVERS
|
||||
#define COAP_MAX_OBSERVERS COAP_MAX_OPEN_TRANSACTIONS - 1
|
||||
#endif /* COAP_MAX_OBSERVERS */
|
||||
|
||||
/* Interval in notifies in which NON notifies are changed to CON notifies to check client. */
|
||||
#define COAP_OBSERVE_REFRESH_INTERVAL 20
|
||||
|
||||
#endif /* ER_COAP_CONF_H_ */
|
||||
@ -1,161 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Collection of constants specified in the CoAP standard.
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_CONSTANTS_H_
|
||||
#define ER_COAP_CONSTANTS_H_
|
||||
|
||||
#define COAP_DEFAULT_PORT 5683
|
||||
|
||||
#define COAP_DEFAULT_MAX_AGE 60
|
||||
#define COAP_RESPONSE_TIMEOUT 3
|
||||
#define COAP_RESPONSE_RANDOM_FACTOR 1.5
|
||||
#define COAP_MAX_RETRANSMIT 4
|
||||
|
||||
#define COAP_HEADER_LEN 4 /* | version:0x03 type:0x0C tkl:0xF0 | code | mid:0x00FF | mid:0xFF00 | */
|
||||
#define COAP_TOKEN_LEN 8 /* The maximum number of bytes for the Token */
|
||||
#define COAP_ETAG_LEN 8 /* The maximum number of bytes for the ETag */
|
||||
|
||||
#define COAP_HEADER_VERSION_MASK 0xC0
|
||||
#define COAP_HEADER_VERSION_POSITION 6
|
||||
#define COAP_HEADER_TYPE_MASK 0x30
|
||||
#define COAP_HEADER_TYPE_POSITION 4
|
||||
#define COAP_HEADER_TOKEN_LEN_MASK 0x0F
|
||||
#define COAP_HEADER_TOKEN_LEN_POSITION 0
|
||||
|
||||
#define COAP_HEADER_OPTION_DELTA_MASK 0xF0
|
||||
#define COAP_HEADER_OPTION_SHORT_LENGTH_MASK 0x0F
|
||||
|
||||
/* CoAP message types */
|
||||
typedef enum {
|
||||
COAP_TYPE_CON, /* confirmables */
|
||||
COAP_TYPE_NON, /* non-confirmables */
|
||||
COAP_TYPE_ACK, /* acknowledgements */
|
||||
COAP_TYPE_RST /* reset */
|
||||
} coap_message_type_t;
|
||||
|
||||
/* CoAP request method codes */
|
||||
typedef enum {
|
||||
COAP_GET = 1, COAP_POST, COAP_PUT, COAP_DELETE
|
||||
} coap_method_t;
|
||||
|
||||
/* CoAP response codes */
|
||||
typedef enum {
|
||||
NO_ERROR = 0,
|
||||
|
||||
CREATED_2_01 = 65, /* CREATED */
|
||||
DELETED_2_02 = 66, /* DELETED */
|
||||
VALID_2_03 = 67, /* NOT_MODIFIED */
|
||||
CHANGED_2_04 = 68, /* CHANGED */
|
||||
CONTENT_2_05 = 69, /* OK */
|
||||
CONTINUE_2_31 = 95, /* CONTINUE */
|
||||
|
||||
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
|
||||
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
|
||||
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
|
||||
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
|
||||
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
|
||||
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
|
||||
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
|
||||
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
|
||||
|
||||
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
|
||||
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
|
||||
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
|
||||
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
|
||||
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
|
||||
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
|
||||
|
||||
/* Erbium errors */
|
||||
MEMORY_ALLOCATION_ERROR = 192, PACKET_SERIALIZATION_ERROR,
|
||||
|
||||
/* Erbium hooks */
|
||||
MANUAL_RESPONSE, PING_RESPONSE
|
||||
} coap_status_t;
|
||||
|
||||
/* CoAP header option numbers */
|
||||
typedef enum {
|
||||
COAP_OPTION_IF_MATCH = 1, /* 0-8 B */
|
||||
COAP_OPTION_URI_HOST = 3, /* 1-255 B */
|
||||
COAP_OPTION_ETAG = 4, /* 1-8 B */
|
||||
COAP_OPTION_IF_NONE_MATCH = 5, /* 0 B */
|
||||
COAP_OPTION_OBSERVE = 6, /* 0-3 B */
|
||||
COAP_OPTION_URI_PORT = 7, /* 0-2 B */
|
||||
COAP_OPTION_LOCATION_PATH = 8, /* 0-255 B */
|
||||
COAP_OPTION_URI_PATH = 11, /* 0-255 B */
|
||||
COAP_OPTION_CONTENT_FORMAT = 12, /* 0-2 B */
|
||||
COAP_OPTION_MAX_AGE = 14, /* 0-4 B */
|
||||
COAP_OPTION_URI_QUERY = 15, /* 0-255 B */
|
||||
COAP_OPTION_ACCEPT = 17, /* 0-2 B */
|
||||
COAP_OPTION_LOCATION_QUERY = 20, /* 0-255 B */
|
||||
COAP_OPTION_BLOCK2 = 23, /* 1-3 B */
|
||||
COAP_OPTION_BLOCK1 = 27, /* 1-3 B */
|
||||
COAP_OPTION_SIZE2 = 28, /* 0-4 B */
|
||||
COAP_OPTION_PROXY_URI = 35, /* 1-1034 B */
|
||||
COAP_OPTION_PROXY_SCHEME = 39, /* 1-255 B */
|
||||
COAP_OPTION_SIZE1 = 60, /* 0-4 B */
|
||||
} coap_option_t;
|
||||
|
||||
/* CoAP Content-Formats */
|
||||
typedef enum {
|
||||
TEXT_PLAIN = 0,
|
||||
TEXT_XML = 1,
|
||||
TEXT_CSV = 2,
|
||||
TEXT_HTML = 3,
|
||||
IMAGE_GIF = 21,
|
||||
IMAGE_JPEG = 22,
|
||||
IMAGE_PNG = 23,
|
||||
IMAGE_TIFF = 24,
|
||||
AUDIO_RAW = 25,
|
||||
VIDEO_RAW = 26,
|
||||
APPLICATION_LINK_FORMAT = 40,
|
||||
APPLICATION_XML = 41,
|
||||
APPLICATION_OCTET_STREAM = 42,
|
||||
APPLICATION_RDF_XML = 43,
|
||||
APPLICATION_SOAP_XML = 44,
|
||||
APPLICATION_ATOM_XML = 45,
|
||||
APPLICATION_XMPP_XML = 46,
|
||||
APPLICATION_EXI = 47,
|
||||
APPLICATION_FASTINFOSET = 48,
|
||||
APPLICATION_SOAP_FASTINFOSET = 49,
|
||||
APPLICATION_JSON = 50,
|
||||
APPLICATION_X_OBIX_BINARY = 51
|
||||
} coap_content_format_t;
|
||||
|
||||
#endif /* ER_COAP_CONSTANTS_H_ */
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,370 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013, Institute for Pervasive Computing, ETH Zurich
|
||||
* 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
|
||||
*
|
||||
* This file is part of the Contiki operating system.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* An implementation of the Constrained Application Protocol (RFC).
|
||||
* \author
|
||||
* Matthias Kovatsch <kovatsch@inf.ethz.ch>
|
||||
*/
|
||||
|
||||
#ifndef ER_COAP_H_
|
||||
#define ER_COAP_H_
|
||||
|
||||
#include "../extension/coap_platforms.h"
|
||||
#include <stddef.h> /* for size_t */
|
||||
#include <stdint.h>
|
||||
//#include "contiki-net.h"
|
||||
#include "er-coap-constants.h"
|
||||
#include "er-coap-conf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* sanity check for configured values */
|
||||
#define COAP_MAX_PACKET_SIZE (COAP_MAX_HEADER_SIZE + REST_MAX_CHUNK_SIZE)
|
||||
/*#if COAP_MAX_PACKET_SIZE > (UIP_BUFSIZE - UIP_IPH_LEN - UIP_UDPH_LEN)
|
||||
#error "UIP_CONF_BUFFER_SIZE too small for REST_MAX_CHUNK_SIZE"
|
||||
#endif
|
||||
*/
|
||||
|
||||
/* ------------------------------------------------------ */
|
||||
/* ------ section added by the coap request --------- */
|
||||
/* ------------------------------------------------------ */
|
||||
|
||||
//typedef int (*restful_response_handler)(void *response,void *data);
|
||||
#define RX_TIMEOUT (-1)
|
||||
typedef int (*Tx_Data)(void * coap_ctx, const uip_ipaddr_t *dst_addr, void *buf, int len);
|
||||
typedef int (*Rx_Data) (void * coap_ctx, void *buf, int len, int timeout);
|
||||
typedef int (*Request_Handler) (void * coap_ctx, void *);
|
||||
|
||||
typedef int (*CoAP_Res_Handler) (void * request, void * response, char **out_payload, int * payload_len);
|
||||
|
||||
typedef struct _coap_resource_handler
|
||||
{
|
||||
struct _coap_resource_handler * next;
|
||||
char * url;
|
||||
CoAP_Res_Handler get_handler;
|
||||
CoAP_Res_Handler put_handler;
|
||||
CoAP_Res_Handler post_handler;
|
||||
CoAP_Res_Handler other_handler; // create | delete
|
||||
}coap_resource_handler_t;
|
||||
|
||||
|
||||
|
||||
typedef struct res_block_state
|
||||
{
|
||||
struct res_block_state * next;
|
||||
char * url;
|
||||
void * buffer;
|
||||
int buffer_size;
|
||||
uint32_t block_num;
|
||||
uint16_t block_size;
|
||||
uint16_t content_fmt;
|
||||
uint32_t last_access;
|
||||
uint8_t is_get;
|
||||
} res_block_state_t;
|
||||
|
||||
|
||||
typedef struct peer_block_state
|
||||
{
|
||||
struct peer_block_state * next;
|
||||
struct net_addr_coap peer_addr;
|
||||
res_block_state_t * list;
|
||||
}peer_block_state_t;
|
||||
|
||||
|
||||
typedef struct coap_context {
|
||||
uint8_t * buf;
|
||||
uint32_t buf_len; // the data length
|
||||
uint32_t buf_size; // the malloced buffer size
|
||||
|
||||
struct net_addr_coap my_addr;
|
||||
|
||||
// the address associated with current buffer
|
||||
struct net_addr_coap src_addr;
|
||||
|
||||
uint8_t status;
|
||||
uint8_t is_used;
|
||||
uint8_t response_on_not_found;
|
||||
uint16_t default_retrans_cnt;
|
||||
uint32_t default_retrans_ms;
|
||||
|
||||
Tx_Data tx_data;
|
||||
Rx_Data rx_data;
|
||||
|
||||
int socket;
|
||||
char * user_data;
|
||||
|
||||
peer_block_state_t * blockwise_list;
|
||||
coap_resource_handler_t * resource_handlers;
|
||||
|
||||
void * transactions;
|
||||
void * transaction_lock;
|
||||
uint32_t last_checktime;
|
||||
|
||||
void * request_handler;
|
||||
|
||||
#ifdef WITH_DTLS
|
||||
struct dtls_context_t *dtls_context;
|
||||
dtls_handler_t dtls_handler;
|
||||
struct process *process;
|
||||
#endif /* WITH_DTLS */
|
||||
|
||||
} coap_context_t;
|
||||
|
||||
int add_resource_handler(coap_context_t * coap_ctx, coap_resource_handler_t * handler);
|
||||
|
||||
|
||||
// coap_context_t * coap_context_new(uip_ipaddr_t *my_addr, uint16_t my_port); //CANNOTBUILD
|
||||
void coap_context_close(coap_context_t *coap_ctx);
|
||||
void coap_ctx_send(coap_context_t *coap_ctx, uint8_t *data,
|
||||
uint16_t length);
|
||||
|
||||
/* ---------------- end of section ------------------ */
|
||||
|
||||
|
||||
/* use Erbium CoAP for the REST Engine. Must come before include of rest-engine.h. */
|
||||
//#define REST coap_rest_implementation
|
||||
//#include "rest-engine.h"
|
||||
|
||||
/* REST_MAX_CHUNK_SIZE can be different from 2^x so we need to get next lower 2^x for COAP_MAX_BLOCK_SIZE */
|
||||
#ifndef COAP_MAX_BLOCK_SIZE
|
||||
#define COAP_MAX_BLOCK_SIZE (REST_MAX_CHUNK_SIZE < 32 ? 16 : \
|
||||
(REST_MAX_CHUNK_SIZE < 64 ? 32 : \
|
||||
(REST_MAX_CHUNK_SIZE < 128 ? 64 : \
|
||||
(REST_MAX_CHUNK_SIZE < 256 ? 128 : \
|
||||
(REST_MAX_CHUNK_SIZE < 512 ? 256 : \
|
||||
(REST_MAX_CHUNK_SIZE < 1024 ? 512 : \
|
||||
(REST_MAX_CHUNK_SIZE < 2048 ? 1024 : 2048)))))))
|
||||
#endif /* COAP_MAX_BLOCK_SIZE */
|
||||
|
||||
/* direct access into the buffer */
|
||||
#define UIP_IP_BUF ((struct uip_ip_hdr *)&uip_buf[UIP_LLH_LEN])
|
||||
#ifdef NETSTACK_CONF_WITH_IPV6
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[uip_l2_l3_hdr_len])
|
||||
#else
|
||||
#define UIP_UDP_BUF ((struct uip_udp_hdr *)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN])
|
||||
#endif
|
||||
|
||||
/* bitmap for set options */
|
||||
enum { OPTION_MAP_SIZE = sizeof(uint8_t) * 8 };
|
||||
|
||||
#define SET_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] |= 1 << (opt % OPTION_MAP_SIZE))
|
||||
#define IS_OPTION(packet, opt) ((packet)->options[opt / OPTION_MAP_SIZE] & (1 << (opt % OPTION_MAP_SIZE)))
|
||||
|
||||
/* parsed message struct */
|
||||
typedef struct {
|
||||
uint8_t *buffer; /* pointer to CoAP header / incoming packet buffer / memory to serialize packet */
|
||||
|
||||
uint8_t version;
|
||||
coap_message_type_t type;
|
||||
uint8_t code;
|
||||
uint16_t mid;
|
||||
|
||||
uint8_t token_len;
|
||||
uint8_t token[COAP_TOKEN_LEN];
|
||||
|
||||
uint8_t options[COAP_OPTION_SIZE1 / OPTION_MAP_SIZE + 1]; /* bitmap to check if option is set */
|
||||
|
||||
coap_content_format_t content_format; /* parse options once and store; allows setting options in random order */
|
||||
uint32_t max_age;
|
||||
uint8_t etag_len;
|
||||
uint8_t etag[COAP_ETAG_LEN];
|
||||
size_t proxy_uri_len;
|
||||
const char *proxy_uri;
|
||||
size_t proxy_scheme_len;
|
||||
const char *proxy_scheme;
|
||||
size_t uri_host_len;
|
||||
const char *uri_host;
|
||||
size_t location_path_len;
|
||||
const char *location_path;
|
||||
uint16_t uri_port;
|
||||
size_t location_query_len;
|
||||
const char *location_query;
|
||||
size_t uri_path_len;
|
||||
const char *uri_path;
|
||||
int32_t observe;
|
||||
coap_content_format_t accept;
|
||||
uint8_t if_match_len;
|
||||
uint8_t if_match[COAP_ETAG_LEN];
|
||||
uint32_t block2_num;
|
||||
uint8_t block2_more;
|
||||
uint32_t block2_size;
|
||||
uint32_t block2_offset;
|
||||
uint32_t block1_num;
|
||||
uint8_t block1_more;
|
||||
uint32_t block1_size;
|
||||
uint32_t block1_offset;
|
||||
uint32_t size2;
|
||||
uint32_t size1;
|
||||
size_t uri_query_len;
|
||||
const char *uri_query;
|
||||
uint8_t if_none_match;
|
||||
|
||||
uint32_t payload_len;
|
||||
uint8_t *payload;
|
||||
} coap_packet_t;
|
||||
|
||||
/* option format serialization */
|
||||
#define COAP_SERIALIZE_INT_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " [%u]\n", coap_pkt->field); \
|
||||
option += coap_serialize_int_option(number, current_number, option, coap_pkt->field); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BYTE_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n", coap_pkt->field##_len, \
|
||||
coap_pkt->field[0], \
|
||||
coap_pkt->field[1], \
|
||||
coap_pkt->field[2], \
|
||||
coap_pkt->field[3], \
|
||||
coap_pkt->field[4], \
|
||||
coap_pkt->field[5], \
|
||||
coap_pkt->field[6], \
|
||||
coap_pkt->field[7] \
|
||||
); /* FIXME always prints 8 bytes */ \
|
||||
option += coap_serialize_array_option(number, current_number, option, coap_pkt->field, coap_pkt->field##_len, '\0'); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_STRING_OPTION(number, field, splitter, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) { \
|
||||
PRINTF(text " [%.*s]\n", coap_pkt->field##_len, coap_pkt->field); \
|
||||
option += coap_serialize_array_option(number, current_number, option, (uint8_t *)coap_pkt->field, coap_pkt->field##_len, splitter); \
|
||||
current_number = number; \
|
||||
}
|
||||
#define COAP_SERIALIZE_BLOCK_OPTION(number, field, text) \
|
||||
if(IS_OPTION(coap_pkt, number)) \
|
||||
{ \
|
||||
PRINTF(text " [%lu%s (%u B/blk)]\n", coap_pkt->field##_num, coap_pkt->field##_more ? "+" : "", coap_pkt->field##_size); \
|
||||
uint32_t block = coap_pkt->field##_num << 4; \
|
||||
if(coap_pkt->field##_more) { block |= 0x8; } \
|
||||
block |= 0xF & coap_log_2(coap_pkt->field##_size / 16); \
|
||||
PRINTF(text " encoded: 0x%lX\n", block); \
|
||||
option += coap_serialize_int_option(number, current_number, option, block); \
|
||||
current_number = number; \
|
||||
}
|
||||
|
||||
/* to store error code and human-readable payload */
|
||||
extern coap_status_t erbium_status_code;
|
||||
extern char *coap_error_message;
|
||||
|
||||
void coap_init_connection(uint16_t port);
|
||||
uint16_t coap_get_mid(void);
|
||||
|
||||
void coap_init_message(void *packet, coap_message_type_t type, uint8_t code,
|
||||
uint16_t mid);
|
||||
size_t coap_serialize_message(void *packet, uint8_t *buffer);
|
||||
void coap_send_message(coap_context_t*, uip_ipaddr_t *addr, uint16_t port, uint8_t *data,
|
||||
uint16_t length);
|
||||
coap_status_t coap_parse_message(void *request, uint8_t *data,
|
||||
uint16_t data_len);
|
||||
|
||||
int coap_get_query_variable(void *packet, const char *name,
|
||||
const char **output);
|
||||
int coap_get_post_variable(void *packet, const char *name,
|
||||
const char **output);
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
int coap_set_status_code(void *packet, unsigned int code);
|
||||
|
||||
int coap_set_token(void *packet, const uint8_t *token, size_t token_len);
|
||||
|
||||
int coap_get_header_content_format(void *packet, unsigned int *format);
|
||||
int coap_set_header_content_format(void *packet, unsigned int format);
|
||||
|
||||
int coap_get_header_accept(void *packet, unsigned int *accept);
|
||||
int coap_set_header_accept(void *packet, unsigned int accept);
|
||||
|
||||
int coap_get_header_max_age(void *packet, uint32_t *age);
|
||||
int coap_set_header_max_age(void *packet, uint32_t age);
|
||||
|
||||
int coap_get_header_etag(void *packet, const uint8_t **etag);
|
||||
int coap_set_header_etag(void *packet, const uint8_t *etag, size_t etag_len);
|
||||
|
||||
int coap_get_header_if_match(void *packet, const uint8_t **etag);
|
||||
int coap_set_header_if_match(void *packet, const uint8_t *etag,
|
||||
size_t etag_len);
|
||||
|
||||
int coap_get_header_if_none_match(void *packet);
|
||||
int coap_set_header_if_none_match(void *packet);
|
||||
|
||||
int coap_get_header_proxy_uri(void *packet, const char **uri); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_proxy_uri(void *packet, const char *uri);
|
||||
|
||||
int coap_get_header_proxy_scheme(void *packet, const char **scheme); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_proxy_scheme(void *packet, const char *scheme);
|
||||
|
||||
int coap_get_header_uri_host(void *packet, const char **host); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_uri_host(void *packet, const char *host);
|
||||
|
||||
int coap_get_header_uri_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_uri_path(void *packet, const char *path);
|
||||
|
||||
int coap_get_header_uri_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_uri_query(void *packet, const char *query);
|
||||
|
||||
int coap_get_header_location_path(void *packet, const char **path); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_location_path(void *packet, const char *path); /* also splits optional query into Location-Query option. */
|
||||
|
||||
int coap_get_header_location_query(void *packet, const char **query); /* in-place string might not be 0-terminated. */
|
||||
int coap_set_header_location_query(void *packet, const char *query);
|
||||
|
||||
int coap_get_header_observe(void *packet, uint32_t *observe);
|
||||
int coap_set_header_observe(void *packet, uint32_t observe);
|
||||
|
||||
int coap_get_header_block2(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint32_t *size, uint32_t *offset);
|
||||
int coap_set_header_block2(void *packet, uint32_t num, uint8_t more,
|
||||
uint32_t size);
|
||||
|
||||
int coap_get_header_block1(void *packet, uint32_t *num, uint8_t *more,
|
||||
uint16_t *size, uint32_t *offset);
|
||||
int coap_set_header_block1(void *packet, uint32_t num, uint8_t more,
|
||||
uint16_t size);
|
||||
|
||||
int coap_get_header_size2(void *packet, uint32_t *size);
|
||||
int coap_set_header_size2(void *packet, uint32_t size);
|
||||
|
||||
int coap_get_header_size1(void *packet, uint32_t *size);
|
||||
int coap_set_header_size1(void *packet, uint32_t size);
|
||||
|
||||
int coap_get_payload(void *packet, const uint8_t **payload);
|
||||
int coap_set_payload(void *packet, const void *payload, size_t length);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ER_COAP_H_ */
|
||||
@ -1,4 +0,0 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
obj-y += coap_over_tcp.o
|
||||
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "coap_ext.h"
|
||||
|
||||
char * coap_get_full_url_alloc(coap_packet_t * request)
|
||||
{
|
||||
const char *url = NULL;
|
||||
const char * query = NULL;
|
||||
int url_len = coap_get_header_uri_path(request, &url);
|
||||
int query_len = coap_get_header_uri_query(request, &query);
|
||||
|
||||
if (url_len == 0)
|
||||
return NULL;
|
||||
|
||||
char * url_alloc = (char*) bh_malloc(url_len + 1 + query_len + 1);
|
||||
memcpy(url_alloc, url, url_len);
|
||||
url_alloc[url_len] = 0;
|
||||
|
||||
// make the url looks like /abc?e=f
|
||||
if (query_len != 0) {
|
||||
strcat(url_alloc, "&");
|
||||
memcpy(url_alloc + strlen(url_alloc), query, query_len);
|
||||
url_alloc[url_len + 1 + query_len] = 0;
|
||||
}
|
||||
|
||||
return url_alloc;
|
||||
}
|
||||
|
||||
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet)
|
||||
{
|
||||
coap_init_message(packet, COAP_TYPE_NON, req->action, req->mid);
|
||||
coap_set_token(packet, (uint8_t *) &req->mid, sizeof(req->mid));
|
||||
coap_set_header_content_format(packet, req->fmt);
|
||||
|
||||
coap_set_header_uri_path(packet, req->url);
|
||||
|
||||
coap_set_payload(packet, req->payload, req->payload_len);
|
||||
|
||||
packet->mid = req->mid;
|
||||
}
|
||||
|
||||
void convert_response_to_coap_packet(response_t * response,
|
||||
coap_packet_t * packet)
|
||||
{
|
||||
coap_init_message(packet, COAP_TYPE_NON, response->status, response->mid);
|
||||
coap_set_token(packet, (uint8_t *) &response->mid, sizeof(response->mid));
|
||||
coap_set_header_content_format(packet, response->fmt);
|
||||
coap_set_payload(packet, response->payload, response->payload_len);
|
||||
|
||||
packet->mid = response->mid;
|
||||
}
|
||||
|
||||
// return: the length of url.
|
||||
// note: the url is probably not end with 0 due to coap packing design.
|
||||
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request)
|
||||
{
|
||||
const char *url = NULL;
|
||||
int url_len = coap_get_header_uri_path(packet, &url);
|
||||
|
||||
memset(request, 0, sizeof(*request));
|
||||
|
||||
request->action = packet->code;
|
||||
request->fmt = packet->content_format;
|
||||
if (packet->token_len == 4) {
|
||||
request->mid = *((unsigned long *) packet->token);
|
||||
} else {
|
||||
request->mid = packet->mid;
|
||||
}
|
||||
request->payload = packet->payload;
|
||||
request->payload_len = packet->payload_len;
|
||||
request->url = (char *)url;
|
||||
return url_len;
|
||||
}
|
||||
|
||||
void convert_coap_packet_to_response(coap_packet_t *packet,
|
||||
response_t *response)
|
||||
{
|
||||
memset(response, 0, sizeof(*response));
|
||||
|
||||
response->status = packet->code;
|
||||
response->fmt = packet->content_format;
|
||||
if (packet->token_len == 4) {
|
||||
response->mid = *((unsigned long *) packet->token);
|
||||
} else {
|
||||
response->mid = packet->mid;
|
||||
}
|
||||
|
||||
response->payload = packet->payload;
|
||||
response->payload_len = packet->payload_len;
|
||||
return;
|
||||
}
|
||||
28
core/shared-lib/coap/extension/coap_ext.h
Executable file → Normal file
28
core/shared-lib/coap/extension/coap_ext.h
Executable file → Normal file
@ -6,8 +6,7 @@
|
||||
#ifndef COAP_EXTENSION_COAP_EXT_H_
|
||||
#define COAP_EXTENSION_COAP_EXT_H_
|
||||
|
||||
#include "er-coap.h"
|
||||
#include "shared_utils.h"
|
||||
#include "coap-constants.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -15,31 +14,6 @@ extern "C" {
|
||||
|
||||
#define COAP_EVENT (COAP_DELETE + 2)
|
||||
|
||||
char * coap_get_full_url_alloc(coap_packet_t * request);
|
||||
|
||||
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
|
||||
uint32_t data_len);
|
||||
|
||||
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out);
|
||||
int coap_set_payload_tcp(void *packet, const void *payload, size_t length);
|
||||
uint8_t coap_is_request(coap_packet_t * coap_message);
|
||||
|
||||
uint16_t coap_find_mid(uint8_t *buffer);
|
||||
uint8_t coap_find_code(uint8_t *buffer);
|
||||
void coap_change_mid(uint8_t *buffer, uint16_t id);
|
||||
|
||||
int add_resource_handler(coap_context_t * coap_ctx,
|
||||
coap_resource_handler_t * handler);
|
||||
uint32_t check_blockwise_timeout_ms(coap_context_t * coap_ctx, int timeout_sec);
|
||||
|
||||
int convert_coap_packet_to_request(coap_packet_t *packet, request_t *request);
|
||||
void convert_coap_packet_to_response(coap_packet_t *packet,
|
||||
response_t *response);
|
||||
|
||||
void convert_response_to_coap_packet(response_t * response,
|
||||
coap_packet_t * packet);
|
||||
void convert_request_to_coap_packet(request_t * req, coap_packet_t * packet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1,470 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "bh_common.h"
|
||||
#include "er-coap.h"
|
||||
#include "coap_ext.h"
|
||||
#include "er-coap-constants.h"
|
||||
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include <stdio.h>
|
||||
#define PRINTF(...) printf(__VA_ARGS__)
|
||||
#define PRINT6ADDR(addr) PRINTF("[%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x]", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
|
||||
#define PRINTLLADDR(lladdr) PRINTF("[%02x:%02x:%02x:%02x:%02x:%02x]", (lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3], (lladdr)->addr[4], (lladdr)->addr[5])
|
||||
#else
|
||||
#define PRINTF(...)
|
||||
#define PRINT6ADDR(addr)
|
||||
#define PRINTLLADDR(addr)
|
||||
#endif
|
||||
|
||||
extern size_t
|
||||
coap_serialize_array_option(unsigned int number, unsigned int current_number,
|
||||
uint8_t *buffer, uint8_t *array, size_t length, char split_char);
|
||||
extern size_t
|
||||
coap_serialize_int_option(unsigned int number, unsigned int current_number,
|
||||
uint8_t *buffer, uint32_t value);
|
||||
extern uint16_t coap_log_2(uint16_t value);
|
||||
extern uint32_t coap_parse_int_option(uint8_t *bytes, size_t length);
|
||||
extern void
|
||||
coap_merge_multi_option(char **dst, size_t *dst_len, uint8_t *option,
|
||||
size_t option_len, char separator);
|
||||
|
||||
/*
|
||||
*
|
||||
0 1 2 3
|
||||
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|Len=15 | TKL | Extended Length (32 bits)
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| | Code | Token (if any, TKL bytes) ...
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
| Options (if any) ...
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|1 1 1 1 1 1 1 1| Payload (if any) ...
|
||||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
||||
|
||||
*/
|
||||
|
||||
int coap_set_payload_tcp(void *packet, const void *payload, size_t length)
|
||||
{
|
||||
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
|
||||
|
||||
coap_pkt->payload = (uint8_t *) payload;
|
||||
coap_pkt->payload_len = MIN(REST_MAX_CHUNK_SIZE, length);
|
||||
|
||||
return coap_pkt->payload_len;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static size_t coap_calc_ext_len_field(int len)
|
||||
{
|
||||
if(len < 13)
|
||||
return 0;
|
||||
else if(len <= (0xFF+13))
|
||||
return 1;
|
||||
else if(len <= (0xFFFF+269))
|
||||
return 2;
|
||||
else if(len < (0xFFFFFFFF+65805))
|
||||
return 4;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static size_t coap_max_options_offset(void *packet)
|
||||
{
|
||||
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
|
||||
return 6 + coap_pkt->token_len;
|
||||
}
|
||||
|
||||
int coap_serialize_message_tcp(void *packet, uint8_t ** buffer_out)
|
||||
{
|
||||
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
|
||||
uint8_t buffer[128];
|
||||
|
||||
uint8_t *option = buffer;
|
||||
unsigned int current_number = 0;
|
||||
|
||||
if (coap_pkt->uri_path_len > 100) {
|
||||
*buffer_out = 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Serialize options */
|
||||
current_number = 0;
|
||||
if (0 == coap_pkt->token_len) {
|
||||
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, &coap_pkt->mid,
|
||||
sizeof(coap_pkt->mid));
|
||||
coap_pkt->token_len = sizeof(coap_pkt->mid);
|
||||
}PRINTF("-Serializing options at %p-\n", option);
|
||||
|
||||
/* The options must be serialized in the order of their number */
|
||||
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_IF_MATCH, if_match, "If-Match");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_HOST, uri_host, '\0',
|
||||
"Uri-Host");
|
||||
COAP_SERIALIZE_BYTE_OPTION(COAP_OPTION_ETAG, etag, "ETag");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_IF_NONE_MATCH,
|
||||
content_format - coap_pkt-> content_format /* hack to get a zero field */,
|
||||
"If-None-Match");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_OBSERVE, observe, "Observe");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_URI_PORT, uri_port, "Uri-Port");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_PATH, location_path, '/',
|
||||
"Location-Path");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_PATH, uri_path, 0, //'/',
|
||||
"Uri-Path");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_CONTENT_FORMAT, content_format,
|
||||
"Content-Format");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_MAX_AGE, max_age, "Max-Age");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_URI_QUERY, uri_query, '&',
|
||||
"Uri-Query");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_ACCEPT, accept, "Accept");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_LOCATION_QUERY, location_query,
|
||||
'&', "Location-Query");
|
||||
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK2, block2, "Block2");
|
||||
COAP_SERIALIZE_BLOCK_OPTION(COAP_OPTION_BLOCK1, block1, "Block1");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE2, size2, "Size2");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_URI, proxy_uri, '\0',
|
||||
"Proxy-Uri");
|
||||
COAP_SERIALIZE_STRING_OPTION(COAP_OPTION_PROXY_SCHEME, proxy_scheme, '\0',
|
||||
"Proxy-Scheme");
|
||||
COAP_SERIALIZE_INT_OPTION(COAP_OPTION_SIZE1, size1, "Size1");
|
||||
|
||||
/* Pack payload */
|
||||
if (coap_pkt->payload_len) {
|
||||
*option = 0xFF;
|
||||
++option;
|
||||
}
|
||||
uint32_t option_len = option - &buffer[0];
|
||||
|
||||
uint8_t * p = (uint8_t *) os_malloc(
|
||||
coap_max_options_offset(packet) + option_len
|
||||
+ coap_pkt->payload_len);
|
||||
if (p == NULL)
|
||||
return 0;
|
||||
*buffer_out = p;
|
||||
|
||||
uint8_t first_4bits;
|
||||
|
||||
*p = (coap_pkt->token_len & 0xF);
|
||||
uint32_t len = option_len + coap_pkt->payload_len;
|
||||
|
||||
if (len < 13) {
|
||||
first_4bits = len;
|
||||
*p++ |= first_4bits << 4;
|
||||
} else if (len <= (0xFF + 13)) {
|
||||
first_4bits = 13;
|
||||
*p++ |= first_4bits << 4;
|
||||
*p++ = len - 13;
|
||||
} else if (len <= (0xFFFF + 269)) {
|
||||
first_4bits = 14;
|
||||
*p++ |= first_4bits << 4;
|
||||
len -= 269;
|
||||
*p = (uint8_t)(len >> 8);
|
||||
p++;
|
||||
*p = (uint8_t)(len & 0xFF);
|
||||
p++;
|
||||
} else {
|
||||
first_4bits = 15;
|
||||
*p++ |= first_4bits << 4;
|
||||
|
||||
len -= 65805;
|
||||
*p++ = (uint8_t)(len >> 24);
|
||||
*p++ = (uint8_t)(len >> 16);
|
||||
*p++ = (uint8_t)(len >> 8);
|
||||
*p++ = (uint8_t)(len & 0xFF);
|
||||
}
|
||||
|
||||
*p = coap_pkt->code;
|
||||
p++;
|
||||
|
||||
if (coap_pkt->token_len)
|
||||
bh_memcpy_s(p, coap_pkt->token_len, coap_pkt->token,
|
||||
coap_pkt->token_len);
|
||||
p += coap_pkt->token_len;
|
||||
|
||||
bh_memcpy_s(p, option_len, buffer, option_len);
|
||||
p += option_len;
|
||||
|
||||
bh_memcpy_s(p, coap_pkt->payload_len, coap_pkt->payload,
|
||||
coap_pkt->payload_len);
|
||||
p += coap_pkt->payload_len;
|
||||
|
||||
return (p - *buffer_out); /* packet length */
|
||||
}
|
||||
|
||||
coap_status_t coap_parse_message_tcp(void *packet, uint8_t *data,
|
||||
uint32_t data_len)
|
||||
{
|
||||
coap_packet_t * const coap_pkt = (coap_packet_t *) packet;
|
||||
|
||||
/* initialize packet */
|
||||
memset(coap_pkt, 0, sizeof(coap_packet_t));
|
||||
|
||||
/* pointer to packet bytes */
|
||||
coap_pkt->buffer = data;
|
||||
|
||||
/* parse header fields */
|
||||
coap_pkt->version = 1;
|
||||
coap_pkt->type = COAP_TYPE_NON;
|
||||
coap_pkt->token_len = MIN(COAP_TOKEN_LEN, data[0] & 0xF);
|
||||
coap_pkt->mid = 0;
|
||||
|
||||
uint8_t *p = data;
|
||||
uint8_t first_4bits = data[0] >> 4;
|
||||
|
||||
uint32_t options_payload_size;
|
||||
uint8_t ext_len_field = 0;
|
||||
if (first_4bits < 13) {
|
||||
options_payload_size = first_4bits;
|
||||
p++;
|
||||
} else if (first_4bits == 13) {
|
||||
ext_len_field = 1;
|
||||
options_payload_size = data[1] + 13;
|
||||
p += 2;
|
||||
} else if (first_4bits == 14) {
|
||||
ext_len_field = 2;
|
||||
options_payload_size = (uint16_t)(data[1] << 8) + data[2] + 269;
|
||||
p += 3;
|
||||
} else if (first_4bits == 15) {
|
||||
ext_len_field = 4;
|
||||
options_payload_size = (data[1] << 24) + (data[2] << 16)
|
||||
+ (data[3] << 8) + data[4] + 65805;
|
||||
p += 5;
|
||||
}
|
||||
|
||||
// check the data size is smaller than the size indicated by the packet
|
||||
if (ext_len_field + coap_pkt->token_len + 2 + options_payload_size
|
||||
> data_len)
|
||||
return BAD_REQUEST_4_00;
|
||||
|
||||
coap_pkt->code = *p++;
|
||||
if (coap_pkt->token_len)
|
||||
bh_memcpy_s(coap_pkt->token, COAP_TOKEN_LEN, p, coap_pkt->token_len);
|
||||
|
||||
if (coap_pkt->token_len >= 2) {
|
||||
union {
|
||||
uint16_t *mid;
|
||||
uint8_t *token;
|
||||
} mid_token_union;
|
||||
|
||||
mid_token_union.token = coap_pkt->token;
|
||||
coap_pkt->mid = *(mid_token_union.mid);
|
||||
}
|
||||
|
||||
p += coap_pkt->token_len;
|
||||
|
||||
uint8_t *current_option = p;
|
||||
uint8_t * option_start = p;
|
||||
|
||||
/* parse options */
|
||||
memset(coap_pkt->options, 0, sizeof(coap_pkt->options));
|
||||
|
||||
unsigned int option_number = 0;
|
||||
unsigned int option_delta = 0;
|
||||
size_t option_length = 0;
|
||||
|
||||
while (current_option < data + data_len) {
|
||||
/* payload marker 0xFF, currently only checking for 0xF* because rest is reserved */
|
||||
if ((current_option[0] & 0xF0) == 0xF0) {
|
||||
coap_pkt->payload = ++current_option;
|
||||
coap_pkt->payload_len = options_payload_size
|
||||
- (coap_pkt->payload - option_start);
|
||||
//coap_pkt->payload_len = data_len - (coap_pkt->payload - data);
|
||||
break;
|
||||
}
|
||||
|
||||
option_delta = current_option[0] >> 4;
|
||||
option_length = current_option[0] & 0x0F;
|
||||
++current_option;
|
||||
|
||||
/* avoids code duplication without function overhead */
|
||||
unsigned int *x = &option_delta;
|
||||
|
||||
do {
|
||||
if (*x == 13) {
|
||||
*x += current_option[0];
|
||||
++current_option;
|
||||
} else if (*x == 14) {
|
||||
*x += 255;
|
||||
*x += current_option[0] << 8;
|
||||
++current_option;
|
||||
*x += current_option[0];
|
||||
++current_option;
|
||||
}
|
||||
} while (x != (unsigned int*) &option_length && (x =
|
||||
(unsigned int*) &option_length));
|
||||
option_length = *x;
|
||||
option_number += option_delta;
|
||||
|
||||
PRINTF("OPTION %u (delta %u, len %u): ", option_number, option_delta,
|
||||
option_length);
|
||||
|
||||
SET_OPTION(coap_pkt, option_number);
|
||||
|
||||
switch (option_number) {
|
||||
|
||||
case COAP_OPTION_CONTENT_FORMAT:
|
||||
coap_pkt->content_format = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Content-Format [%u]\n", coap_pkt->content_format);
|
||||
break;
|
||||
case COAP_OPTION_MAX_AGE:
|
||||
coap_pkt->max_age = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Max-Age [%lu]\n", coap_pkt->max_age);
|
||||
break;
|
||||
case COAP_OPTION_ETAG:
|
||||
coap_pkt->etag_len = MIN(COAP_ETAG_LEN, option_length);
|
||||
bh_memcpy_s(coap_pkt->etag, COAP_ETAG_LEN, current_option,
|
||||
coap_pkt->etag_len);
|
||||
PRINTF("ETag %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
|
||||
coap_pkt->etag_len, coap_pkt->etag[0], coap_pkt->etag[1],
|
||||
coap_pkt->etag[2], coap_pkt->etag[3], coap_pkt->etag[4],
|
||||
coap_pkt->etag[5], coap_pkt->etag[6], coap_pkt->etag[7]
|
||||
); /*FIXME always prints 8 bytes */
|
||||
break;
|
||||
case COAP_OPTION_ACCEPT:
|
||||
coap_pkt->accept = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Accept [%u]\n", coap_pkt->accept);
|
||||
break;
|
||||
case COAP_OPTION_IF_MATCH:
|
||||
/* TODO support multiple ETags */
|
||||
coap_pkt->if_match_len = MIN(COAP_ETAG_LEN, option_length);
|
||||
bh_memcpy_s(coap_pkt->if_match, COAP_ETAG_LEN, current_option,
|
||||
coap_pkt->if_match_len);
|
||||
PRINTF("If-Match %u [0x%02X%02X%02X%02X%02X%02X%02X%02X]\n",
|
||||
coap_pkt->if_match_len, coap_pkt->if_match[0],
|
||||
coap_pkt->if_match[1], coap_pkt->if_match[2],
|
||||
coap_pkt->if_match[3], coap_pkt->if_match[4],
|
||||
coap_pkt->if_match[5], coap_pkt->if_match[6],
|
||||
coap_pkt->if_match[7]
|
||||
); /* FIXME always prints 8 bytes */
|
||||
break;
|
||||
case COAP_OPTION_IF_NONE_MATCH:
|
||||
coap_pkt->if_none_match = 1;
|
||||
PRINTF("If-None-Match\n");
|
||||
break;
|
||||
|
||||
case COAP_OPTION_PROXY_URI:
|
||||
#if COAP_PROXY_OPTION_PROCESSING
|
||||
coap_pkt->proxy_uri = (char *)current_option;
|
||||
coap_pkt->proxy_uri_len = option_length;
|
||||
#endif
|
||||
PRINTF("Proxy-Uri NOT IMPLEMENTED [%.*s]\n", coap_pkt->proxy_uri_len,
|
||||
coap_pkt->proxy_uri);
|
||||
coap_error_message = "This is a constrained server (Contiki)";
|
||||
return PROXYING_NOT_SUPPORTED_5_05;
|
||||
break;
|
||||
case COAP_OPTION_PROXY_SCHEME:
|
||||
#if COAP_PROXY_OPTION_PROCESSING
|
||||
coap_pkt->proxy_scheme = (char *)current_option;
|
||||
coap_pkt->proxy_scheme_len = option_length;
|
||||
#endif
|
||||
PRINTF("Proxy-Scheme NOT IMPLEMENTED [%.*s]\n",
|
||||
coap_pkt->proxy_scheme_len, coap_pkt->proxy_scheme);
|
||||
coap_error_message = "This is a constrained server (Contiki)";
|
||||
return PROXYING_NOT_SUPPORTED_5_05;
|
||||
break;
|
||||
|
||||
case COAP_OPTION_URI_HOST:
|
||||
coap_pkt->uri_host = (char *) current_option;
|
||||
coap_pkt->uri_host_len = option_length;
|
||||
PRINTF("Uri-Host [%.*s]\n", coap_pkt->uri_host_len, coap_pkt->uri_host);
|
||||
break;
|
||||
case COAP_OPTION_URI_PORT:
|
||||
coap_pkt->uri_port = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Uri-Port [%u]\n", coap_pkt->uri_port);
|
||||
break;
|
||||
case COAP_OPTION_URI_PATH:
|
||||
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
|
||||
coap_merge_multi_option((char **) &(coap_pkt->uri_path),
|
||||
&(coap_pkt->uri_path_len), current_option, option_length,
|
||||
'/');
|
||||
PRINTF("Uri-Path [%.*s]\n", coap_pkt->uri_path_len, coap_pkt->uri_path);
|
||||
break;
|
||||
case COAP_OPTION_URI_QUERY:
|
||||
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
|
||||
coap_merge_multi_option((char **) &(coap_pkt->uri_query),
|
||||
&(coap_pkt->uri_query_len), current_option, option_length,
|
||||
'&');
|
||||
PRINTF("Uri-Query [%.*s]\n", coap_pkt->uri_query_len,
|
||||
coap_pkt->uri_query);
|
||||
break;
|
||||
|
||||
case COAP_OPTION_LOCATION_PATH:
|
||||
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
|
||||
coap_merge_multi_option((char **) &(coap_pkt->location_path),
|
||||
&(coap_pkt->location_path_len), current_option,
|
||||
option_length, '/');
|
||||
PRINTF("Location-Path [%.*s]\n", coap_pkt->location_path_len,
|
||||
coap_pkt->location_path);
|
||||
break;
|
||||
case COAP_OPTION_LOCATION_QUERY:
|
||||
/* coap_merge_multi_option() operates in-place on the IPBUF, but final packet field should be const string -> cast to string */
|
||||
coap_merge_multi_option((char **) &(coap_pkt->location_query),
|
||||
&(coap_pkt->location_query_len), current_option,
|
||||
option_length, '&');
|
||||
PRINTF("Location-Query [%.*s]\n", coap_pkt->location_query_len,
|
||||
coap_pkt->location_query);
|
||||
break;
|
||||
|
||||
case COAP_OPTION_OBSERVE:
|
||||
coap_pkt->observe = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Observe [%lu]\n", coap_pkt->observe);
|
||||
break;
|
||||
case COAP_OPTION_BLOCK2:
|
||||
coap_pkt->block2_num = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
coap_pkt->block2_more = (coap_pkt->block2_num & 0x08) >> 3;
|
||||
coap_pkt->block2_size = 16 << (coap_pkt->block2_num & 0x07);
|
||||
coap_pkt->block2_offset = (coap_pkt->block2_num & ~0x0000000F)
|
||||
<< (coap_pkt->block2_num & 0x07);
|
||||
coap_pkt->block2_num >>= 4;
|
||||
PRINTF("Block2 [%lu%s (%u B/blk)]\n", coap_pkt->block2_num,
|
||||
coap_pkt->block2_more ? "+" : "", coap_pkt->block2_size);
|
||||
break;
|
||||
case COAP_OPTION_BLOCK1:
|
||||
coap_pkt->block1_num = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
coap_pkt->block1_more = (coap_pkt->block1_num & 0x08) >> 3;
|
||||
coap_pkt->block1_size = 16 << (coap_pkt->block1_num & 0x07);
|
||||
coap_pkt->block1_offset = (coap_pkt->block1_num & ~0x0000000F)
|
||||
<< (coap_pkt->block1_num & 0x07);
|
||||
coap_pkt->block1_num >>= 4;
|
||||
PRINTF("Block1 [%lu%s (%u B/blk)]\n", coap_pkt->block1_num,
|
||||
coap_pkt->block1_more ? "+" : "", coap_pkt->block1_size);
|
||||
break;
|
||||
case COAP_OPTION_SIZE2:
|
||||
coap_pkt->size2 = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Size2 [%lu]\n", coap_pkt->size2);
|
||||
break;
|
||||
case COAP_OPTION_SIZE1:
|
||||
coap_pkt->size1 = coap_parse_int_option(current_option,
|
||||
option_length);
|
||||
PRINTF("Size1 [%lu]\n", coap_pkt->size1);
|
||||
break;
|
||||
default:
|
||||
PRINTF("unknown (%u)\n", option_number);
|
||||
/* check if critical (odd) */
|
||||
if (option_number & 1) {
|
||||
coap_error_message = "Unsupported critical option";
|
||||
return BAD_OPTION_4_02;
|
||||
}
|
||||
}
|
||||
|
||||
current_option += option_length;
|
||||
} /* for */
|
||||
PRINTF("-Done parsing-------\n");
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef COAP_PLATFORMS_H_
|
||||
#define COAP_PLATFORMS_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "bh_platform.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
/*#include "list_coap.h"*/
|
||||
#include <stdbool.h>
|
||||
|
||||
#define COAP_TRANS_LOCK(ctx) coap_lock(ctx->transaction_lock)
|
||||
#define COAP_TRANS_UNLOCK(ctx ) coap_unlock(ctx->transaction_lock)
|
||||
|
||||
/* REST_MAX_CHUNK_SIZE is the max size of payload.
|
||||
* The maximum buffer size that is provided for resource responses and must be respected due to the limited IP buffer.
|
||||
* Larger data must be handled by the resource and will be sent chunk-wise through a TCP stream or CoAP blocks.
|
||||
*/
|
||||
#ifndef REST_MAX_CHUNK_SIZE
|
||||
#define REST_MAX_CHUNK_SIZE (1024*1024)
|
||||
#endif
|
||||
|
||||
#ifndef MIN
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
#endif /* MIN */
|
||||
|
||||
#define CLOCK_SECOND 1000
|
||||
|
||||
typedef enum {
|
||||
A_Raw, A_Sock_Addr, A_IP_Addr, A_Custom
|
||||
} Net_Addr_Type;
|
||||
|
||||
#define NET_ADDR_RAW_SIZE 32
|
||||
|
||||
typedef struct net_addr_coap {
|
||||
Net_Addr_Type addr_type;
|
||||
union {
|
||||
char raw[NET_ADDR_RAW_SIZE];
|
||||
struct sockaddr_in sock_addr;
|
||||
} u;
|
||||
uint16_t port;
|
||||
uint16_t addr_len;
|
||||
} net_addr_t;
|
||||
|
||||
#define uip_ipaddr_t struct net_addr_coap
|
||||
|
||||
#define memb_free(x, y) free(x)
|
||||
|
||||
void set_addr_ip(uip_ipaddr_t *, char * ip, int port);
|
||||
uip_ipaddr_t * new_net_addr(Net_Addr_Type type);
|
||||
void copy_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
|
||||
bool compare_net_addr(uip_ipaddr_t * dest, uip_ipaddr_t * src);
|
||||
|
||||
uint32_t get_elpased_ms(uint32_t * last_system_clock);
|
||||
uint32_t get_platform_time();
|
||||
uint32_t get_platform_time_sec();
|
||||
|
||||
void coap_sleep_ms(uint32_t ms);
|
||||
void coap_lock(void *);
|
||||
void coap_unlock(void *);
|
||||
void * coap_create_lock();
|
||||
void coap_free_lock(void *);
|
||||
|
||||
void *xalloc(uint32_t size);
|
||||
|
||||
#define os_malloc bh_malloc
|
||||
#define os_free bh_free
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* COAP_PLATFORMS_H_ */
|
||||
@ -8,7 +8,6 @@
|
||||
|
||||
#include "bh_assert.h"
|
||||
#include "bh_platform.h"
|
||||
#include "bh_log.h"
|
||||
#include "bh_list.h"
|
||||
|
||||
typedef void (*bh_print_function_t)(const char* message);
|
||||
|
||||
@ -45,7 +45,7 @@ void bh_memory_destroy();
|
||||
* Get the pool size of memory, if memory is initialized with allocator,
|
||||
* return 1GB by default.
|
||||
*/
|
||||
int bh_memory_pool_size();
|
||||
unsigned bh_memory_pool_size();
|
||||
|
||||
#if BEIHAI_ENABLE_MEMORY_PROFILING == 0
|
||||
|
||||
|
||||
@ -54,7 +54,7 @@ void
|
||||
bh_queue_destroy(bh_queue *queue);
|
||||
|
||||
char * bh_message_payload(bh_message_t message);
|
||||
int bh_message_payload_len(bh_message_t message);
|
||||
uint32 bh_message_payload_len(bh_message_t message);
|
||||
int bh_message_type(bh_message_t message);
|
||||
|
||||
bh_message_t bh_new_msg(unsigned short tag, void *body, unsigned int len,
|
||||
|
||||
@ -95,7 +95,7 @@ void bh_memory_destroy()
|
||||
memory_mode = MEMORY_MODE_UNKNOWN;
|
||||
}
|
||||
|
||||
int bh_memory_pool_size()
|
||||
unsigned bh_memory_pool_size()
|
||||
{
|
||||
if (memory_mode == MEMORY_MODE_POOL)
|
||||
return global_pool_size;
|
||||
@ -155,7 +155,7 @@ void* bh_malloc_profile(const char *file,
|
||||
profile = bh_malloc_internal(sizeof(memory_profile_t));
|
||||
if (!profile) {
|
||||
vm_mutex_unlock(&profile_lock);
|
||||
memcpy(p, &size, sizeof(size));
|
||||
bh_memcpy_s(p, size + 8, &size, sizeof(size));
|
||||
return (char *)p + 8;
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ void* bh_malloc_profile(const char *file,
|
||||
|
||||
vm_mutex_unlock(&profile_lock);
|
||||
|
||||
memcpy(p, &size, sizeof(size));
|
||||
bh_memcpy_s(p, size + 8, &size, sizeof(size));
|
||||
memory_in_use += size;
|
||||
|
||||
memory_profile_print(file, line, func, size);
|
||||
|
||||
@ -94,7 +94,7 @@ static void unlink_hmu(gc_heap_t *heap, hmu_t *hmu)
|
||||
size = hmu_get_size(hmu);
|
||||
|
||||
if (HMU_IS_FC_NORMAL(size)) {
|
||||
int node_idx = size >> 3;
|
||||
uint32 node_idx = size >> 3;
|
||||
hmu_normal_node_t* node = heap->kfc_normal_list[node_idx].next;
|
||||
hmu_normal_node_t** p = &(heap->kfc_normal_list[node_idx].next);
|
||||
while (node) {
|
||||
@ -120,7 +120,7 @@ static void hmu_set_free_size(hmu_t *hmu)
|
||||
bh_assert(hmu && hmu_get_ut(hmu) == HMU_FC);
|
||||
|
||||
size = hmu_get_size(hmu);
|
||||
*((int*) ((char*) hmu + size) - 1) = size;
|
||||
*((uint32*) ((char*) hmu + size) - 1) = size;
|
||||
}
|
||||
|
||||
/* Add free chunk back to KFC*/
|
||||
@ -135,7 +135,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||
{
|
||||
hmu_normal_node_t *np = NULL;
|
||||
hmu_tree_node_t *root = NULL, *tp = NULL, *node = NULL;
|
||||
int node_idx;
|
||||
uint32 node_idx;
|
||||
|
||||
bh_assert(gci_is_heap_valid(heap));
|
||||
bh_assert(
|
||||
@ -203,7 +203,7 @@ void gci_add_fc(gc_heap_t *heap, hmu_t *hmu, gc_size_t size)
|
||||
BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||
{
|
||||
hmu_normal_node_t *node = NULL, *p = NULL;
|
||||
int node_idx = 0, init_node_idx = 0;
|
||||
uint32 node_idx = 0, init_node_idx = 0;
|
||||
hmu_tree_node_t *root = NULL, *tp = NULL, *last_tp = NULL;
|
||||
hmu_t *next, *rest;
|
||||
|
||||
@ -216,7 +216,7 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||
/* check normal list at first*/
|
||||
if (HMU_IS_FC_NORMAL(size)) {
|
||||
/* find a non-empty slot in normal_node_list with good size*/
|
||||
init_node_idx = (int) (size >> 3);
|
||||
init_node_idx = (size >> 3);
|
||||
for (node_idx = init_node_idx; node_idx < HMU_NORMAL_NODE_CNT;
|
||||
node_idx++) {
|
||||
node = heap->kfc_normal_list + node_idx;
|
||||
@ -233,8 +233,8 @@ BH_STATIC hmu_t *alloc_hmu(gc_heap_t *heap, gc_size_t size)
|
||||
node->next = p->next;
|
||||
bh_assert(((gc_int32)(uintptr_t)hmu_to_obj(p) & 7) == 0);
|
||||
|
||||
if ((gc_size_t) node_idx
|
||||
!= init_node_idx&& ((gc_size_t)node_idx << 3) >= size + GC_SMALLEST_SIZE) { /* with bigger size*/
|
||||
if ((gc_size_t)node_idx != (uint32)init_node_idx
|
||||
&& ((gc_size_t)node_idx << 3) >= size + GC_SMALLEST_SIZE) { /* with bigger size*/
|
||||
rest = (hmu_t*) (((char *) p) + size);
|
||||
gci_add_fc(heap, rest, (node_idx << 3) - size);
|
||||
hmu_mark_pinuse(rest);
|
||||
|
||||
@ -169,7 +169,7 @@ extern int gc_destroy_with_pool(gc_handle_t handle);
|
||||
* @param size [in] the size of stats
|
||||
* @param mmt [in] type of heap, MMT_SHARED or MMT_INSTANCE
|
||||
*/
|
||||
extern void* gc_heap_stats(void *heap, int* stats, int size, gc_mm_t mmt);
|
||||
extern void* gc_heap_stats(void *heap, uint32* stats, int size, gc_mm_t mmt);
|
||||
|
||||
/**
|
||||
* Set GC threshold factor
|
||||
|
||||
@ -77,7 +77,7 @@ extern void hmu_verify(hmu_t *hmu);
|
||||
|
||||
#define hmu_obj_size(s) ((s)-OBJ_EXTRA_SIZE)
|
||||
|
||||
#define GC_ALIGN_8(s) (((int)(s) + 7) & ~7)
|
||||
#define GC_ALIGN_8(s) (((uint32)(s) + 7) & (uint32)~7)
|
||||
|
||||
#define GC_SMALLEST_SIZE GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + 8)
|
||||
#define GC_GET_REAL_SIZE(x) GC_ALIGN_8(HMU_SIZE + OBJ_PREFIX_SIZE + OBJ_SUFFIX_SIZE + (((x) > 8) ? (x): 8))
|
||||
@ -86,14 +86,14 @@ extern void hmu_verify(hmu_t *hmu);
|
||||
|
||||
#define SETBIT(v, offset) (v) |= (1 << (offset))
|
||||
#define GETBIT(v, offset) ((v) & (1 << (offset)) ? 1 : 0)
|
||||
#define CLRBIT(v, offset) (v) &= ~(1 << (offset))
|
||||
#define CLRBIT(v, offset) (v) &= (uint32)(~(1 << (offset)))
|
||||
|
||||
#define SETBITS(v, offset, size, value) do { \
|
||||
(v) &= ~(((1 << size) - 1) << offset); \
|
||||
(v) |= value << offset; \
|
||||
} while(0)
|
||||
(v) &= (uint32)(~(((1 << size) - 1) << offset));\
|
||||
(v) |= (uint32)(value << offset); \
|
||||
} while(0)
|
||||
#define CLRBITS(v, offset, size) (v) &= ~(((1 << size) - 1) << offset)
|
||||
#define GETBITS(v, offset, size) (((v) & (((1 << size) - 1) << offset)) >> offset)
|
||||
#define GETBITS(v, offset, size) (((v) & ((uint32)(((1 << size) - 1) << offset))) >> offset)
|
||||
|
||||
/*////// gc object layout definition*/
|
||||
|
||||
|
||||
@ -41,7 +41,7 @@ int gci_check_platform()
|
||||
gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
|
||||
{
|
||||
char *buf_end = buf + buf_size;
|
||||
char *buf_aligned = (char*) (((uintptr_t) buf + 7) & ~7);
|
||||
char *buf_aligned = (char*) (((uintptr_t) buf + 7) & (uintptr_t)~7);
|
||||
char *base_addr = buf_aligned + sizeof(gc_heap_t);
|
||||
gc_heap_t *heap = (gc_heap_t*) buf_aligned;
|
||||
gc_size_t heap_max_size;
|
||||
@ -60,8 +60,8 @@ gc_handle_t gc_init_with_pool(char *buf, gc_size_t buf_size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
base_addr = (char*) (((uintptr_t) base_addr + 7) & ~7) + GC_HEAD_PADDING;
|
||||
heap_max_size = (buf_end - base_addr) & ~7;
|
||||
base_addr = (char*) (((uintptr_t) base_addr + 7) & (uintptr_t)~7) + GC_HEAD_PADDING;
|
||||
heap_max_size = (uint32)(buf_end - base_addr) & (uint32)~7;
|
||||
|
||||
memset(heap, 0, sizeof *heap);
|
||||
memset(base_addr, 0, heap_max_size);
|
||||
@ -154,7 +154,7 @@ void gci_verify_heap(gc_heap_t *heap)
|
||||
}
|
||||
#endif
|
||||
|
||||
void* gc_heap_stats(void *heap_arg, int* stats, int size, gc_mm_t mmt)
|
||||
void* gc_heap_stats(void *heap_arg, uint32* stats, int size, gc_mm_t mmt)
|
||||
{
|
||||
(void) mmt;
|
||||
int i;
|
||||
@ -175,7 +175,7 @@ void* gc_heap_stats(void *heap_arg, int* stats, int size, gc_mm_t mmt)
|
||||
stats[i] = heap->total_gc_count;
|
||||
break;
|
||||
case GC_STAT_TIME:
|
||||
stats[i] = (int) heap->total_gc_time;
|
||||
stats[i] = (uint32)heap->total_gc_time;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
include_directories (./include ../include ./${PLATFORM})
|
||||
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=199309L -D_BSD_SOURCE)
|
||||
add_definitions (-D__POSIX__ -D_XOPEN_SOURCE=600 -D_POSIX_C_SOURCE=200809L -D_BSD_SOURCE)
|
||||
|
||||
file (GLOB_RECURSE source_all ${PLATFORM}/*.c)
|
||||
add_library (supportlib ${source_all})
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user