Friday, July 4, 2008

Ruby 1.9 C API !! - Internal Structures


To access the internal structure of any Ruby object, 'ruby.h' defines the following macros:
#define RBASIC(obj) (R_CAST(RBasic)(obj))
#define ROBJECT(obj) (R_CAST(RObject)(obj))
#define RCLASS(obj) (R_CAST(RClass)(obj))
#define RMODULE(obj) RCLASS(obj)
#define RFLOAT(obj) (R_CAST(RFloat)(obj))
#define RSTRING(obj) (R_CAST(RString)(obj))
#define RREGEXP(obj) (R_CAST(RRegexp)(obj))
#define RARRAY(obj) (R_CAST(RArray)(obj))
#define RHASH(obj) (R_CAST(RHash)(obj))
#define RDATA(obj) (R_CAST(RData)(obj))
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
#define RFILE(obj) (R_CAST(RFile)(obj))
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))


The most important are:
struct RFloat {
struct RBasic basic;
double float_value;
};

struct RBignum {
struct RBasic basic;
union {
struct {
long len;
BDIGIT *digits;
} heap;
BDIGIT ary[RBIGNUM_EMBED_LEN_MAX];
} as;
};

struct RBasic basic;
union {
struct {
long len;
char *ptr;
union {
long capa;
VALUE shared;
} aux;
} heap;
char ary[RSTRING_EMBED_LEN_MAX];
} as;

To Access the value of a float number you will call:

RFLOAT(ruby_value)->double_value;


Fixnum's (Integers) are stored differently:

10 in Ruby => (10 >> 1) in C
10 in C => (10 << 1 | 1) in Ruby
-10 in Ruby => (10 >> 1) in C
-10 in C => (10 >> 1 | 1) in Ruby (0xffffffed)

Bignums are usually 8 bytes (long long).

No comments: