diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-02-27 04:23:57 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2014-02-27 04:23:57 +0900 |
| commit | 0c1c4416e7c96cf589dbeee2103fa9432dc17473 (patch) | |
| tree | cc026cb2987701ae417cc21a594f68c118a42215 /src/class.c | |
| parent | d264e1addd97f67b9ac647a0be27fbc099ba0579 (diff) | |
| download | mruby-0c1c4416e7c96cf589dbeee2103fa9432dc17473.tar.gz mruby-0c1c4416e7c96cf589dbeee2103fa9432dc17473.zip | |
avoid recursion when method_missing happened in inspect; fix #1746
Diffstat (limited to 'src/class.c')
| -rw-r--r-- | src/class.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/src/class.c b/src/class.c index ebe2bdb4a..be38fd55c 100644 --- a/src/class.c +++ b/src/class.c @@ -1189,22 +1189,28 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod) mrb_sym name; mrb_value *a; int alen; - mrb_value inspect; + mrb_sym inspect; + mrb_value repr; mrb_get_args(mrb, "n*", &name, &a, &alen); - if (mrb_respond_to(mrb,mod,mrb_intern_lit(mrb, "inspect"))){ - inspect = mrb_funcall(mrb, mod, "inspect", 0); - if (RSTRING_LEN(inspect) > 64) { - inspect = mrb_any_to_s(mrb, mod); + inspect = mrb_intern_lit(mrb, "inspect"); + if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { + /* method missing in inspect; avoid recursion */ + repr = mrb_any_to_s(mrb, mod); + } + else if (mrb_respond_to(mrb, mod, inspect)) { + repr = mrb_funcall_argv(mrb, mod, inspect, 0, 0); + if (RSTRING_LEN(repr) > 64) { + repr = mrb_any_to_s(mrb, mod); } } else { - inspect = mrb_any_to_s(mrb, mod); + repr = mrb_any_to_s(mrb, mod); } mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S", - mrb_sym2str(mrb, name), inspect); + mrb_sym2str(mrb, name), repr); /* not reached */ return mrb_nil_value(); } |
