Browse Source

Add build configuration for Mac (#110)

* Add build configuration for Mac

This patch implements Mac build basically based on Linux platform
implementations and configurations.

The document to build it on Mac has been updated as well.

* Update wasm_application.h

* Update lib_export.h

Add comments for the functions.
Jonathan Dong 6 years ago
parent
commit
8deef78624

+ 2 - 0
.gitignore

@@ -0,0 +1,2 @@
+.vscode
+**/*build/

+ 19 - 0
README.md

@@ -67,6 +67,25 @@ cd build
 cmake ..
 make
 ```
+
+Mac
+-------------------------
+Make sure to install Xcode from App Store firstly, and install cmake.
+
+If you use Homebrew, install cmake from the command line:
+``` Bash
+brew install cmake
+```
+
+Then build the source codes:
+```
+cd core/iwasm/products/darwin/
+mkdir build
+cd build
+cmake ..
+make
+```
+
 VxWorks
 -------------------------
 VxWorks 7 SR0620 release is validated.

+ 107 - 0
core/iwasm/products/darwin/CMakeLists.txt

@@ -0,0 +1,107 @@
+# Copyright (C) 2019 Intel Corporation.  All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required (VERSION 2.8)
+
+project (iwasm)
+
+set (PLATFORM "darwin")
+
+# Reset default linker flags
+set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
+set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
+
+# Enable repl mode if want to test spec cases
+# add_definitions(-DWASM_ENABLE_REPL)
+
+if (NOT ("$ENV{VALGRIND}" STREQUAL "YES"))
+  add_definitions(-DNVALGRIND)
+endif ()
+
+# Currently build as 64-bit by default.
+set (BUILD_AS_64BIT_SUPPORT "YES")
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+if (${BUILD_AS_64BIT_SUPPORT} STREQUAL "YES")
+  # Add -fPIC flag if build as 64-bit
+  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
+  set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -fPIC")
+else ()
+  add_definitions (-m32)
+  set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32")
+  set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
+endif ()
+endif ()
+
+if (NOT CMAKE_BUILD_TYPE)
+  set(CMAKE_BUILD_TYPE Release)
+endif (NOT CMAKE_BUILD_TYPE)
+message ("CMAKE_BUILD_TYPE = " ${CMAKE_BUILD_TYPE})
+
+set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl")
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections -Wall -Wno-unused-parameter -Wno-pedantic")
+
+set (CMAKE_MACOSX_RPATH True)
+
+set (SHARED_LIB_DIR ../../../shared-lib)
+
+include_directories (.
+                     ../../runtime/include
+                     ../../runtime/platform/include
+                     ${SHARED_LIB_DIR}/include)
+
+enable_language (ASM)
+
+include (../../runtime/platform/${PLATFORM}/platform.cmake)
+include (../../runtime/utils/utils.cmake)
+include (../../runtime/vmcore-wasm/vmcore.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)
+
+add_library (vmlib
+             ${WASM_PLATFORM_LIB_SOURCE}
+             ${WASM_UTILS_LIB_SOURCE}
+             ${VMCORE_LIB_SOURCE}
+             ${WASM_LIB_BASE_DIR}/base_lib_export.c
+             ${WASM_LIBC_SOURCE}
+             ${PLATFORM_SHARED_SOURCE}
+             ${MEM_ALLOC_SHARED_SOURCE}
+             ${UTILS_SHARED_SOURCE})
+
+add_executable (iwasm main.c ext_lib_export.c)
+
+install (TARGETS iwasm DESTINATION bin)
+
+target_link_libraries (iwasm vmlib -lm -ldl -lpthread)
+
+add_library (libiwasm SHARED
+             ${WASM_PLATFORM_LIB_SOURCE}
+             ${WASM_UTILS_LIB_SOURCE}
+             ${VMCORE_LIB_SOURCE}
+             ${WASM_LIB_BASE_DIR}/base_lib_export.c
+             ${WASM_LIBC_SOURCE}
+             ${PLATFORM_SHARED_SOURCE}
+             ${MEM_ALLOC_SHARED_SOURCE}
+             ${UTILS_SHARED_SOURCE}
+             ext_lib_export.c)
+
+install (TARGETS libiwasm DESTINATION lib)
+
+set_target_properties (libiwasm PROPERTIES OUTPUT_NAME iwasm)
+
+target_link_libraries (libiwasm -lm -ldl -lpthread)
+

+ 21 - 0
core/iwasm/products/darwin/ext_lib_export.c

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

+ 251 - 0
core/iwasm/products/darwin/main.c

@@ -0,0 +1,251 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "bh_platform.h"
+#include "wasm_application.h"
+#include "wasm_assert.h"
+#include "wasm_log.h"
+#include "wasm_platform_log.h"
+#include "wasm_thread.h"
+#include "wasm_export.h"
+#include "wasm_memory.h"
+#include "bh_memory.h"
+
+static int app_argc;
+static char **app_argv;
+
+static int print_help()
+{
+    wasm_printf("Usage: iwasm [-options] wasm_file [args...]\n");
+    wasm_printf("options:\n");
+    wasm_printf("  -f|--function name     Specify function name to run in module\n"
+                "                         rather than main\n");
+#if WASM_ENABLE_LOG != 0
+    wasm_printf("  -v=X                   Set log verbose level (0 to 2, default is 1),\n"
+                "                         larger level with more log\n");
+#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");
+    return 1;
+}
+
+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)))
+        wasm_printf("%s\n", exception);
+    return NULL;
+}
+
+static void*
+app_instance_func(wasm_module_inst_t module_inst, const char *func_name)
+{
+    const char *exception;
+
+    wasm_application_execute_func(module_inst, func_name, app_argc - 1,
+                                  app_argv + 1);
+    if ((exception = wasm_runtime_get_exception(module_inst)))
+        wasm_printf("%s\n", exception);
+    return NULL;
+}
+
+/**
+ * Split a space separated strings into an array of strings
+ * Returns NULL on failure
+ * Memory must be freed by caller
+ * Based on: http://stackoverflow.com/a/11198630/471795
+ */
+static char **
+split_string(char *str, int *count)
+{
+    char **res = NULL;
+    char *p;
+    int idx = 0;
+
+    /* split string and append tokens to 'res' */
+    do {
+        p = strtok(str, " ");
+        str = NULL;
+        res = (char**) realloc(res, sizeof(char*) * (idx + 1));
+        if (res == NULL) {
+            return NULL;
+        }
+        res[idx++] = p;
+    } while (p);
+
+    if (count) {
+        *count = idx - 1;
+    }
+    return res;
+}
+
+static void*
+app_instance_repl(wasm_module_inst_t module_inst)
+{
+    char *cmd = NULL;
+    size_t len = 0;
+    ssize_t n;
+
+    while ((wasm_printf("webassembly> "), n = getline(&cmd, &len, stdin)) != -1) {
+        wasm_assert(n > 0);
+        if (cmd[n - 1] == '\n') {
+            if (n == 1)
+                continue;
+            else
+                cmd[n - 1] = '\0';
+        }
+        app_argv = split_string(cmd, &app_argc);
+        if (app_argv == NULL) {
+            LOG_ERROR("Wasm prepare param failed: split string failed.\n");
+            break;
+        }
+        if (app_argc != 0) {
+            wasm_application_execute_func(module_inst, app_argv[0],
+                                          app_argc - 1, app_argv + 1);
+        }
+        free(app_argv);
+    }
+    free(cmd);
+    return NULL;
+}
+
+#define USE_GLOBAL_HEAP_BUF 0
+
+#if USE_GLOBAL_HEAP_BUF != 0
+static char global_heap_buf[10 * 1024 * 1024] = { 0 };
+#endif
+
+int main(int argc, char *argv[])
+{
+    char *wasm_file = NULL;
+    const char *func_name = NULL;
+    uint8 *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 WASM_ENABLE_LOG != 0
+    int log_verbose_level = 1;
+#endif
+    bool is_repl_mode = false;
+
+    /* Process options.  */
+    for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
+        if (!strcmp(argv[0], "-f") || !strcmp(argv[0], "--function")) {
+            argc--, argv++;
+            if (argc < 2) {
+                print_help();
+                return 0;
+            }
+            func_name = argv[0];
+        }
+#if WASM_ENABLE_LOG != 0
+        else if (!strncmp(argv[0], "-v=", 3)) {
+            log_verbose_level = atoi(argv[0] + 3);
+            if (log_verbose_level < 0 || log_verbose_level > 2)
+                return print_help();
+        }
+#endif
+        else if (!strcmp(argv[0], "--repl"))
+            is_repl_mode = true;
+        else
+            return print_help();
+    }
+
+    if (argc == 0)
+        return print_help();
+
+    wasm_file = argv[0];
+    app_argc = argc;
+    app_argv = argv;
+
+#if USE_GLOBAL_HEAP_BUF != 0
+    if (bh_memory_init_with_pool(global_heap_buf, sizeof(global_heap_buf))
+        != 0) {
+        wasm_printf("Init memory with global heap buffer failed.\n");
+        return -1;
+    }
+#else
+    if (bh_memory_init_with_allocator(malloc, free)) {
+        wasm_printf("Init memory with memory allocator failed.\n");
+        return -1;
+    }
+#endif
+
+    /* initialize runtime environment */
+    if (!wasm_runtime_init())
+        goto fail1;
+
+    wasm_log_set_verbose_level(log_verbose_level);
+
+    /* load WASM byte buffer from WASM bin file */
+    if (!(wasm_file_buf = (uint8*) bh_read_file_to_buffer(wasm_file,
+                                                          &wasm_file_size)))
+        goto fail2;
+
+    /* load WASM module */
+    if (!(wasm_module = wasm_runtime_load(wasm_file_buf, wasm_file_size,
+                                          error_buf, sizeof(error_buf)))) {
+        wasm_printf("%s\n", error_buf);
+        goto fail3;
+    }
+
+    /* instantiate the module */
+    if (!(wasm_module_inst = wasm_runtime_instantiate(wasm_module,
+                                                      64 * 1024, /* stack size */
+                                                      64 * 1024, /* heap size */
+                                                      error_buf,
+                                                      sizeof(error_buf)))) {
+        wasm_printf("%s\n", error_buf);
+        goto fail4;
+    }
+
+    if (is_repl_mode)
+        app_instance_repl(wasm_module_inst);
+    else if (func_name)
+        app_instance_func(wasm_module_inst, func_name);
+    else
+        app_instance_main(wasm_module_inst);
+
+    /* destroy the module instance */
+    wasm_runtime_deinstantiate(wasm_module_inst);
+
+fail4:
+    /* unload the module */
+    wasm_runtime_unload(wasm_module);
+
+fail3:
+    /* free the file buffer */
+    wasm_free(wasm_file_buf);
+
+fail2:
+    /* destroy runtime environment */
+    wasm_runtime_destroy();
+
+fail1:
+    bh_memory_destroy();
+    return 0;
+}
+

+ 7 - 1
core/iwasm/runtime/include/lib_export.h

@@ -40,7 +40,13 @@ int
 get_base_lib_export_apis(NativeSymbol **p_base_lib_apis);
 
 /**
- * Get the exported APIs of extend lib
+ * Get the exported APIs of extended lib, this API isn't provided by WASM VM,
+ * it must be provided by developer to register the extended native APIs,
+ * for example, developer can register his native APIs to extended_native_symbol_defs,
+ * array, and include file ext_lib_export.h which implements this API.
+ * And if developer hasn't any native API to register, he can define an empty
+ * extended_native_symbol_defs array, and then include file ext_lib_export.h to
+ * implements this API.
  *
  * @param p_base_lib_apis return the exported API array of extend lib
  *

+ 65 - 0
core/iwasm/runtime/include/wasm_application.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 Taobao (China) Inc.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _WASM_APPLICATION_H
+#define _WASM_APPLICATION_H
+
+//#include "wasm_runtime.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct WASMModuleInstance;
+
+/**
+ * Find the unique main function from a WASM module instance
+ * and execute that function.
+ *
+ * @param module_inst the WASM module instance
+ * @param argc the number of arguments
+ * @param argv the arguments array
+ *
+ * @return true if the main function is called, false otherwise and exception will be thrown,
+ *   the caller can call wasm_runtime_get_exception to get exception info.
+ */
+bool
+wasm_application_execute_main(struct WASMModuleInstance *module_inst,
+                              int argc, char *argv[]);
+
+/**
+ * Find the specified function in argv[0] from a WASM module instance
+ * and execute that function.
+ *
+ * @param module_inst the WASM module instance
+ * @param name the name of the function to execute
+ * @param argc the number of arguments
+ * @param argv the arguments array
+ *
+ * @return true if the specified function is called, false otherwise and exception will be thrown,
+ *   the caller can call wasm_runtime_get_exception to get exception info.
+ */
+bool
+wasm_application_execute_func(struct WASMModuleInstance *module_inst,
+                              char *name, int argc, char *argv[]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* end of _WASM_APPLICATION_H */
+

+ 25 - 0
core/iwasm/runtime/platform/darwin/platform.cmake

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

+ 25 - 0
core/iwasm/runtime/platform/darwin/wasm_native.c

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

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

@@ -18,6 +18,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "wasm.h"
+#include "wasm_application.h"
 #include "wasm_interp.h"
 #include "wasm_runtime.h"
 #include "wasm_thread.h"

+ 69 - 0
core/shared-lib/platform/darwin/bh_assert.c

@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_platform.h"
+#include "bh_assert.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef BH_TEST
+#include <setjmp.h>
+#endif
+
+#ifdef BH_TEST
+/* for exception throwing */
+jmp_buf bh_test_jb;
+#endif
+
+void bh_assert_internal(int v, const char *file_name, int line_number,
+        const char *expr_string)
+{
+    if (v)
+        return;
+
+    if (!file_name)
+        file_name = "NULL FILENAME";
+    if (!expr_string)
+        expr_string = "NULL EXPR_STRING";
+
+    printf("\nASSERTION FAILED: %s, at FILE=%s, LINE=%d\n", expr_string,
+            file_name, line_number);
+
+#ifdef BH_TEST
+    longjmp(bh_test_jb, 1);
+#endif
+
+    abort();
+}
+
+void bh_debug_internal(const char *file_name, int line_number, const char *fmt,
+        ...)
+{
+#ifndef JEFF_TEST_VERIFIER
+    va_list args;
+
+    va_start(args, fmt);
+    bh_assert(file_name);
+
+    printf("\nDebug info FILE=%s, LINE=%d: ", file_name, line_number);
+    vprintf(fmt, args);
+
+    va_end(args);
+    printf("\n");
+#endif
+}
+

+ 81 - 0
core/shared-lib/platform/darwin/bh_definition.c

@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_definition.h"
+#include "bh_platform.h"
+
+int bh_return(int ret)
+{
+    return ret;
+}
+
+#define RSIZE_MAX 0x7FFFFFFF
+int b_memcpy_s(void * s1, unsigned int s1max, const void * s2, unsigned int n)
+{
+    char *dest = (char*) s1;
+    char *src = (char*) s2;
+    if (n == 0) {
+        return 0;
+    }
+
+    if (s1 == NULL || s1max > RSIZE_MAX) {
+        return -1;
+    }
+    if (s2 == NULL || n > s1max) {
+        memset(dest, 0, s1max);
+        return -1;
+    }
+    memcpy(dest, src, n);
+    return 0;
+}
+
+int b_strcat_s(char * s1, size_t s1max, const char * s2)
+{
+    if (NULL
+            == s1|| NULL == s2 || s1max < (strlen(s1) + strlen(s2) + 1) || s1max > RSIZE_MAX) {
+        return -1;
+    }
+
+    strcat(s1, s2);
+
+    return 0;
+}
+
+int b_strcpy_s(char * s1, size_t s1max, const char * s2)
+{
+    if (NULL
+            == s1|| NULL == s2 || s1max < (strlen(s2) + 1) || s1max > RSIZE_MAX) {
+        return -1;
+    }
+
+    strcpy(s1, s2);
+
+    return 0;
+}
+
+int fopen_s(FILE ** pFile, const char *filename, const char *mode)
+{
+    if (NULL == pFile || NULL == filename || NULL == mode) {
+        return -1;
+    }
+
+    *pFile = fopen(filename, mode);
+
+    if (NULL == *pFile)
+        return -1;
+
+    return 0;
+}

+ 82 - 0
core/shared-lib/platform/darwin/bh_platform.c

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

+ 122 - 0
core/shared-lib/platform/darwin/bh_platform.h

@@ -0,0 +1,122 @@
+/*
+ * 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_PLATFORM_H
+#define _BH_PLATFORM_H
+
+#include "bh_config.h"
+#include "bh_types.h"
+#include "bh_memory.h"
+#include <inttypes.h>
+#include <stdbool.h>
+#include <assert.h>
+#include <time.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <stdarg.h>
+#include <ctype.h>
+#include <pthread.h>
+#include <limits.h>
+#include <semaphore.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef uint64_t uint64;
+typedef int64_t int64;
+
+extern void DEBUGME(void);
+
+#define DIE do{bh_debug("Die here\n\n\n\n\n\n\n\n\n\n\n\n\n\n"); DEBUGME(void); while(1);}while(0)
+
+#define BH_PLATFORM "Darwin"
+
+/* NEED qsort */
+
+#define _STACK_SIZE_ADJUSTMENT (32 * 1024)
+
+/* Stack size of applet threads's native part.  */
+#define BH_APPLET_PRESERVED_STACK_SIZE      (8 * 1024 + _STACK_SIZE_ADJUSTMENT)
+
+/* Default thread priority */
+#define BH_THREAD_DEFAULT_PRIORITY 0
+
+#define BH_ROUTINE_MODIFIER
+
+#define BHT_TIMEDOUT ETIMEDOUT
+
+#define INVALID_THREAD_ID 0xFFffFFff
+
+typedef pthread_t korp_tid;
+typedef pthread_mutex_t korp_mutex;
+typedef sem_t korp_sem;
+typedef pthread_cond_t korp_cond;
+typedef pthread_t korp_thread;
+typedef void* (*thread_start_routine_t)(void*);
+
+#define wa_malloc bh_malloc
+#define wa_free bh_free
+#define wa_strdup bh_strdup
+
+//int snprintf(char *buffer, size_t count, const char *format, ...);
+double fmod(double x, double y);
+float fmodf(float x, float y);
+double sqrt(double x);
+
+#define BH_WAIT_FOREVER 0xFFFFFFFF
+
+#ifndef NULL
+#  define NULL ((void*) 0)
+#endif
+
+/**
+ * Return the offset of the given field in the given type.
+ *
+ * @param Type the type containing the filed
+ * @param field the field in the type
+ *
+ * @return the offset of field in Type
+ */
+#ifndef offsetof
+#define offsetof(Type, field) ((size_t)(&((Type *)0)->field))
+#endif
+
+#define bh_assert assert
+
+int b_memcpy_s(void * s1, unsigned int s1max, const void * s2,
+               unsigned int n);
+int b_strcat_s(char * s1, size_t s1max, const char * s2);
+int b_strcpy_s(char * s1, size_t s1max, const char * s2);
+
+int fopen_s(FILE ** pFile, const char *filename, const char *mode);
+
+char *bh_read_file_to_buffer(const char *filename, int *ret_size);
+
+char *bh_strdup(const char *s);
+
+int bh_platform_init();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 41 - 0
core/shared-lib/platform/darwin/bh_platform_log.c

@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_platform.h"
+#include <stdio.h>
+
+void bh_log_emit(const char *fmt, va_list ap)
+{
+    vprintf(fmt, ap);
+    fflush(stdout);
+}
+
+int bh_fprintf(FILE *stream, const char *fmt, ...)
+{
+    va_list ap;
+    int ret;
+
+    va_start(ap, fmt);
+    ret = vfprintf(stream ? stream : stdout, fmt, ap);
+    va_end(ap);
+
+    return ret;
+}
+
+int bh_fflush(void *stream)
+{
+    return fflush(stream ? stream : stdout);
+}

+ 405 - 0
core/shared-lib/platform/darwin/bh_thread.c

@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_thread.h"
+#include "bh_assert.h"
+#include "bh_log.h"
+#include "bh_memory.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+
+static bool is_thread_sys_inited = false;
+
+static korp_mutex thread_list_lock;
+static pthread_key_t thread_local_storage_key[BH_MAX_TLS_NUM];
+
+int _vm_thread_sys_init()
+{
+    unsigned i, j;
+    int ret;
+
+    if (is_thread_sys_inited)
+        return 0;
+
+    for (i = 0; i < BH_MAX_TLS_NUM; i++) {
+        ret = pthread_key_create(&thread_local_storage_key[i], NULL);
+        if (ret)
+            goto fail;
+    }
+
+    ret = vm_mutex_init(&thread_list_lock);
+    if (ret)
+        goto fail;
+
+    is_thread_sys_inited = true;
+    return 0;
+
+    fail: for (j = 0; j < i; j++)
+        pthread_key_delete(thread_local_storage_key[j]);
+    return -1;
+}
+
+void vm_thread_sys_destroy(void)
+{
+    if (is_thread_sys_inited) {
+        unsigned i;
+        for (i = 0; i < BH_MAX_TLS_NUM; i++)
+            pthread_key_delete(thread_local_storage_key[i]);
+        vm_mutex_destroy(&thread_list_lock);
+        is_thread_sys_inited = false;
+    }
+}
+
+typedef struct {
+    thread_start_routine_t start;
+    void* stack;
+    int stack_size;
+    void* arg;
+} thread_wrapper_arg;
+
+static void *vm_thread_wrapper(void *arg)
+{
+    thread_wrapper_arg * targ = arg;
+    LOG_VERBOSE("THREAD CREATE 0x%08x\n", &targ);
+    targ->stack = (void *)((uintptr_t)(&arg) & ~0xfff);
+    _vm_tls_put(1, targ);
+    targ->start(targ->arg);
+    bh_free(targ);
+    _vm_tls_put(1, NULL);
+    return NULL;
+}
+
+int _vm_thread_create_with_prio(korp_tid *tid, thread_start_routine_t start,
+        void *arg, unsigned int stack_size, int prio)
+{
+    pthread_attr_t tattr;
+    thread_wrapper_arg *targ;
+
+    bh_assert(stack_size > 0);
+    bh_assert(tid);
+    bh_assert(start);
+
+    *tid = INVALID_THREAD_ID;
+
+    pthread_attr_init(&tattr);
+    pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_JOINABLE);
+    if (pthread_attr_setstacksize(&tattr, stack_size) != 0) {
+        bh_debug("Invalid thread stack size %u. Min stack size on Linux = %u",
+                stack_size, PTHREAD_STACK_MIN);
+        pthread_attr_destroy(&tattr);
+        return BHT_ERROR;
+    }
+
+    targ = (thread_wrapper_arg*) bh_malloc(sizeof(*targ));
+    if (!targ) {
+        pthread_attr_destroy(&tattr);
+        return BHT_ERROR;
+    }
+
+    targ->start = start;
+    targ->arg = arg;
+    targ->stack_size = stack_size;
+
+    if (pthread_create(tid, &tattr, vm_thread_wrapper, targ) != 0) {
+        pthread_attr_destroy(&tattr);
+        bh_free(targ);
+        return BHT_ERROR;
+    }
+
+    pthread_attr_destroy(&tattr);
+    return BHT_OK;
+}
+
+int _vm_thread_create(korp_tid *tid, thread_start_routine_t start, void *arg,
+        unsigned int stack_size)
+{
+    return _vm_thread_create_with_prio(tid, start, arg, stack_size,
+                                       BH_THREAD_DEFAULT_PRIORITY);
+}
+
+korp_tid _vm_self_thread()
+{
+    return (korp_tid) pthread_self();
+}
+
+void vm_thread_exit(void * code)
+{
+    bh_free(_vm_tls_get(1));
+    _vm_tls_put(1, NULL);
+    pthread_exit(code);
+}
+
+void *_vm_tls_get(unsigned idx)
+{
+    bh_assert(idx < BH_MAX_TLS_NUM);
+    return pthread_getspecific(thread_local_storage_key[idx]);
+}
+
+int _vm_tls_put(unsigned idx, void * tls)
+{
+    bh_assert(idx < BH_MAX_TLS_NUM);
+    pthread_setspecific(thread_local_storage_key[idx], tls);
+    return BHT_OK;
+}
+
+int _vm_mutex_init(korp_mutex *mutex)
+{
+    return pthread_mutex_init(mutex, NULL) == 0 ? BHT_OK : BHT_ERROR;
+}
+
+int _vm_recursive_mutex_init(korp_mutex *mutex)
+{
+    int ret;
+
+    pthread_mutexattr_t mattr;
+
+    bh_assert(mutex);
+    ret = pthread_mutexattr_init(&mattr);
+    if (ret)
+        return BHT_ERROR;
+
+    pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE);
+    ret = pthread_mutex_init(mutex, &mattr);
+    pthread_mutexattr_destroy(&mattr);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+int _vm_mutex_destroy(korp_mutex *mutex)
+{
+    int ret;
+
+    bh_assert(mutex);
+    ret = pthread_mutex_destroy(mutex);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+/* Returned error (EINVAL, EAGAIN and EDEADLK) from
+ locking the mutex indicates some logic error present in
+ the program somewhere.
+ Don't try to recover error for an existing unknown error.*/
+void vm_mutex_lock(korp_mutex *mutex)
+{
+    int ret;
+
+    bh_assert(mutex);
+    ret = pthread_mutex_lock(mutex);
+    if (0 != ret) {
+        printf("vm mutex lock failed (ret=%d)!\n", ret);
+        exit(-1);
+    }
+}
+
+int vm_mutex_trylock(korp_mutex *mutex)
+{
+    int ret;
+
+    bh_assert(mutex);
+    ret = pthread_mutex_trylock(mutex);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+/* Returned error (EINVAL, EAGAIN and EPERM) from
+ unlocking the mutex indicates some logic error present
+ in the program somewhere.
+ Don't try to recover error for an existing unknown error.*/
+void vm_mutex_unlock(korp_mutex *mutex)
+{
+    int ret;
+
+    bh_assert(mutex);
+    ret = pthread_mutex_unlock(mutex);
+    if (0 != ret) {
+        printf("vm mutex unlock failed (ret=%d)!\n", ret);
+        exit(-1);
+    }
+}
+
+int _vm_sem_init(korp_sem* sem, unsigned int c)
+{
+    int ret;
+
+    bh_assert(sem);
+    ret = sem_init(sem, 0, c);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+int _vm_sem_destroy(korp_sem *sem)
+{
+    int ret;
+
+    bh_assert(sem);
+    ret = sem_destroy(sem);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+int _vm_sem_wait(korp_sem *sem)
+{
+    int ret;
+
+    bh_assert(sem);
+
+    ret = sem_wait(sem);
+
+    return ret == 0 ? BHT_OK : BHT_ERROR;
+}
+
+/*int _vm_sem_reltimedwait(korp_sem *sem, int mills)
+{
+    int ret = BHT_OK;
+
+    struct timespec timeout;
+    const int mills_per_sec = 1000;
+    const int mills_to_nsec = 1E6;
+
+    bh_assert(sem);
+
+    if (mills == BHT_WAIT_FOREVER) {
+        ret = sem_wait(sem);
+    } else {
+
+        timeout.tv_sec = mills / mills_per_sec;
+        timeout.tv_nsec = (mills % mills_per_sec) * mills_to_nsec;
+        timeout.tv_sec += time(NULL);
+
+        ret = sem_timedwait(sem, &timeout);
+    }
+
+    if (ret != BHT_OK) {
+        if (errno == BHT_TIMEDOUT) {
+            ret = BHT_TIMEDOUT;
+            errno = 0;
+        } else {
+            bh_debug("Faliure happens when timed wait is called");
+            bh_assert(0);
+        }
+    }
+
+    return ret;
+}
+*/
+
+int _vm_sem_post(korp_sem *sem)
+{
+    bh_assert(sem);
+
+    return sem_post(sem) == 0 ? BHT_OK : BHT_ERROR;
+}
+
+int _vm_cond_init(korp_cond *cond)
+{
+    bh_assert(cond);
+
+    if (pthread_cond_init(cond, NULL) != BHT_OK)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+int _vm_cond_destroy(korp_cond *cond)
+{
+    bh_assert(cond);
+
+    if (pthread_cond_destroy(cond) != BHT_OK)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+int _vm_cond_wait(korp_cond *cond, korp_mutex *mutex)
+{
+    bh_assert(cond);
+    bh_assert(mutex);
+
+    if (pthread_cond_wait(cond, mutex) != BHT_OK)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+static void msec_nsec_to_abstime(struct timespec *ts, int64 msec, int32 nsec)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+
+    ts->tv_sec = tv.tv_sec + msec / 1000;
+    ts->tv_nsec = tv.tv_usec * 1000 + (msec % 1000) * 1000000 + nsec;
+
+    if (ts->tv_nsec >= 1000000000L) {
+        ts->tv_sec++;
+        ts->tv_nsec -= 1000000000L;
+    }
+}
+
+int _vm_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, int mills)
+{
+    int ret;
+    struct timespec abstime;
+
+    if (mills == BHT_WAIT_FOREVER)
+        ret = pthread_cond_wait(cond, mutex);
+    else {
+        msec_nsec_to_abstime(&abstime, mills, 0);
+        ret = pthread_cond_timedwait(cond, mutex, &abstime);
+    }
+
+    if (ret != BHT_OK && ret != BHT_TIMEDOUT)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+int _vm_cond_signal(korp_cond *cond)
+{
+    bh_assert(cond);
+
+    if (pthread_cond_signal(cond) != BHT_OK)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+int _vm_cond_broadcast(korp_cond *cond)
+{
+    bh_assert(cond);
+
+    if (pthread_cond_broadcast(cond) != BHT_OK)
+        return BHT_ERROR;
+
+    return BHT_OK;
+}
+
+int _vm_thread_cancel(korp_tid thread)
+{
+    return pthread_cancel(thread);
+}
+
+int _vm_thread_join(korp_tid thread, void **value_ptr, int mills)
+{
+    return pthread_join(thread, value_ptr);
+}
+
+int _vm_thread_detach(korp_tid thread)
+{
+    return pthread_detach(thread);
+}
+

+ 80 - 0
core/shared-lib/platform/darwin/bh_time.c

@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2019 Intel Corporation.  All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bh_time.h"
+
+#include <unistd.h>
+#include <stdio.h>
+#include <sys/timeb.h>
+#include <time.h>
+
+/*
+ * This function returns milliseconds per tick.
+ * @return milliseconds per tick.
+ */
+uint64 _bh_time_get_tick_millisecond()
+{
+    return sysconf(_SC_CLK_TCK);
+}
+
+/*
+ * This function returns milliseconds after boot.
+ * @return milliseconds after boot.
+ */
+uint64 _bh_time_get_boot_millisecond()
+{
+    struct timespec ts;
+    if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
+        return 0;
+    }
+
+    return ((uint64) ts.tv_sec) * 1000 + ts.tv_nsec / (1000 * 1000);
+}
+
+uint32 bh_get_tick_sec()
+{
+    return _bh_time_get_boot_millisecond() / 1000;
+}
+
+/*
+ * This function returns GMT time milliseconds since from 1970.1.1, AKA UNIX time.
+ * @return milliseconds since from 1970.1.1.
+ */
+uint64 _bh_time_get_millisecond_from_1970()
+{
+    struct timeb tp;
+    ftime(&tp);
+
+    return ((uint64) tp.time) * 1000 + tp.millitm
+            - (tp.dstflag == 0 ? 0 : 60 * 60 * 1000) + tp.timezone * 60 * 1000;
+}
+
+size_t _bh_time_strftime(char *s, size_t max, const char *format, int64 time)
+{
+    time_t time_sec = time / 1000;
+    struct timeb tp;
+    struct tm *ltp;
+
+    ftime(&tp);
+    time_sec -= tp.timezone * 60;
+
+    ltp = localtime(&time_sec);
+    if (ltp == NULL) {
+        return 0;
+    }
+    return strftime(s, max, format, ltp);
+}
+

+ 24 - 0
core/shared-lib/platform/darwin/shared_platform.cmake

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