Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 77 additions & 23 deletions ffi/include/tvm/ffi/c_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,12 +303,54 @@ typedef int (*TVMFFIFieldGetter)(void* field, TVMFFIAny* result);
*/
typedef int (*TVMFFIFieldSetter)(void* field, const TVMFFIAny* value);

/*!
* \brief bitmask of the field.
*/
#ifdef __cplusplus
enum TVMFFIFieldFlagBitMask : int32_t {
#else
typedef enum {
#endif
/*! \brief The field is writable. */
TVMFFIFieldFlagBitMaskWritable = 1 << 0,
/*! \brief The field has default value. */
TVMFFIFieldFlagBitMaskHasDefault = 1 << 1,
/*! \brief The field is a static method. */
TVMFFIFieldFlagBitMaskIsStaticMethod = 1 << 2,
#ifdef __cplusplus
};
#else
} TVMFFIFieldFlagBitMask;
#endif

/*!
* \brief Information support for optional object reflection.
*/
typedef struct {
/*! \brief The name of the field. */
TVMFFIByteArray name;
/*! \brief The docstring about the field. */
TVMFFIByteArray doc;
/*!
* \brief bitmask flags of the field.
*/
int64_t flags;
/*!
* \brief Byte offset of the field.
*/
int64_t byte_offset;
/*! \brief The getter to access the field. */
TVMFFIFieldGetter getter;
/*!
* \brief The setter to access the field.
* \note The setter is set even if the field is readonly for serialization.
*/
TVMFFIFieldSetter setter;
/*!
* \brief The default value of the field, this field hold AnyView,
* valid when flags set TVMFFIFieldFlagBitMaskHasDefault
*/
TVMFFIAny default_value;
/*!
* \brief Records the static type kind of the field.
*
Expand All @@ -317,28 +359,18 @@ typedef struct {
* - TVMFFITypeIndex::kTVMFFIObject for general objects
* - The value is nullable when kTVMFFIObject is chosen
* - static object type kinds such as Map, Dict, String
* - POD type index
* - POD type index, note it does not give information about storage size of the field.
* - TVMFFITypeIndex::kTVMFFIAny if we don't have specialized info
* about the field.
*
* \note This information is helpful in designing serializer
* of the field. As it helps to narrow down the type of the
* object. It also helps to provide opportunities to enable
* short-cut access to the field.
* When the value is a type index of Object type, the field is storaged as an ObjectRef.
*
* \note This information maybe helpful in designing serializer.
* As it helps to narrow down the field type so we don't have to
* print type_key for cases like POD types.
* It also helps to provide opportunities to enable short-cut getter to ObjectRef fields.
*/
int32_t field_static_type_index;
/*!
* \brief Mark whether field is readonly.
*/
int32_t readonly;
/*!
* \brief Byte offset of the field.
*/
int64_t byte_offset;
/*! \brief The getter to access the field. */
TVMFFIFieldGetter getter;
/*! \brief The setter to access the field. */
TVMFFIFieldSetter setter;
} TVMFFIFieldInfo;

/*!
Expand All @@ -347,11 +379,15 @@ typedef struct {
typedef struct {
/*! \brief The name of the field. */
TVMFFIByteArray name;
/*! \brief The docstring about the method. */
TVMFFIByteArray doc;
/*! \brief bitmask flags of the method. */
int64_t flags;
/*!
* \brief The method wrapped as Function
* \note The first argument to the method is always the self.
* \brief The method wrapped as ffi::Function, stored as AnyView.
* \note The first argument to the method is always the self for instance methods.
*/
TVMFFIObjectHandle method;
TVMFFIAny method;
} TVMFFIMethodInfo;

/*!
Expand Down Expand Up @@ -379,6 +415,7 @@ typedef struct {
int32_t num_fields;
/*! \brief number of reflection acccesible methods. */
int32_t num_methods;

/*! \brief The reflection field information. */
TVMFFIFieldInfo* fields;
/*! \brief The reflection method. */
Expand Down Expand Up @@ -522,12 +559,29 @@ TVM_FFI_DLL int TVMFFIEnvRegisterCAPI(const TVMFFIByteArray* name, void* symbol)
// Section: Type reflection support APIs
//------------------------------------------------------------
/*!
* \brief Register type field information for rutnime reflection.
* \brief Register type field information for runtime reflection.
* \param type_index The type index
* \param info The field info to be registered.
* \return 0 when success, nonzero when failure happens
*/
TVM_FFI_DLL int TVMFFIRegisterTypeField(int32_t type_index, const TVMFFIFieldInfo* info);
TVM_FFI_DLL int TVMFFITypeRegisterField(int32_t type_index, const TVMFFIFieldInfo* info);

/*!
* \brief Register type method information for runtime reflection.
* \param type_index The type index
* \param info The method info to be registered.
* \return 0 when success, nonzero when failure happens
*/
TVM_FFI_DLL int TVMFFITypeRegisterMethod(int32_t type_index, const TVMFFIMethodInfo* info);

/*!
* \brief Get dynamic type info by type index.
*
* \param type_index The type index
* \param result The output type information
* \return The type info
*/
TVM_FFI_DLL const TVMFFITypeInfo* TVMFFITypeGetMethod(int32_t type_index);

//------------------------------------------------------------
// Section: DLPack support APIs
Expand Down Expand Up @@ -638,7 +692,7 @@ TVM_FFI_DLL const TVMFFIByteArray* TVMFFITraceback(const char* filename, int lin
*
* \return 0 if success, -1 if error occured
*/
TVM_FFI_DLL int32_t TVMFFIGetOrAllocTypeIndex(const TVMFFIByteArray* type_key,
TVM_FFI_DLL int32_t TVMFFITypeGetOrAllocIndex(const TVMFFIByteArray* type_key,
int32_t static_type_index, int32_t type_depth,
int32_t num_child_slots,
int32_t child_slots_can_overflow,
Expand Down
8 changes: 4 additions & 4 deletions ffi/include/tvm/ffi/function.h
Original file line number Diff line number Diff line change
Expand Up @@ -836,14 +836,14 @@ class Function::Registry {
if constexpr (std::is_base_of_v<ObjectRef, T>) {
auto fwrap = [f](T target, Args... params) -> R {
// call method pointer
return (target.*f)(params...);
return (target.*f)(std::forward<Args>(params)...);
};
return Register(ffi::Function::FromTyped(fwrap, name_));
}
if constexpr (std::is_base_of_v<Object, T>) {
auto fwrap = [f](const T* target, Args... params) -> R {
// call method pointer
return (const_cast<T*>(target)->*f)(params...);
return (const_cast<T*>(target)->*f)(std::forward<Args>(params)...);
};
return Register(ffi::Function::FromTyped(fwrap, name_));
}
Expand All @@ -857,14 +857,14 @@ class Function::Registry {
if constexpr (std::is_base_of_v<ObjectRef, T>) {
auto fwrap = [f](const T target, Args... params) -> R {
// call method pointer
return (target.*f)(params...);
return (target.*f)(std::forward<Args>(params)...);
};
return Register(ffi::Function::FromTyped(fwrap, name_));
}
if constexpr (std::is_base_of_v<Object, T>) {
auto fwrap = [f](const T* target, Args... params) -> R {
// call method pointer
return (target->*f)(params...);
return (target->*f)(std::forward<Args>(params)...);
};
return Register(ffi::Function::FromTyped(fwrap, name_));
}
Expand Down
8 changes: 6 additions & 2 deletions ffi/include/tvm/ffi/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ TVM_FFI_INLINE bool IsObjectInstance(int32_t object_type_index);
* This field is automatically set by macro TVM_DECLARE_FINAL_OBJECT_INFO
* It is still OK to sub-class a terminal object type T and construct it using make_object.
* But IsInstance check will only show that the object type is T(instead of the sub-class).
* - _type_mutable:
* Whether we would like to expose cast to non-constant pointer
* ObjectType* from Any/AnyView. By default, we set to false so it is not exposed.
*
* The following two fields are necessary for base classes that can be sub-classed.
*
Expand Down Expand Up @@ -191,6 +194,7 @@ class Object {

// Default object type properties for sub-classes
static constexpr bool _type_final = false;
static constexpr bool _type_mutable = false;
static constexpr uint32_t _type_child_slots = 0;
static constexpr bool _type_child_slots_can_overflow = true;
// NOTE: static type index field of the class
Expand Down Expand Up @@ -546,7 +550,7 @@ struct ObjectPtrEqual {
"Need to set _type_child_slots when parent specifies it."); \
TVMFFIByteArray type_key{TypeName::_type_key, \
std::char_traits<char>::length(TypeName::_type_key)}; \
static int32_t tindex = TVMFFIGetOrAllocTypeIndex( \
static int32_t tindex = TVMFFITypeGetOrAllocIndex( \
&type_key, TypeName::_type_index, TypeName::_type_depth, TypeName::_type_child_slots, \
TypeName::_type_child_slots_can_overflow, ParentType::_GetOrAllocRuntimeTypeIndex()); \
return tindex; \
Expand Down Expand Up @@ -576,7 +580,7 @@ struct ObjectPtrEqual {
"Need to set _type_child_slots when parent specifies it."); \
TVMFFIByteArray type_key{TypeName::_type_key, \
std::char_traits<char>::length(TypeName::_type_key)}; \
static int32_t tindex = TVMFFIGetOrAllocTypeIndex( \
static int32_t tindex = TVMFFITypeGetOrAllocIndex( \
&type_key, -1, TypeName::_type_depth, TypeName::_type_child_slots, \
TypeName::_type_child_slots_can_overflow, ParentType::_GetOrAllocRuntimeTypeIndex()); \
return tindex; \
Expand Down
Loading
Loading