From 90ba47ccfe67859e3f139199da33e89137a74a41 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 2 Sep 2014 16:41:38 +0900 Subject: implement attr_reader and attr_writer in C; use cfunc closure to speed-up --- mrblib/class.rb | 25 +------------ src/class.c | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 98 insertions(+), 34 deletions(-) diff --git a/mrblib/class.rb b/mrblib/class.rb index ebb44ca4c..39e0d5091 100644 --- a/mrblib/class.rb +++ b/mrblib/class.rb @@ -1,28 +1,5 @@ class Module - # 15.2.2.4.13 - def attr_reader(*names) - names.each do |name| - name = name.to_s - raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$') - - attr_name = '@'+name - define_method(name){self.instance_variable_get(attr_name)} - end - nil - end - # 15.2.2.4.14 - def attr_writer(*names) - names.each do |name| - name = name.to_s - raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$') - - attr_name = '@'+name - name = (name+"=").intern - define_method(name){|v|self.instance_variable_set(attr_name,v)} - end - nil - end - # 15.2.2.4.12 + # 15.2.2.4.12 def attr_accessor(*names) attr_reader(*names) attr_writer(*names) diff --git a/src/class.c b/src/class.c index 91ee711bc..b7da56514 100644 --- a/src/class.c +++ b/src/class.c @@ -393,6 +393,21 @@ to_hash(mrb_state *mrb, mrb_value val) return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); } +static mrb_sym +to_sym(mrb_state *mrb, mrb_value ss) +{ + if (mrb_type(ss) == MRB_TT_SYMBOL) { + return mrb_symbol(ss); + } + else if (mrb_string_p(ss)) { + return mrb_intern_str(mrb, to_str(mrb, ss)); + } + else { + mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); + } +} + /* retrieve arguments from mrb_state. @@ -635,16 +650,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value ss; ss = *sp++; - if (mrb_type(ss) == MRB_TT_SYMBOL) { - *symp = mrb_symbol(ss); - } - else if (mrb_string_p(ss)) { - *symp = mrb_intern_str(mrb, to_str(mrb, ss)); - } - else { - mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); - } + *symp = to_sym(mrb, ss); i++; } } @@ -1050,6 +1056,85 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) return m; } +static mrb_value +attr_reader(mrb_state *mrb, mrb_value obj) +{ + mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); + return mrb_iv_get(mrb, obj, to_sym(mrb, name)); +} + +static mrb_value +mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_value *argv; + mrb_int argc, i; + + mrb_get_args(mrb, "*", &argv, &argc); + for (i=0; i