From: Nobuyoshi Nakada Date: 2008-10-10T18:23:30+09:00 Subject: [ruby-dev:36703] Re: Segmentation fault in eval なかだです。 At Fri, 10 Oct 2008 06:59:39 +0900, Kazuhiro NISHIYAMA wrote in [ruby-dev:36698]: > http://d.hatena.ne.jp/mamamoto/20081007/1223349255 > のスクリプトを元にいじっていたらs="n=$*"で落ちました。 $*=0; $* が最小ですね。 argf回りを整理したときに、rb_define_virtual_variable()と間違えて rb_define_hooked_variable()のsetterに0を渡すようにしたために、デ フォルトのsetterが使われてしまっているというミスでした。 しかし、見直してみるとrb_define_hooked_variable()でreadonly変数 を作る方法はないようです。readonly_setter()などを公開するのが簡 単なのですが、どうしたものでしょうか。 さらにいうと、markerを独自に指定する方法もありません。 Index: io.c =================================================================== --- io.c (revision 19741) +++ io.c (working copy) @@ -8445,9 +8445,9 @@ Init_IO(void) rb_define_hooked_variable("$.", &argf, argf_lineno_getter, argf_lineno_setter); - rb_define_hooked_variable("$FILENAME", &argf, argf_filename_getter, 0); + rb_define_hooked_variable("$FILENAME", &argf, argf_filename_getter, rb_gvar_readonly_setter); ARGF.filename = rb_str_new2("-"); rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set); - rb_define_hooked_variable("$*", &argf, argf_argv_getter, 0); + rb_define_hooked_variable("$*", &argf, argf_argv_getter, rb_gvar_readonly_setter); #if defined (_WIN32) || defined(__CYGWIN__) Index: variable.c =================================================================== --- variable.c (revision 19741) +++ variable.c (working copy) @@ -287,9 +287,9 @@ rb_obj_classname(VALUE obj) } -struct global_variable; +#define global_variable rb_global_variable -typedef VALUE gvar_getter_t(ID id, void *data, struct global_variable *gvar); -typedef void gvar_setter_t(VALUE val, ID id, void *data, struct global_variable *gvar); -typedef void gvar_marker_t(VALUE *var); +#define gvar_getter_t rb_gvar_getter_t +#define gvar_setter_t rb_gvar_setter_t +#define gvar_marker_t rb_gvar_marker_t struct trace_var { @@ -315,15 +315,17 @@ struct global_entry { }; -static VALUE undef_getter(ID id, void *data, struct global_variable *gvar); -static void undef_setter(VALUE val, ID id, void *data, struct global_variable *gvar); -static void undef_marker(VALUE *var); - -static VALUE val_getter(ID id, void *data, struct global_variable *gvar); -static void val_setter(VALUE val, ID id, void *data, struct global_variable *gvar); -static void val_marker(VALUE *var); - -static VALUE var_getter(ID id, void *data, struct global_variable *gvar); -static void var_setter(VALUE val, ID id, void *data, struct global_variable *gvar); -static void var_marker(VALUE *var); +#define undef_getter rb_gvar_undef_getter +#define undef_setter rb_gvar_undef_setter +#define undef_marker rb_gvar_undef_marker + +#define val_getter rb_gvar_val_getter +#define val_setter rb_gvar_val_setter +#define val_marker rb_gvar_val_marker + +#define var_getter rb_gvar_var_getter +#define var_setter rb_gvar_var_setter +#define var_marker rb_gvar_var_marker + +#define readonly_setter rb_gvar_readonly_setter struct global_entry* @@ -355,5 +357,5 @@ rb_global_entry(ID id) } -static VALUE +VALUE undef_getter(ID id, void *data, struct global_variable *var) { @@ -363,5 +365,5 @@ undef_getter(ID id, void *data, struct g } -static void +void undef_setter(VALUE val, ID id, void *data, struct global_variable *var) { @@ -373,10 +375,10 @@ undef_setter(VALUE val, ID id, void *dat } -static void +void undef_marker(VALUE *var) { } -static VALUE +VALUE val_getter(ID id, void *data, struct global_variable *var) { @@ -384,5 +386,5 @@ val_getter(ID id, void *data, struct glo } -static void +void val_setter(VALUE val, ID id, void *data, struct global_variable *var) { @@ -390,5 +392,5 @@ val_setter(VALUE val, ID id, void *data, } -static void +void val_marker(VALUE *var) { @@ -397,5 +399,5 @@ val_marker(VALUE *var) } -static VALUE +VALUE var_getter(ID id, void *data, struct global_variable *gvar) { @@ -405,5 +407,5 @@ var_getter(ID id, void *data, struct glo } -static void +void var_setter(VALUE val, ID id, void *data, struct global_variable *gvar) { @@ -411,5 +413,5 @@ var_setter(VALUE val, ID id, void *data, } -static void +void var_marker(VALUE *var) { @@ -417,5 +419,5 @@ var_marker(VALUE *var) } -static void +void readonly_setter(VALUE val, ID id, void *data, struct global_variable *gvar) { Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 19741) +++ include/ruby/ruby.h (working copy) @@ -847,4 +847,24 @@ void rb_include_module(VALUE,VALUE); void rb_extend_object(VALUE,VALUE); +struct rb_global_variable; + +typedef VALUE rb_gvar_getter_t(ID id, void *data, struct rb_global_variable *gvar); +typedef void rb_gvar_setter_t(VALUE val, ID id, void *data, struct rb_global_variable *gvar); +typedef void rb_gvar_marker_t(VALUE *var); + +VALUE rb_gvar_undef_getter(ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_undef_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_undef_marker(VALUE *var); + +VALUE rb_gvar_val_getter(ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_val_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_val_marker(VALUE *var); + +VALUE rb_gvar_var_getter(ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_var_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar); +void rb_gvar_var_marker(VALUE *var); + +void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar); + void rb_define_variable(const char*,VALUE*); void rb_define_virtual_variable(const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS)); -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦