From: SASADA Koichi Date: 2009-06-15T12:07:20+09:00 Subject: [ruby-dev:38620] [Feature: trunk] RTypedData  ささだです.  現在,RData に格納された情報は,その元になった型情報がなくなってしまい ますが,型情報を陽に持たせた RTypedData を新設するのはどうでしょうか.型 には,従来どおり mark, free 関数が紐づけられており,さらに名前とサイズを 返す関数も付けてみました. # サイズを返す関数を付けるのが動機なんですが.  どうでしょうか.ちょっと大きな変更で,例えばこれに対応したソースは 1.9.1 ではコンパイルできないプログラムになっちゃいますけど. # 1.9.1 用のプログラムはコンパイルできる.  使う側は,alloc 時にちょっとインターフェースが変わるだけです.  とりあえず,ruby.h だけ,こんな感じということで. Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (リビジョン 23689) +++ include/ruby/ruby.h (作業コピー) @@ -347,6 +347,7 @@ enum ruby_value_type { RUBY_T_SYMBOL = 0x14, RUBY_T_FIXNUM = 0x15, + RUBY_T_TYPEDDATA = 0x1a, RUBY_T_UNDEF = 0x1b, RUBY_T_NODE = 0x1c, RUBY_T_ICLASS = 0x1d, @@ -373,6 +374,7 @@ enum ruby_value_type { #define T_TRUE RUBY_T_TRUE #define T_FALSE RUBY_T_FALSE #define T_DATA RUBY_T_DATA +#define T_TYPEDDATA RUBY_T_TYPEDDATA #define T_MATCH RUBY_T_MATCH #define T_SYMBOL RUBY_T_SYMBOL #define T_RATIONAL RUBY_T_RATIONAL @@ -735,7 +737,25 @@ struct RData { void *data; }; +typedef struct rb_data_type_struct { + const char *name; + void (*dmark)(void*); + void (*dfree)(void*); + size_t (*dsize)(void *); + void *ary[4]; /* for extension */ +} rb_data_type_t; + +struct RTypedData { + struct RBasic basic; + rb_data_type_t *type; + VALUE dummy; + void *data; +}; + #define DATA_PTR(dta) (RDATA(dta)->data) +#define RTYPEDDATA_TYPE(v) (RTYPEDDATA(v)->type) +#define RTYPEDDATA_DATA(v) (RTYPEDDATA(v)->data) /* #define RUBY_DATA_FUNC(func) ((void (*)(void*))func) @@ -743,6 +763,7 @@ struct RData { typedef void (*RUBY_DATA_FUNC)(void*); VALUE rb_data_object_alloc(VALUE,void*,RUBY_DATA_FUNC,RUBY_DATA_FUNC); +VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, rb_data_type_t *); #define Data_Wrap_Struct(klass,mark,free,sval)\ rb_data_object_alloc(klass,sval,(RUBY_DATA_FUNC)mark,(RUBY_DATA_FUNC)free) @@ -753,6 +774,15 @@ VALUE rb_data_object_alloc(VALUE,void*,R Data_Wrap_Struct(klass,mark,free,sval)\ ) +#define Data_Wrap_TypedStruct(klass,data_type,sval)\ + rb_data_typed_object_alloc(klass,sval,data_type) + +#define Data_Make_TypedStruct(klass, type, data_type, sval) (\ + sval = ALLOC(type),\ + memset(sval, 0, sizeof(type)),\ + Data_Wrap_TypedStruct(klass,data_type,sval)\ +) + #define Data_Get_Struct(obj,type,sval) do {\ Check_Type(obj, T_DATA); \ sval = (type*)DATA_PTR(obj);\ @@ -826,6 +856,7 @@ struct RBignum { #define RARRAY(obj) (R_CAST(RArray)(obj)) #define RHASH(obj) (R_CAST(RHash)(obj)) #define RDATA(obj) (R_CAST(RData)(obj)) +#define RTYPEDDATA(obj) (R_CAST(RTypedData)(obj)) #define RSTRUCT(obj) (R_CAST(RStruct)(obj)) #define RBIGNUM(obj) (R_CAST(RBignum)(obj)) #define RFILE(obj) (R_CAST(RFile)(obj)) -- // SASADA Koichi at atdot dot net