gemini-code-assist[bot] commented on code in PR #392:
URL: https://github.com/apache/tvm-ffi/pull/392#discussion_r2675376937


##########
docs/concepts/object_and_class.rst:
##########
@@ -0,0 +1,475 @@
+..  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.
+
+Object and Class
+================
+
+TVM-FFI provides a unified object system that enables cross-language 
interoperability
+between C++, Python, and Rust. The object system is built around 
:cpp:class:`tvm::ffi::Object`
+and :cpp:class:`tvm::ffi::ObjectRef`, which together form the foundation for:
+
+- **Type-safe runtime type identification** without relying on C++ RTTI
+- **Intrusive reference counting** for smart memory management
+- **Reflection-based class exposure** across programming languages
+- **Serialization and deserialization** via reflection metadata
+
+This tutorial covers everything you need to know about defining, using, and 
extending
+TVM-FFI objects across languages.
+
+
+Glossary
+--------
+
+:cpp:class:`tvm::ffi::Object`
+  A heap-allocated, reference-counted container.
+  All TVM-FFI objects inherit from this base class and share a common 24-byte 
header
+  that stores reference counts, type index, and a deleter callback.
+
+:cpp:class:`tvm::ffi::ObjectRef`
+  An intrusive pointer that manages an :cpp:class:`~tvm::ffi::Object`'s 
lifetime through reference counting.
+  Its subclasses provide type-safe access to specific object types. In its 
low-level implementation, it is
+  equivalent to a normal C++ pointer to a heap-allocated 
:cpp:class:`~tvm::ffi::Object`.
+
+Type index and type key
+  Type index is an integer that uniquely identifies each object type.
+  Built-in types have statically assigned indices defined in 
:cpp:enum:`TVMFFITypeIndex`,
+  while user-defined types receive indices at startup when first accessed.
+  Type key is a unique string identifier (e.g., ``"my_ext.MyClass"``) that 
names an object type.
+  It is used for registration, serialization, and cross-language mapping.
+
+Common Usage
+------------
+
+Define a Class in C++
+~~~~~~~~~~~~~~~~~~~~~
+
+To define a custom object class in normal C++, inherit it from 
:cpp:class:`tvm::ffi::Object` or its subclasses,
+and then add one of the following macros that declares its metadata:
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO>`
+   Declare an object type that can be subclassed. Type index is assigned 
dynamically.
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO_FINAL(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO_FINAL>`
+   Declare a final object type (no subclasses). Enables faster type checking.
+
+**Example**. The code below shows a minimal example of defining a TVM-FFI 
object class.
+It declares a class ``MyObjectObj`` that inherits from 
:cpp:class:`~tvm::ffi::Object`.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/tvm_ffi.h>
+
+   namespace ffi = tvm::ffi;
+
+   class MyObjectObj : public ffi::Object {
+    public:
+     // Normal C++ code: Declare fields, methods, constructor, destructor, etc.
+     int64_t value;
+     ffi::String name;
+
+     MyObjectObj(int64_t value, ffi::String name) : value(value), 
name(std::move(name)) {}
+
+     int64_t GetValue() const { return value; }
+
+     void AddToValue(int64_t other) { value += other; }
+
+     // Declare object type info
+     TVM_FFI_DECLARE_OBJECT_INFO(
+       /*type_key=*/"my_ext.MyObject",
+       /*type_name=*/MyObjectObj,
+       /*parent_type=*/ffi::Object);
+   };
+
+**Managed reference**. Optionally, a managed reference class can be defined by 
inheriting
+from :cpp:class:`~tvm::ffi::ObjectRef` and using one of the following macros 
to define the methods.
+Define its constructor by wrapping the :cpp:func:`tvm::ffi::make_object` 
function.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE>`
+   Define a nullable reference class.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE>`
+   Define a non-nullable reference class.
+
+For example, a non-nullable reference class ``MyObject`` can be defined as 
follows:
+
+.. code-block:: cpp
+
+   class MyObject : public ffi::ObjectRef {
+    public:
+     MyObject(int64_t value, ffi::String name)
+         : ObjectRef(ffi::make_object<MyObjectObj>(value, std::move(name))) {}
+     TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(
+        /*type_name=*/MyObject,
+        /*parent_type=*/ffi::ObjectRef,
+        /*object_name=*/MyObjectObj);
+   };
+
+   // Create a managed object
+   MyObject obj = MyObject(42, "hello");
+
+   // Access fields via operator->
+   std::cout << obj->value << std::endl;  // -> 42
+
+
+Expose a Class in Python
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Reflection**. The object's metadata is used for reflection. Use 
:cpp:class:`tvm::ffi::reflection::ObjectDef`
+to register an object's constructor, fields, and methods.
+
+.. code-block:: cpp
+
+   TVM_FFI_STATIC_INIT_BLOCK() {
+     namespace refl = tvm::ffi::reflection;
+     refl::ObjectDef<MyObjectObj>()
+         // Register constructor with signature
+         .def(refl::init<int64_t, ffi::String>())
+         // Register read-write fields
+         .def_rw("value", &MyObjectObj::value, "The integer value")
+         .def_rw("name", &MyObjectObj::name, "The name string")
+         // Register methods
+         .def("get_value", &MyObjectObj::GetValue, "Returns the value");
+   }
+
+**Python binding**. After registration, the object is automatically available 
in Python. Use
+:py:func:`tvm_ffi.register_object` to bind a Python class to a registered C++ 
type:
+
+.. code-block:: python
+
+   import tvm_ffi
+   from typing import TYPE_CHECKING
+
+   @tvm_ffi.register_object("my_ext.MyObject")
+   class MyObject(tvm_ffi.Object):
+       # tvm-ffi-stubgen(begin): object/my_ext.MyObject
+       value: int
+       name: str
+
+       if TYPE_CHECKING:
+         def __init__(self, value: int, name: str) -> None: ...
+         def get_value(self) -> int: ...
+       # tvm-ffi-stubgen(end)
+
+   # Create and use objects
+   obj = MyObject(42, "hello")
+   print(obj.value)        # -> 42
+   print(obj.get_value())  # -> 42
+   obj.value = 100         # Mutable field access
+
+The decorator looks up the type key ``"my_ext.MyObject"`` in the C++ type 
registry and binds the Python class to it.
+Fields and methods registered via 
:cpp:class:`~tvm::ffi::reflection::ObjectDef` are automatically available on 
the Python class.
+
+The tool ``tvm-ffi-stubgen`` automatically generates the Python type stubs 
(the code between the markers)
+from reflection metadata. See :ref:`Stub Generation Tool <sec-stubgen>` for 
details.
+
+
+.. _type-checking-and-casting:
+
+Type Checking and Casting
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Type checking**. Use :cpp:func:`Object::IsInstance\<T\>() 
<tvm::ffi::Object::IsInstance>`
+for runtime type checking:
+
+.. code-block:: cpp
+
+   bool CheckType(const ffi::ObjectRef& obj) {
+     if (obj->IsInstance<MyObjectObj>()) {
+       // obj is a MyObjectObj or subclass
+       return true;
+     }
+     return false;
+   }
+
+**Type casting**. Use :cpp:func:`ObjectRef::as\<T\>() 
<tvm::ffi::ObjectRef::as>` for safe downcasting:
+
+.. code-block:: cpp
+
+   ffi::ObjectRef obj = ...;
+
+   // as<ObjectType>() returns a pointer (nullptr if type doesn't match)
+   if (const MyObjectObj* ptr = obj.as<MyObjectObj>()) {
+     std::cout << ptr->value << std::endl;
+   }
+
+   // as<ObjectRefType>() returns std::optional
+   if (auto opt = obj.as<MyObject>()) {
+     std::cout << opt->get()->value << std::endl;
+   }
+
+**Type info**. Type index is available via :cpp:func:`ObjectRef::type_index() 
<tvm::ffi::ObjectRef::type_index>`
+and type key is available via :cpp:func:`ObjectRef::GetTypeKey() 
<tvm::ffi::ObjectRef::GetTypeKey>`. These methods
+can be used to safely identify object types without relying on C++ RTTI.
+
+.. note::
+  C++ RTTI (e.g. ``typeid``, ``dynamic_cast``) is strictly not useful in 
TVM-FFI-based approaches.
+
+Miscellaneous APIs
+~~~~~~~~~~~~~~~~~~
+
+**C++ Serialization**. Use :cpp:func:`tvm::ffi::ToJSONGraph` to serialize an 
object to a JSON value,
+and :cpp:func:`tvm::ffi::FromJSONGraph` to deserialize a JSON value to an 
object.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/extra/serialization.h>
+
+   // Serialize to JSON
+   ffi::Any obj = ...;
+   ffi::json::Value json = ffi::ToJSONGraph(obj);
+
+   // Deserialize from JSON
+   ffi::Any restored = ffi::FromJSONGraph(json);
+
+**Python Serialization**. Pickle is overloaded in Python to support TVM-FFI 
object serialization.
+Or explicitly use the :py:func:`tvm_ffi.serialization.to_json_graph_str`
+and :py:func:`tvm_ffi.serialization.from_json_graph_str` to serialize and 
deserialize an object to a JSON string.
+
+.. code-block:: python
+
+   import pickle
+
+   obj = MyObject(42, "test")
+   data = pickle.dumps(obj)
+   restored = pickle.loads(data)
+
+**Convert between raw and managed references**. Use 
:cpp:func:`tvm::ffi::GetRef` to convert a raw object pointer to a managed 
reference,
+and :cpp:func:`tvm::ffi::ObjectRef::get` to convert a managed reference to a 
raw object pointer.
+
+ABI and Layout
+--------------
+
+Stable C Layout
+~~~~~~~~~~~~~~~
+
+All subclasses of :cpp:class:`tvm::ffi::Object` share a common 24-byte header 
(:cpp:class:`TVMFFIObject`):
+
+.. code-block:: cpp
+
+   typedef struct {
+     uint64_t combined_ref_count;  // Bytes 0-7: strong + weak ref counts
+     int32_t type_index;           // Bytes 8-11: runtime type identifier
+     uint32_t __padding;           // Bytes 12-15: alignment padding
+     void (*deleter)(void*, int);  // Bytes 16-23: destructor callback
+   } TVMFFIObject;
+
+
+which is designed as a combination of

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The phrase 'which is designed as a combination of' is a bit awkward. 
Consider rephrasing for clarity, for example: 'It is designed with the 
following components:' or 'It combines the following features:'.



##########
docs/concepts/object_and_class.rst:
##########
@@ -0,0 +1,475 @@
+..  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.
+
+Object and Class
+================
+
+TVM-FFI provides a unified object system that enables cross-language 
interoperability
+between C++, Python, and Rust. The object system is built around 
:cpp:class:`tvm::ffi::Object`
+and :cpp:class:`tvm::ffi::ObjectRef`, which together form the foundation for:
+
+- **Type-safe runtime type identification** without relying on C++ RTTI
+- **Intrusive reference counting** for smart memory management
+- **Reflection-based class exposure** across programming languages
+- **Serialization and deserialization** via reflection metadata
+
+This tutorial covers everything you need to know about defining, using, and 
extending
+TVM-FFI objects across languages.
+
+
+Glossary
+--------
+
+:cpp:class:`tvm::ffi::Object`
+  A heap-allocated, reference-counted container.
+  All TVM-FFI objects inherit from this base class and share a common 24-byte 
header
+  that stores reference counts, type index, and a deleter callback.
+
+:cpp:class:`tvm::ffi::ObjectRef`
+  An intrusive pointer that manages an :cpp:class:`~tvm::ffi::Object`'s 
lifetime through reference counting.
+  Its subclasses provide type-safe access to specific object types. In its 
low-level implementation, it is
+  equivalent to a normal C++ pointer to a heap-allocated 
:cpp:class:`~tvm::ffi::Object`.
+
+Type index and type key
+  Type index is an integer that uniquely identifies each object type.
+  Built-in types have statically assigned indices defined in 
:cpp:enum:`TVMFFITypeIndex`,
+  while user-defined types receive indices at startup when first accessed.
+  Type key is a unique string identifier (e.g., ``"my_ext.MyClass"``) that 
names an object type.
+  It is used for registration, serialization, and cross-language mapping.
+
+Common Usage
+------------
+
+Define a Class in C++
+~~~~~~~~~~~~~~~~~~~~~
+
+To define a custom object class in normal C++, inherit it from 
:cpp:class:`tvm::ffi::Object` or its subclasses,
+and then add one of the following macros that declares its metadata:
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO>`
+   Declare an object type that can be subclassed. Type index is assigned 
dynamically.
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO_FINAL(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO_FINAL>`
+   Declare a final object type (no subclasses). Enables faster type checking.
+
+**Example**. The code below shows a minimal example of defining a TVM-FFI 
object class.
+It declares a class ``MyObjectObj`` that inherits from 
:cpp:class:`~tvm::ffi::Object`.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/tvm_ffi.h>
+
+   namespace ffi = tvm::ffi;
+
+   class MyObjectObj : public ffi::Object {
+    public:
+     // Normal C++ code: Declare fields, methods, constructor, destructor, etc.
+     int64_t value;
+     ffi::String name;
+
+     MyObjectObj(int64_t value, ffi::String name) : value(value), 
name(std::move(name)) {}
+
+     int64_t GetValue() const { return value; }
+
+     void AddToValue(int64_t other) { value += other; }
+
+     // Declare object type info
+     TVM_FFI_DECLARE_OBJECT_INFO(
+       /*type_key=*/"my_ext.MyObject",
+       /*type_name=*/MyObjectObj,
+       /*parent_type=*/ffi::Object);
+   };
+
+**Managed reference**. Optionally, a managed reference class can be defined by 
inheriting
+from :cpp:class:`~tvm::ffi::ObjectRef` and using one of the following macros 
to define the methods.
+Define its constructor by wrapping the :cpp:func:`tvm::ffi::make_object` 
function.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE>`
+   Define a nullable reference class.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE>`
+   Define a non-nullable reference class.
+
+For example, a non-nullable reference class ``MyObject`` can be defined as 
follows:
+
+.. code-block:: cpp
+
+   class MyObject : public ffi::ObjectRef {
+    public:
+     MyObject(int64_t value, ffi::String name)
+         : ObjectRef(ffi::make_object<MyObjectObj>(value, std::move(name))) {}
+     TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(
+        /*type_name=*/MyObject,
+        /*parent_type=*/ffi::ObjectRef,
+        /*object_name=*/MyObjectObj);
+   };
+
+   // Create a managed object
+   MyObject obj = MyObject(42, "hello");
+
+   // Access fields via operator->
+   std::cout << obj->value << std::endl;  // -> 42
+
+
+Expose a Class in Python
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Reflection**. The object's metadata is used for reflection. Use 
:cpp:class:`tvm::ffi::reflection::ObjectDef`
+to register an object's constructor, fields, and methods.
+
+.. code-block:: cpp
+
+   TVM_FFI_STATIC_INIT_BLOCK() {
+     namespace refl = tvm::ffi::reflection;
+     refl::ObjectDef<MyObjectObj>()
+         // Register constructor with signature
+         .def(refl::init<int64_t, ffi::String>())
+         // Register read-write fields
+         .def_rw("value", &MyObjectObj::value, "The integer value")
+         .def_rw("name", &MyObjectObj::name, "The name string")
+         // Register methods
+         .def("get_value", &MyObjectObj::GetValue, "Returns the value");
+   }
+
+**Python binding**. After registration, the object is automatically available 
in Python. Use
+:py:func:`tvm_ffi.register_object` to bind a Python class to a registered C++ 
type:
+
+.. code-block:: python
+
+   import tvm_ffi
+   from typing import TYPE_CHECKING
+
+   @tvm_ffi.register_object("my_ext.MyObject")
+   class MyObject(tvm_ffi.Object):
+       # tvm-ffi-stubgen(begin): object/my_ext.MyObject
+       value: int
+       name: str
+
+       if TYPE_CHECKING:
+         def __init__(self, value: int, name: str) -> None: ...
+         def get_value(self) -> int: ...
+       # tvm-ffi-stubgen(end)
+
+   # Create and use objects
+   obj = MyObject(42, "hello")
+   print(obj.value)        # -> 42
+   print(obj.get_value())  # -> 42
+   obj.value = 100         # Mutable field access
+
+The decorator looks up the type key ``"my_ext.MyObject"`` in the C++ type 
registry and binds the Python class to it.
+Fields and methods registered via 
:cpp:class:`~tvm::ffi::reflection::ObjectDef` are automatically available on 
the Python class.
+
+The tool ``tvm-ffi-stubgen`` automatically generates the Python type stubs 
(the code between the markers)
+from reflection metadata. See :ref:`Stub Generation Tool <sec-stubgen>` for 
details.
+
+
+.. _type-checking-and-casting:
+
+Type Checking and Casting
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Type checking**. Use :cpp:func:`Object::IsInstance\<T\>() 
<tvm::ffi::Object::IsInstance>`
+for runtime type checking:
+
+.. code-block:: cpp
+
+   bool CheckType(const ffi::ObjectRef& obj) {
+     if (obj->IsInstance<MyObjectObj>()) {
+       // obj is a MyObjectObj or subclass
+       return true;
+     }
+     return false;
+   }
+
+**Type casting**. Use :cpp:func:`ObjectRef::as\<T\>() 
<tvm::ffi::ObjectRef::as>` for safe downcasting:
+
+.. code-block:: cpp
+
+   ffi::ObjectRef obj = ...;
+
+   // as<ObjectType>() returns a pointer (nullptr if type doesn't match)
+   if (const MyObjectObj* ptr = obj.as<MyObjectObj>()) {
+     std::cout << ptr->value << std::endl;
+   }
+
+   // as<ObjectRefType>() returns std::optional
+   if (auto opt = obj.as<MyObject>()) {
+     std::cout << opt->get()->value << std::endl;
+   }
+
+**Type info**. Type index is available via :cpp:func:`ObjectRef::type_index() 
<tvm::ffi::ObjectRef::type_index>`
+and type key is available via :cpp:func:`ObjectRef::GetTypeKey() 
<tvm::ffi::ObjectRef::GetTypeKey>`. These methods
+can be used to safely identify object types without relying on C++ RTTI.
+
+.. note::
+  C++ RTTI (e.g. ``typeid``, ``dynamic_cast``) is strictly not useful in 
TVM-FFI-based approaches.
+
+Miscellaneous APIs
+~~~~~~~~~~~~~~~~~~
+
+**C++ Serialization**. Use :cpp:func:`tvm::ffi::ToJSONGraph` to serialize an 
object to a JSON value,
+and :cpp:func:`tvm::ffi::FromJSONGraph` to deserialize a JSON value to an 
object.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/extra/serialization.h>
+
+   // Serialize to JSON
+   ffi::Any obj = ...;
+   ffi::json::Value json = ffi::ToJSONGraph(obj);
+
+   // Deserialize from JSON
+   ffi::Any restored = ffi::FromJSONGraph(json);
+
+**Python Serialization**. Pickle is overloaded in Python to support TVM-FFI 
object serialization.
+Or explicitly use the :py:func:`tvm_ffi.serialization.to_json_graph_str`
+and :py:func:`tvm_ffi.serialization.from_json_graph_str` to serialize and 
deserialize an object to a JSON string.
+
+.. code-block:: python
+
+   import pickle
+
+   obj = MyObject(42, "test")
+   data = pickle.dumps(obj)
+   restored = pickle.loads(data)
+
+**Convert between raw and managed references**. Use 
:cpp:func:`tvm::ffi::GetRef` to convert a raw object pointer to a managed 
reference,
+and :cpp:func:`tvm::ffi::ObjectRef::get` to convert a managed reference to a 
raw object pointer.
+
+ABI and Layout
+--------------
+
+Stable C Layout
+~~~~~~~~~~~~~~~
+
+All subclasses of :cpp:class:`tvm::ffi::Object` share a common 24-byte header 
(:cpp:class:`TVMFFIObject`):
+
+.. code-block:: cpp
+
+   typedef struct {
+     uint64_t combined_ref_count;  // Bytes 0-7: strong + weak ref counts
+     int32_t type_index;           // Bytes 8-11: runtime type identifier
+     uint32_t __padding;           // Bytes 12-15: alignment padding
+     void (*deleter)(void*, int);  // Bytes 16-23: destructor callback
+   } TVMFFIObject;
+
+
+which is designed as a combination of
+
+- Reference counting and deleter callback, which are used to manage the 
lifetime of the object;
+- Type index, which is used to interact with type registration system for type 
checking and casting.
+
+:cpp:class:`tvm::ffi::ObjectRef` and :cpp:class:`tvm::ffi::ObjectPtr` are 
smart pointers whose
+layout is equivalent to:
+
+.. code-block:: cpp
+
+   struct { void* data; };
+
+
+Reference Counting
+~~~~~~~~~~~~~~~~~~
+
+**Deleter action**. When an object is managed by 
:cpp:class:`~tvm::ffi::ObjectRef`, the ``deleter`` callback is invoked:
+
+- When strong reference count reaches zero: the object's destructor is called.
+- When weak reference count reaches zero: the memory is freed.
+
+The flags in :cpp:enum:`TVMFFIObjectDeleterFlagBitMask` indicate which action 
to perform.
+
+**Intrusive reference counting**. The reference count is stored directly in 
the object header, not in a separate control block.
+This design reduces memory overhead and improves cache locality. Specifically, 
the :cpp:member:`TVMFFIObject::combined_ref_count`
+field stores a 64-bit integer that packs both strong and weak reference counts:
+
+.. code-block:: cpp
+
+   // Strong ref count: lower 32 bits
+   uint32_t strong_ref_count = combined_ref_count & 0xFFFFFFFF;
+   // Weak ref count: upper 32 bits
+   uint32_t weak_ref_count = (combined_ref_count >> 32) & 0xFFFFFFFF;
+
+C APIs are provided to manipulate the reference count of an object:
+
+- :cpp:func:`TVMFFIObjectIncRef` to increase the strong reference count;
+- :cpp:func:`TVMFFIObjectDecRef` to decrease the strong reference count.
+
+
+Conversion between :cpp:class:`~tvm::ffi::Any`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the stable C ABI boundary, TVM-FFI passes values using :cpp:class:`Any 
<tvm::ffi::Any>` (owning)
+or :cpp:class:`AnyView <tvm::ffi::AnyView>` (non-owning). Object handles are 
stored in the
+:cpp:member:`TVMFFIAny::v_obj` field with a type index >= 
``kTVMFFIStaticObjectBegin``.
+
+**Any/AnyView to Object**. Extract an object handle from 
:cpp:class:`TVMFFIAny`:
+
+.. code-block:: cpp
+
+   // Converts Any/AnyView to Object handle (non-owning)
+   int AnyToObjectPtr(const TVMFFIAny* value, TVMFFIObject** out) {
+     if (value->type_index >= kTVMFFIStaticObjectBegin) {
+       *out = (TVMFFIObject*)(value->v_obj);
+       return SUCCESS;
+     }
+     return FAILURE;  // Not an object type
+   }
+
+**Object to AnyView**. Store an object handle into non-owning 
:cpp:class:`AnyView <tvm::ffi::AnyView>`:
+
+.. code-block:: cpp
+
+   // Converts Object handle to AnyView (non-owning)
+   void ObjectToAnyView(TVMFFIObject* obj, int32_t type_index, TVMFFIAny* out) 
{
+     out->type_index = type_index;
+     out->zero_padding = 0;
+     out->v_obj = obj;
+   }
+
+**Object to Any**. Store an object handle into owning :cpp:class:`Any 
<tvm::ffi::Any>`.
+The function increments the reference count to take shared ownership.
+
+.. code-block:: cpp
+
+   // Converts Object handle to Any (owning, increments refcount)
+   void ObjectToAny(TVMFFIObject* obj, int32_t type_index, TVMFFIAny* out) {
+     ObjectToAnyView(obj, type_index, out);
+     TVMFFIObjectIncRef(obj);  // Take ownership
+   }
+
+Later, release ownership by calling :cpp:func:`TVMFFIObjectDecRef` on 
:cpp:member:`TVMFFIAny::v_obj`.
+
+Object Type Registry
+--------------------
+
+TVM-FFI maintains a global type registry that keeps track of all registered 
object types,
+their inheritance relationships, and their reflection metadata.
+
+Inheritance and Type Casting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. warning::
+    Only single inheritance is supported in TVM-FFI Object system.
+
+TVM-FFI implements its own runtime type system that enables type-safe 
operations
+without relying on C++ RTTI. Every object carries a runtime type index in its 
header.
+
+**Example**. Code below shows a minimal example of defining a base class and a 
derived class.
+
+.. code-block:: cpp
+
+   class MyBaseObj : public ffi::Object {
+    public:
+     TVM_FFI_DECLARE_OBJECT_INFO("my_ext.MyBase", MyBaseObj, ffi::Object);
+   };
+
+   class MyDerivedObj : public MyBaseObj {
+    public:
+     // Final class: no subclasses allowed
+     TVM_FFI_DECLARE_OBJECT_INFO_FINAL("my_ext.MyDerived", MyDerivedObj, 
MyBaseObj);
+   };
+
+
+The registration happens automatically when first accessed, which 
:cpp:func:`TVMFFITypeGetOrAllocIndex`
+helps to allocate inside :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO` or 
:c:macro:`TVM_FFI_DECLARE_OBJECT_INFO_FINAL`.
+
+See :ref:`type-checking-and-casting` for how to use the type system.
+
+Reflect Fields and Methods
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The reflection system enables cross-language exposure of C++ classes, their 
fields,
+and methods. Use :cpp:class:`ObjectDef\<T\> <tvm::ffi::reflection::ObjectDef>`
+to register reflection metadata for object type ``T``:
+
+.. list-table::
+   :header-rows: 1
+   :widths: 30 70
+
+   * - Method
+     - Description
+   * - ``.def(init<Args...>())``
+     - Register a constructor with the given argument types
+   * - ``.def_ro("name", &T::field)``
+     - Register a read-only field
+   * - ``.def_rw("name", &T::field)``
+     - Register a read-write field
+   * - ``.def("name", &T::method)``
+     - Register a member method
+   * - ``.def_static("name", &func)``
+     - Register a static method
+
+**Example**. Code below shows a minimal example of registering a class with 
reflection metadata.
+
+.. code-block:: cpp
+
+   class IntPairObj : public ffi::Object {
+    public:
+     int64_t a;
+     int64_t b;
+
+     IntPairObj(int64_t a, int64_t b) : a(a), b(b) {}
+
+     int64_t Sum() const { return a + b; }
+
+     TVM_FFI_DECLARE_OBJECT_INFO_FINAL("my_ext.IntPair", IntPairObj, 
ffi::Object);
+   };
+
+   TVM_FFI_STATIC_INIT_BLOCK() {
+     namespace refl = tvm::ffi::reflection;
+     refl::ObjectDef<IntPairObj>()
+         .def(refl::init<int64_t, int64_t>())
+         .def_rw("a", &IntPairObj::a, "the first field")
+         .def_rw("b", &IntPairObj::b, "the second field")
+         .def("sum", &IntPairObj::Sum, "compute a + b");
+   }
+
+
+**Metadata and Documentation**. Add documentation strings and custom metadata 
to fields and methods:
+
+.. code-block:: cpp
+
+   refl::ObjectDef<MyObjectObj>()
+       .def_rw("value", &MyObjectObj::value,
+               "The numeric value",                    // docstring
+               refl::DefaultValue(0),                  // default value
+               refl::Metadata{{"min", 0}, {"max", 100}})  // custom metadata
+       .def("add_to_value", &MyObjectObj::AddToValue,
+            "Add a value to the object's value field");

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   This example switches context back to `MyObjectObj` after the previous 
example used `IntPairObj`. This can be confusing for readers. Adding a comment 
to clarify that this example refers to the earlier `MyObjectObj` would improve 
readability.
   
   ```suggestion
      // The following example uses MyObjectObj defined earlier to show
      // how to add documentation and metadata.
      refl::ObjectDef<MyObjectObj>()
          .def_rw("value", &MyObjectObj::value,
                  "The numeric value",                    // docstring
                  refl::DefaultValue(0),                  // default value
                  refl::Metadata{{"min", 0}, {"max", 100}})  // custom metadata
          .def("add_to_value", &MyObjectObj::AddToValue,
               "Add a value to the object's value field");
   ```



##########
docs/concepts/object_and_class.rst:
##########
@@ -0,0 +1,475 @@
+..  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.
+
+Object and Class
+================
+
+TVM-FFI provides a unified object system that enables cross-language 
interoperability
+between C++, Python, and Rust. The object system is built around 
:cpp:class:`tvm::ffi::Object`
+and :cpp:class:`tvm::ffi::ObjectRef`, which together form the foundation for:
+
+- **Type-safe runtime type identification** without relying on C++ RTTI
+- **Intrusive reference counting** for smart memory management
+- **Reflection-based class exposure** across programming languages
+- **Serialization and deserialization** via reflection metadata
+
+This tutorial covers everything you need to know about defining, using, and 
extending
+TVM-FFI objects across languages.
+
+
+Glossary
+--------
+
+:cpp:class:`tvm::ffi::Object`
+  A heap-allocated, reference-counted container.
+  All TVM-FFI objects inherit from this base class and share a common 24-byte 
header
+  that stores reference counts, type index, and a deleter callback.
+
+:cpp:class:`tvm::ffi::ObjectRef`
+  An intrusive pointer that manages an :cpp:class:`~tvm::ffi::Object`'s 
lifetime through reference counting.
+  Its subclasses provide type-safe access to specific object types. In its 
low-level implementation, it is
+  equivalent to a normal C++ pointer to a heap-allocated 
:cpp:class:`~tvm::ffi::Object`.
+
+Type index and type key
+  Type index is an integer that uniquely identifies each object type.
+  Built-in types have statically assigned indices defined in 
:cpp:enum:`TVMFFITypeIndex`,
+  while user-defined types receive indices at startup when first accessed.
+  Type key is a unique string identifier (e.g., ``"my_ext.MyClass"``) that 
names an object type.
+  It is used for registration, serialization, and cross-language mapping.
+
+Common Usage
+------------
+
+Define a Class in C++
+~~~~~~~~~~~~~~~~~~~~~
+
+To define a custom object class in normal C++, inherit it from 
:cpp:class:`tvm::ffi::Object` or its subclasses,
+and then add one of the following macros that declares its metadata:
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO>`
+   Declare an object type that can be subclassed. Type index is assigned 
dynamically.
+
+ :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO_FINAL(TypeKey, TypeName, ParentType) 
<TVM_FFI_DECLARE_OBJECT_INFO_FINAL>`
+   Declare a final object type (no subclasses). Enables faster type checking.
+
+**Example**. The code below shows a minimal example of defining a TVM-FFI 
object class.
+It declares a class ``MyObjectObj`` that inherits from 
:cpp:class:`~tvm::ffi::Object`.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/tvm_ffi.h>
+
+   namespace ffi = tvm::ffi;
+
+   class MyObjectObj : public ffi::Object {
+    public:
+     // Normal C++ code: Declare fields, methods, constructor, destructor, etc.
+     int64_t value;
+     ffi::String name;
+
+     MyObjectObj(int64_t value, ffi::String name) : value(value), 
name(std::move(name)) {}
+
+     int64_t GetValue() const { return value; }
+
+     void AddToValue(int64_t other) { value += other; }
+
+     // Declare object type info
+     TVM_FFI_DECLARE_OBJECT_INFO(
+       /*type_key=*/"my_ext.MyObject",
+       /*type_name=*/MyObjectObj,
+       /*parent_type=*/ffi::Object);
+   };
+
+**Managed reference**. Optionally, a managed reference class can be defined by 
inheriting
+from :cpp:class:`~tvm::ffi::ObjectRef` and using one of the following macros 
to define the methods.
+Define its constructor by wrapping the :cpp:func:`tvm::ffi::make_object` 
function.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NULLABLE>`
+   Define a nullable reference class.
+
+ :c:macro:`TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(TypeName, ParentType, 
ObjectName) <TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE>`
+   Define a non-nullable reference class.
+
+For example, a non-nullable reference class ``MyObject`` can be defined as 
follows:
+
+.. code-block:: cpp
+
+   class MyObject : public ffi::ObjectRef {
+    public:
+     MyObject(int64_t value, ffi::String name)
+         : ObjectRef(ffi::make_object<MyObjectObj>(value, std::move(name))) {}
+     TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(
+        /*type_name=*/MyObject,
+        /*parent_type=*/ffi::ObjectRef,
+        /*object_name=*/MyObjectObj);
+   };
+
+   // Create a managed object
+   MyObject obj = MyObject(42, "hello");
+
+   // Access fields via operator->
+   std::cout << obj->value << std::endl;  // -> 42
+
+
+Expose a Class in Python
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Reflection**. The object's metadata is used for reflection. Use 
:cpp:class:`tvm::ffi::reflection::ObjectDef`
+to register an object's constructor, fields, and methods.
+
+.. code-block:: cpp
+
+   TVM_FFI_STATIC_INIT_BLOCK() {
+     namespace refl = tvm::ffi::reflection;
+     refl::ObjectDef<MyObjectObj>()
+         // Register constructor with signature
+         .def(refl::init<int64_t, ffi::String>())
+         // Register read-write fields
+         .def_rw("value", &MyObjectObj::value, "The integer value")
+         .def_rw("name", &MyObjectObj::name, "The name string")
+         // Register methods
+         .def("get_value", &MyObjectObj::GetValue, "Returns the value");
+   }
+
+**Python binding**. After registration, the object is automatically available 
in Python. Use
+:py:func:`tvm_ffi.register_object` to bind a Python class to a registered C++ 
type:
+
+.. code-block:: python
+
+   import tvm_ffi
+   from typing import TYPE_CHECKING
+
+   @tvm_ffi.register_object("my_ext.MyObject")
+   class MyObject(tvm_ffi.Object):
+       # tvm-ffi-stubgen(begin): object/my_ext.MyObject
+       value: int
+       name: str
+
+       if TYPE_CHECKING:
+         def __init__(self, value: int, name: str) -> None: ...
+         def get_value(self) -> int: ...
+       # tvm-ffi-stubgen(end)
+
+   # Create and use objects
+   obj = MyObject(42, "hello")
+   print(obj.value)        # -> 42
+   print(obj.get_value())  # -> 42
+   obj.value = 100         # Mutable field access
+
+The decorator looks up the type key ``"my_ext.MyObject"`` in the C++ type 
registry and binds the Python class to it.
+Fields and methods registered via 
:cpp:class:`~tvm::ffi::reflection::ObjectDef` are automatically available on 
the Python class.
+
+The tool ``tvm-ffi-stubgen`` automatically generates the Python type stubs 
(the code between the markers)
+from reflection metadata. See :ref:`Stub Generation Tool <sec-stubgen>` for 
details.
+
+
+.. _type-checking-and-casting:
+
+Type Checking and Casting
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Type checking**. Use :cpp:func:`Object::IsInstance\<T\>() 
<tvm::ffi::Object::IsInstance>`
+for runtime type checking:
+
+.. code-block:: cpp
+
+   bool CheckType(const ffi::ObjectRef& obj) {
+     if (obj->IsInstance<MyObjectObj>()) {
+       // obj is a MyObjectObj or subclass
+       return true;
+     }
+     return false;
+   }
+
+**Type casting**. Use :cpp:func:`ObjectRef::as\<T\>() 
<tvm::ffi::ObjectRef::as>` for safe downcasting:
+
+.. code-block:: cpp
+
+   ffi::ObjectRef obj = ...;
+
+   // as<ObjectType>() returns a pointer (nullptr if type doesn't match)
+   if (const MyObjectObj* ptr = obj.as<MyObjectObj>()) {
+     std::cout << ptr->value << std::endl;
+   }
+
+   // as<ObjectRefType>() returns std::optional
+   if (auto opt = obj.as<MyObject>()) {
+     std::cout << opt->get()->value << std::endl;
+   }
+
+**Type info**. Type index is available via :cpp:func:`ObjectRef::type_index() 
<tvm::ffi::ObjectRef::type_index>`
+and type key is available via :cpp:func:`ObjectRef::GetTypeKey() 
<tvm::ffi::ObjectRef::GetTypeKey>`. These methods
+can be used to safely identify object types without relying on C++ RTTI.
+
+.. note::
+  C++ RTTI (e.g. ``typeid``, ``dynamic_cast``) is strictly not useful in 
TVM-FFI-based approaches.
+
+Miscellaneous APIs
+~~~~~~~~~~~~~~~~~~
+
+**C++ Serialization**. Use :cpp:func:`tvm::ffi::ToJSONGraph` to serialize an 
object to a JSON value,
+and :cpp:func:`tvm::ffi::FromJSONGraph` to deserialize a JSON value to an 
object.
+
+.. code-block:: cpp
+
+   #include <tvm/ffi/extra/serialization.h>
+
+   // Serialize to JSON
+   ffi::Any obj = ...;
+   ffi::json::Value json = ffi::ToJSONGraph(obj);
+
+   // Deserialize from JSON
+   ffi::Any restored = ffi::FromJSONGraph(json);
+
+**Python Serialization**. Pickle is overloaded in Python to support TVM-FFI 
object serialization.
+Or explicitly use the :py:func:`tvm_ffi.serialization.to_json_graph_str`
+and :py:func:`tvm_ffi.serialization.from_json_graph_str` to serialize and 
deserialize an object to a JSON string.
+
+.. code-block:: python
+
+   import pickle
+
+   obj = MyObject(42, "test")
+   data = pickle.dumps(obj)
+   restored = pickle.loads(data)
+
+**Convert between raw and managed references**. Use 
:cpp:func:`tvm::ffi::GetRef` to convert a raw object pointer to a managed 
reference,
+and :cpp:func:`tvm::ffi::ObjectRef::get` to convert a managed reference to a 
raw object pointer.
+
+ABI and Layout
+--------------
+
+Stable C Layout
+~~~~~~~~~~~~~~~
+
+All subclasses of :cpp:class:`tvm::ffi::Object` share a common 24-byte header 
(:cpp:class:`TVMFFIObject`):
+
+.. code-block:: cpp
+
+   typedef struct {
+     uint64_t combined_ref_count;  // Bytes 0-7: strong + weak ref counts
+     int32_t type_index;           // Bytes 8-11: runtime type identifier
+     uint32_t __padding;           // Bytes 12-15: alignment padding
+     void (*deleter)(void*, int);  // Bytes 16-23: destructor callback
+   } TVMFFIObject;
+
+
+which is designed as a combination of
+
+- Reference counting and deleter callback, which are used to manage the 
lifetime of the object;
+- Type index, which is used to interact with type registration system for type 
checking and casting.
+
+:cpp:class:`tvm::ffi::ObjectRef` and :cpp:class:`tvm::ffi::ObjectPtr` are 
smart pointers whose
+layout is equivalent to:
+
+.. code-block:: cpp
+
+   struct { void* data; };
+
+
+Reference Counting
+~~~~~~~~~~~~~~~~~~
+
+**Deleter action**. When an object is managed by 
:cpp:class:`~tvm::ffi::ObjectRef`, the ``deleter`` callback is invoked:
+
+- When strong reference count reaches zero: the object's destructor is called.
+- When weak reference count reaches zero: the memory is freed.
+
+The flags in :cpp:enum:`TVMFFIObjectDeleterFlagBitMask` indicate which action 
to perform.
+
+**Intrusive reference counting**. The reference count is stored directly in 
the object header, not in a separate control block.
+This design reduces memory overhead and improves cache locality. Specifically, 
the :cpp:member:`TVMFFIObject::combined_ref_count`
+field stores a 64-bit integer that packs both strong and weak reference counts:
+
+.. code-block:: cpp
+
+   // Strong ref count: lower 32 bits
+   uint32_t strong_ref_count = combined_ref_count & 0xFFFFFFFF;
+   // Weak ref count: upper 32 bits
+   uint32_t weak_ref_count = (combined_ref_count >> 32) & 0xFFFFFFFF;
+
+C APIs are provided to manipulate the reference count of an object:
+
+- :cpp:func:`TVMFFIObjectIncRef` to increase the strong reference count;
+- :cpp:func:`TVMFFIObjectDecRef` to decrease the strong reference count.
+
+
+Conversion between :cpp:class:`~tvm::ffi::Any`
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the stable C ABI boundary, TVM-FFI passes values using :cpp:class:`Any 
<tvm::ffi::Any>` (owning)
+or :cpp:class:`AnyView <tvm::ffi::AnyView>` (non-owning). Object handles are 
stored in the
+:cpp:member:`TVMFFIAny::v_obj` field with a type index >= 
``kTVMFFIStaticObjectBegin``.
+
+**Any/AnyView to Object**. Extract an object handle from 
:cpp:class:`TVMFFIAny`:
+
+.. code-block:: cpp
+
+   // Converts Any/AnyView to Object handle (non-owning)
+   int AnyToObjectPtr(const TVMFFIAny* value, TVMFFIObject** out) {
+     if (value->type_index >= kTVMFFIStaticObjectBegin) {
+       *out = (TVMFFIObject*)(value->v_obj);
+       return SUCCESS;
+     }
+     return FAILURE;  // Not an object type
+   }
+
+**Object to AnyView**. Store an object handle into non-owning 
:cpp:class:`AnyView <tvm::ffi::AnyView>`:
+
+.. code-block:: cpp
+
+   // Converts Object handle to AnyView (non-owning)
+   void ObjectToAnyView(TVMFFIObject* obj, int32_t type_index, TVMFFIAny* out) 
{
+     out->type_index = type_index;
+     out->zero_padding = 0;
+     out->v_obj = obj;
+   }
+
+**Object to Any**. Store an object handle into owning :cpp:class:`Any 
<tvm::ffi::Any>`.
+The function increments the reference count to take shared ownership.
+
+.. code-block:: cpp
+
+   // Converts Object handle to Any (owning, increments refcount)
+   void ObjectToAny(TVMFFIObject* obj, int32_t type_index, TVMFFIAny* out) {
+     ObjectToAnyView(obj, type_index, out);
+     TVMFFIObjectIncRef(obj);  // Take ownership
+   }
+
+Later, release ownership by calling :cpp:func:`TVMFFIObjectDecRef` on 
:cpp:member:`TVMFFIAny::v_obj`.
+
+Object Type Registry
+--------------------
+
+TVM-FFI maintains a global type registry that keeps track of all registered 
object types,
+their inheritance relationships, and their reflection metadata.
+
+Inheritance and Type Casting
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. warning::
+    Only single inheritance is supported in TVM-FFI Object system.
+
+TVM-FFI implements its own runtime type system that enables type-safe 
operations
+without relying on C++ RTTI. Every object carries a runtime type index in its 
header.
+
+**Example**. Code below shows a minimal example of defining a base class and a 
derived class.
+
+.. code-block:: cpp
+
+   class MyBaseObj : public ffi::Object {
+    public:
+     TVM_FFI_DECLARE_OBJECT_INFO("my_ext.MyBase", MyBaseObj, ffi::Object);
+   };
+
+   class MyDerivedObj : public MyBaseObj {
+    public:
+     // Final class: no subclasses allowed
+     TVM_FFI_DECLARE_OBJECT_INFO_FINAL("my_ext.MyDerived", MyDerivedObj, 
MyBaseObj);
+   };
+
+
+The registration happens automatically when first accessed, which 
:cpp:func:`TVMFFITypeGetOrAllocIndex`
+helps to allocate inside :c:macro:`TVM_FFI_DECLARE_OBJECT_INFO` or 
:c:macro:`TVM_FFI_DECLARE_OBJECT_INFO_FINAL`.

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The phrasing of this sentence is a bit clumsy. Consider rephrasing for 
better readability. For example: 'Registration happens automatically on first 
access. The `:c:macro:TVM_FFI_DECLARE_OBJECT_INFO` and 
`:c:macro:TVM_FFI_DECLARE_OBJECT_INFO_FINAL` macros use 
`:cpp:func:TVMFFITypeGetOrAllocIndex` internally to allocate a type index.'



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to