mruby / mruby

Lightweight Ruby

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

mrb_obj_ptr and RHash - is RHash RObject?

dmajkic opened this issue · comments

In object.h:

struct RObject {
  MRB_OBJECT_HEADER;
  struct iv_tbl *iv;
};
#define mrb_obj_ptr(v)   ((struct RObject*)(mrb_ptr(v)))

in hash.h (when MRB_64BIT defined)

/* offset of `iv` must be 3 words */
struct RHash {
  MRB_OBJECT_HEADER;
  uint32_t size;
  struct iv_tbl *iv;
  uint32_t ea_capa;
  uint32_t ea_n_used;
  union {
    struct hash_entry *ea;
    struct hash_table *ht;
  } hsh;
};

Since RHash has an extra size before *iv, when MRB_64BIT defined, does that mean that RHash cannot be used in MRB_API where RObject pointer is required?

Is there some compiler packing in place that I am missing?

The struct RHash can be cast to struct RObject.

The size field appears to be floating, but it is stored immediately after the MRB_OBJECT_HEADER which is 20 bytes.

See also the definition of MRB_OBJECT_HEADER:

#define MRB_OBJECT_HEADER \
struct RClass *c; \
struct RBasic *gcnext; \
enum mrb_vtype tt:8; \
uint32_t color:3; \
uint32_t flags:21

This is tricky. As @dearblue stated, the size member fit in an alignment gap between MRB_OBJECT_HEADER and iv on 64bit platforms.

@dearblue thank you.

On 32bit: 32bit (*c) + 32bit (*gcnext) + 32bit (8 tt + 3 color + 21 flags) -> 3 x 32bit
On 64bit: 64bit (*c) + 64bit (*gcnext) + 32bit (8 tt + 3 color + 21 flags), and RHash size will fill 32bits -> 3 x 64bits