This is an automated email from the ASF dual-hosted git repository.

tqchen pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 27d13db9a4 [FFI][REFACTOR] Cleanup API locations (#18218)
27d13db9a4 is described below

commit 27d13db9a476e5379609d49f990dc0509801a9ce
Author: Tianqi Chen <[email protected]>
AuthorDate: Wed Aug 20 09:57:31 2025 -0400

    [FFI][REFACTOR] Cleanup API locations (#18218)
    
    This PR cleans up the env api and move it to extra.
---
 apps/android_rpc/app/src/main/jni/tvm_runtime.h |   2 +-
 ffi/CMakeLists.txt                              |   3 +-
 ffi/include/tvm/ffi/c_api.h                     | 371 ++++++++++++------------
 ffi/include/tvm/ffi/extra/c_env_api.h           |  25 +-
 ffi/src/ffi/extra/env_c_api.cc                  | 148 ++++++++++
 ffi/src/ffi/extra/library_module.cc             |   2 +-
 ffi/src/ffi/extra/library_module_system_lib.cc  |   2 +-
 ffi/src/ffi/extra/module.cc                     |   4 +-
 ffi/src/ffi/extra/module_internal.h             |   2 +-
 ffi/src/ffi/{ => extra}/testing.cc              |   1 +
 ffi/src/ffi/function.cc                         | 119 --------
 include/tvm/runtime/c_backend_api.h             |   2 +-
 python/tvm/ffi/cython/base.pxi                  |  12 +-
 python/tvm/ffi/cython/function.pxi              |   1 -
 src/runtime/device_api.cc                       |   2 +-
 src/runtime/module.cc                           |   2 +-
 src/support/errno_handling.h                    |   1 +
 src/target/codegen.cc                           |   6 +-
 src/target/llvm/codegen_blob.cc                 |   4 +-
 src/target/llvm/codegen_cpu.cc                  |   4 +-
 web/emcc/wasm_runtime.cc                        |   2 +-
 21 files changed, 373 insertions(+), 342 deletions(-)

diff --git a/apps/android_rpc/app/src/main/jni/tvm_runtime.h 
b/apps/android_rpc/app/src/main/jni/tvm_runtime.h
index feed444989..94fc642289 100644
--- a/apps/android_rpc/app/src/main/jni/tvm_runtime.h
+++ b/apps/android_rpc/app/src/main/jni/tvm_runtime.h
@@ -41,10 +41,10 @@
 #include "../ffi/src/ffi/extra/library_module_dynamic_lib.cc"
 #include "../ffi/src/ffi/extra/library_module_system_lib.cc"
 #include "../ffi/src/ffi/extra/module.cc"
+#include "../ffi/src/ffi/extra/testing.cc"
 #include "../ffi/src/ffi/function.cc"
 #include "../ffi/src/ffi/ndarray.cc"
 #include "../ffi/src/ffi/object.cc"
-#include "../ffi/src/ffi/testing.cc"
 #include "../ffi/src/ffi/traceback.cc"
 #include "../src/runtime/cpu_device_api.cc"
 #include "../src/runtime/device_api.cc"
diff --git a/ffi/CMakeLists.txt b/ffi/CMakeLists.txt
index b5823b76a7..466571c288 100644
--- a/ffi/CMakeLists.txt
+++ b/ffi/CMakeLists.txt
@@ -57,7 +57,6 @@ set(tvm_ffi_objs_sources
   "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/function.cc"
   "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/ndarray.cc"
   "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/dtype.cc"
-  "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/testing.cc"
   "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/container.cc"
 )
 
@@ -74,6 +73,8 @@ if (TVM_FFI_USE_EXTRA_CXX_API)
     "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_system_lib.cc"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/library_module_dynamic_lib.cc"
     "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/stream_context.cc"
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/env_c_api.cc"
+    "${CMAKE_CURRENT_SOURCE_DIR}/src/ffi/extra/testing.cc"
   )
 endif()
 
diff --git a/ffi/include/tvm/ffi/c_api.h b/ffi/include/tvm/ffi/c_api.h
index c8d46d4552..39b7de69fa 100644
--- a/ffi/include/tvm/ffi/c_api.h
+++ b/ffi/include/tvm/ffi/c_api.h
@@ -300,6 +300,185 @@ typedef struct {
   TVMFFISafeCallType safe_call;
 } TVMFFIFunctionCell;
 
+//------------------------------------------------------------
+// Section: Basic object API
+//------------------------------------------------------------
+/*!
+ * \brief Free an object handle by decreasing reference
+ * \param obj The object handle.
+ * \note Internally we decrease the reference counter of the object.
+ *       The object will be freed when every reference to the object are 
removed.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIObjectFree(TVMFFIObjectHandle obj);
+
+/*!
+ * \brief Convert type key to type index.
+ * \param type_key The key of the type.
+ * \param out_tindex the corresponding type index.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFITypeKeyToIndex(const TVMFFIByteArray* type_key, int32_t* 
out_tindex);
+
+//-----------------------------------------------------------------------
+// Section: Basic function calling API for function implementation
+//-----------------------------------------------------------------------
+/*!
+ * \brief Create a FFIFunc by passing in callbacks from C callback.
+ *
+ * The registered function then can be pulled by the backend by the name.
+ *
+ * \param self The resource handle of the C callback.
+ * \param safe_call The C callback implementation
+ * \param deleter deleter to recycle
+ * \param out The output of the function.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIFunctionCreate(void* self, TVMFFISafeCallType safe_call,
+                                     void (*deleter)(void* self), 
TVMFFIObjectHandle* out);
+
+/*!
+ * \brief Get a global function registered in system.
+ *
+ * \param name The name of the function.
+ * \param out the result function pointer, NULL if it does not exist.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIFunctionGetGlobal(const TVMFFIByteArray* name, 
TVMFFIObjectHandle* out);
+
+/*!
+ * \brief Convert a AnyView to an owned Any.
+ * \param any The AnyView to convert.
+ * \param out The output Any, must be an empty object
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIAnyViewToOwnedAny(const TVMFFIAny* any_view, TVMFFIAny* 
out);
+
+/*!
+ * \brief Call a FFIFunc by passing in arguments.
+ *
+ * \param func The resource handle of the C callback.
+ * \param args The input arguments to the call.
+ * \param num_args The number of input arguments.
+ * \param result The output result, caller must ensure result->type_index is 
set to kTVMFFINone.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIFunctionCall(TVMFFIObjectHandle func, TVMFFIAny* args, 
int32_t num_args,
+                                   TVMFFIAny* result);
+
+/*!
+ * \brief Move the last error from the environment to result.
+ *
+ * \param result The result error.
+ *
+ * \note This function clears the error stored in the TLS.
+ */
+TVM_FFI_DLL void TVMFFIErrorMoveFromRaised(TVMFFIObjectHandle* result);
+
+/*!
+ * \brief Set raised error in TLS, which can be fetched by 
TVMFFIErrorMoveFromRaised.
+ *
+ * \param error The error object handle
+ */
+TVM_FFI_DLL void TVMFFIErrorSetRaised(TVMFFIObjectHandle error);
+
+/*!
+ * \brief Set raised error in TLS, which can be fetched by 
TVMFFIMoveFromRaised.
+ *
+ * \param kind The kind of the error.
+ * \param message The error message.
+ * \note This is a convenient method for C API side to set error directly from 
string.
+ */
+TVM_FFI_DLL void TVMFFIErrorSetRaisedFromCStr(const char* kind, const char* 
message);
+
+/*!
+ * \brief Create an initial error object.
+ *
+ * \param kind The kind of the error.
+ * \param message The error message.
+ * \param traceback The traceback of the error.
+ * \return The created error object handle.
+ * \note This function is different from other functions as it is used in 
error handling loop.
+ *       So we do not follow normal error handling patterns via returning 
error code.
+ */
+TVM_FFI_DLL TVMFFIObjectHandle TVMFFIErrorCreate(const TVMFFIByteArray* kind,
+                                                 const TVMFFIByteArray* 
message,
+                                                 const TVMFFIByteArray* 
traceback);
+
+//------------------------------------------------------------
+// Section: DLPack support APIs
+//------------------------------------------------------------
+/*!
+ * \brief Produce a managed NDArray from a DLPack tensor.
+ * \param from The source DLPack tensor.
+ * \param require_alignment The minimum alignment requored of the data + 
byte_offset.
+ * \param require_contiguous Boolean flag indicating if we need to check for 
contiguity.
+ * \param out The output NDArray handle.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFINDArrayFromDLPack(DLManagedTensor* from, int32_t 
require_alignment,
+                                        int32_t require_contiguous, 
TVMFFIObjectHandle* out);
+
+/*!
+ * \brief Produce a DLMangedTensor from the array that shares data memory with 
the array.
+ * \param from The source array.
+ * \param out The DLManagedTensor handle.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFINDArrayToDLPack(TVMFFIObjectHandle from, 
DLManagedTensor** out);
+
+/*!
+ * \brief Produce a managed NDArray from a DLPack tensor.
+ * \param from The source DLPack tensor.
+ * \param require_alignment The minimum alignment requored of the data + 
byte_offset.
+ * \param require_contiguous Boolean flag indicating if we need to check for 
contiguity.
+ * \param out The output NDArray handle.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFINDArrayFromDLPackVersioned(DLManagedTensorVersioned* 
from,
+                                                 int32_t require_alignment,
+                                                 int32_t require_contiguous,
+                                                 TVMFFIObjectHandle* out);
+
+/*!
+ * \brief Produce a DLMangedTensor from the array that shares data memory with 
the array.
+ * \param from The source array.
+ * \param out The DLManagedTensor handle.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFINDArrayToDLPackVersioned(TVMFFIObjectHandle from,
+                                               DLManagedTensorVersioned** out);
+
+//---------------------------------------------------------------
+// Section: dtype string support APIs.
+// These APIs are used to simplify the dtype printings during FFI
+//---------------------------------------------------------------
+
+/*!
+ * \brief Convert a string to a DLDataType.
+ * \param str The string to convert.
+ * \param out The output DLDataType.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIDataTypeFromString(const TVMFFIByteArray* str, 
DLDataType* out);
+
+/*!
+* \brief Convert a DLDataType to a string.
+* \param dtype The DLDataType to convert.
+* \param out The output string.
+* \return 0 when success, nonzero when failure happens
+* \note out is a String object that needs to be freed by the caller via 
TVMFFIObjectFree.
+The content of string can be accessed via TVMFFIObjectGetByteArrayPtr.
+
+* \note The input dtype is a pointer to the DLDataType to avoid ABI 
compatibility issues.
+*/
+TVM_FFI_DLL int TVMFFIDataTypeToString(const DLDataType* dtype, TVMFFIAny* 
out);
+
+//------------------------------------------------------------
+// Section: Type reflection support APIs
+//
+// The reflec
+//------------------------------------------------------------
 /*!
  * \brief Getter that can take address of a field and set the result.
  * \param field The raw address of the field.
@@ -577,63 +756,6 @@ typedef struct TVMFFITypeInfo {
   const TVMFFITypeMetadata* metadata;
 } TVMFFITypeInfo;
 
-//------------------------------------------------------------
-// Section: User APIs to interact with the FFI
-//------------------------------------------------------------
-/*!
- * \brief Free an object handle by decreasing reference
- * \param obj The object handle.
- * \note Internally we decrease the reference counter of the object.
- *       The object will be freed when every reference to the object are 
removed.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIObjectFree(TVMFFIObjectHandle obj);
-
-/*!
- * \brief Convert type key to type index.
- * \param type_key The key of the type.
- * \param out_tindex the corresponding type index.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFITypeKeyToIndex(const TVMFFIByteArray* type_key, int32_t* 
out_tindex);
-
-//-----------------------------------------------------------------------
-// Section: Function calling APIs and support API for func implementation
-//-----------------------------------------------------------------------
-/*!
- * \brief Create a FFIFunc by passing in callbacks from C callback.
- *
- * The registered function then can be pulled by the backend by the name.
- *
- * \param self The resource handle of the C callback.
- * \param safe_call The C callback implementation
- * \param deleter deleter to recycle
- * \param out The output of the function.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIFunctionCreate(void* self, TVMFFISafeCallType safe_call,
-                                     void (*deleter)(void* self), 
TVMFFIObjectHandle* out);
-
-/*!
- * \brief Convert a AnyView to an owned Any.
- * \param any The AnyView to convert.
- * \param out The output Any, must be an empty object
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIAnyViewToOwnedAny(const TVMFFIAny* any_view, TVMFFIAny* 
out);
-
-/*!
- * \brief Call a FFIFunc by passing in arguments.
- *
- * \param func The resource handle of the C callback.
- * \param args The input arguments to the call.
- * \param num_args The number of input arguments.
- * \param result The output result, caller must ensure result->type_index is 
set to kTVMFFINone.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIFunctionCall(TVMFFIObjectHandle func, TVMFFIAny* args, 
int32_t num_args,
-                                   TVMFFIAny* result);
-
 /*!
  * \brief Register the function to runtime's global table.
  *
@@ -660,72 +782,6 @@ TVM_FFI_DLL int TVMFFIFunctionSetGlobal(const 
TVMFFIByteArray* name, TVMFFIObjec
 TVM_FFI_DLL int TVMFFIFunctionSetGlobalFromMethodInfo(const TVMFFIMethodInfo* 
method_info,
                                                       int override);
 
-/*!
- * \brief Get a global function.
- *
- * \param name The name of the function.
- * \param out the result function pointer, NULL if it does not exist.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIFunctionGetGlobal(const TVMFFIByteArray* name, 
TVMFFIObjectHandle* out);
-
-/*!
- * \brief Move the last error from the environment to result.
- *
- * \param result The result error.
- *
- * \note This function clears the error stored in the TLS.
- */
-TVM_FFI_DLL void TVMFFIErrorMoveFromRaised(TVMFFIObjectHandle* result);
-
-/*!
- * \brief Set raised error in TLS, which can be fetched by 
TVMFFIErrorMoveFromRaised.
- *
- * \param error The error object handle
- */
-TVM_FFI_DLL void TVMFFIErrorSetRaised(TVMFFIObjectHandle error);
-
-/*!
- * \brief Set raised error in TLS, which can be fetched by 
TVMFFIMoveFromRaised.
- *
- * \param kind The kind of the error.
- * \param message The error message.
- * \note This is a convenient method for C API side to set error directly from 
string.
- */
-TVM_FFI_DLL void TVMFFIErrorSetRaisedFromCStr(const char* kind, const char* 
message);
-
-/*!
- * \brief Create an initial error object.
- *
- * \param kind The kind of the error.
- * \param message The error message.
- * \param traceback The traceback of the error.
- * \return The created error object handle.
- * \note This function is different from other functions as it is used in 
error handling loop.
- *       So we do not follow normal error handling patterns via returning 
error code.
- */
-TVM_FFI_DLL TVMFFIObjectHandle TVMFFIErrorCreate(const TVMFFIByteArray* kind,
-                                                 const TVMFFIByteArray* 
message,
-                                                 const TVMFFIByteArray* 
traceback);
-
-/*!
- * \brief Check if there are any signals raised in the surrounding env.
- * \return 0 when success, nonzero when failure happens
- * \note Under python this function redirects to PyErr_CheckSignals
- */
-TVM_FFI_DLL int TVMFFIEnvCheckSignals();
-
-/*!
- * \brief Register a symbol into the from the surrounding env.
- * \param name The name of the symbol.
- * \param symbol The symbol to register.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIEnvRegisterCAPI(const TVMFFIByteArray* name, void* 
symbol);
-
-//------------------------------------------------------------
-// Section: Type reflection support APIs
-//------------------------------------------------------------
 /*!
  * \brief Register type field information for runtime reflection.
  * \param type_index The type index
@@ -767,75 +823,6 @@ TVM_FFI_DLL int TVMFFITypeRegisterAttr(int32_t type_index, 
const TVMFFIByteArray
  */
 TVM_FFI_DLL const TVMFFITypeAttrColumn* TVMFFIGetTypeAttrColumn(const 
TVMFFIByteArray* attr_name);
 
-//------------------------------------------------------------
-// Section: DLPack support APIs
-//------------------------------------------------------------
-/*!
- * \brief Produce a managed NDArray from a DLPack tensor.
- * \param from The source DLPack tensor.
- * \param require_alignment The minimum alignment requored of the data + 
byte_offset.
- * \param require_contiguous Boolean flag indicating if we need to check for 
contiguity.
- * \param out The output NDArray handle.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFINDArrayFromDLPack(DLManagedTensor* from, int32_t 
require_alignment,
-                                        int32_t require_contiguous, 
TVMFFIObjectHandle* out);
-
-/*!
- * \brief Produce a DLMangedTensor from the array that shares data memory with 
the array.
- * \param from The source array.
- * \param out The DLManagedTensor handle.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFINDArrayToDLPack(TVMFFIObjectHandle from, 
DLManagedTensor** out);
-
-/*!
- * \brief Produce a managed NDArray from a DLPack tensor.
- * \param from The source DLPack tensor.
- * \param require_alignment The minimum alignment requored of the data + 
byte_offset.
- * \param require_contiguous Boolean flag indicating if we need to check for 
contiguity.
- * \param out The output NDArray handle.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFINDArrayFromDLPackVersioned(DLManagedTensorVersioned* 
from,
-                                                 int32_t require_alignment,
-                                                 int32_t require_contiguous,
-                                                 TVMFFIObjectHandle* out);
-
-/*!
- * \brief Produce a DLMangedTensor from the array that shares data memory with 
the array.
- * \param from The source array.
- * \param out The DLManagedTensor handle.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFINDArrayToDLPackVersioned(TVMFFIObjectHandle from,
-                                               DLManagedTensorVersioned** out);
-
-//---------------------------------------------------------------
-// Section: dtype string support APIs.
-// These APIs are used to simplify the dtype printings during FFI
-//---------------------------------------------------------------
-
-/*!
- * \brief Convert a string to a DLDataType.
- * \param str The string to convert.
- * \param out The output DLDataType.
- * \return 0 when success, nonzero when failure happens
- */
-TVM_FFI_DLL int TVMFFIDataTypeFromString(const TVMFFIByteArray* str, 
DLDataType* out);
-
-/*!
- * \brief Convert a DLDataType to a string.
- * \param dtype The DLDataType to convert.
- * \param out The output string.
- * \return 0 when success, nonzero when failure happens
- * \note out is a String object that needs to be freed by the caller via 
TVMFFIObjectFree.
-         The content of string can be accessed via TVMFFIObjectGetByteArrayPtr.
-
- * \note The input dtype is a pointer to the DLDataType to avoid ABI 
compatibility issues.
- */
-TVM_FFI_DLL int TVMFFIDataTypeToString(const DLDataType* dtype, TVMFFIAny* 
out);
-
 //------------------------------------------------------------
 // Section: Backend noexcept functions for internal use
 //
diff --git a/ffi/include/tvm/ffi/extra/c_env_api.h 
b/ffi/include/tvm/ffi/extra/c_env_api.h
index 1211ab0eeb..17cb3af6d0 100644
--- a/ffi/include/tvm/ffi/extra/c_env_api.h
+++ b/ffi/include/tvm/ffi/extra/c_env_api.h
@@ -59,8 +59,23 @@ TVM_FFI_DLL int TVMFFIEnvSetStream(int32_t device_type, 
int32_t device_id,
  */
 TVM_FFI_DLL TVMFFIStreamHandle TVMFFIEnvGetCurrentStream(int32_t device_type, 
int32_t device_id);
 
+/*!
+ * \brief Check if there are any signals raised in the surrounding env.
+ * \return 0 when success, nonzero when failure happens
+ * \note Under python this function redirects to PyErr_CheckSignals
+ */
+TVM_FFI_DLL int TVMFFIEnvCheckSignals();
+
+/*!
+ * \brief Register a symbol into the from the surrounding env such as python
+ * \param name The name of the symbol.
+ * \param symbol The symbol to register.
+ * \return 0 when success, nonzero when failure happens
+ */
+TVM_FFI_DLL int TVMFFIEnvRegisterCAPI(const char* name, void* symbol);
+
 // ----------------------------------------------------------------------------
-// Module symbol management
+// Module symbol management in callee side
 // ----------------------------------------------------------------------------
 /*!
  * \brief FFI function to lookup a function from a module's imports.
@@ -73,8 +88,8 @@ TVM_FFI_DLL TVMFFIStreamHandle 
TVMFFIEnvGetCurrentStream(int32_t device_type, in
  * \note The returned function is a weak reference that is cached/owned by the 
module.
  * \return 0 when no error is thrown, -1 when failure happens
  */
-TVM_FFI_DLL int TVMFFIEnvLookupFromImports(TVMFFIObjectHandle library_ctx, 
const char* func_name,
-                                           TVMFFIObjectHandle* out);
+TVM_FFI_DLL int TVMFFIEnvModLookupFromImports(TVMFFIObjectHandle library_ctx, 
const char* func_name,
+                                              TVMFFIObjectHandle* out);
 
 /*
  * \brief Register a symbol value that will be initialized when a library with 
the symbol is loaded.
@@ -86,7 +101,7 @@ TVM_FFI_DLL int 
TVMFFIEnvLookupFromImports(TVMFFIObjectHandle library_ctx, const
  * \param symbol The symbol to register.
  * \return 0 when success, nonzero when failure happens
  */
-TVM_FFI_DLL int TVMFFIEnvRegisterContextSymbol(const char* name, void* symbol);
+TVM_FFI_DLL int TVMFFIEnvModRegisterContextSymbol(const char* name, void* 
symbol);
 
 /*!
  * \brief Register a symbol that will be initialized when a system library is 
loaded.
@@ -95,7 +110,7 @@ TVM_FFI_DLL int TVMFFIEnvRegisterContextSymbol(const char* 
name, void* symbol);
  * \param symbol The symbol to register.
  * \return 0 when success, nonzero when failure happens
  */
-TVM_FFI_DLL int TVMFFIEnvRegisterSystemLibSymbol(const char* name, void* 
symbol);
+TVM_FFI_DLL int TVMFFIEnvModRegisterSystemLibSymbol(const char* name, void* 
symbol);
 
 #ifdef __cplusplus
 }  // extern "C"
diff --git a/ffi/src/ffi/extra/env_c_api.cc b/ffi/src/ffi/extra/env_c_api.cc
new file mode 100644
index 0000000000..121cc9a3cc
--- /dev/null
+++ b/ffi/src/ffi/extra/env_c_api.cc
@@ -0,0 +1,148 @@
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+/*
+ * \file src/ffi/extra/env_c_api.cc
+ * \brief Environment C API implementation.
+ */
+#include <tvm/ffi/extra/c_env_api.h>
+#include <tvm/ffi/function.h>
+
+namespace tvm {
+namespace ffi {
+/*!
+ * \brief Execution environment specific API registry.
+ *
+ *  This registry stores C API function pointers about
+ *  execution environment(e.g. python) specific API function that
+ *  we need for specific low-level handling(e.g. signal checking).
+ *
+ *  We only stores the C API function when absolutely necessary (e.g. when 
signal handler
+ *  cannot trap back into python). Always consider use the Function FFI when 
possible
+ *  in other cases.
+ */
+class EnvCAPIRegistry {
+ public:
+  /*!
+   * \brief Callback to check if signals have been sent to the process and
+   *        if so invoke the registered signal handler in the frontend 
environment.
+   *
+   *  When running FFI in another language (Python), the signal handler
+   *  may not be immediately executed, but instead the signal is marked
+   *  in the interpreter state (to ensure non-blocking of the signal handler).
+   *
+   * \return 0 if no error happens, -1 if error happens.
+   */
+  typedef int (*F_PyErr_CheckSignals)();
+
+  /*! \brief Callback to increment/decrement the python ref count */
+  typedef void (*F_Py_IncDefRef)(void*);
+
+  /*!
+   * \brief PyErr_CheckSignal function
+   */
+  F_PyErr_CheckSignals pyerr_check_signals = nullptr;
+
+  /*!
+    \brief PyGILState_Ensure function
+   */
+  void* (*py_gil_state_ensure)() = nullptr;
+
+  /*!
+    \brief PyGILState_Release function
+   */
+  void (*py_gil_state_release)(void*) = nullptr;
+
+  static EnvCAPIRegistry* Global() {
+    static EnvCAPIRegistry* inst = new EnvCAPIRegistry();
+    return inst;
+  }
+
+  // register environment(e.g. python) specific api functions
+  void Register(const String& symbol_name, void* fptr) {
+    if (symbol_name == "PyErr_CheckSignals") {
+      Update(symbol_name, &pyerr_check_signals, fptr);
+    } else if (symbol_name == "PyGILState_Ensure") {
+      Update(symbol_name, &py_gil_state_ensure, fptr);
+    } else if (symbol_name == "PyGILState_Release") {
+      Update(symbol_name, &py_gil_state_release, fptr);
+    } else {
+      TVM_FFI_THROW(ValueError) << "Unknown env API " + symbol_name;
+    }
+  }
+
+  int EnvCheckSignals() {
+    // check python signal to see if there are exception raised
+    if (pyerr_check_signals != nullptr) {
+      // The C++ env comes without gil, so we need to grab gil here
+      WithGIL context(this);
+      if ((*pyerr_check_signals)() != 0) {
+        // The error will let FFI know that the frontend environment
+        // already set an error.
+        return -1;
+      }
+    }
+    return 0;
+  }
+
+ private:
+  // update the internal API table
+  template <typename FType>
+  void Update(const String& symbol_name, FType* target, void* ptr) {
+    FType ptr_casted = reinterpret_cast<FType>(ptr);
+    target[0] = ptr_casted;
+  }
+
+  struct WithGIL {
+    explicit WithGIL(EnvCAPIRegistry* self) : self(self) {
+      TVM_FFI_ICHECK(self->py_gil_state_ensure);
+      TVM_FFI_ICHECK(self->py_gil_state_release);
+      gil_state = self->py_gil_state_ensure();
+    }
+    ~WithGIL() {
+      if (self && gil_state) {
+        self->py_gil_state_release(gil_state);
+      }
+    }
+    WithGIL(const WithGIL&) = delete;
+    WithGIL(WithGIL&&) = delete;
+    WithGIL& operator=(const WithGIL&) = delete;
+    WithGIL& operator=(WithGIL&&) = delete;
+
+    EnvCAPIRegistry* self = nullptr;
+    void* gil_state = nullptr;
+  };
+};
+}  // namespace ffi
+}  // namespace tvm
+
+int TVMFFIEnvCheckSignals() { return 
tvm::ffi::EnvCAPIRegistry::Global()->EnvCheckSignals(); }
+
+/*!
+ * \brief Register a symbol into the from the surrounding env.
+ * \param name The name of the symbol.
+ * \param symbol The symbol to register.
+ * \return 0 when success, nonzero when failure happens
+ */
+int TVMFFIEnvRegisterCAPI(const char* name, void* symbol) {
+  TVM_FFI_SAFE_CALL_BEGIN();
+  tvm::ffi::String s_name(name);
+  tvm::ffi::EnvCAPIRegistry::Global()->Register(s_name, symbol);
+  TVM_FFI_SAFE_CALL_END();
+}
diff --git a/ffi/src/ffi/extra/library_module.cc 
b/ffi/src/ffi/extra/library_module.cc
index 34286d6d0e..71c6da6f7c 100644
--- a/ffi/src/ffi/extra/library_module.cc
+++ b/ffi/src/ffi/extra/library_module.cc
@@ -191,7 +191,7 @@ Module CreateLibraryModule(ObjectPtr<Library> lib) {
 }  // namespace ffi
 }  // namespace tvm
 
-int TVMFFIEnvRegisterContextSymbol(const char* name, void* symbol) {
+int TVMFFIEnvModRegisterContextSymbol(const char* name, void* symbol) {
   TVM_FFI_SAFE_CALL_BEGIN();
   tvm::ffi::String s_name(name);
   tvm::ffi::ContextSymbolRegistry::Global()->Register(s_name, symbol);
diff --git a/ffi/src/ffi/extra/library_module_system_lib.cc 
b/ffi/src/ffi/extra/library_module_system_lib.cc
index 64b95a122d..cdc932cba2 100644
--- a/ffi/src/ffi/extra/library_module_system_lib.cc
+++ b/ffi/src/ffi/extra/library_module_system_lib.cc
@@ -123,7 +123,7 @@ TVM_FFI_STATIC_INIT_BLOCK({
 }  // namespace ffi
 }  // namespace tvm
 
-int TVMFFIEnvRegisterSystemLibSymbol(const char* name, void* ptr) {
+int TVMFFIEnvModRegisterSystemLibSymbol(const char* name, void* ptr) {
   tvm::ffi::SystemLibSymbolRegistry::Global()->RegisterSymbol(name, ptr);
   return 0;
 }
diff --git a/ffi/src/ffi/extra/module.cc b/ffi/src/ffi/extra/module.cc
index a7f6d44600..d8ec77f98c 100644
--- a/ffi/src/ffi/extra/module.cc
+++ b/ffi/src/ffi/extra/module.cc
@@ -130,8 +130,8 @@ TVM_FFI_STATIC_INIT_BLOCK({
 }  // namespace ffi
 }  // namespace tvm
 
-int TVMFFIEnvLookupFromImports(TVMFFIObjectHandle library_ctx, const char* 
func_name,
-                               TVMFFIObjectHandle* out) {
+int TVMFFIEnvModLookupFromImports(TVMFFIObjectHandle library_ctx, const char* 
func_name,
+                                  TVMFFIObjectHandle* out) {
   TVM_FFI_SAFE_CALL_BEGIN();
   *out = tvm::ffi::ModuleObj::InternalUnsafe::GetFunctionFromImports(
       reinterpret_cast<tvm::ffi::ModuleObj*>(library_ctx), func_name);
diff --git a/ffi/src/ffi/extra/module_internal.h 
b/ffi/src/ffi/extra/module_internal.h
index f43d3a3d2c..472d531f4b 100644
--- a/ffi/src/ffi/extra/module_internal.h
+++ b/ffi/src/ffi/extra/module_internal.h
@@ -57,7 +57,7 @@ struct ModuleObj::InternalUnsafe {
   static Array<Any>* GetImports(ModuleObj* module) { return 
&(module->imports_); }
 
   static void* GetFunctionFromImports(ModuleObj* module, const char* name) {
-    // backend implementation for TVMFFIEnvLookupFromImports
+    // backend implementation for TVMFFIEnvModLookupFromImports
     static std::mutex mutex_;
     std::lock_guard<std::mutex> lock(mutex_);
     String s_name(name);
diff --git a/ffi/src/ffi/testing.cc b/ffi/src/ffi/extra/testing.cc
similarity index 98%
rename from ffi/src/ffi/testing.cc
rename to ffi/src/ffi/extra/testing.cc
index 8fddf54ebd..3d27d5ccb6 100644
--- a/ffi/src/ffi/testing.cc
+++ b/ffi/src/ffi/extra/testing.cc
@@ -19,6 +19,7 @@
 // This file is used for testing the FFI API.
 #include <tvm/ffi/container/array.h>
 #include <tvm/ffi/container/map.h>
+#include <tvm/ffi/extra/c_env_api.h>
 #include <tvm/ffi/function.h>
 #include <tvm/ffi/reflection/registry.h>
 
diff --git a/ffi/src/ffi/function.cc b/ffi/src/ffi/function.cc
index a2d3fb9db3..8db03bf28e 100644
--- a/ffi/src/ffi/function.cc
+++ b/ffi/src/ffi/function.cc
@@ -137,110 +137,6 @@ class GlobalFunctionTable {
  private:
   Map<String, Any> table_;
 };
-
-/*!
- * \brief Execution environment specific API registry.
- *
- *  This registry stores C API function pointers about
- *  execution environment(e.g. python) specific API function that
- *  we need for specific low-level handling(e.g. signal checking).
- *
- *  We only stores the C API function when absolutely necessary (e.g. when 
signal handler
- *  cannot trap back into python). Always consider use the Function FFI when 
possible
- *  in other cases.
- */
-class EnvCAPIRegistry {
- public:
-  /*!
-   * \brief Callback to check if signals have been sent to the process and
-   *        if so invoke the registered signal handler in the frontend 
environment.
-   *
-   *  When running FFI in another language (Python), the signal handler
-   *  may not be immediately executed, but instead the signal is marked
-   *  in the interpreter state (to ensure non-blocking of the signal handler).
-   *
-   * \return 0 if no error happens, -1 if error happens.
-   */
-  typedef int (*F_PyErr_CheckSignals)();
-
-  /*! \brief Callback to increment/decrement the python ref count */
-  typedef void (*F_Py_IncDefRef)(void*);
-
-  /*!
-   * \brief PyErr_CheckSignal function
-   */
-  F_PyErr_CheckSignals pyerr_check_signals = nullptr;
-
-  /*!
-    \brief PyGILState_Ensure function
-   */
-  void* (*py_gil_state_ensure)() = nullptr;
-
-  /*!
-    \brief PyGILState_Release function
-   */
-  void (*py_gil_state_release)(void*) = nullptr;
-
-  static EnvCAPIRegistry* Global() {
-    static EnvCAPIRegistry* inst = new EnvCAPIRegistry();
-    return inst;
-  }
-
-  // register environment(e.g. python) specific api functions
-  void Register(const String& symbol_name, void* fptr) {
-    if (symbol_name == "PyErr_CheckSignals") {
-      Update(symbol_name, &pyerr_check_signals, fptr);
-    } else if (symbol_name == "PyGILState_Ensure") {
-      Update(symbol_name, &py_gil_state_ensure, fptr);
-    } else if (symbol_name == "PyGILState_Release") {
-      Update(symbol_name, &py_gil_state_release, fptr);
-    } else {
-      TVM_FFI_THROW(ValueError) << "Unknown env API " + symbol_name;
-    }
-  }
-
-  int EnvCheckSignals() {
-    // check python signal to see if there are exception raised
-    if (pyerr_check_signals != nullptr) {
-      // The C++ env comes without gil, so we need to grab gil here
-      WithGIL context(this);
-      if ((*pyerr_check_signals)() != 0) {
-        // The error will let FFI know that the frontend environment
-        // already set an error.
-        return -1;
-      }
-    }
-    return 0;
-  }
-
- private:
-  // update the internal API table
-  template <typename FType>
-  void Update(const String& symbol_name, FType* target, void* ptr) {
-    FType ptr_casted = reinterpret_cast<FType>(ptr);
-    target[0] = ptr_casted;
-  }
-
-  struct WithGIL {
-    explicit WithGIL(EnvCAPIRegistry* self) : self(self) {
-      TVM_FFI_ICHECK(self->py_gil_state_ensure);
-      TVM_FFI_ICHECK(self->py_gil_state_release);
-      gil_state = self->py_gil_state_ensure();
-    }
-    ~WithGIL() {
-      if (self && gil_state) {
-        self->py_gil_state_release(gil_state);
-      }
-    }
-    WithGIL(const WithGIL&) = delete;
-    WithGIL(WithGIL&&) = delete;
-    WithGIL& operator=(const WithGIL&) = delete;
-    WithGIL& operator=(WithGIL&&) = delete;
-
-    EnvCAPIRegistry* self = nullptr;
-    void* gil_state = nullptr;
-  };
-};
 }  // namespace ffi
 }  // namespace tvm
 
@@ -296,21 +192,6 @@ int TVMFFIFunctionCall(TVMFFIObjectHandle func, TVMFFIAny* 
args, int32_t num_arg
   return reinterpret_cast<FunctionObj*>(func)->safe_call(func, args, num_args, 
result);
 }
 
-int TVMFFIEnvCheckSignals() { return 
tvm::ffi::EnvCAPIRegistry::Global()->EnvCheckSignals(); }
-
-/*!
- * \brief Register a symbol into the from the surrounding env.
- * \param name The name of the symbol.
- * \param symbol The symbol to register.
- * \return 0 when success, nonzero when failure happens
- */
-int TVMFFIEnvRegisterCAPI(const TVMFFIByteArray* name, void* symbol) {
-  TVM_FFI_SAFE_CALL_BEGIN();
-  tvm::ffi::String s_name(name->data, name->size);
-  tvm::ffi::EnvCAPIRegistry::Global()->Register(s_name, symbol);
-  TVM_FFI_SAFE_CALL_END();
-}
-
 TVM_FFI_STATIC_INIT_BLOCK({
   namespace refl = tvm::ffi::reflection;
   refl::GlobalDef()
diff --git a/include/tvm/runtime/c_backend_api.h 
b/include/tvm/runtime/c_backend_api.h
index e44fe465bc..4e6c2f5364 100644
--- a/include/tvm/runtime/c_backend_api.h
+++ b/include/tvm/runtime/c_backend_api.h
@@ -54,7 +54,7 @@ TVM_DLL int TVMBackendGetFuncFromEnv(void* mod_node, const 
char* func_name,
  * \param ptr The symbol address.
  * \return 0 when no error is thrown, -1 when failure happens
  */
-TVM_DLL int TVMFFIEnvRegisterSystemLibSymbol(const char* name, void* ptr);
+TVM_DLL int TVMFFIEnvModRegisterSystemLibSymbol(const char* name, void* ptr);
 
 /*!
  * \brief Backend function to allocate temporal workspace.
diff --git a/python/tvm/ffi/cython/base.pxi b/python/tvm/ffi/cython/base.pxi
index 24c7290959..e61eaf322d 100644
--- a/python/tvm/ffi/cython/base.pxi
+++ b/python/tvm/ffi/cython/base.pxi
@@ -183,7 +183,7 @@ cdef extern from "tvm/ffi/c_api.h":
     void TVMFFIErrorSetRaised(TVMFFIObjectHandle error) nogil
     TVMFFIObjectHandle TVMFFIErrorCreate(TVMFFIByteArray* kind, 
TVMFFIByteArray* message,
                                          TVMFFIByteArray* traceback) nogil
-    int TVMFFIEnvRegisterCAPI(TVMFFIByteArray* name, void* ptr) nogil
+
     int TVMFFITypeKeyToIndex(TVMFFIByteArray* type_key, int32_t* out_tindex) 
nogil
     int TVMFFIDataTypeFromString(TVMFFIByteArray* str, DLDataType* out) nogil
     int TVMFFIDataTypeToString(const DLDataType* dtype, TVMFFIAny* out) nogil
@@ -208,6 +208,7 @@ cdef extern from "tvm/ffi/c_api.h":
 cdef extern from "tvm/ffi/extra/c_env_api.h":
     ctypedef void* TVMFFIStreamHandle
 
+    int TVMFFIEnvRegisterCAPI(const char* name, void* ptr) nogil
     void* TVMFFIEnvGetCurrentStream(int32_t device_type, int32_t device_id) 
nogil
     int TVMFFIEnvSetStream(int32_t device_type, int32_t device_id,
                            TVMFFIStreamHandle stream,
@@ -279,11 +280,8 @@ cdef _init_env_api():
     # Initialize env api for signal handling
     # Also registers the gil state release and ensure as PyErr_CheckSignals
     # function is called with gil released and we need to regrab the gil
-    cdef ByteArrayArg pyerr_check_signals_arg = 
ByteArrayArg(c_str("PyErr_CheckSignals"))
-    cdef ByteArrayArg pygilstate_ensure_arg = 
ByteArrayArg(c_str("PyGILState_Ensure"))
-    cdef ByteArrayArg pygilstate_release_arg = 
ByteArrayArg(c_str("PyGILState_Release"))
-    CHECK_CALL(TVMFFIEnvRegisterCAPI(pyerr_check_signals_arg.cptr(), 
<void*>PyErr_CheckSignals))
-    CHECK_CALL(TVMFFIEnvRegisterCAPI(pygilstate_ensure_arg.cptr(), 
<void*>PyGILState_Ensure))
-    CHECK_CALL(TVMFFIEnvRegisterCAPI(pygilstate_release_arg.cptr(), 
<void*>PyGILState_Release))
+    CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyErr_CheckSignals"), 
<void*>PyErr_CheckSignals))
+    CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyGILState_Ensure"), 
<void*>PyGILState_Ensure))
+    CHECK_CALL(TVMFFIEnvRegisterCAPI(c_str("PyGILState_Release"), 
<void*>PyGILState_Release))
 
 _init_env_api()
diff --git a/python/tvm/ffi/cython/function.pxi 
b/python/tvm/ffi/cython/function.pxi
index 3ab232e959..4148cc6c88 100644
--- a/python/tvm/ffi/cython/function.pxi
+++ b/python/tvm/ffi/cython/function.pxi
@@ -43,7 +43,6 @@ def load_torch_get_current_cuda_stream():
     def fallback_get_current_cuda_stream(device_id):
         """Fallback with python api"""
         return torch.cuda.current_stream(device_id).cuda_stream
-    return fallback_get_current_cuda_stream
     try:
         result = cpp_extension.load_inline(
             name="get_current_cuda_stream",
diff --git a/src/runtime/device_api.cc b/src/runtime/device_api.cc
index 31006069a2..28dc313ba3 100644
--- a/src/runtime/device_api.cc
+++ b/src/runtime/device_api.cc
@@ -242,7 +242,7 @@ TVM_FFI_STATIC_INIT_BLOCK({
 using namespace tvm::runtime;
 
 int TVMBackendGetFuncFromEnv(void* mod_node, const char* func_name, 
TVMFFIObjectHandle* func) {
-  return TVMFFIEnvLookupFromImports(mod_node, func_name, func);
+  return TVMFFIEnvModLookupFromImports(mod_node, func_name, func);
 }
 
 void* TVMBackendAllocWorkspace(int device_type, int device_id, uint64_t size, 
int dtype_code_hint,
diff --git a/src/runtime/module.cc b/src/runtime/module.cc
index 12b58da2df..16c617ce3f 100644
--- a/src/runtime/module.cc
+++ b/src/runtime/module.cc
@@ -70,7 +70,7 @@ bool RuntimeEnabled(const String& target_str) {
 
 #define TVM_INIT_CONTEXT_FUNC(FuncName) \
   TVM_FFI_CHECK_SAFE_CALL(              \
-      TVMFFIEnvRegisterContextSymbol("__" #FuncName, 
reinterpret_cast<void*>(FuncName)))
+      TVMFFIEnvModRegisterContextSymbol("__" #FuncName, 
reinterpret_cast<void*>(FuncName)))
 
 TVM_FFI_STATIC_INIT_BLOCK({
   namespace refl = tvm::ffi::reflection;
diff --git a/src/support/errno_handling.h b/src/support/errno_handling.h
index 748e390e78..b2b59ed16d 100644
--- a/src/support/errno_handling.h
+++ b/src/support/errno_handling.h
@@ -24,6 +24,7 @@
 #ifndef TVM_SUPPORT_ERRNO_HANDLING_H_
 #define TVM_SUPPORT_ERRNO_HANDLING_H_
 #include <errno.h>
+#include <tvm/ffi/extra/c_env_api.h>
 
 #include "ssize.h"
 
diff --git a/src/target/codegen.cc b/src/target/codegen.cc
index 9607545018..bd45ce32e0 100644
--- a/src/target/codegen.cc
+++ b/src/target/codegen.cc
@@ -311,10 +311,10 @@ std::string PackImportsToC(const ffi::Module& mod, bool 
system_lib,
   }
   os << "\n};\n";
   if (system_lib) {
-    os << "extern int TVMFFIEnvRegisterSystemLibSymbol(const char*, void*);\n";
+    os << "extern int TVMFFIEnvModRegisterSystemLibSymbol(const char*, 
void*);\n";
     os << "static int " << mdev_blob_name << "_reg_ = "
-       << "TVMFFIEnvRegisterSystemLibSymbol(\"" << mdev_blob_name << "\", 
(void*)" << mdev_blob_name
-       << ");\n";
+       << "TVMFFIEnvModRegisterSystemLibSymbol(\"" << mdev_blob_name << "\", 
(void*)"
+       << mdev_blob_name << ");\n";
   }
   os << "#ifdef __cplusplus\n"
      << "}\n"
diff --git a/src/target/llvm/codegen_blob.cc b/src/target/llvm/codegen_blob.cc
index fc2acfddfb..17056c3312 100644
--- a/src/target/llvm/codegen_blob.cc
+++ b/src/target/llvm/codegen_blob.cc
@@ -151,11 +151,11 @@ std::unique_ptr<llvm::Module> CodeGenBlob(const 
std::string& data, bool system_l
         llvm::FunctionType::get(void_ty, false), 
llvm::GlobalValue::InternalLinkage,
         llvm::Twine("__cxx_global_var_init"), module.get());
 
-    // Create TVMFFIEnvRegisterSystemLibSymbol function
+    // Create TVMFFIEnvModRegisterSystemLibSymbol function
     llvm::Function* tvm_backend_fn =
         llvm::Function::Create(llvm::FunctionType::get(int32_ty, {int8_ptr_ty, 
int8_ptr_ty}, false),
                                llvm::GlobalValue::ExternalLinkage,
-                               
llvm::Twine("TVMFFIEnvRegisterSystemLibSymbol"), module.get());
+                               
llvm::Twine("TVMFFIEnvModRegisterSystemLibSymbol"), module.get());
 
     // Set necessary fn sections
     auto get_static_init_section_specifier = [&triple]() -> std::string {
diff --git a/src/target/llvm/codegen_cpu.cc b/src/target/llvm/codegen_cpu.cc
index eebbd5b64f..5ce8b1ec65 100644
--- a/src/target/llvm/codegen_cpu.cc
+++ b/src/target/llvm/codegen_cpu.cc
@@ -146,10 +146,10 @@ void CodeGenCPU::Init(const std::string& module_name, 
LLVMTarget* llvm_target,
   if (system_lib_prefix_.has_value() && !target_c_runtime) {
     // We will need this in environment for backward registration.
     // Defined in include/tvm/runtime/c_backend_api.h:
-    // int TVMFFIEnvRegisterSystemLibSymbol(const char* name, void* ptr);
+    // int TVMFFIEnvModRegisterSystemLibSymbol(const char* name, void* ptr);
     f_tvm_register_system_symbol_ = llvm::Function::Create(
         llvm::FunctionType::get(t_int_, {llvmGetPointerTo(t_char_, 0), 
t_void_p_}, false),
-        llvm::Function::ExternalLinkage, "TVMFFIEnvRegisterSystemLibSymbol", 
module_.get());
+        llvm::Function::ExternalLinkage, 
"TVMFFIEnvModRegisterSystemLibSymbol", module_.get());
   } else {
     f_tvm_register_system_symbol_ = nullptr;
   }
diff --git a/web/emcc/wasm_runtime.cc b/web/emcc/wasm_runtime.cc
index 6e2664a93b..31f4943226 100644
--- a/web/emcc/wasm_runtime.cc
+++ b/web/emcc/wasm_runtime.cc
@@ -54,10 +54,10 @@
 #include "ffi/src/ffi/extra/library_module.cc"
 #include "ffi/src/ffi/extra/library_module_system_lib.cc"
 #include "ffi/src/ffi/extra/module.cc"
+#include "ffi/src/ffi/extra/testing.cc"
 #include "ffi/src/ffi/function.cc"
 #include "ffi/src/ffi/ndarray.cc"
 #include "ffi/src/ffi/object.cc"
-#include "ffi/src/ffi/testing.cc"
 #include "ffi/src/ffi/traceback.cc"
 #include "src/runtime/memory/memory_manager.cc"
 #include "src/runtime/nvtx.cc"


Reply via email to