From 7815cbd7d0699ab0b9e50998882b7981acca8e07 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 22 Dec 2012 10:40:03 +0000 Subject: [PATCH] object.c: defer creating string * object.c (rb_mod_const_get): defer creating partinal name string until needed. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@38552 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- object.c | 69 +++++++++++++++++++++----------------------------------- 1 file changed, 26 insertions(+), 43 deletions(-) diff --git a/object.c b/object.c index b385135019..eb7df7eae3 100644 --- a/object.c +++ b/object.c @@ -1860,34 +1860,6 @@ rb_mod_attr_accessor(int argc, VALUE *argv, VALUE klass) return Qnil; } -static VALUE -rb_mod_single_const_get(VALUE mod, VALUE name, VALUE recur) -{ - ID id; - - id = rb_check_id(&name); - if (!id) { - if (!rb_is_const_name(name)) { - rb_name_error_str(name, "wrong constant name %s", RSTRING_PTR(name)); - } - else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) { - id = rb_to_id(name); - } - else if (mod && rb_class_real(mod) != rb_cObject) { - rb_name_error_str(name, "uninitialized constant %s::%s", - rb_class2name(mod), - RSTRING_PTR(name)); - } - else { - rb_name_error_str(name, "uninitialized constant %s", RSTRING_PTR(name)); - } - } - if (!rb_is_const_id(id)) { - rb_name_error(id, "wrong constant name %s", rb_id2name(id)); - } - return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id); -} - /* * call-seq: * mod.const_get(sym, inherit=true) -> obj @@ -1955,7 +1927,8 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod) pbeg = p = path; pend = path + RSTRING_LEN(name); - if (!*p) { + if (p >= pend || !*p) { + wrong_name: rb_raise(rb_eNameError, "wrong constant name %s", path); } @@ -1967,24 +1940,16 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod) while (p < pend) { VALUE part; + long len; while (p < pend && *p != ':') p++; - if (pbeg == p) { - rb_raise(rb_eNameError, "wrong constant name %s", path); - } + if (pbeg == p) goto wrong_name; + + id = rb_check_id_cstr(pbeg, len = p-pbeg, enc); - id = rb_check_id_cstr(pbeg, p-pbeg, enc); - if (id) { - part = ID2SYM(id); - } - else { - part = rb_str_subseq(name, pbeg-path, p-pbeg); - } if (p < pend && p[0] == ':') { - if (p + 2 >= pend || p[1] != ':') { - rb_raise(rb_eNameError, "wrong constant name %s", path); - } + if (p + 2 >= pend || p[1] != ':') goto wrong_name; p += 2; pbeg = p; } @@ -1993,7 +1958,25 @@ rb_mod_const_get(int argc, VALUE *argv, VALUE mod) rb_raise(rb_eTypeError, "%s does not refer to class/module", path); } - mod = rb_mod_single_const_get(mod, part, recur); + if (!id) { + if (!ISUPPER(*pbeg) || !rb_enc_symname2_p(pbeg, len, enc)) { + part = rb_str_subseq(name, pbeg-path, len); + rb_name_error_str(part, "wrong constant name %s", RSTRING_PTR(part)); + } + else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) { + id = rb_intern3(pbeg, len, enc); + } + else { + part = rb_str_subseq(name, pbeg-path, len); + rb_name_error_str(part, "uninitialized constant %.*s%s", + rb_long2int(pbeg-path), path, + RSTRING_PTR(part)); + } + } + if (!rb_is_const_id(id)) { + rb_name_error(id, "wrong constant name %s", rb_id2name(id)); + } + mod = RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id); } return mod;