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


##########
python/tvm_ffi/structural.py:
##########
@@ -231,3 +290,260 @@ def __hash__(self) -> int:
     def __eq__(self, other: Any) -> bool:
         """Compare by structural equality."""
         return isinstance(other, StructuralKey) and 
_ffi_api.StructuralKeyEqual(self, other)
+
+
+@register_object("ffi.VisitInterrupt")
+class VisitInterrupt(Object):
+    """Payload-carrying signal that stops a structural visit.
+
+    This object can be returned from structural walk callbacks and structural
+    visit hooks to halt traversal early. The optional payload is preserved in
+    :py:attr:`value` and returned to the caller.
+
+    Examples
+    --------
+    Use ``VisitInterrupt`` to stop a structural walk when a target node is 
found:
+
+    .. code-block:: python
+
+        import tvm_ffi
+
+
+        def on_node(node):
+            if is_target(node):
+                return tvm_ffi.VisitInterrupt(node)
+            return None
+
+
+        result = tvm_ffi.structural_walk(root, (object, on_node))
+        if result is not None:
+            found = result.value
+
+    See Also
+    --------
+    :py:func:`tvm_ffi.structural_walk`
+        Structural walk API whose callbacks may return ``VisitInterrupt``.
+
+    """
+
+    # tvm-ffi-stubgen(begin): object/ffi.VisitInterrupt
+    # fmt: off
+    value: Any
+    if TYPE_CHECKING:
+        def __init__(self, value: Any = ...) -> None: ...
+        def __ffi_init__(self, _0: Any, /) -> None: ...  # ty: 
ignore[invalid-method-override]
+    # fmt: on
+    # tvm-ffi-stubgen(end)
+
+    def __init__(self, value: Any = None) -> None:
+        """Create an interrupt with an optional payload.
+
+        Parameters
+        ----------
+        value
+            Payload returned to the caller when traversal stops.
+
+        """
+        self.__init_handle_by_constructor__(_ffi_api.VisitInterrupt, value)
+
+
+@register_object("ffi.StructuralVisitor")
+class StructuralVisitor(Object):
+    """Low-level structural traversal visitor.
+
+    This class exposes the low-level visitor object used by structural
+    traversal hooks.
+    """
+
+    # tvm-ffi-stubgen(begin): object/ffi.StructuralVisitor
+    # fmt: off
+    if TYPE_CHECKING:
+        def __init__(self) -> None: ...
+        def __ffi_init__(self) -> None: ...  # ty: 
ignore[invalid-method-override]
+    # fmt: on
+    # tvm-ffi-stubgen(end)
+
+    def __init__(self) -> None:
+        """Create a default structural visitor."""
+        self.__init_handle_by_constructor__(_ffi_api.StructuralVisitor)
+
+    def visit(self, value: Any) -> VisitInterrupt | None:
+        """Low-level API to visit ``value`` using this visitor's dispatch 
behavior.
+
+        Parameters
+        ----------
+        value
+            Value to visit.
+
+        Returns
+        -------
+        result
+            ``None`` if traversal should continue, otherwise a
+            :class:`VisitInterrupt` carrying the early-exit payload.
+
+        """
+        return _ffi_api.StructuralVisitorVisit(self, value)
+
+    def def_region_kind(self) -> DefRegionKind:
+        """Low-level API to return the currently active structural def-region 
kind.
+
+        Returns
+        -------
+        kind
+            The active :class:`DefRegionKind`.
+
+        """
+        return DefRegionKind(_ffi_api.StructuralVisitorDefRegionKind(self))
+
+    def with_def_region_kind(
+        self,
+        kind: int,
+        callback: Callable[[], Any],
+    ) -> Any:
+        """Low-level API to run ``callback`` with a temporarily active 
def-region kind.
+
+        Parameters
+        ----------
+        kind
+            Def region kind to use while running ``callback``.
+
+        callback
+            Nullary callable to execute inside the scoped region.
+
+        Returns
+        -------
+        result
+            The value returned by ``callback``.
+
+        """
+        return _ffi_api.StructuralVisitorWithDefRegionKind(self, kind, 
callback)
+
+
+def structural_walk(
+    root: Any,
+    *callbacks: tuple | Sequence | Callable,
+    with_def_region_kind: tuple | Sequence | Callable = (),
+    order: str | WalkOrder = "pre",
+) -> VisitInterrupt | None:
+    """Walk a value structurally and invoke the first matching typed callback.
+
+    Parameters
+    ----------
+    root
+        Root value to traverse.
+
+    callbacks
+        Normal callbacks. These callbacks receive one argument: ``value``.
+        Callback entries are tried in order.
+
+        Each positional callback slot may be one of:
+
+        - A single callback, used as a ``typing.Any`` catch-all.
+        - A ``(type, callback)`` entry.
+        - A grouped ``((type1, type2, ...), callback)`` entry.
+        - A sequence of entries.
+
+        Types may be builtins, registered FFI object classes, or
+        ``typing.Any``/``object`` as a catch-all.
+
+    with_def_region_kind
+        Def-region-aware callbacks. These callbacks receive two arguments:
+        ``(value, def_region_kind)``. They accept the same callback entry forms
+        as ``callbacks``.
+
+    order
+        ``"pre"``/``WalkOrder.PREORDER`` to invoke callbacks before children, 
or
+        ``"post"``/``WalkOrder.POSTORDER`` to invoke callbacks after children.
+
+    Returns
+    -------
+    result
+        ``None`` if traversal completed, otherwise a :class:`VisitInterrupt`
+        returned by a callback.
+
+    Examples
+    --------
+    .. code-block:: python
+
+        visited = []
+
+
+        uses = []
+        result = tvm_ffi.structural_walk(
+            node,
+            ((int, float), lambda value: visited.append(("leaf", value))),
+            with_def_region_kind=(
+                Var,
+                lambda var, kind: (
+                    uses.append(var) if kind == tvm_ffi.DefRegionKind.NONE 
else None
+                ),
+            ),
+        )
+
+    """
+    if isinstance(order, WalkOrder):
+        order_int = int(order)
+    elif order in ("pre", "post"):
+        order_int = int(WalkOrder.PREORDER if order == "pre" else 
WalkOrder.POSTORDER)
+    else:
+        raise ValueError(f"Unknown structural walk order: {order!r}")
+
+    def normalize_callback_slots(
+        callback_slots: tuple[tuple | Sequence | Callable, ...],
+    ) -> list[tuple[object, Callable]]:
+        callback_entries = []
+
+        def add_callback_entry(callback_entry: tuple) -> None:
+            callback_type, fn = callback_entry
+            callback_types = callback_type if isinstance(callback_type, tuple) 
else (callback_type,)
+            callback_entries.extend((t, fn) for t in callback_types)
+
+        for slot in callback_slots:
+            if callable(slot):
+                callback_entries.append((Any, slot))
+            elif isinstance(slot, tuple) and len(slot) == 2 and 
callable(slot[1]):
+                add_callback_entry(slot)
+            elif isinstance(slot, Sequence):
+                for callback in slot:
+                    assert isinstance(callback, tuple)
+                    assert len(callback) == 2 and callable(callback[1])
+                    add_callback_entry(callback)

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   Using `assert` statements for input validation in public APIs is a known 
anti-pattern because assertions can be completely optimized away when Python is 
run with the `-O` flag, bypassing the validation entirely. Additionally, `str` 
and `bytes` are sequences in Python and would be incorrectly processed as 
collections of callbacks if passed directly. Replacing `assert` with explicit 
`if` checks and raising `TypeError` provides robust validation, and explicitly 
excluding `str` and `bytes` prevents unexpected behavior.
   
   ```python
               elif isinstance(slot, Sequence) and not isinstance(slot, (str, 
bytes)):
                   for callback in slot:
                       if not isinstance(callback, tuple) or len(callback) != 2 
or not callable(callback[1]):
                           raise TypeError(
                               "structural_walk callbacks within a sequence 
must be (type, callback) tuples"
                           )
                       add_callback_entry(callback)
   ```



##########
include/tvm/ffi/extra/structural_visit.h:
##########
@@ -0,0 +1,763 @@
+/*
+ * 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 tvm/ffi/extra/structural_visit.h
+ * \brief Structural visit API.
+ */
+#ifndef TVM_FFI_EXTRA_STRUCTURAL_VISIT_H_
+#define TVM_FFI_EXTRA_STRUCTURAL_VISIT_H_
+
+#include <tvm/ffi/any.h>
+#include <tvm/ffi/c_api.h>
+#include <tvm/ffi/cast.h>
+#include <tvm/ffi/container/array.h>
+#include <tvm/ffi/container/tuple.h>
+#include <tvm/ffi/container/variant.h>
+#include <tvm/ffi/expected.h>
+#include <tvm/ffi/extra/visit_error_context.h>
+#include <tvm/ffi/function.h>
+#include <tvm/ffi/function_details.h>
+#include <tvm/ffi/optional.h>
+#include <tvm/ffi/reflection/accessor.h>
+
+#include <cstddef>
+#include <exception>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+namespace tvm {
+namespace ffi {
+
+/*!
+ * \brief Object node carrying the optional payload for an interrupted 
structural visit.
+ */
+class VisitInterruptObj : public Object {
+ public:
+  /*! \brief Payload returned with the interrupt, or FFI None for no payload. 
*/
+  Any value;
+
+  VisitInterruptObj() = default;
+  /*!
+   * \brief Construct a VisitInterruptObj with a payload.
+   * \param value The payload carried by the interrupt.
+   */
+  explicit VisitInterruptObj(Any value) : value(std::move(value)) {}
+
+  /// \cond Doxygen_Suppress
+  static constexpr const int32_t _type_index = 
TypeIndex::kTVMFFIVisitInterrupt;
+  static const constexpr bool _type_final = true;
+  TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIVisitInterrupt, 
VisitInterruptObj,
+                                     Object);
+  /// \endcond
+};
+
+/*!
+ * \brief ObjectRef wrapper for VisitInterruptObj.
+ */
+class VisitInterrupt : public ObjectRef {
+ public:
+  /*! \brief Construct an interrupt with no payload. */
+  VisitInterrupt() : VisitInterrupt(Any(nullptr)) {}
+  /*!
+   * \brief Construct an interrupt with a user-defined payload.
+   * \param value The payload carried by the interrupt.
+   */
+  explicit VisitInterrupt(Any value)
+      : ObjectRef(make_object<VisitInterruptObj>(std::move(value))) {}
+
+  /// \cond Doxygen_Suppress
+  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(VisitInterrupt, ObjectRef, 
VisitInterruptObj);
+  /// \endcond
+};
+
+class StructuralVisitorObj;
+
+/*!
+ * \brief ABI of structural visit for ``kStructuralVisit`` type attribute and
+ * ``StructuralVisitorVTable`` function pointer signature.
+ *
+ * The callback receives the visitor and the value being visited as an
+ * ``AnyView``. It returns a raw ``TVMFFIAny`` storing
+ * ``Expected<Optional<VisitInterrupt>>``.
+ */
+using FStructuralVisit = TVMFFIAny (*)(StructuralVisitorObj* visitor, AnyView 
value) noexcept;
+
+namespace details {
+
+// Visit reflected structural fields of an object-backed value.
+TVM_FFI_INLINE static Expected<Optional<VisitInterrupt>> 
VisitReflectedFieldsExpected(
+    StructuralVisitorObj* visitor, const Object* obj) noexcept;
+
+}  // namespace details
+
+/*!
+ * \brief VTable ABI for \ref StructuralVisitor dispatch. This function table 
provides a stable ABI
+ * for the visit method.
+ */
+struct StructuralVisitorVTable {
+  /*!
+   * \brief Visit callback.
+   * \param visitor The active structural visitor.
+   * \param value The value to visit.
+   * \return TVMFFIAny carrying Expected<Optional<VisitInterrupt>>.
+   *
+   * \note The raw ``visitor`` pointer and ``value`` view are non-owning. On
+   * failure, the returned ``TVMFFIAny`` stores ``Error``; on success, it 
stores
+   * either None or ``VisitInterrupt``.
+   */
+  FStructuralVisit visit = nullptr;
+};
+
+/*!
+ * \brief Object node of a structural visitor.
+ *
+ * A structural visitor is an active traversal context.  It carries the 
dispatch
+ * table used to visit each object and the current def-region state used by
+ * structural equality/hash semantics.  The visitor is ref-counted so it can
+ * cross FFI boundaries, but one underlying visitor object should not be shared
+ * by overlapping top-level traversals.
+ */
+class StructuralVisitorObj : public Object {
+ public:
+  /*! \brief Construct the default structural visitor. */
+  StructuralVisitorObj() : StructuralVisitorObj(VTable()) {}
+
+  /*!
+   * \brief Visit a value, dispatching through this visitor's vtable.
+   *
+   * \param value The value to visit.
+   * \return ``std::nullopt`` to continue traversal, or a \ref VisitInterrupt
+   *         to halt the entire visit.
+   */
+  TVM_FFI_INLINE Optional<VisitInterrupt> Visit(AnyView value) {
+    return VisitExpected(value).value();
+  }
+
+  /*!
+   * \brief Visit a value, propagating error through expected return.
+   *
+   * \param value The value to visit.
+   * \return Expected interrupt state. An error means traversal failed.
+   */
+  TVM_FFI_INLINE Expected<Optional<VisitInterrupt>> VisitExpected(AnyView 
value) noexcept {
+    return 
details::ExpectedUnsafe::MoveFromTVMFFIAny<Optional<VisitInterrupt>>(
+        (*vtable_->visit)(this, value));
+  }
+
+  /*!
+   * \brief Visit using the structural visit behavior registered by 
kStructuralVisit for each type,
+   * or reflected structural fields when no custom behavior is registered.
+   */
+  TVM_FFI_INLINE Optional<VisitInterrupt> DefaultVisit(AnyView value) {
+    return DefaultVisitExpected(value).value();
+  }
+
+  /*!
+   * \brief Visit using the registered structural visit behavior by 
kStructuralVisit, propagating
+   * errors by Expected.
+   *
+   * \param value The value to visit.
+   * \return Expected interrupt state. An error means traversal failed.
+   */
+  TVM_FFI_INLINE Expected<Optional<VisitInterrupt>> 
DefaultVisitExpected(AnyView value) noexcept {
+    int32_t type_index = value.type_index();
+    static reflection::TypeAttrColumn 
column(reflection::type_attr::kStructuralVisit);
+    AnyView attr = column[type_index];
+
+    // case 1: Type-specific override registered as an opaque ABI visit 
function pointer.
+    if (attr.type_index() == TypeIndex::kTVMFFIOpaquePtr) {
+      auto* visit_fn = reinterpret_cast<FStructuralVisit>(attr.cast<void*>());
+      return 
details::ExpectedUnsafe::MoveFromTVMFFIAny<Optional<VisitInterrupt>>(
+          (*visit_fn)(this, value));
+    }
+
+    // case 2: Type-specific override registered as an ffi::Function.
+    if (attr.type_index() == TypeIndex::kTVMFFIFunction) {
+      return 
attr.cast<Function>().CallExpected<Optional<VisitInterrupt>>(this, value);
+    }
+
+    if (TVM_FFI_PREDICT_FALSE(attr.type_index() != TypeIndex::kTVMFFINone)) {
+      return Unexpected(Error("TypeError",
+                              
std::string(reflection::type_attr::kStructuralVisit) +
+                                  " must be an opaque function pointer or 
ffi.Function",
+                              ""));
+    }
+
+    if (type_index < TypeIndex::kTVMFFIStaticObjectBegin) {
+      return Optional<VisitInterrupt>(std::nullopt);
+    }
+
+    return details::VisitReflectedFieldsExpected(this, value.cast<const 
Object*>());
+  }
+
+  /*!
+   * \brief Return the current def-region context.
+   * \return The active def-region kind.
+   */
+  TVM_FFI_INLINE TVMFFIDefRegionKind def_region_kind() const { return 
def_region_mode_; }
+
+  /*!
+   * \brief Temporarily switch the def-region context while invoking \p 
callback.
+   *
+   * This helper scopes updates to the traversal state used by def/use-region
+   * aware visitors. The previous state is restored when the callback returns
+   * or throws.
+   *
+   * \param kind The def-region kind to set during the callback.
+   * \param callback A nullary callable that performs recursive visiting.
+   * \return The value returned by \p callback.
+   */
+  template <typename Callback>
+  TVM_FFI_INLINE auto WithDefRegionKind(TVMFFIDefRegionKind kind, Callback&& 
callback) {
+    class Scope {
+     public:
+      Scope(StructuralVisitorObj* visitor, TVMFFIDefRegionKind kind)
+          : visitor_(visitor), old_kind_(visitor->def_region_mode_) {
+        visitor_->def_region_mode_ = kind;
+      }
+      ~Scope() { visitor_->def_region_mode_ = old_kind_; }
+      Scope(const Scope&) = delete;
+      Scope& operator=(const Scope&) = delete;
+
+     private:
+      StructuralVisitorObj* visitor_;
+      TVMFFIDefRegionKind old_kind_;
+    };
+    Scope scope(this, kind);
+    return std::forward<Callback>(callback)();
+  }
+
+  /// \cond Doxygen_Suppress
+  static constexpr const bool _type_mutable = true;
+  TVM_FFI_DECLARE_OBJECT_INFO("ffi.StructuralVisitor", StructuralVisitorObj, 
Object);
+  /// \endcond
+
+ protected:
+  /*!
+   * \brief Construct a structural visitor subclass with a custom dispatch 
vtable.
+   *
+   * \param vtable The non-null dispatch table for this visitor.
+   *
+   * \note This constructor is for internal subclasses.  The vtable and its
+   *       ``visit`` callback must be valid for the lifetime of the visitor.
+   */
+  explicit StructuralVisitorObj(const StructuralVisitorVTable* vtable) : 
vtable_(vtable) {}
+
+  /*!
+   * \brief Required ABI dispatch table. \ref StructuralVisitorVTable
+   * It must never be null on a constructed visitor.
+   */
+  const StructuralVisitorVTable* vtable_ = nullptr;
+
+  /*!
+   * \brief Current def-region context for structural equality/hash semantics.
+   *
+   * This is shared mutable traversal state. Be careful when mutating it 
through
+   * multiple references to the same visitor object. Use \ref WithDefRegionKind
+   * to scope temporary changes.
+   */
+  TVMFFIDefRegionKind def_region_mode_ = kTVMFFIDefRegionKindNone;
+
+ private:
+  /*!
+   * \brief Return the vtable used by the default visitor.
+   * \return Pointer to the static structural visitor vtable.
+   */
+  static const StructuralVisitorVTable* VTable() {
+    static const StructuralVisitorVTable 
vtable{&StructuralVisitorObj::DispatchVisit};
+    return &vtable;
+  }
+
+  /*!
+   * \brief Dispatch from the vtable to the default visitor.
+   * \param visitor The structural visitor object.
+   * \param value The value to visit.
+   * \return Interrupt state, or an error if traversal failed.
+   */
+  static TVMFFIAny DispatchVisit(StructuralVisitorObj* visitor, AnyView value) 
noexcept {
+    auto interrupt = visitor->DefaultVisitExpected(value);
+    if (TVM_FFI_PREDICT_FALSE(interrupt.type_index() == 
TypeIndex::kTVMFFIError)) {
+      if (value.type_index() >= TypeIndex::kTVMFFIStaticObjectBegin) {
+        Error err = interrupt.error();
+        details::UpdateVisitErrorContext(err, value.cast<ObjectRef>());
+      }
+    }
+    return details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(interrupt));
+  }
+};
+
+/*!
+ * \brief ObjectRef wrapper of \ref StructuralVisitorObj.
+ *
+ * \sa StructuralVisitorObj
+ */
+class StructuralVisitor : public ObjectRef {
+ public:
+  /*!
+   * \brief Construct the default structural visitor.
+   */
+  StructuralVisitor() : ObjectRef(make_object<StructuralVisitorObj>()) {}
+  /*!
+   * \brief Construct from an existing object pointer.
+   * \param n The object pointer to wrap.
+   */
+  explicit StructuralVisitor(ObjectPtr<StructuralVisitorObj> n) : 
ObjectRef(std::move(n)) {}
+
+  /// \cond Doxygen_Suppress
+  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(StructuralVisitor, ObjectRef, 
StructuralVisitorObj);
+  /// \endcond
+};
+
+namespace details {
+
+/*!
+ * \brief Return true when \p result already carries a traversal-stopping 
state.
+ * \tparam T The Expected success type.
+ * \param result The Expected value to inspect.
+ * \return Whether \p result stores an Error or VisitInterrupt.
+ */
+template <typename T>
+TVM_FFI_INLINE bool StructuralVisitNeedEarlyReturn(const Expected<T>& result) 
noexcept {
+  int32_t type_index = result.type_index();
+  return type_index == TypeIndex::kTVMFFIError || type_index == 
TypeIndex::kTVMFFIVisitInterrupt;
+}
+
+/*!
+ * \brief Walk reflected structural fields of object-backed \p obj.
+ *
+ * Fields marked with ``kTVMFFIFieldFlagBitMaskSEqHashIgnore`` are skipped.
+ * Def-region field flags are scoped around recursive child visits.
+ *
+ * \param visitor The active visitor.
+ * \param obj The object whose reflected fields should be visited.
+ * \return Expected interrupt state. An error means traversal failed.
+ */
+TVM_FFI_INLINE static Expected<Optional<VisitInterrupt>> 
VisitReflectedFieldsExpected(
+    StructuralVisitorObj* visitor, const Object* obj) noexcept {
+  int32_t type_index = obj->type_index();
+  const TVMFFITypeInfo* type_info = TVMFFIGetTypeInfo(type_index);
+
+  Expected<Optional<VisitInterrupt>> result = 
Optional<VisitInterrupt>(std::nullopt);
+  reflection::ForEachFieldInfoWithEarlyStop(
+      type_info, [&](const TVMFFIFieldInfo* field_info) -> bool {
+        if (field_info->flags & kTVMFFIFieldFlagBitMaskSEqHashIgnore) {
+          return false;
+        }
+
+        Any field_value;
+        const void* field_addr = reinterpret_cast<const char*>(obj) + 
field_info->offset;
+        int ret_code = field_info->getter(const_cast<void*>(field_addr),
+                                          
reinterpret_cast<TVMFFIAny*>(&field_value));
+        if (TVM_FFI_PREDICT_FALSE(ret_code != 0)) {
+          result = Unexpected(details::MoveFromSafeCallRaised());
+          return true;
+        }
+
+        TVMFFIDefRegionKind kind = kTVMFFIDefRegionKindNone;
+        if (field_info->flags & kTVMFFIFieldFlagBitMaskSEqHashDefNonRecursive) 
{
+          kind = kTVMFFIDefRegionKindNonRecursive;
+        } else if (field_info->flags & 
kTVMFFIFieldFlagBitMaskSEqHashDefRecursive) {
+          kind = kTVMFFIDefRegionKindRecursive;
+        }
+
+        if (kind != kTVMFFIDefRegionKindNone) {
+          result = visitor->WithDefRegionKind(
+              kind, [&]() { return visitor->VisitExpected(field_value); });
+        } else {
+          result = visitor->VisitExpected(field_value);
+        }
+        return StructuralVisitNeedEarlyReturn(result);
+      });
+  return result;
+}
+
+}  // namespace details
+
+// ---------------------------------------------------------------------------
+// Structural Walk API.
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief Per-node control signal returned by structural walk callbacks.
+ *
+ * Walk control result with one of three actions:
+ * - ``WalkResult::Advance()``: continue traversal, including this node's 
children.
+ * - ``WalkResult::Skip()``: continue traversal but skip this node's children.
+ * - ``WalkResult::Interrupt()``: halt the entire walk, optionally carrying a 
payload.
+ */
+class WalkResult : public Variant<VisitInterrupt, int32_t> {
+ public:
+  /*! \brief Internal tag value carried by ``WalkResult::Advance()``. */
+  static constexpr int32_t kAdvanceTag = 0;
+  /*! \brief Internal tag value carried by ``WalkResult::Skip()``. */
+  static constexpr int32_t kSkipTag = 1;
+
+  /*! \brief The underlying ``Variant`` used as storage. */
+  using Storage = Variant<VisitInterrupt, int32_t>;
+
+  /*! \brief Continue traversal and visit this node's children. */
+  static WalkResult Advance() { return WalkResult(kAdvanceTag); }
+
+  /*! \brief Continue traversal but skip this node's children. */
+  static WalkResult Skip() { return WalkResult(kSkipTag); }
+
+  /*!
+   * \brief Halt the walk and propagate an interrupt.
+   * \param signal The interrupt to propagate. Defaults to an interrupt with
+   *               FFI None payload.
+   */
+  static WalkResult Interrupt(VisitInterrupt signal = VisitInterrupt()) {
+    return WalkResult(Storage(std::move(signal)));
+  }
+
+ private:
+  // Keep raw storage construction behind the named factories.
+  explicit WalkResult(int32_t tag) : Storage(tag) {}
+  explicit WalkResult(Storage storage) : Storage(std::move(storage)) {}
+
+  friend struct TypeTraits<WalkResult>;
+};
+
+/// \cond Doxygen_Suppress
+template <>
+inline constexpr bool use_default_type_traits_v<WalkResult> = false;
+
+// Allow WalkResult to round-trip through Any / Expected while reusing Variant 
storage.
+template <>
+struct TypeTraits<WalkResult> : public TypeTraits<WalkResult::Storage> {
+  using Base = TypeTraits<WalkResult::Storage>;
+
+  TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
+    return src->type_index == TypeIndex::kTVMFFINone || 
Base::CheckAnyStrict(src);
+  }
+  // Decode from borrowed Any storage after a strict type check.
+  TVM_FFI_INLINE static WalkResult CopyFromAnyViewAfterCheck(const TVMFFIAny* 
src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    return WalkResult(Base::CopyFromAnyViewAfterCheck(src));
+  }
+  // Decode by moving from owned Any storage after a strict type check.
+  TVM_FFI_INLINE static WalkResult MoveFromAnyAfterCheck(TVMFFIAny* src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    return WalkResult(Base::MoveFromAnyAfterCheck(src));
+  }
+  // Try all conversions supported by the underlying Variant storage.
+  TVM_FFI_INLINE static std::optional<WalkResult> TryCastFromAnyView(const 
TVMFFIAny* src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    if (auto opt = Base::TryCastFromAnyView(src)) {
+      return WalkResult(*std::move(opt));
+    }
+    return std::nullopt;
+  }
+  TVM_FFI_INLINE static std::string TypeStr() { return "WalkResult"; }
+};
+/// \endcond
+
+/*!
+ * \brief Callback order for \ref tvm::ffi::StructuralWalk.
+ */
+enum class WalkOrder : int32_t {
+  /*! \brief Invoke the callback before visiting children. */
+  kPreOrder = 0,
+  /*! \brief Invoke the callback after visiting children. */
+  kPostOrder = 1,
+};
+
+namespace details {
+
+/// \cond Doxygen_Suppress
+// Return from the current ABI visit function if Result stops traversal.
+// Result must be an existing Expected variable whose raw storage can be moved 
to TVMFFIAny.
+#define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(Result)                             
             \
+  if 
(TVM_FFI_PREDICT_FALSE(::tvm::ffi::details::StructuralVisitNeedEarlyReturn(Result)))
 { \
+    return 
::tvm::ffi::details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(Result));        
 \
+  }

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The `TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN` macro evaluates its `Result` 
argument multiple times (once in `StructuralVisitNeedEarlyReturn` and once in 
`std::move`). If `Result` is a complex expression or a function call with side 
effects, this can lead to multiple evaluations and unexpected behavior. 
Wrapping the macro in a `do { ... } while (0)` block and binding `Result` to a 
local reference ensures it is evaluated exactly once.
   
   ```c
   #define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(Result)                           
               \
     do {                                                                       
               \
       auto&& _tvm_ffi_res_ = (Result);                                         
               \
       if 
(TVM_FFI_PREDICT_FALSE(::tvm::ffi::details::StructuralVisitNeedEarlyReturn(_tvm_ffi_res_)))
 { \
         return 
::tvm::ffi::details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(_tvm_ffi_res_)); 
\
       }                                                                        
               \
     } while (0)
   ```



##########
include/tvm/ffi/extra/structural_visit.h:
##########
@@ -0,0 +1,763 @@
+/*
+ * 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 tvm/ffi/extra/structural_visit.h
+ * \brief Structural visit API.
+ */
+#ifndef TVM_FFI_EXTRA_STRUCTURAL_VISIT_H_
+#define TVM_FFI_EXTRA_STRUCTURAL_VISIT_H_
+
+#include <tvm/ffi/any.h>
+#include <tvm/ffi/c_api.h>
+#include <tvm/ffi/cast.h>
+#include <tvm/ffi/container/array.h>
+#include <tvm/ffi/container/tuple.h>
+#include <tvm/ffi/container/variant.h>
+#include <tvm/ffi/expected.h>
+#include <tvm/ffi/extra/visit_error_context.h>
+#include <tvm/ffi/function.h>
+#include <tvm/ffi/function_details.h>
+#include <tvm/ffi/optional.h>
+#include <tvm/ffi/reflection/accessor.h>
+
+#include <cstddef>
+#include <exception>
+#include <optional>
+#include <string>
+#include <tuple>
+#include <type_traits>
+#include <utility>
+
+namespace tvm {
+namespace ffi {
+
+/*!
+ * \brief Object node carrying the optional payload for an interrupted 
structural visit.
+ */
+class VisitInterruptObj : public Object {
+ public:
+  /*! \brief Payload returned with the interrupt, or FFI None for no payload. 
*/
+  Any value;
+
+  VisitInterruptObj() = default;
+  /*!
+   * \brief Construct a VisitInterruptObj with a payload.
+   * \param value The payload carried by the interrupt.
+   */
+  explicit VisitInterruptObj(Any value) : value(std::move(value)) {}
+
+  /// \cond Doxygen_Suppress
+  static constexpr const int32_t _type_index = 
TypeIndex::kTVMFFIVisitInterrupt;
+  static const constexpr bool _type_final = true;
+  TVM_FFI_DECLARE_OBJECT_INFO_STATIC(StaticTypeKey::kTVMFFIVisitInterrupt, 
VisitInterruptObj,
+                                     Object);
+  /// \endcond
+};
+
+/*!
+ * \brief ObjectRef wrapper for VisitInterruptObj.
+ */
+class VisitInterrupt : public ObjectRef {
+ public:
+  /*! \brief Construct an interrupt with no payload. */
+  VisitInterrupt() : VisitInterrupt(Any(nullptr)) {}
+  /*!
+   * \brief Construct an interrupt with a user-defined payload.
+   * \param value The payload carried by the interrupt.
+   */
+  explicit VisitInterrupt(Any value)
+      : ObjectRef(make_object<VisitInterruptObj>(std::move(value))) {}
+
+  /// \cond Doxygen_Suppress
+  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(VisitInterrupt, ObjectRef, 
VisitInterruptObj);
+  /// \endcond
+};
+
+class StructuralVisitorObj;
+
+/*!
+ * \brief ABI of structural visit for ``kStructuralVisit`` type attribute and
+ * ``StructuralVisitorVTable`` function pointer signature.
+ *
+ * The callback receives the visitor and the value being visited as an
+ * ``AnyView``. It returns a raw ``TVMFFIAny`` storing
+ * ``Expected<Optional<VisitInterrupt>>``.
+ */
+using FStructuralVisit = TVMFFIAny (*)(StructuralVisitorObj* visitor, AnyView 
value) noexcept;
+
+namespace details {
+
+// Visit reflected structural fields of an object-backed value.
+TVM_FFI_INLINE static Expected<Optional<VisitInterrupt>> 
VisitReflectedFieldsExpected(
+    StructuralVisitorObj* visitor, const Object* obj) noexcept;
+
+}  // namespace details
+
+/*!
+ * \brief VTable ABI for \ref StructuralVisitor dispatch. This function table 
provides a stable ABI
+ * for the visit method.
+ */
+struct StructuralVisitorVTable {
+  /*!
+   * \brief Visit callback.
+   * \param visitor The active structural visitor.
+   * \param value The value to visit.
+   * \return TVMFFIAny carrying Expected<Optional<VisitInterrupt>>.
+   *
+   * \note The raw ``visitor`` pointer and ``value`` view are non-owning. On
+   * failure, the returned ``TVMFFIAny`` stores ``Error``; on success, it 
stores
+   * either None or ``VisitInterrupt``.
+   */
+  FStructuralVisit visit = nullptr;
+};
+
+/*!
+ * \brief Object node of a structural visitor.
+ *
+ * A structural visitor is an active traversal context.  It carries the 
dispatch
+ * table used to visit each object and the current def-region state used by
+ * structural equality/hash semantics.  The visitor is ref-counted so it can
+ * cross FFI boundaries, but one underlying visitor object should not be shared
+ * by overlapping top-level traversals.
+ */
+class StructuralVisitorObj : public Object {
+ public:
+  /*! \brief Construct the default structural visitor. */
+  StructuralVisitorObj() : StructuralVisitorObj(VTable()) {}
+
+  /*!
+   * \brief Visit a value, dispatching through this visitor's vtable.
+   *
+   * \param value The value to visit.
+   * \return ``std::nullopt`` to continue traversal, or a \ref VisitInterrupt
+   *         to halt the entire visit.
+   */
+  TVM_FFI_INLINE Optional<VisitInterrupt> Visit(AnyView value) {
+    return VisitExpected(value).value();
+  }
+
+  /*!
+   * \brief Visit a value, propagating error through expected return.
+   *
+   * \param value The value to visit.
+   * \return Expected interrupt state. An error means traversal failed.
+   */
+  TVM_FFI_INLINE Expected<Optional<VisitInterrupt>> VisitExpected(AnyView 
value) noexcept {
+    return 
details::ExpectedUnsafe::MoveFromTVMFFIAny<Optional<VisitInterrupt>>(
+        (*vtable_->visit)(this, value));
+  }
+
+  /*!
+   * \brief Visit using the structural visit behavior registered by 
kStructuralVisit for each type,
+   * or reflected structural fields when no custom behavior is registered.
+   */
+  TVM_FFI_INLINE Optional<VisitInterrupt> DefaultVisit(AnyView value) {
+    return DefaultVisitExpected(value).value();
+  }
+
+  /*!
+   * \brief Visit using the registered structural visit behavior by 
kStructuralVisit, propagating
+   * errors by Expected.
+   *
+   * \param value The value to visit.
+   * \return Expected interrupt state. An error means traversal failed.
+   */
+  TVM_FFI_INLINE Expected<Optional<VisitInterrupt>> 
DefaultVisitExpected(AnyView value) noexcept {
+    int32_t type_index = value.type_index();
+    static reflection::TypeAttrColumn 
column(reflection::type_attr::kStructuralVisit);
+    AnyView attr = column[type_index];
+
+    // case 1: Type-specific override registered as an opaque ABI visit 
function pointer.
+    if (attr.type_index() == TypeIndex::kTVMFFIOpaquePtr) {
+      auto* visit_fn = reinterpret_cast<FStructuralVisit>(attr.cast<void*>());
+      return 
details::ExpectedUnsafe::MoveFromTVMFFIAny<Optional<VisitInterrupt>>(
+          (*visit_fn)(this, value));
+    }
+
+    // case 2: Type-specific override registered as an ffi::Function.
+    if (attr.type_index() == TypeIndex::kTVMFFIFunction) {
+      return 
attr.cast<Function>().CallExpected<Optional<VisitInterrupt>>(this, value);
+    }
+
+    if (TVM_FFI_PREDICT_FALSE(attr.type_index() != TypeIndex::kTVMFFINone)) {
+      return Unexpected(Error("TypeError",
+                              
std::string(reflection::type_attr::kStructuralVisit) +
+                                  " must be an opaque function pointer or 
ffi.Function",
+                              ""));
+    }
+
+    if (type_index < TypeIndex::kTVMFFIStaticObjectBegin) {
+      return Optional<VisitInterrupt>(std::nullopt);
+    }
+
+    return details::VisitReflectedFieldsExpected(this, value.cast<const 
Object*>());
+  }
+
+  /*!
+   * \brief Return the current def-region context.
+   * \return The active def-region kind.
+   */
+  TVM_FFI_INLINE TVMFFIDefRegionKind def_region_kind() const { return 
def_region_mode_; }
+
+  /*!
+   * \brief Temporarily switch the def-region context while invoking \p 
callback.
+   *
+   * This helper scopes updates to the traversal state used by def/use-region
+   * aware visitors. The previous state is restored when the callback returns
+   * or throws.
+   *
+   * \param kind The def-region kind to set during the callback.
+   * \param callback A nullary callable that performs recursive visiting.
+   * \return The value returned by \p callback.
+   */
+  template <typename Callback>
+  TVM_FFI_INLINE auto WithDefRegionKind(TVMFFIDefRegionKind kind, Callback&& 
callback) {
+    class Scope {
+     public:
+      Scope(StructuralVisitorObj* visitor, TVMFFIDefRegionKind kind)
+          : visitor_(visitor), old_kind_(visitor->def_region_mode_) {
+        visitor_->def_region_mode_ = kind;
+      }
+      ~Scope() { visitor_->def_region_mode_ = old_kind_; }
+      Scope(const Scope&) = delete;
+      Scope& operator=(const Scope&) = delete;
+
+     private:
+      StructuralVisitorObj* visitor_;
+      TVMFFIDefRegionKind old_kind_;
+    };
+    Scope scope(this, kind);
+    return std::forward<Callback>(callback)();
+  }
+
+  /// \cond Doxygen_Suppress
+  static constexpr const bool _type_mutable = true;
+  TVM_FFI_DECLARE_OBJECT_INFO("ffi.StructuralVisitor", StructuralVisitorObj, 
Object);
+  /// \endcond
+
+ protected:
+  /*!
+   * \brief Construct a structural visitor subclass with a custom dispatch 
vtable.
+   *
+   * \param vtable The non-null dispatch table for this visitor.
+   *
+   * \note This constructor is for internal subclasses.  The vtable and its
+   *       ``visit`` callback must be valid for the lifetime of the visitor.
+   */
+  explicit StructuralVisitorObj(const StructuralVisitorVTable* vtable) : 
vtable_(vtable) {}
+
+  /*!
+   * \brief Required ABI dispatch table. \ref StructuralVisitorVTable
+   * It must never be null on a constructed visitor.
+   */
+  const StructuralVisitorVTable* vtable_ = nullptr;
+
+  /*!
+   * \brief Current def-region context for structural equality/hash semantics.
+   *
+   * This is shared mutable traversal state. Be careful when mutating it 
through
+   * multiple references to the same visitor object. Use \ref WithDefRegionKind
+   * to scope temporary changes.
+   */
+  TVMFFIDefRegionKind def_region_mode_ = kTVMFFIDefRegionKindNone;
+
+ private:
+  /*!
+   * \brief Return the vtable used by the default visitor.
+   * \return Pointer to the static structural visitor vtable.
+   */
+  static const StructuralVisitorVTable* VTable() {
+    static const StructuralVisitorVTable 
vtable{&StructuralVisitorObj::DispatchVisit};
+    return &vtable;
+  }
+
+  /*!
+   * \brief Dispatch from the vtable to the default visitor.
+   * \param visitor The structural visitor object.
+   * \param value The value to visit.
+   * \return Interrupt state, or an error if traversal failed.
+   */
+  static TVMFFIAny DispatchVisit(StructuralVisitorObj* visitor, AnyView value) 
noexcept {
+    auto interrupt = visitor->DefaultVisitExpected(value);
+    if (TVM_FFI_PREDICT_FALSE(interrupt.type_index() == 
TypeIndex::kTVMFFIError)) {
+      if (value.type_index() >= TypeIndex::kTVMFFIStaticObjectBegin) {
+        Error err = interrupt.error();
+        details::UpdateVisitErrorContext(err, value.cast<ObjectRef>());
+      }
+    }
+    return details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(interrupt));
+  }
+};
+
+/*!
+ * \brief ObjectRef wrapper of \ref StructuralVisitorObj.
+ *
+ * \sa StructuralVisitorObj
+ */
+class StructuralVisitor : public ObjectRef {
+ public:
+  /*!
+   * \brief Construct the default structural visitor.
+   */
+  StructuralVisitor() : ObjectRef(make_object<StructuralVisitorObj>()) {}
+  /*!
+   * \brief Construct from an existing object pointer.
+   * \param n The object pointer to wrap.
+   */
+  explicit StructuralVisitor(ObjectPtr<StructuralVisitorObj> n) : 
ObjectRef(std::move(n)) {}
+
+  /// \cond Doxygen_Suppress
+  TVM_FFI_DEFINE_OBJECT_REF_METHODS_NOTNULLABLE(StructuralVisitor, ObjectRef, 
StructuralVisitorObj);
+  /// \endcond
+};
+
+namespace details {
+
+/*!
+ * \brief Return true when \p result already carries a traversal-stopping 
state.
+ * \tparam T The Expected success type.
+ * \param result The Expected value to inspect.
+ * \return Whether \p result stores an Error or VisitInterrupt.
+ */
+template <typename T>
+TVM_FFI_INLINE bool StructuralVisitNeedEarlyReturn(const Expected<T>& result) 
noexcept {
+  int32_t type_index = result.type_index();
+  return type_index == TypeIndex::kTVMFFIError || type_index == 
TypeIndex::kTVMFFIVisitInterrupt;
+}
+
+/*!
+ * \brief Walk reflected structural fields of object-backed \p obj.
+ *
+ * Fields marked with ``kTVMFFIFieldFlagBitMaskSEqHashIgnore`` are skipped.
+ * Def-region field flags are scoped around recursive child visits.
+ *
+ * \param visitor The active visitor.
+ * \param obj The object whose reflected fields should be visited.
+ * \return Expected interrupt state. An error means traversal failed.
+ */
+TVM_FFI_INLINE static Expected<Optional<VisitInterrupt>> 
VisitReflectedFieldsExpected(
+    StructuralVisitorObj* visitor, const Object* obj) noexcept {
+  int32_t type_index = obj->type_index();
+  const TVMFFITypeInfo* type_info = TVMFFIGetTypeInfo(type_index);
+
+  Expected<Optional<VisitInterrupt>> result = 
Optional<VisitInterrupt>(std::nullopt);
+  reflection::ForEachFieldInfoWithEarlyStop(
+      type_info, [&](const TVMFFIFieldInfo* field_info) -> bool {
+        if (field_info->flags & kTVMFFIFieldFlagBitMaskSEqHashIgnore) {
+          return false;
+        }
+
+        Any field_value;
+        const void* field_addr = reinterpret_cast<const char*>(obj) + 
field_info->offset;
+        int ret_code = field_info->getter(const_cast<void*>(field_addr),
+                                          
reinterpret_cast<TVMFFIAny*>(&field_value));
+        if (TVM_FFI_PREDICT_FALSE(ret_code != 0)) {
+          result = Unexpected(details::MoveFromSafeCallRaised());
+          return true;
+        }
+
+        TVMFFIDefRegionKind kind = kTVMFFIDefRegionKindNone;
+        if (field_info->flags & kTVMFFIFieldFlagBitMaskSEqHashDefNonRecursive) 
{
+          kind = kTVMFFIDefRegionKindNonRecursive;
+        } else if (field_info->flags & 
kTVMFFIFieldFlagBitMaskSEqHashDefRecursive) {
+          kind = kTVMFFIDefRegionKindRecursive;
+        }
+
+        if (kind != kTVMFFIDefRegionKindNone) {
+          result = visitor->WithDefRegionKind(
+              kind, [&]() { return visitor->VisitExpected(field_value); });
+        } else {
+          result = visitor->VisitExpected(field_value);
+        }
+        return StructuralVisitNeedEarlyReturn(result);
+      });
+  return result;
+}
+
+}  // namespace details
+
+// ---------------------------------------------------------------------------
+// Structural Walk API.
+// ---------------------------------------------------------------------------
+
+/*!
+ * \brief Per-node control signal returned by structural walk callbacks.
+ *
+ * Walk control result with one of three actions:
+ * - ``WalkResult::Advance()``: continue traversal, including this node's 
children.
+ * - ``WalkResult::Skip()``: continue traversal but skip this node's children.
+ * - ``WalkResult::Interrupt()``: halt the entire walk, optionally carrying a 
payload.
+ */
+class WalkResult : public Variant<VisitInterrupt, int32_t> {
+ public:
+  /*! \brief Internal tag value carried by ``WalkResult::Advance()``. */
+  static constexpr int32_t kAdvanceTag = 0;
+  /*! \brief Internal tag value carried by ``WalkResult::Skip()``. */
+  static constexpr int32_t kSkipTag = 1;
+
+  /*! \brief The underlying ``Variant`` used as storage. */
+  using Storage = Variant<VisitInterrupt, int32_t>;
+
+  /*! \brief Continue traversal and visit this node's children. */
+  static WalkResult Advance() { return WalkResult(kAdvanceTag); }
+
+  /*! \brief Continue traversal but skip this node's children. */
+  static WalkResult Skip() { return WalkResult(kSkipTag); }
+
+  /*!
+   * \brief Halt the walk and propagate an interrupt.
+   * \param signal The interrupt to propagate. Defaults to an interrupt with
+   *               FFI None payload.
+   */
+  static WalkResult Interrupt(VisitInterrupt signal = VisitInterrupt()) {
+    return WalkResult(Storage(std::move(signal)));
+  }
+
+ private:
+  // Keep raw storage construction behind the named factories.
+  explicit WalkResult(int32_t tag) : Storage(tag) {}
+  explicit WalkResult(Storage storage) : Storage(std::move(storage)) {}
+
+  friend struct TypeTraits<WalkResult>;
+};
+
+/// \cond Doxygen_Suppress
+template <>
+inline constexpr bool use_default_type_traits_v<WalkResult> = false;
+
+// Allow WalkResult to round-trip through Any / Expected while reusing Variant 
storage.
+template <>
+struct TypeTraits<WalkResult> : public TypeTraits<WalkResult::Storage> {
+  using Base = TypeTraits<WalkResult::Storage>;
+
+  TVM_FFI_INLINE static bool CheckAnyStrict(const TVMFFIAny* src) {
+    return src->type_index == TypeIndex::kTVMFFINone || 
Base::CheckAnyStrict(src);
+  }
+  // Decode from borrowed Any storage after a strict type check.
+  TVM_FFI_INLINE static WalkResult CopyFromAnyViewAfterCheck(const TVMFFIAny* 
src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    return WalkResult(Base::CopyFromAnyViewAfterCheck(src));
+  }
+  // Decode by moving from owned Any storage after a strict type check.
+  TVM_FFI_INLINE static WalkResult MoveFromAnyAfterCheck(TVMFFIAny* src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    return WalkResult(Base::MoveFromAnyAfterCheck(src));
+  }
+  // Try all conversions supported by the underlying Variant storage.
+  TVM_FFI_INLINE static std::optional<WalkResult> TryCastFromAnyView(const 
TVMFFIAny* src) {
+    if (src->type_index == TypeIndex::kTVMFFINone) {
+      return WalkResult::Advance();
+    }
+    if (auto opt = Base::TryCastFromAnyView(src)) {
+      return WalkResult(*std::move(opt));
+    }
+    return std::nullopt;
+  }
+  TVM_FFI_INLINE static std::string TypeStr() { return "WalkResult"; }
+};
+/// \endcond
+
+/*!
+ * \brief Callback order for \ref tvm::ffi::StructuralWalk.
+ */
+enum class WalkOrder : int32_t {
+  /*! \brief Invoke the callback before visiting children. */
+  kPreOrder = 0,
+  /*! \brief Invoke the callback after visiting children. */
+  kPostOrder = 1,
+};
+
+namespace details {
+
+/// \cond Doxygen_Suppress
+// Return from the current ABI visit function if Result stops traversal.
+// Result must be an existing Expected variable whose raw storage can be moved 
to TVMFFIAny.
+#define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN(Result)                             
             \
+  if 
(TVM_FFI_PREDICT_FALSE(::tvm::ffi::details::StructuralVisitNeedEarlyReturn(Result)))
 { \
+    return 
::tvm::ffi::details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(Result));        
 \
+  }
+
+// Return from the current ABI visit function if Result stops traversal.
+// If Result is an Error, append Node to the visit error context before 
returning.
+#define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN_WITH_ERROR_CONTEXT(Result, Node)    
                \
+  if 
(TVM_FFI_PREDICT_FALSE(::tvm::ffi::details::StructuralVisitNeedEarlyReturn(Result)))
 {    \
+    if (TVM_FFI_PREDICT_FALSE((Result).type_index() == 
::tvm::ffi::TypeIndex::kTVMFFIError)) { \
+      if ((Node).type_index() >= 
::tvm::ffi::TypeIndex::kTVMFFIStaticObjectBegin) {            \
+        ::tvm::ffi::Error _tvm_ffi_visit_err_ = (Result).error();              
                \
+        ::tvm::ffi::details::UpdateVisitErrorContext(_tvm_ffi_visit_err_,      
                \
+                                                     
(Node).cast<::tvm::ffi::ObjectRef>());    \
+      }                                                                        
                \
+    }                                                                          
                \
+    return 
::tvm::ffi::details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(Result));        
    \
+  }

Review Comment:
   ![medium](https://www.gstatic.com/codereviewagent/medium-priority.svg)
   
   The `TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN_WITH_ERROR_CONTEXT` macro evaluates 
its `Result` argument up to four times. If `Result` is a function call or has 
side effects, this will cause multiple evaluations. Wrapping the macro in a `do 
{ ... } while (0)` block and binding `Result` to a local reference ensures it 
is evaluated exactly once.
   
   ```c
   #define TVM_FFI_S_VISIT_MAYBE_EARLY_RETURN_WITH_ERROR_CONTEXT(Result, Node)  
                  \
     do {                                                                       
                  \
       auto&& _tvm_ffi_res_ = (Result);                                         
                  \
       if 
(TVM_FFI_PREDICT_FALSE(::tvm::ffi::details::StructuralVisitNeedEarlyReturn(_tvm_ffi_res_)))
 { \
         if (TVM_FFI_PREDICT_FALSE(_tvm_ffi_res_.type_index() == 
::tvm::ffi::TypeIndex::kTVMFFIError)) { \
           if ((Node).type_index() >= 
::tvm::ffi::TypeIndex::kTVMFFIStaticObjectBegin) {          \
             ::tvm::ffi::Error _tvm_ffi_visit_err_ = _tvm_ffi_res_.error();     
                  \
             ::tvm::ffi::details::UpdateVisitErrorContext(_tvm_ffi_visit_err_,  
                  \
                                                          
(Node).cast<::tvm::ffi::ObjectRef>());  \
           }                                                                    
                  \
         }                                                                      
                  \
         return 
::tvm::ffi::details::ExpectedUnsafe::MoveToTVMFFIAny(std::move(_tvm_ffi_res_)); 
  \
       }                                                                        
                  \
     } while (0)
   ```



-- 
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