Browse Source

Implement register/call native API with raw (unextracted) arguments (#222)

wenyongh 5 years ago
parent
commit
c1a0e6d877

+ 3 - 1
core/iwasm/aot/aot_loader.c

@@ -786,7 +786,9 @@ load_import_funcs(const uint8 **p_buf, const uint8 *buf_end,
         if (!(import_funcs[i].func_ptr_linked =
                     wasm_native_resolve_symbol(module_name, field_name,
                                                import_funcs[i].func_type,
-                                               &import_funcs[i].signature))) {
+                                               &import_funcs[i].signature,
+                                               &import_funcs[i].attachment,
+                                               &import_funcs[i].call_conv_raw))) {
             LOG_WARNING("warning: fail to link import function (%s, %s)\n",
                         module_name, field_name);
         }

+ 28 - 12
core/iwasm/aot/aot_runtime.c

@@ -457,7 +457,7 @@ aot_call_function(WASMExecEnv *exec_env,
     AOTModuleInstance *module_inst = (AOTModuleInstance*)exec_env->module_inst;
     AOTFuncType *func_type = function->func_type;
     bool ret = wasm_runtime_invoke_native(exec_env, function->func_ptr,
-                                          func_type, NULL, argv, argc, argv);
+                                          func_type, NULL, NULL, argv, argc, argv);
     return ret && !aot_get_exception(module_inst) ? true : false;
 }
 
@@ -824,7 +824,8 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
     void **func_ptrs = (void**)module_inst->func_ptrs.ptr;
     void *func_ptr = func_ptrs[func_idx];
     AOTImportFunc *import_func;
-    const char *signature = NULL;
+    const char *signature;
+    void *attachment;
     char buf[128];
 
     bh_assert(func_idx < aot_module->import_func_count);
@@ -839,9 +840,17 @@ aot_invoke_native(WASMExecEnv *exec_env, uint32 func_idx,
     }
 
     signature = import_func->signature;
-    return wasm_runtime_invoke_native(exec_env, func_ptr,
-                                      func_type, signature,
-                                      frame_lp, argc, argv_ret);
+    attachment = import_func->attachment;
+    if (!import_func->call_conv_raw) {
+        return wasm_runtime_invoke_native(exec_env, func_ptr,
+                                          func_type, signature, attachment,
+                                          frame_lp, argc, argv_ret);
+    }
+    else {
+        return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
+                                              func_type, signature, attachment,
+                                              frame_lp, argc, argv_ret);
+    }
 }
 
 bool
@@ -860,6 +869,7 @@ aot_call_indirect(WASMExecEnv *exec_env,
     uint32 func_idx, func_type_idx1;
     AOTImportFunc *import_func;
     const char *signature = NULL;
+    void *attachment = NULL;
     char buf[128];
 
     if (table_elem_idx >= table_size) {
@@ -879,12 +889,6 @@ aot_call_indirect(WASMExecEnv *exec_env,
         return false;
     }
 
-    if (func_idx < aot_module->import_func_count) {
-        /* Call native function */
-        import_func = aot_module->import_funcs + func_idx;
-        signature = import_func->signature;
-    }
-
     if (!(func_ptr = func_ptrs[func_idx])) {
         bh_assert(func_idx < aot_module->import_func_count);
         import_func = aot_module->import_funcs + func_idx;
@@ -895,8 +899,20 @@ aot_call_indirect(WASMExecEnv *exec_env,
         return false;
     }
 
+    if (func_idx < aot_module->import_func_count) {
+        /* Call native function */
+        import_func = aot_module->import_funcs + func_idx;
+        signature = import_func->signature;
+        if (import_func->call_conv_raw) {
+            attachment = import_func->attachment;
+            return wasm_runtime_invoke_native_raw(exec_env, func_ptr,
+                                                  func_type, signature, attachment,
+                                                  frame_lp, argc, argv_ret);
+        }
+    }
+
     return wasm_runtime_invoke_native(exec_env, func_ptr,
-                                      func_type, signature,
+                                      func_type, signature, attachment,
                                       frame_lp, argc, argv_ret);
 }
 

+ 5 - 0
core/iwasm/common/wasm_exec_env.h

@@ -33,6 +33,11 @@ typedef struct WASMExecEnv {
     uint32 *argv_buf;
 #endif
 
+    /* attachment for native function */
+    void *attachment;
+
+    void *user_data;
+
     /* Current interpreter frame of current thread */
     struct WASMInterpFrame *cur_frame;
 

+ 33 - 9
core/iwasm/common/wasm_native.c

@@ -110,7 +110,7 @@ sort_symbol_ptr(NativeSymbol *native_symbols, uint32 n_native_symbols)
 
 static void *
 lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
-              const char *symbol, const char **p_signature)
+              const char *symbol, const char **p_signature, void **p_attachment)
 {
     int low = 0, mid, ret;
     int high = n_native_symbols - 1;
@@ -120,6 +120,7 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
         ret = strcmp(symbol, native_symbols[mid].symbol);
         if (ret == 0) {
             *p_signature = native_symbols[mid].signature;
+            *p_attachment = native_symbols[mid].attachment;
             return native_symbols[mid].func_ptr;
         }
         else if (ret < 0)
@@ -133,11 +134,12 @@ lookup_symbol(NativeSymbol *native_symbols, uint32 n_native_symbols,
 
 void*
 wasm_native_resolve_symbol(const char *module_name, const char *field_name,
-                           const WASMType *func_type, const char **p_signature)
+                           const WASMType *func_type, const char **p_signature,
+                           void **p_attachment, bool *p_call_conv_raw)
 {
     NativeSymbolsNode *node, *node_next;
     const char *signature = NULL;
-    void *func_ptr = NULL;
+    void *func_ptr = NULL, *attachment;
 
     node = g_native_symbols_list;
     while (node) {
@@ -145,11 +147,12 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
         if (!strcmp(node->module_name, module_name)) {
             if ((func_ptr = lookup_symbol(node->native_symbols,
                                           node->n_native_symbols,
-                                          field_name, &signature))
+                                          field_name, &signature, &attachment))
                 || (field_name[0] == '_'
                     && (func_ptr = lookup_symbol(node->native_symbols,
                                                  node->n_native_symbols,
-                                                 field_name + 1, &signature))))
+                                                 field_name + 1,
+                                                 &signature, &attachment))))
             break;
         }
         node = node_next;
@@ -172,15 +175,19 @@ wasm_native_resolve_symbol(const char *module_name, const char *field_name,
         else
             /* signature is empty */
             *p_signature = NULL;
+
+        *p_attachment = attachment;
+        *p_call_conv_raw = node->call_conv_raw;
     }
 
     return func_ptr;
 }
 
-bool
-wasm_native_register_natives(const char *module_name,
-                             NativeSymbol *native_symbols,
-                             uint32 n_native_symbols)
+static bool
+register_natives(const char *module_name,
+                 NativeSymbol *native_symbols,
+                 uint32 n_native_symbols,
+                 bool call_conv_raw)
 {
     NativeSymbolsNode *node;
 
@@ -190,6 +197,7 @@ wasm_native_register_natives(const char *module_name,
     node->module_name = module_name;
     node->native_symbols = native_symbols;
     node->n_native_symbols = n_native_symbols;
+    node->call_conv_raw = call_conv_raw;
     node->next = NULL;
 
     if (g_native_symbols_list_end) {
@@ -204,6 +212,22 @@ wasm_native_register_natives(const char *module_name,
     return true;
 }
 
+bool
+wasm_native_register_natives(const char *module_name,
+                             NativeSymbol *native_symbols,
+                             uint32 n_native_symbols)
+{
+    return register_natives(module_name, native_symbols, n_native_symbols, false);
+}
+
+bool
+wasm_native_register_natives_raw(const char *module_name,
+                                 NativeSymbol *native_symbols,
+                                 uint32 n_native_symbols)
+{
+    return register_natives(module_name, native_symbols, n_native_symbols, true);
+}
+
 bool
 wasm_native_init()
 {

+ 8 - 1
core/iwasm/common/wasm_native.h

@@ -19,6 +19,7 @@ typedef struct NativeSymbolsNode {
     const char *module_name;
     NativeSymbol *native_symbols;
     uint32 n_native_symbols;
+    bool call_conv_raw;
 } NativeSymbolsNode, *NativeSymbolsList;
 
 /**
@@ -50,13 +51,19 @@ wasm_native_lookup_libc_builtin_global(const char *module_name,
  */
 void*
 wasm_native_resolve_symbol(const char *module_name, const char *field_name,
-                           const WASMType *func_type, const char **p_signature);
+                           const WASMType *func_type, const char **p_signature,
+                           void **p_attachment, bool *p_call_conv_raw);
 
 bool
 wasm_native_register_natives(const char *module_name,
                              NativeSymbol *native_symbols,
                              uint32 n_native_symbols);
 
+bool
+wasm_native_register_natives_raw(const char *module_name,
+                                 NativeSymbol *native_symbols,
+                                 uint32 n_native_symbols);
+
 bool
 wasm_native_init();
 

+ 141 - 0
core/iwasm/common/wasm_runtime_common.c

@@ -233,6 +233,24 @@ wasm_runtime_get_module_inst(WASMExecEnv *exec_env)
     return wasm_exec_env_get_module_inst(exec_env);
 }
 
+void *
+wasm_runtime_get_function_attachment(WASMExecEnv *exec_env)
+{
+    return exec_env->attachment;
+}
+
+void
+wasm_runtime_set_user_data(WASMExecEnv *exec_env, void *user_data)
+{
+    exec_env->user_data = user_data;
+}
+
+void *
+wasm_runtime_get_user_data(WASMExecEnv *exec_env)
+{
+    return exec_env->user_data;
+}
+
 WASMFunctionInstanceCommon *
 wasm_runtime_lookup_function(WASMModuleInstanceCommon * const module_inst,
                              const char *name,
@@ -1421,6 +1439,120 @@ wasm_runtime_register_natives(const char *module_name,
                                         native_symbols, n_native_symbols);
 }
 
+bool
+wasm_runtime_register_natives_raw(const char *module_name,
+                                  NativeSymbol *native_symbols,
+                                  uint32 n_native_symbols)
+{
+    return wasm_native_register_natives_raw(module_name,
+                                            native_symbols, n_native_symbols);
+}
+
+bool
+wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
+                               const WASMType *func_type, const char *signature,
+                               void *attachment,
+                               uint32 *argv, uint32 argc, uint32 *argv_ret)
+{
+    WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
+    typedef void (*NativeRawFuncPtr)(WASMExecEnv*, uint64*);
+    NativeRawFuncPtr invokeNativeRaw = (NativeRawFuncPtr)func_ptr;
+    uint64 argv_buf[16] = { 0 }, *argv1 = argv_buf, *argv_dst, size;
+    uint32 *argv_src = argv, i, argc1, ptr_len;
+    int32 arg_i32;
+    bool ret = false;
+
+    argc1 = func_type->param_count;
+    if (argc1 > sizeof(argv_buf) / sizeof(uint64)) {
+        size = sizeof(uint64) * (uint64)argc1;
+        if (size >= UINT32_MAX
+            || !(argv1 = wasm_runtime_malloc((uint32)size))) {
+            wasm_runtime_set_exception(exec_env->module_inst,
+                                       "allocate memory failed.");
+            return false;
+        }
+        memset(argv1, 0, (uint32)size);
+    }
+
+    argv_dst = argv1;
+
+    /* Traverse secondly to fill in each argument */
+    for (i = 0; i < func_type->param_count; i++, argv_dst++) {
+        switch (func_type->types[i]) {
+            case VALUE_TYPE_I32:
+            {
+                *(int32*)argv_dst = arg_i32 = (int32)*argv_src++;
+                if (signature) {
+                    if (signature[i + 1] == '*') {
+                        /* param is a pointer */
+                        if (signature[i + 2] == '~')
+                            /* pointer with length followed */
+                            ptr_len = *argv_src;
+                        else
+                            /* pointer without length followed */
+                            ptr_len = 1;
+
+                        if (!wasm_runtime_validate_app_addr(module, arg_i32, ptr_len))
+                            goto fail;
+
+                        *(uintptr_t*)argv_dst = (uintptr_t)
+                                      wasm_runtime_addr_app_to_native(module, arg_i32);
+                    }
+                    else if (signature[i + 1] == '$') {
+                        /* param is a string */
+                        if (!wasm_runtime_validate_app_str_addr(module, arg_i32))
+                            goto fail;
+
+                        *(uintptr_t*)argv_dst = (uintptr_t)
+                                      wasm_runtime_addr_app_to_native(module, arg_i32);
+                    }
+                }
+                break;
+            }
+            case VALUE_TYPE_I64:
+            case VALUE_TYPE_F64:
+                bh_memcpy_s(argv_dst, sizeof(uint64), argv_src, sizeof(uint32) * 2);
+                argv_src += 2;
+                break;
+            case VALUE_TYPE_F32:
+                *(float32*)argv_dst = *(float32*)argv_src++;
+                break;
+            default:
+                bh_assert(0);
+                break;
+        }
+    }
+
+    exec_env->attachment = attachment;
+    invokeNativeRaw(exec_env, argv1);
+    exec_env->attachment = NULL;
+
+    if (func_type->result_count > 0) {
+        switch (func_type->types[func_type->param_count]) {
+            case VALUE_TYPE_I32:
+                argv_ret[0] = *(uint32*)argv1;
+                break;
+            case VALUE_TYPE_F32:
+                *(float32*)argv_ret = *(float32*)argv1;
+                break;
+            case VALUE_TYPE_I64:
+            case VALUE_TYPE_F64:
+                bh_memcpy_s(argv_ret, sizeof(uint32) * 2, argv1, sizeof(uint64));
+                break;
+            default:
+                bh_assert(0);
+                break;
+        }
+    }
+
+    ret = true;
+
+fail:
+    if (argv1 != argv_buf)
+        wasm_runtime_free(argv1);
+     return ret;
+}
+
 /**
  * Implementation of wasm_runtime_invoke_native()
  */
@@ -1469,6 +1601,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
 bool
 wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                            const WASMType *func_type, const char *signature,
+                           void *attachment,
                            uint32 *argv, uint32 argc, uint32 *argv_ret)
 {
     WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
@@ -1634,6 +1767,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
         }
     }
 
+    exec_env->attachment = attachment;
     if (func_type->result_count == 0) {
         invokeNative_Void(func_ptr, argv1, n_stacks);
     }
@@ -1656,6 +1790,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                 break;
         }
     }
+    exec_env->attachment = NULL;
 
     ret = true;
 
@@ -1689,6 +1824,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)invokeNative;
 bool
 wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                            const WASMType *func_type, const char *signature,
+                           void *attachment,
                            uint32 *argv, uint32 argc, uint32 *argv_ret)
 {
     WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
@@ -1774,6 +1910,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
     }
 
     argc1 = j;
+    exec_env->attachment = attachment;
     if (func_type->result_count == 0) {
         invokeNative_Void(func_ptr, argv1, argc1);
     }
@@ -1796,6 +1933,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                 break;
         }
     }
+    exec_env->attachment = NULL;
 
     ret = true;
 
@@ -1844,6 +1982,7 @@ static VoidFuncPtr invokeNative_Void = (VoidFuncPtr)(uintptr_t)invokeNative;
 bool
 wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                            const WASMType *func_type, const char *signature,
+                           void *attachment,
                            uint32 *argv, uint32 argc, uint32 *argv_ret)
 {
     WASMModuleInstanceCommon *module = wasm_runtime_get_module_inst(exec_env);
@@ -1938,6 +2077,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
         }
     }
 
+    exec_env->attachment = attachment;
     if (func_type->result_count == 0) {
         invokeNative_Void(func_ptr, argv1, n_stacks);
     }
@@ -1960,6 +2100,7 @@ wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                 break;
         }
     }
+    exec_env->attachment = NULL;
 
     ret = true;
 fail:

+ 25 - 0
core/iwasm/common/wasm_runtime_common.h

@@ -113,6 +113,18 @@ wasm_runtime_destroy_exec_env(WASMExecEnv *exec_env);
 WASMModuleInstanceCommon *
 wasm_runtime_get_module_inst(WASMExecEnv *exec_env);
 
+/* See wasm_export.h for description */
+void *
+wasm_runtime_get_function_attachment(wasm_exec_env_t exec_env);
+
+/* See wasm_export.h for description */
+void
+wasm_runtime_set_user_data(wasm_exec_env_t exec_env, void *user_data);
+
+/* See wasm_export.h for description */
+void *
+wasm_runtime_get_user_data(wasm_exec_env_t exec_env);
+
 /* See wasm_export.h for description */
 bool
 wasm_runtime_call_wasm(WASMExecEnv *exec_env,
@@ -275,11 +287,24 @@ wasm_runtime_register_natives(const char *module_name,
                               NativeSymbol *native_symbols,
                               uint32 n_native_symbols);
 
+/* See wasm_export.h for description */
+bool
+wasm_runtime_register_natives_raw(const char *module_name,
+                                  NativeSymbol *native_symbols,
+                                  uint32 n_native_symbols);
+
 bool
 wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
                            const WASMType *func_type, const char *signature,
+                           void *attachment,
                            uint32 *argv, uint32 argc, uint32 *ret);
 
+bool
+wasm_runtime_invoke_native_raw(WASMExecEnv *exec_env, void *func_ptr,
+                               const WASMType *func_type, const char *signature,
+                               void *attachment,
+                               uint32 *argv, uint32 argc, uint32 *ret);
+
 
 #ifdef __cplusplus
 }

+ 2 - 0
core/iwasm/compilation/aot.c

@@ -265,6 +265,8 @@ aot_create_import_funcs(const WASMModule *module)
     import_funcs[i].func_ptr_linked = import_func->func_ptr_linked;
     import_funcs[i].func_type = import_func->func_type;
     import_funcs[i].signature = import_func->signature;
+    import_funcs[i].attachment = import_func->attachment;
+    import_funcs[i].call_conv_raw = import_func->call_conv_raw;
     /* Resolve function type index */
     for (j = 0; j < module->type_count; j++)
       if (import_func->func_type == module->types[j]) {

+ 3 - 0
core/iwasm/compilation/aot.h

@@ -85,6 +85,9 @@ typedef struct AOTImportFunc {
   void *func_ptr_linked;
   /* signature from registered native symbols */
   const char *signature;
+  /* attachment */
+  void *attachment;
+  bool call_conv_raw;
 } AOTImportFunc;
 
 /**

+ 12 - 4
core/iwasm/include/lib_export.h

@@ -16,15 +16,23 @@ typedef struct NativeSymbol {
     const char *symbol;
     void *func_ptr;
     const char *signature;
+    /* attachment which can be retrieved in native API by
+       calling wasm_runtime_get_function_attachment(exec_env) */
+    void *attachment;
 } NativeSymbol;
 
-#define EXPORT_WASM_API(symbol)  {#symbol, (void*)symbol, NULL}
-#define EXPORT_WASM_API2(symbol) {#symbol, (void*)symbol##_wrapper, NULL}
+#define EXPORT_WASM_API(symbol)  {#symbol, (void*)symbol, NULL, NULL}
+#define EXPORT_WASM_API2(symbol) {#symbol, (void*)symbol##_wrapper, NULL, NULL}
 
 #define EXPORT_WASM_API_WITH_SIG(symbol, signature) \
-                                 {#symbol, (void*)symbol, signature}
+                                 {#symbol, (void*)symbol, signature, NULL}
 #define EXPORT_WASM_API_WITH_SIG2(symbol, signature) \
-                                 {#symbol, (void*)symbol##_wrapper, signature}
+                                 {#symbol, (void*)symbol##_wrapper, signature, NULL}
+
+#define EXPORT_WASM_API_WITH_ATT(symbol, signature, attachment) \
+                                 {#symbol, (void*)symbol, signature, attachment}
+#define EXPORT_WASM_API_WITH_ATT2(symbol, signature, attachment) \
+                                 {#symbol, (void*)symbol##_wrapper, signature, attachment}
 
 /**
  * Get the exported APIs of base lib

+ 48 - 0
core/iwasm/include/wasm_export.h

@@ -36,6 +36,11 @@ extern "C" {
 #define module_free(offset) \
     wasm_runtime_module_free(module_inst, offset)
 
+#define native_raw_return_type(type, args) type *raw_ret = (type*)(args)
+
+#define native_raw_get_arg(type, name, args) type name = *((type*)(args++))
+
+#define native_raw_set_return(val) *raw_ret = (val)
 
 
 /* Uninstantiated WASM module loaded from WASM binary file
@@ -561,6 +566,49 @@ bool wasm_runtime_register_natives(const char *module_name,
                                    NativeSymbol *native_symbols,
                                    uint32_t n_native_symbols);
 
+/**
+ * Register native functions with same module name, similar to
+ *   wasm_runtime_register_natives, the difference is that runtime passes raw
+ * arguments to native API, which means that the native API should be defined as:
+ *   void foo(wasm_exec_env_t exec_env, uint64 *args);
+ * and native API should extract arguments one by one from args array with macro
+ *   native_raw_get_arg
+ * and write the return value back to args[0] with macro
+ *   native_raw_return_type and native_raw_set_return
+ */
+bool wasm_runtime_register_natives_raw(const char *module_name,
+                                       NativeSymbol *native_symbols,
+                                       uint32_t n_native_symbols);
+
+/**
+ * Get attachment of native function from execution environment
+ *
+ * @param exec_env the execution environment to retrieve
+ *
+ * @return the attachment of native function
+ */
+void *
+wasm_runtime_get_function_attachment(wasm_exec_env_t exec_env);
+
+/**
+ * Set user data to execution environment.
+ *
+ * @param exec_env the execution environment
+ * @param user_data the user data to be set
+ */
+void
+wasm_runtime_set_user_data(wasm_exec_env_t exec_env,
+                           void *user_data);
+/**
+ * Get the user data within execution environment.
+ *
+ * @param exec_env the execution environment
+ *
+ * @return the user data (NULL if not set yet)
+ */
+void *
+wasm_runtime_get_user_data(wasm_exec_env_t exec_env);
+
 #ifdef __cplusplus
 }
 #endif

+ 4 - 1
core/iwasm/interpreter/wasm.h

@@ -137,8 +137,11 @@ typedef struct WASMFunctionImport {
     WASMType *func_type;
     /* function pointer after linked */
     void *func_ptr_linked;
-  /* signature from registered native symbols */
+    /* signature from registered native symbols */
     const char *signature;
+    /* attachment */
+    void *attachment;
+    bool call_conv_raw;
 } WASMFunctionImport;
 
 typedef struct WASMGlobalImport {

+ 12 - 3
core/iwasm/interpreter/wasm_interp_classic.c

@@ -748,9 +748,18 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
         return;
     }
 
-    ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
-                                     func_import->func_type, func_import->signature,
-                                     frame->lp, cur_func->param_cell_num, argv_ret);
+    if (!func_import->call_conv_raw) {
+        ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
+                                         func_import->func_type, func_import->signature,
+                                         func_import->attachment,
+                                         frame->lp, cur_func->param_cell_num, argv_ret);
+    }
+    else {
+        ret = wasm_runtime_invoke_native_raw(exec_env, func_import->func_ptr_linked,
+                                             func_import->func_type, func_import->signature,
+                                             func_import->attachment,
+                                             frame->lp, cur_func->param_cell_num, argv_ret);
+    }
 
     if (!ret)
         return;

+ 15 - 7
core/iwasm/interpreter/wasm_interp_fast.c

@@ -651,6 +651,7 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
                              WASMFunctionInstance *cur_func,
                              WASMInterpFrame *prev_frame)
 {
+    WASMFunctionImport *func_import = cur_func->u.func_import;
     unsigned local_cell_num = 2;
     WASMInterpFrame *frame;
     uint32 argv_ret[2];
@@ -667,20 +668,27 @@ wasm_interp_call_func_native(WASMModuleInstance *module_inst,
 
     wasm_exec_env_set_cur_frame(exec_env, frame);
 
-    if (!cur_func->u.func_import->func_ptr_linked) {
+    if (!func_import->func_ptr_linked) {
         char buf[128];
         snprintf(buf,
                  sizeof(buf), "fail to call unlinked import function (%s, %s)",
-                 cur_func->u.func_import->module_name,
-                 cur_func->u.func_import->field_name);
+                 func_import->module_name, func_import->field_name);
         wasm_set_exception((WASMModuleInstance*)module_inst, buf);
         return;
     }
 
-    ret = wasm_runtime_invoke_native(exec_env, cur_func->u.func_import->func_ptr_linked,
-                                     cur_func->u.func_import->func_type,
-                                     cur_func->u.func_import->signature,
-                                     frame->lp, cur_func->param_cell_num, argv_ret);
+    if (!func_import->call_conv_raw) {
+        ret = wasm_runtime_invoke_native(exec_env, func_import->func_ptr_linked,
+                                         func_import->func_type, func_import->signature,
+                                         func_import->attachment,
+                                         frame->lp, cur_func->param_cell_num, argv_ret);
+    }
+    else {
+        ret = wasm_runtime_invoke_native_raw(exec_env, func_import->func_ptr_linked,
+                                             func_import->func_type, func_import->signature,
+                                             func_import->attachment,
+                                             frame->lp, cur_func->param_cell_num, argv_ret);
+    }
 
     if (!ret)
         return;

+ 3 - 1
core/iwasm/interpreter/wasm_loader.c

@@ -721,7 +721,9 @@ load_import_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
                     if (!(import->u.function.func_ptr_linked =
                             wasm_native_resolve_symbol(module_name, field_name,
                                         import->u.function.func_type,
-                                        &import->u.function.signature))) {
+                                        &import->u.function.signature,
+                                        &import->u.function.attachment,
+                                        &import->u.function.call_conv_raw))) {
 #if WASM_ENABLE_WAMR_COMPILER == 0 /* Output warning except running aot compiler */
                         LOG_WARNING("warning: fail to link import function (%s, %s)\n",
                                     module_name, field_name);

+ 1 - 1
core/iwasm/libraries/libc-builtin/libc_builtin_wrapper.c

@@ -1000,7 +1000,7 @@ print_i32_wrapper(wasm_exec_env_t exec_env, int32 i32)
 }
 
 #define REG_NATIVE_FUNC(func_name, signature)  \
-    { #func_name, func_name##_wrapper, signature }
+    { #func_name, func_name##_wrapper, signature, NULL }
 
 static NativeSymbol native_symbols_libc_builtin[] = {
     REG_NATIVE_FUNC(printf, "($*)i"),

+ 1 - 1
core/iwasm/libraries/libc-wasi/libc_wasi_wrapper.c

@@ -982,7 +982,7 @@ wasi_sched_yield(wasm_exec_env_t exec_env)
 }
 
 #define REG_NATIVE_FUNC(func_name, signature)     \
-    { #func_name, wasi_##func_name, signature }
+    { #func_name, wasi_##func_name, signature, NULL }
 
 static NativeSymbol native_symbols_libc_wasi[] = {
     REG_NATIVE_FUNC(args_get, "(**)i"),