Просмотр исходного кода

Refine binary size and fix several minor issues (#104)

* Implement memory profiler, optimize memory usage, modify code indent

* Implement memory.grow and limit heap space base offset to 1G; modify iwasm build type to Release and 64 bit by default

* Add a new extension library: connection

* Fix bug of reading magic number and version in big endian platform

* Re-org platform APIs: move most platform APIs from iwasm to shared-lib

* Enhance wasm loader to fix some security issues

* Fix issue about illegal load of EXC_RETURN into PC on stm32 board

* Updates that let a restricted version of the interpreter run in SGX

* Enable native/app address validation and conversion for wasm app

* Remove wasm_application_exectue_* APIs from wasm_export.h which makes confused

* Refine binary size and fix several minor issues

Optimize interpreter LOAD/STORE opcodes to decrease the binary size
Fix issues when using iwasm library: _bh_log undefined, bh_memory.h not found
Remove unused _stdin/_stdout/_stderr global variables resolve in libc wrapper
Add macros of global heap size, stack size, heap size for Zephyr main.c
Clear compile warning of wasm_application.c
wenyongh 6 лет назад
Родитель
Сommit
92cbecbec8

+ 0 - 17
core/iwasm/lib/native/libc/libc_wrapper.c

@@ -984,23 +984,6 @@ wasm_native_global_lookup(const char *module_name, const char *global_name,
         global_def++;
     }
 
-    /* Lookup non-constant globals which cannot be defined by table */
-    if (!strcmp(module_name, "env")) {
-        if (!strcmp(global_name, "_stdin")) {
-            global->global_data_linked.addr = (uintptr_t)stdin;
-            global->is_addr = true;
-            return true;
-        } else if (!strcmp(global_name, "_stdout")) {
-            global->global_data_linked.addr = (uintptr_t)stdout;
-            global->is_addr = true;
-            return true;
-        } else if (!strcmp(global_name, "_stderr")) {
-            global->global_data_linked.addr = (uintptr_t)stderr;
-            global->is_addr = true;
-            return true;
-        }
-    }
-
     return false;
 }
 

+ 5 - 2
core/iwasm/products/linux/CMakeLists.txt

@@ -68,6 +68,7 @@ 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)
 
 add_library (vmlib
              ${WASM_PLATFORM_LIB_SOURCE}
@@ -76,7 +77,8 @@ add_library (vmlib
              ${WASM_LIB_BASE_DIR}/base_lib_export.c
              ${WASM_LIBC_SOURCE}
              ${PLATFORM_SHARED_SOURCE}
-             ${MEM_ALLOC_SHARED_SOURCE})
+             ${MEM_ALLOC_SHARED_SOURCE}
+             ${UTILS_SHARED_SOURCE})
 
 add_executable (iwasm main.c ext_lib_export.c)
 
@@ -91,7 +93,8 @@ add_library (libiwasm SHARED
              ${WASM_LIB_BASE_DIR}/base_lib_export.c
              ${WASM_LIBC_SOURCE}
              ${PLATFORM_SHARED_SOURCE}
-             ${MEM_ALLOC_SHARED_SOURCE})
+             ${MEM_ALLOC_SHARED_SOURCE}
+             ${UTILS_SHARED_SOURCE})
 
 install (TARGETS libiwasm DESTINATION lib)
 

+ 19 - 12
core/iwasm/products/zephyr/simple/src/main.c

@@ -26,6 +26,11 @@
 #include "bh_memory.h"
 #include "test_wasm.h"
 
+#define CONFIG_GLOBAL_HEAP_BUF_SIZE 131072
+#define CONFIG_APP_STACK_SIZE 8192
+#define CONFIG_APP_HEAP_SIZE 8192
+#define CONFIG_MAIN_THREAD_STACK_SIZE 4096
+
 static int app_argc;
 static char **app_argv;
 
@@ -54,7 +59,7 @@ app_instance_main(wasm_module_inst_t module_inst)
     return NULL;
 }
 
-static char global_heap_buf[512 * 1024] = { 0 };
+static char global_heap_buf[CONFIG_GLOBAL_HEAP_BUF_SIZE] = { 0 };
 
 void iwasm_main(void *arg1, void *arg2, void *arg3)
 {
@@ -72,7 +77,7 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
     (void) arg3;
 
     if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
-            != 0) {
+        != 0) {
         wasm_printf("Init global heap failed.\n");
         return;
     }
@@ -91,14 +96,17 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
 
     /* load WASM module */
     if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
-            error_buf, sizeof(error_buf)))) {
+                                          error_buf, sizeof(error_buf)))) {
         wasm_printf("%s\n", error_buf);
         goto fail2;
     }
 
     /* instantiate the module */
-    if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module, 8 * 1024,
-            8 * 1024, error_buf, sizeof(error_buf)))) {
+    if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
+                                                      CONFIG_APP_STACK_SIZE,
+                                                      CONFIG_APP_HEAP_SIZE,
+                                                      error_buf,
+                                                      sizeof(error_buf)))) {
         wasm_printf("%s\n", error_buf);
         goto fail3;
     }
@@ -119,24 +127,23 @@ void iwasm_main(void *arg1, void *arg2, void *arg3)
     fail1: bh_memory_destroy();
 }
 
-#define DEFAULT_THREAD_STACKSIZE (6 * 1024)
-#define DEFAULT_THREAD_PRIORITY 5
+#define MAIN_THREAD_STACK_SIZE (CONFIG_MAIN_THREAD_STACK_SIZE)
+#define MAIN_THREAD_PRIORITY 5
 
-K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, DEFAULT_THREAD_STACKSIZE);
+K_THREAD_STACK_DEFINE(iwasm_main_thread_stack, MAIN_THREAD_STACK_SIZE);
 static struct k_thread iwasm_main_thread;
 
 bool iwasm_init(void)
 {
     k_tid_t tid = k_thread_create(&iwasm_main_thread, iwasm_main_thread_stack,
-    DEFAULT_THREAD_STACKSIZE, iwasm_main, NULL, NULL, NULL,
-    DEFAULT_THREAD_PRIORITY, 0, K_NO_WAIT);
+                                  MAIN_THREAD_STACK_SIZE,
+                                  iwasm_main, NULL, NULL, NULL,
+                                  MAIN_THREAD_PRIORITY, 0, K_NO_WAIT);
     return tid ? true : false;
 }
 
-#ifndef CONFIG_AEE_ENABLE
 void main(void)
 {
     iwasm_init();
 }
-#endif
 

+ 110 - 0
core/iwasm/runtime/include/bh_memory.h

@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BH_MEMORY_H
+#define _BH_MEMORY_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define BH_KB (1024)
+#define BH_MB ((BH_KB)*1024)
+#define BH_GB ((BH_MB)*1024)
+
+/**
+ * Initialize memory allocator with a pool, the bh_malloc/bh_free function
+ * will malloc/free memory from the pool
+ *
+ * @param mem the pool buffer
+ * @param bytes the size bytes of the buffer
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int bh_memory_init_with_pool(void *mem, unsigned int bytes);
+
+/**
+ * Initialize memory allocator with memory allocator, the bh_malloc/bh_free
+ * function will malloc/free memory with the allocator passed
+ *
+ * @param malloc_func the malloc function
+ * @param free_func the free function
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int bh_memory_init_with_allocator(void *malloc_func, void *free_func);
+
+/**
+ * Destroy memory
+ */
+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();
+
+#if BEIHAI_ENABLE_MEMORY_PROFILING == 0
+
+/**
+ * This function allocates a memory chunk from system
+ *
+ * @param size bytes need allocate
+ *
+ * @return the pointer to memory allocated
+ */
+void* bh_malloc(unsigned int size);
+
+/**
+ * This function frees memory chunk
+ *
+ * @param ptr the pointer to memory need free
+ */
+void bh_free(void *ptr);
+
+#else
+
+void* bh_malloc_profile(const char *file, int line, const char *func, unsigned int size);
+void bh_free_profile(const char *file, int line, const char *func, void *ptr);
+
+#define bh_malloc(size) bh_malloc_profile(__FILE__, __LINE__, __func__, size)
+#define bh_free(ptr) bh_free_profile(__FILE__, __LINE__, __func__, ptr)
+
+/**
+ * Print current memory profiling data
+ *
+ * @param file file name of the caller
+ * @param line line of the file of the caller
+ * @param func function name of the caller
+ */
+void memory_profile_print(const char *file, int line, const char *func, int alloc);
+
+/**
+ * Summarize memory usage and print it out
+ * Can use awk to analyze the output like below:
+ * awk -F: '{print $2,$4,$6,$8,$9}' OFS="\t" ./out.txt | sort -n -r -k 1
+ */
+void memory_usage_summarize();
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* #ifndef _BH_MEMORY_H */
+

+ 6 - 1
core/iwasm/runtime/vmcore-wasm/wasm_application.c

@@ -293,10 +293,15 @@ wasm_application_execute_func(WASMModuleInstance *module_inst,
             break;
         case VALUE_TYPE_I64:
         {
+            char buf[16];
             union { uint64 val; uint32 parts[2]; } u;
             u.parts[0] = argv1[0];
             u.parts[1] = argv1[1];
-            wasm_printf("0x%llx:i64", u.val);
+            if (sizeof(long) == 4)
+                snprintf(buf, sizeof(buf), "%s", "0x%llx:i64");
+            else
+                snprintf(buf, sizeof(buf), "%s", "0x%lx:i64");
+            wasm_printf(buf, u.val);
             break;
         }
         case VALUE_TYPE_F32:

+ 129 - 63
core/iwasm/runtime/vmcore-wasm/wasm_interp.c

@@ -753,7 +753,7 @@ wasm_interp_call_func_bytecode(WASMThread *self,
   uint32 i, depth, cond, count, fidx, tidx, frame_size = 0, all_cell_num = 0;
   int32 didx, val;
   uint8 *else_addr, *end_addr;
-  uint8 *maddr;
+  uint8 *maddr = NULL;
 
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
   #define HANDLE_OPCODE(op) &&HANDLE_##op
@@ -1148,70 +1148,98 @@ wasm_interp_call_func_bytecode(WASMThread *self,
 
       /* memory load instructions */
       HANDLE_OP (WASM_OP_I32_LOAD):
-        DEF_OP_LOAD(PUSH_I32(*(int32*)maddr));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD):
-        DEF_OP_LOAD(PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_F32_LOAD):
-        DEF_OP_LOAD(PUSH_F32(*(float32*)maddr));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_F64_LOAD):
-        DEF_OP_LOAD(PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I32_LOAD8_S):
-        DEF_OP_LOAD(PUSH_I32(sign_ext_8_32(*(int8*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I32_LOAD8_U):
-        DEF_OP_LOAD(PUSH_I32((uint32)(*(uint8*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I32_LOAD16_S):
-        DEF_OP_LOAD(PUSH_I32(sign_ext_16_32(*(int16*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I32_LOAD16_U):
-        DEF_OP_LOAD(PUSH_I32((uint32)(*(uint16*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD8_S):
-        DEF_OP_LOAD(PUSH_I64(sign_ext_8_64(*(int8*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD8_U):
-        DEF_OP_LOAD(PUSH_I64((uint64)(*(uint8*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD16_S):
-        DEF_OP_LOAD(PUSH_I64(sign_ext_16_64(*(int16*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD16_U):
-        DEF_OP_LOAD(PUSH_I64((uint64)(*(uint16*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD32_S):
-        DEF_OP_LOAD(PUSH_I64(sign_ext_32_64(*(int32*)maddr)));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_LOAD32_U):
-        DEF_OP_LOAD(PUSH_I64((uint64)(*(uint32*)maddr)));
-        HANDLE_OP_END ();
+        {
+          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();
+#if WASM_ENABLE_LABELS_AS_VALUES != 0
+          static const void *handle_load_table[] = {
+              &&HANDLE_LOAD_WASM_OP_I32_LOAD,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD,
+              &&HANDLE_LOAD_WASM_OP_F32_LOAD,
+              &&HANDLE_LOAD_WASM_OP_F64_LOAD,
+              &&HANDLE_LOAD_WASM_OP_I32_LOAD8_S,
+              &&HANDLE_LOAD_WASM_OP_I32_LOAD8_U,
+              &&HANDLE_LOAD_WASM_OP_I32_LOAD16_S,
+              &&HANDLE_LOAD_WASM_OP_I32_LOAD16_U,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD8_S,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD8_U,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD16_S,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD16_U,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD32_S,
+              &&HANDLE_LOAD_WASM_OP_I64_LOAD32_U
+          };
+          #define HANDLE_OP_LOAD(opcode) HANDLE_LOAD_##opcode
+          goto *handle_load_table[opcode - WASM_OP_I32_LOAD];
+#else
+          #define HANDLE_OP_LOAD(opcode) case opcode
+          switch (opcode)
+#endif
+          {
+            HANDLE_OP_LOAD(WASM_OP_I32_LOAD):
+              PUSH_I32(*(int32*)maddr);
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD):
+              PUSH_I64(GET_I64_FROM_ADDR((uint32*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_F32_LOAD):
+              PUSH_F32(*(float32*)maddr);
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_F64_LOAD):
+              PUSH_F64(GET_F64_FROM_ADDR((uint32*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_S):
+              PUSH_I32(sign_ext_8_32(*(int8*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I32_LOAD8_U):
+              PUSH_I32((uint32)(*(uint8*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_S):
+              PUSH_I32(sign_ext_16_32(*(int16*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I32_LOAD16_U):
+              PUSH_I32((uint32)(*(uint16*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_S):
+              PUSH_I64(sign_ext_8_64(*(int8*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD8_U):
+              PUSH_I64((uint64)(*(uint8*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_S):
+              PUSH_I64(sign_ext_16_64(*(int16*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD16_U):
+              PUSH_I64((uint64)(*(uint16*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_S):
+              PUSH_I64(sign_ext_32_64(*(int32*)maddr));
+              HANDLE_OP_END();
+            HANDLE_OP_LOAD(WASM_OP_I64_LOAD32_U):
+              PUSH_I64((uint64)(*(uint32*)maddr));
+              HANDLE_OP_END();
+          }
+          (void)flags;
+          HANDLE_OP_END ();
+        }
 
       /* memory store instructions */
-      HANDLE_OP (WASM_OP_I32_STORE):
-        DEF_OP_STORE(uint32, I32, *(int32*)maddr = sval);
-        HANDLE_OP_END ();
-
-      HANDLE_OP (WASM_OP_I64_STORE):
-        DEF_OP_STORE(uint64, I64, PUT_I64_TO_ADDR((uint32*)maddr, sval));
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_F32_STORE):
         {
           uint32 offset, flags, addr;
@@ -1241,25 +1269,63 @@ wasm_interp_call_func_bytecode(WASMThread *self,
           HANDLE_OP_END ();
         }
 
+      HANDLE_OP (WASM_OP_I32_STORE):
       HANDLE_OP (WASM_OP_I32_STORE8):
-        DEF_OP_STORE(uint32, I32, *(uint8*)maddr = (uint8)sval);
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I32_STORE16):
-        DEF_OP_STORE(uint32, I32, *(uint16*)maddr = (uint16)sval);
-        HANDLE_OP_END ();
+        {
+          uint32 offset, flags, addr;
+          uint32 sval;
+          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();
+          CHECK_MEMORY_OVERFLOW();
+          switch (opcode) {
+            case WASM_OP_I32_STORE:
+              *(int32*)maddr = sval;
+              break;
+            case WASM_OP_I32_STORE8:
+              *(uint8*)maddr = (uint8)sval;
+              break;
+            case WASM_OP_I32_STORE16:
+              *(uint16*)maddr = (uint16)sval;
+              break;
+          }
+          (void)flags;
+          HANDLE_OP_END ();
+        }
 
+      HANDLE_OP (WASM_OP_I64_STORE):
       HANDLE_OP (WASM_OP_I64_STORE8):
-        DEF_OP_STORE(uint64, I64, *(uint8*)maddr = (uint8)sval);
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_STORE16):
-        DEF_OP_STORE(uint64, I64, *(uint16*)maddr = (uint16)sval);
-        HANDLE_OP_END ();
-
       HANDLE_OP (WASM_OP_I64_STORE32):
-        DEF_OP_STORE(uint64, I64, *(uint32*)maddr = (uint32)sval);
-        HANDLE_OP_END ();
+        {
+          uint32 offset, flags, addr;
+          uint64 sval;
+          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();
+          CHECK_MEMORY_OVERFLOW();
+          switch (opcode) {
+            case WASM_OP_I64_STORE:
+              PUT_I64_TO_ADDR((uint32*)maddr, sval);
+              break;
+            case WASM_OP_I64_STORE8:
+              *(uint8*)maddr = (uint8)sval;
+              break;
+            case WASM_OP_I64_STORE16:
+              *(uint16*)maddr = (uint16)sval;
+              break;
+            case WASM_OP_I64_STORE32:
+              *(uint32*)maddr = (uint32)sval;
+              break;
+          }
+          (void)flags;
+          HANDLE_OP_END ();
+        }
 
       /* memory size and memory grow instructions */
       HANDLE_OP (WASM_OP_MEMORY_SIZE):

+ 5 - 12
core/iwasm/runtime/vmcore-wasm/wasm_runtime.c

@@ -947,18 +947,11 @@ wasm_runtime_instantiate(WASMModule *module,
     wasm_runtime_set_tlr(&module_inst->main_tlr);
     module_inst->main_tlr.handle = ws_self_thread();
 
-    /* Execute __post_instantiate function */
-    if (!execute_post_inst_function(module_inst)) {
-        const char *exception = wasm_runtime_get_exception(module_inst);
-        wasm_printf("%s\n", exception);
-        wasm_runtime_deinstantiate(module_inst);
-        return NULL;
-    }
-
-    /* Execute start function */
-    if (!execute_start_function(module_inst)) {
-        const char *exception = wasm_runtime_get_exception(module_inst);
-        wasm_printf("%s\n", exception);
+    /* Execute __post_instantiate and start function */
+    if (!execute_post_inst_function(module_inst)
+        || !execute_start_function(module_inst)) {
+        set_error_buf(error_buf, error_buf_size,
+                      module_inst->cur_exception);
         wasm_runtime_deinstantiate(module_inst);
         return NULL;
     }