summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-08-02 01:53:01 +0900
committerYukihiro Matsumoto <[email protected]>2012-08-02 01:53:01 +0900
commitb00529e672a6b64ec41b36c25395d66364f8cc20 (patch)
tree187dd3065ad51c24d402aea5f2ce5f8c8196a2f8
parent9ccf9767e1661739bb046cc8956a4437e2e75b55 (diff)
downloadmruby-b00529e672a6b64ec41b36c25395d66364f8cc20.tar.gz
mruby-b00529e672a6b64ec41b36c25395d66364f8cc20.zip
reduce invoking const_missing
-rw-r--r--src/variable.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/src/variable.c b/src/variable.c
index a62e7e126..0b4288734 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -309,7 +309,8 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
struct RClass *c = base;
khash_t(iv) *h;
khiter_t k;
- mrb_sym cm = mrb_intern(mrb, "const_missing");
+ int retry = 0;
+ mrb_sym cm;
L_RETRY:
while (c) {
@@ -319,18 +320,23 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
if (k != kh_end(h)) {
return kh_value(h, k);
}
- if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
- mrb_value name = mrb_symbol_value(sym);
- return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name);
- }
}
c = c->super;
}
-
- if (base->tt == MRB_TT_MODULE) {
- c = base = mrb->object_class;
+ if (!retry && base->tt == MRB_TT_MODULE) {
+ c = mrb->object_class;
+ retry = 1;
goto L_RETRY;
}
+ c = base;
+ cm = mrb_intern(mrb, "const_missing");
+ while (c) {
+ if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
+ mrb_value name = mrb_symbol_value(sym);
+ return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name);
+ }
+ c = c->super;
+ }
mrb_raise(mrb, E_NAME_ERROR, "uninitialized constant %s",
mrb_sym2name(mrb, sym));
/* not reached */