1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

objspace_dump.c: special const

* ext/objspace/objspace_dump.c: support special constant objects.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52191 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2015-10-19 06:25:01 +00:00
parent 7594a99322
commit c92322b537
2 changed files with 68 additions and 18 deletions

View file

@ -51,8 +51,9 @@ dump_append(struct dump_config *dc, const char *format, ...)
static void
dump_append_string_value(struct dump_config *dc, VALUE obj)
{
int i;
char c, *value;
long i;
char c;
const char *value;
dump_append(dc, "\"");
for (i = 0, value = RSTRING_PTR(obj); i < RSTRING_LEN(obj); i++) {
@ -89,6 +90,14 @@ dump_append_string_value(struct dump_config *dc, VALUE obj)
dump_append(dc, "\"");
}
static void
dump_append_symbol_value(struct dump_config *dc, VALUE obj)
{
dump_append(dc, "{\"type\":\"SYMBOL\", \"value\":");
dump_append_string_value(dc, rb_sym2str(obj));
dump_append(dc, "}");
}
static inline const char *
obj_type(VALUE obj)
{
@ -125,6 +134,32 @@ obj_type(VALUE obj)
return "UNKNOWN";
}
static void
dump_append_special_const(struct dump_config *dc, VALUE value)
{
if (value == Qtrue) {
dump_append(dc, "true");
}
else if (value == Qfalse) {
dump_append(dc, "false");
}
else if (value == Qnil) {
dump_append(dc, "null");
}
else if (FIXNUM_P(value)) {
dump_append(dc, "%ld", FIX2LONG(value));
}
else if (FLONUM_P(value)) {
dump_append(dc, "%#g", RFLOAT_VALUE(value));
}
else if (SYMBOL_P(value)) {
dump_append_symbol_value(dc, value);
}
else {
dump_append(dc, "{}");
}
}
static void
reachable_object_i(VALUE ref, void *data)
{
@ -141,6 +176,19 @@ reachable_object_i(VALUE ref, void *data)
dc->cur_obj_references++;
}
static void
dump_append_string_content(struct dump_config *dc, VALUE obj)
{
dump_append(dc, ", \"bytesize\":%ld", RSTRING_LEN(obj));
if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj))
dump_append(dc, ", \"capacity\":%ld", rb_str_capacity(obj));
if (is_ascii_string(obj)) {
dump_append(dc, ", \"value\":");
dump_append_string_value(dc, obj);
}
}
static void
dump_object(VALUE obj, struct dump_config *dc)
{
@ -151,7 +199,7 @@ dump_object(VALUE obj, struct dump_config *dc)
size_t n, i;
if (SPECIAL_CONST_P(obj)) {
dump_append(dc, "{}");
dump_append_special_const(dc, obj);
return;
}
@ -174,6 +222,10 @@ dump_object(VALUE obj, struct dump_config *dc)
dump_append(dc, ", \"node_type\":\"%s\"", ruby_node_name(nd_type(obj)));
break;
case T_SYMBOL:
dump_append_string_content(dc, rb_sym2str(obj));
break;
case T_STRING:
if (STR_EMBED_P(obj))
dump_append(dc, ", \"embedded\":true");
@ -183,16 +235,8 @@ dump_object(VALUE obj, struct dump_config *dc)
dump_append(dc, ", \"fstring\":true");
if (STR_SHARED_P(obj))
dump_append(dc, ", \"shared\":true");
else {
dump_append(dc, ", \"bytesize\":%ld", RSTRING_LEN(obj));
if (!STR_EMBED_P(obj) && !STR_SHARED_P(obj) && (long)rb_str_capacity(obj) != RSTRING_LEN(obj))
dump_append(dc, ", \"capacity\":%ld", rb_str_capacity(obj));
if (is_ascii_string(obj)) {
dump_append(dc, ", \"value\":");
dump_append_string_value(dc, obj);
}
}
else
dump_append_string_content(dc, obj);
if (!ENCODING_IS_ASCII8BIT(obj))
dump_append(dc, ", \"encoding\":\"%s\"", rb_enc_name(rb_enc_from_index(ENCODING_GET(obj))));

View file

@ -255,11 +255,17 @@ class TestObjSpace < Test::Unit::TestCase
def test_dump_special_consts
# [ruby-core:69692] [Bug #11291]
assert_equal('{}', ObjectSpace.dump(nil))
assert_equal('{}', ObjectSpace.dump(true))
assert_equal('{}', ObjectSpace.dump(false))
assert_equal('{}', ObjectSpace.dump(0))
assert_equal('{}', ObjectSpace.dump(:foo))
assert_equal('null', ObjectSpace.dump(nil))
assert_equal('true', ObjectSpace.dump(true))
assert_equal('false', ObjectSpace.dump(false))
assert_equal('0', ObjectSpace.dump(0))
assert_equal('{"type":"SYMBOL", "value":"foo"}', ObjectSpace.dump(:foo))
end
def test_dump_dynamic_symbol
dump = ObjectSpace.dump(("foobar%x" % rand(0x10000)).to_sym)
assert_match /"type":"SYMBOL"/, dump
assert_match /"value":"foobar\h+"/, dump
end
def test_dump_all