- improve the interface of rtti to pass meta_obj_t* as parameter of type function to easy to access private/data

- rename some macro with RTTI
- add RTTI_MAGIC in object header
- add new rtti api
This commit is contained in:
Rongsong Shen 2026-01-30 12:26:23 +08:00
parent c8c1749347
commit f78ed03591
15 changed files with 252 additions and 114 deletions

View file

@ -9,12 +9,14 @@
#include <stdlib.h>
#include <sys/types.h>
#define RTTI_MAGIC (0x5254544949545452)
#define var void*
#define SIZE_ROUNDUP(sz) \
#define RTTI_SIZE_ROUNDUP(sz) \
((((sz + sizeof(void*) - 1)) / (sizeof(void*))) * sizeof(void*))
#define OBJ_HEADER_SIZE SIZE_ROUNDUP(sizeof(meta_obj_t))
#define RTTI_OBJ_HEADER_SIZE RTTI_SIZE_ROUNDUP(sizeof(meta_obj_t))
/** Object format
**
@ -23,10 +25,34 @@
** +=====================+===================+===================+
**
**/
#define OBJ_TO_DATA(T, obj) ((T*)(((char*)obj) + OBJ_HEADER_SIZE))
#define DATA_TO_OBJ(v) ((meta_obj_t*)(((char*)v) - OBJ_HEADER_SIZE))
#define OBJ_TO_PRIV(obj) \
((void*)(((char*)obj) - SIZE_ROUNDUP((obj)->type->privateSize)))
#define RTTI_OBJ_TO_DATA(T, obj) ((T*)((obj)->data))
#define RTTI_DATA_TO_OBJ(v) \
(((v) == NULL) ? NULL : ((meta_obj_t*)(((char*)v) - RTTI_OBJ_HEADER_SIZE)))
#define RTTI_OBJ_TO_PRIV(obj) ((obj)->privdata)
#define RTTI_GET_METHOD(result, obj, intf, method) \
do { \
typeinfo_t* type_ = NULL; \
\
(result) = NULL; \
\
if ((obj) == NULL) { \
break; \
} \
\
type_ = obj->type; \
if (type_ == NULL) { \
break; \
} \
\
if (type_->interfaces.intf == NULL) { \
break; \
} \
\
(result) = type_->interfaces.intf->method; \
} while (0)
#define RTTI_OBJ_INVALID(obj) (((obj) == NULL) || ((obj)->magic != RTTI_MAGIC))
struct meta_obj_;
struct typeinfo_;
@ -38,12 +64,12 @@ typedef struct typeinfo_ typeinfo_t;
typedef size_t (*datasize_fn_t)(va_list);
/* object life cycle */
typedef int (*obj_init_fn_t)(typeinfo_t*, va_list);
typedef void (*obj_destroy_fn_t)(var);
typedef int (*obj_init_fn_t)(meta_obj_t*, va_list);
typedef void (*obj_destroy_fn_t)(meta_obj_t*);
/* lock/unlock */
typedef int (*lock_fn_t)(var, uint64_t);
typedef void (*unlock_fn_t)(var);
typedef int (*lock_fn_t)(meta_obj_t*, uint64_t);
typedef void (*unlock_fn_t)(meta_obj_t*);
typedef struct {
lock_fn_t lock;
@ -51,7 +77,7 @@ typedef struct {
} intf_lock_t;
/* convert to string */
typedef char* (*to_string_fn_t)(var, va_list);
typedef char* (*to_string_fn_t)(meta_obj_t*, va_list);
typedef struct {
to_string_fn_t toString;
@ -59,15 +85,15 @@ typedef struct {
/* iterator function */
#define ITER_NO_DATA (0)
#define ITER_OK (1)
#define RTTI_ITER_NO_DATA (0)
#define RTTI_ITER_OK (1)
typedef struct {
var v;
var data;
meta_obj_t* obj;
var data;
} iterator_t;
typedef int (*iter_make_fn_t)(iterator_t*, var);
typedef int (*iter_make_fn_t)(iterator_t*);
typedef int (*iter_next_fn_t)(iterator_t*, void**);
typedef int (*iter_reset_fn_t)(iterator_t*);
typedef void (*iter_destroy_fn_t)(iterator_t*);
@ -80,8 +106,8 @@ typedef struct {
} intf_iterator_t;
/* reference and deref */
typedef int32_t (*reference_fn_t)(var);
typedef void (*dereference_fn_t)(var);
typedef int32_t (*reference_fn_t)(meta_obj_t*);
typedef void (*dereference_fn_t)(meta_obj_t*);
typedef struct {
reference_fn_t reference;
@ -90,14 +116,14 @@ typedef struct {
/* hash */
typedef int32_t (*hash_fn_t)(var);
typedef int32_t (*hash_fn_t)(meta_obj_t*);
typedef struct {
hash_fn_t hash;
} intf_hash_t;
/* length */
typedef int64_t (*length_fn_t)(var);
typedef int64_t (*length_fn_t)(meta_obj_t*);
typedef struct {
length_fn_t length;
@ -122,11 +148,15 @@ struct typeinfo_ {
};
struct meta_obj_ {
uint64_t magic;
typeinfo_t* type;
void* privdata;
void* data;
};
extern var makeInstance(typeinfo_t*, ...);
extern void destroy(var);
extern int is_rtti_obj(var);
extern int lock(var, uint64_t);
extern void unlock(var);
extern char* toString(var, ...);

View file

@ -1,30 +0,0 @@
#if !defined(_RTTI_UTILS_H_)
#define _RTTI_UTILS_H_ 1
#define RTTI_GET_METHOD(result, obj, intf, method) \
do { \
typeinfo_t* type_ = NULL; \
meta_obj_t* obj_ = NULL; \
\
(result) = NULL; \
\
if ((obj) == NULL) { \
break; \
} \
\
obj_ = DATA_TO_OBJ(obj); \
\
type_ = obj_->type; \
if (type_ == NULL) { \
break; \
} \
\
if (type_->interfaces.intf == NULL) { \
break; \
} \
\
(result) = type_->interfaces.intf->method; \
} while (0)
#endif