From 5a65a7258f2bbd92901531ccafcccb48a5f66f52 Mon Sep 17 00:00:00 2001 From: skandhas Date: Thu, 20 Dec 2012 21:29:35 +0800 Subject: add mrb_mod_cv_get --- src/variable.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src') diff --git a/src/variable.c b/src/variable.c index 992663408..b4e262f8d 100644 --- a/src/variable.c +++ b/src/variable.c @@ -673,6 +673,21 @@ mrb_mod_class_variables(mrb_state *mrb, mrb_value mod) return ary; } +mrb_value +mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym) +{ + while (c) { + if (c->iv) { + iv_tbl *t = c->iv; + mrb_value v; + + if (iv_get(mrb, t, sym, &v)) + return v; + } + c = c->super; + } + return mrb_nil_value(); +} mrb_value mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) -- cgit v1.2.3 From a9f1c4593c83194a5a53f856d3b26fc7376b44de Mon Sep 17 00:00:00 2001 From: skandhas Date: Thu, 20 Dec 2012 21:33:30 +0800 Subject: add mrb_cv_get --- include/mruby/variable.h | 1 + src/variable.c | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'src') diff --git a/include/mruby/variable.h b/include/mruby/variable.h index d33a20d5e..8754e8a90 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -56,6 +56,7 @@ mrb_value mrb_obj_iv_inspect(mrb_state*, struct RObject*); mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer); mrb_value mrb_mod_class_variables(mrb_state*, mrb_value); mrb_value mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym); +mrb_value mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym); /* GC functions */ void mrb_gc_mark_gv(mrb_state*); diff --git a/src/variable.c b/src/variable.c index b4e262f8d..816b703bf 100644 --- a/src/variable.c +++ b/src/variable.c @@ -689,6 +689,12 @@ mrb_mod_cv_get(mrb_state *mrb, struct RClass * c, mrb_sym sym) return mrb_nil_value(); } +mrb_value +mrb_cv_get(mrb_state *mrb, mrb_value mod, mrb_sym sym) +{ + return mrb_mod_cv_get(mrb, mrb_class_ptr(mod), sym); +} + mrb_value mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) { -- cgit v1.2.3 From f341957fe57f9ee1f492bf89cf95685eac9ef1f2 Mon Sep 17 00:00:00 2001 From: skandhas Date: Thu, 20 Dec 2012 22:13:08 +0800 Subject: mrb_mod_cvar_get --- src/class.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'src') diff --git a/src/class.c b/src/class.c index 339920b6e..d46b63f2b 100644 --- a/src/class.c +++ b/src/class.c @@ -1444,6 +1444,33 @@ mrb_sym_value(mrb_state *mrb, mrb_value val) return mrb_symbol(val); } +/* 15.2.2.4.17 */ +/* + * call-seq: + * mod.class_variable_get(symbol) -> obj + * + * Returns the value of the given class variable (or throws a + * NameError exception). The @@ part of the + * variable name should be included for regular class variables + * + * class Fred + * @@foo = 99 + * end + * Fred.class_variable_get(:@@foo) #=> 99 + */ + +static mrb_value +mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) +{ + mrb_value sym; + mrb_sym id; + mrb_get_args(mrb, "o", &sym); + + id = mrb_sym_value(mrb,sym); + check_cvar_name(mrb, id); + return mrb_cv_get(mrb, mod, id); +} + static void check_const_name(mrb_state *mrb, mrb_sym id) { @@ -1545,6 +1572,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, ARGS_NONE()); /* 15.2.3.3.4 */ mrb_define_method(mrb, cls, "new", mrb_instance_new, ARGS_ANY()); /* 15.2.3.3.3 */ mrb_define_method(mrb, cls, "inherited", mrb_bob_init, ARGS_REQ(1)); + mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, ARGS_REQ(1)); /* 15.2.2.4.17 */ mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, ARGS_REQ(1)); /* 15.2.2.4.25 */ mrb_define_method(mrb, mod, "extended", mrb_bob_init, ARGS_REQ(1)); /* 15.2.2.4.26 */ mrb_define_method(mrb, mod, "include", mrb_mod_include, ARGS_ANY()); /* 15.2.2.4.27 */ -- cgit v1.2.3 From 2ca47bba8f509337f3b3fb22ad6c8bac46e542ac Mon Sep 17 00:00:00 2001 From: skandhas Date: Thu, 20 Dec 2012 22:17:36 +0800 Subject: add check_cv_name --- src/class.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/class.c b/src/class.c index d46b63f2b..19a697bc8 100644 --- a/src/class.c +++ b/src/class.c @@ -1444,6 +1444,18 @@ mrb_sym_value(mrb_state *mrb, mrb_value val) return mrb_symbol(val); } +static void +check_cv_name(mrb_state *mrb, mrb_sym id) +{ + const char *s; + int len; + + s = mrb_sym2name_len(mrb, id, &len); + if (len < 3 || !(s[0] == '@' && s[1] == '@')) { + mrb_name_error(mrb, id, "`%s' is not allowed as a class variable name", s); + } +} + /* 15.2.2.4.17 */ /* * call-seq: @@ -1467,7 +1479,7 @@ mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) mrb_get_args(mrb, "o", &sym); id = mrb_sym_value(mrb,sym); - check_cvar_name(mrb, id); + check_cv_name(mrb, id); return mrb_cv_get(mrb, mod, id); } -- cgit v1.2.3 From e6a47323b8d67fdf85f095c30b2d66a00d2d2ca5 Mon Sep 17 00:00:00 2001 From: skandhas Date: Thu, 20 Dec 2012 22:29:26 +0800 Subject: refactor mrb_vm_cv_get --- src/variable.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/variable.c b/src/variable.c index 816b703bf..147373bd4 100644 --- a/src/variable.c +++ b/src/variable.c @@ -701,17 +701,8 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) struct RClass *c = mrb->ci->proc->target_class; if (!c) c = mrb->ci->target_class; - while (c) { - if (c->iv) { - iv_tbl *t = c->iv; - mrb_value v; - - if (iv_get(mrb, t, sym, &v)) - return v; - } - c = c->super; - } - return mrb_nil_value(); + + return mrb_mod_cv_get(mrb, c, sym); } void -- cgit v1.2.3