なかだです。

At Sat, 10 Sep 2005 14:36:37 +0900,
H.Yamamoto wrote in [ruby-dev:27004]:
> これはしかたないとしても、
> 
>   2. 内部の挙動も知る必要がある
> 
> これは誤算でした。

案としては可変引数を使うというのも考えたんですが、これでも関数
ポインタのキャストは避けられないし。

  typedef VALUE rb_var_getter_func(ID id, VALUE *data, ...);

variable.c関係。


Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.828 diff -U2 -p -r1.828 eval.c --- eval.c 12 Sep 2005 16:21:50 -0000 1.828 +++ eval.c 13 Sep 2005 07:25:46 -0000 @@ -224,6 +224,6 @@ int ruby_safe_level = 0; */ -static VALUE safe_getter _((void)); -static void safe_setter _((VALUE val)); +static rb_var_getter_func safe_getter; +static rb_var_setter_func safe_setter; void @@ -7312,5 +7312,5 @@ errinfo_setter(VALUE val, ID id, VALUE * static VALUE -errat_getter(ID id) +errat_getter(ID id, VALUE *var) { return get_backtrace(ruby_errinfo); @@ -9818,5 +9818,5 @@ rb_set_safe_level(int level) static VALUE -safe_getter(void) +safe_getter(ID id, VALUE *p) { return INT2NUM(ruby_safe_level); @@ -9824,5 +9824,5 @@ safe_getter(void) static void -safe_setter(VALUE val) +safe_setter(VALUE val, ID id, VALUE *p) { int level = NUM2INT(val); Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.179 diff -U2 -p -r1.179 intern.h --- intern.h 12 Sep 2005 15:02:46 -0000 1.179 +++ intern.h 13 Sep 2005 07:21:26 -0000 @@ -514,5 +514,5 @@ VALUE rb_str_split _((VALUE, const char* void rb_str_associate _((VALUE, VALUE)); VALUE rb_str_associated _((VALUE)); -void rb_str_setter _((VALUE, ID, VALUE*)); +rb_var_setter_func rb_str_setter; VALUE rb_str_intern _((VALUE)); /* struct.c */ Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.380 diff -U2 -p -r1.380 io.c --- io.c 12 Sep 2005 15:23:54 -0000 1.380 +++ io.c 13 Sep 2005 07:29:18 -0000 @@ -5296,5 +5296,5 @@ argf_to_s(void) static VALUE -opt_i_get(void) +opt_i_get(ID id, VALUE *var) { if (!ruby_inplace_mode) return Qnil; @@ -5303,5 +5303,5 @@ opt_i_get(void) static void -opt_i_set(VALUE val) +opt_i_set(VALUE val, ID id, VALUE *var) { if (!RTEST(val)) { @@ -5316,4 +5316,16 @@ opt_i_set(VALUE val) } +static VALUE +lastline_get(ID id, VALUE *var) +{ + return rb_lastline_get(); +} + +static void +lastline_set(VALUE val, ID id, VALUE *var) +{ + rb_lastline_set(val); +} + /* * Class <code>IO</code> is the basis for all input and output in Ruby. @@ -5464,5 +5476,5 @@ Init_IO(void) rb_define_hooked_variable("$.", &lineno, 0, lineno_setter); - rb_define_virtual_variable("$_", rb_lastline_get, rb_lastline_set); + rb_define_virtual_variable("$_", lastline_get, lastline_set); rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1); Index: process.c =================================================================== RCS file: /cvs/ruby/src/ruby/process.c,v retrieving revision 1.137 diff -U2 -p -r1.137 process.c --- process.c 12 Sep 2005 10:44:20 -0000 1.137 +++ process.c 13 Sep 2005 07:29:47 -0000 @@ -129,5 +129,5 @@ static VALUE S_Tms; static VALUE -get_pid(void) +get_pid(ID id, VALUE *var) { rb_secure(2); Index: re.c =================================================================== RCS file: /cvs/ruby/src/ruby/re.c,v retrieving revision 1.142 diff -U2 -p -r1.142 re.c --- re.c 12 Sep 2005 10:44:20 -0000 1.142 +++ re.c 13 Sep 2005 07:35:41 -0000 @@ -1060,5 +1060,5 @@ rb_reg_match_last(VALUE match) static VALUE -last_match_getter(void) +last_match_getter(ID id, VALUE *var) { return rb_reg_last_match(rb_backref_get()); @@ -1066,5 +1066,5 @@ last_match_getter(void) static VALUE -prematch_getter(void) +prematch_getter(ID id, VALUE *var) { return rb_reg_match_pre(rb_backref_get()); @@ -1072,5 +1072,5 @@ prematch_getter(void) static VALUE -postmatch_getter(void) +postmatch_getter(ID id, VALUE *var) { return rb_reg_match_post(rb_backref_get()); @@ -1078,5 +1078,5 @@ postmatch_getter(void) static VALUE -last_paren_match_getter(void) +last_paren_match_getter(ID id, VALUE *var) { return rb_reg_match_last(rb_backref_get()); @@ -2078,5 +2078,5 @@ rb_get_kcode(void) static VALUE -kcode_getter(void) +kcode_getter(ID id, VALUE *var) { return rb_str_new2(rb_get_kcode()); @@ -2117,5 +2117,5 @@ rb_set_kcode(const char *code) static void -kcode_setter(VALUE val) +kcode_setter(VALUE val, ID id, VALUE *var) { may_need_recompile = 1; @@ -2124,5 +2124,5 @@ kcode_setter(VALUE val) static VALUE -ignorecase_getter(void) +ignorecase_getter(ID id, VALUE *var) { return ruby_ignorecase?Qtrue:Qfalse; @@ -2130,5 +2130,5 @@ ignorecase_getter(void) static void -ignorecase_setter(VALUE val, ID id) +ignorecase_setter(VALUE val, ID id, VALUE *var) { rb_warn("modifying %s is deprecated", rb_id2name(id)); @@ -2138,5 +2138,5 @@ ignorecase_setter(VALUE val, ID id) static VALUE -match_getter(void) +match_get(void) { VALUE match = rb_backref_get(); @@ -2147,6 +2147,12 @@ match_getter(void) } +static VALUE +match_getter(ID id, VALUE *var) +{ + return match_get(); +} + static void -match_setter(VALUE val) +match_setter(VALUE val, ID id, VALUE *var) { if (!NIL_P(val)) { @@ -2181,5 +2187,5 @@ rb_reg_s_last_match(int argc, VALUE *arg return rb_reg_nth_match(NUM2INT(nth), rb_backref_get()); } - return match_getter(); + return match_get(); } Index: ruby.c =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.c,v retrieving revision 1.107 diff -U2 -p -r1.107 ruby.c --- ruby.c 12 Sep 2005 11:03:24 -0000 1.107 +++ ruby.c 13 Sep 2005 07:34:17 -0000 @@ -1022,5 +1022,5 @@ set_arg0space() static void -set_arg0(VALUE val, ID id) +set_arg0(VALUE val, ID id, VALUE *var) { char *s; @@ -1140,5 +1140,5 @@ verbose_setter(VALUE val, ID id, VALUE * static VALUE -opt_W_getter(VALUE val, ID id) +opt_W_getter(ID id, VALUE *var) { if (ruby_verbose == Qnil) return INT2FIX(0); Index: ruby.h =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.h,v retrieving revision 1.118 diff -U2 -p -r1.118 ruby.h --- ruby.h 27 Jul 2005 07:27:17 -0000 1.118 +++ ruby.h 13 Sep 2005 07:23:44 -0000 @@ -493,7 +493,9 @@ void rb_include_module _((VALUE,VALUE)); void rb_extend_object _((VALUE,VALUE)); +typedef VALUE rb_var_getter_func _((ID,VALUE*)); +typedef void rb_var_setter_func _((VALUE,ID,VALUE*)); void rb_define_variable _((const char*,VALUE*)); -void rb_define_virtual_variable _((const char*,VALUE(*)(ANYARGS),void(*)(ANYARGS))); -void rb_define_hooked_variable _((const char*,VALUE*,VALUE(*)(ANYARGS),void(*)(ANYARGS))); +void rb_define_virtual_variable _((const char*,rb_var_getter_func*,rb_var_setter_func*)); +void rb_define_hooked_variable _((const char*,VALUE*,rb_var_getter_func*,rb_var_setter_func*)); void rb_define_readonly_variable _((const char*,VALUE*)); void rb_define_const _((VALUE,const char*,VALUE)); Index: variable.c =================================================================== RCS file: /cvs/ruby/src/ruby/variable.c,v retrieving revision 1.126 diff -U2 -p -r1.126 variable.c --- variable.c 12 Sep 2005 10:44:21 -0000 1.126 +++ variable.c 13 Sep 2005 08:47:24 -0000 @@ -285,15 +285,20 @@ rb_obj_classname(VALUE obj) struct trace_var { int removed; - void (*func)(); + void (*func)(VALUE, VALUE); VALUE data; struct trace_var *next; }; +struct global_variable; + +typedef VALUE real_getter(ID id, VALUE *data, struct global_variable *var); +typedef void real_setter(VALUE val, ID id, VALUE *data, struct global_variable *var); + struct global_variable { int counter; void *data; - VALUE (*getter)(); - void (*setter)(); - void (*marker)(); + real_getter *getter; + real_setter *setter; + RUBY_DATA_FUNC marker; int block_trace; struct trace_var *trace; @@ -305,15 +310,15 @@ struct global_entry { }; -static VALUE undef_getter(ID id); -static void undef_setter(VALUE val, ID id, void *data, struct global_variable *var); -static void undef_marker(void); - -static VALUE val_getter(ID id, VALUE val); -static void val_setter(VALUE val, ID id, void *data, struct global_variable *var); -static void val_marker(VALUE data); +static real_getter undef_getter; +static real_setter undef_setter; +static void undef_marker(void *p); + +static real_getter val_getter; +static real_setter val_setter; +static void val_marker(void *data); static VALUE var_getter(ID id, VALUE *var); static void var_setter(VALUE val, ID id, VALUE *var); -static void var_marker(VALUE *var); +static void var_marker(void *var); struct global_entry* @@ -342,5 +347,5 @@ rb_global_entry(ID id) static VALUE -undef_getter(ID id) +undef_getter(ID id, VALUE *val, struct global_variable *var) { rb_warning("global variable `%s' not initialized", rb_id2name(id)); @@ -350,5 +355,5 @@ undef_getter(ID id) static void -undef_setter(VALUE val, ID id, void *data, struct global_variable *var) +undef_setter(VALUE val, ID id, VALUE *data, struct global_variable *var) { var->getter = val_getter; @@ -360,16 +365,16 @@ undef_setter(VALUE val, ID id, void *dat static void -undef_marker(void) +undef_marker(void *p) { } static VALUE -val_getter(ID id, VALUE val) +val_getter(ID id, VALUE *val, struct global_variable *var) { - return val; + return (VALUE)val; } static void -val_setter(VALUE val, ID id, void *data, struct global_variable *var) +val_setter(VALUE val, ID id, VALUE *data, struct global_variable *var) { var->data = (void*)val; @@ -377,7 +382,7 @@ val_setter(VALUE val, ID id, void *data, static void -val_marker(VALUE data) +val_marker(void *data) { - if (data) rb_gc_mark_maybe(data); + if (data) rb_gc_mark_maybe((VALUE)data); } @@ -396,11 +401,11 @@ var_setter(VALUE val, ID id, VALUE *var) static void -var_marker(VALUE *var) +var_marker(void *var) { - if (var) rb_gc_mark_maybe(*var); + if (var) rb_gc_mark_maybe(*(VALUE *)var); } static void -readonly_setter(VALUE val, ID id, void *var) +readonly_setter(VALUE val, ID id, VALUE *var) { rb_name_error(id, "%s is a read-only variable", rb_id2name(id)); @@ -444,9 +449,5 @@ global_id(const char *name) void -rb_define_hooked_variable( - const char *name, - VALUE *var, - VALUE (*getter) (/* ??? */), - void (*setter) (/* ??? */)) +rb_define_hooked_variable(const char *name, VALUE *var, rb_var_getter_func *getter, rb_var_setter_func *setter) { struct global_variable *gvar; @@ -455,6 +456,6 @@ rb_define_hooked_variable( gvar = rb_global_entry(id)->var; gvar->data = (void*)var; - gvar->getter = getter?getter:var_getter; - gvar->setter = setter?setter:var_setter; + gvar->getter = (real_getter *)(getter?getter:var_getter); + gvar->setter = (real_setter *)(setter?setter:var_setter); gvar->marker = var_marker; } @@ -473,10 +474,7 @@ rb_define_readonly_variable(const char * void -rb_define_virtual_variable( - const char *name, - VALUE (*getter) (/* ??? */), - void (*setter) (/* ??? */)) +rb_define_virtual_variable(const char *name, rb_var_getter_func *getter, rb_var_setter_func *setter) { - if (!getter) getter = val_getter; + if (!getter) getter = (rb_var_getter_func *)val_getter; if (!setter) setter = readonly_setter; rb_define_hooked_variable(name, 0, getter, setter);
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦