Skip to content

Commit 2548c47

Browse files
committed
Add namespace debug methods and assertions
1 parent 52c6b32 commit 2548c47

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

internal/class.h

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,26 +336,31 @@ RCLASS_SET_NAMESPACE_CLASSEXT(VALUE obj, const rb_namespace_t *ns, rb_classext_t
336336
return first_set;
337337
}
338338

339+
#define VM_ASSERT_NAMESPACEABLE_TYPE(klass) \
340+
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS), "%s is not namespaceable type", rb_type_str(BUILTIN_TYPE(klass)))
341+
339342
static inline bool
340343
RCLASS_PRIME_CLASSEXT_READABLE_P(VALUE klass)
341344
{
342-
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
345+
VM_ASSERT(klass != 0, "klass should be a valid object");
346+
VM_ASSERT_NAMESPACEABLE_TYPE(klass);
343347
// if the lookup table exists, then it means the prime classext is NOT directly readable.
344348
return !FL_TEST_RAW(klass, RCLASS_NAMESPACEABLE) || RCLASS_CLASSEXT_TBL(klass) == NULL;
345349
}
346350

347351
static inline bool
348352
RCLASS_PRIME_CLASSEXT_WRITABLE_P(VALUE klass)
349353
{
350-
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
354+
VM_ASSERT(klass != 0, "klass should be a valid object");
355+
VM_ASSERT_NAMESPACEABLE_TYPE(klass);
351356
return FL_TEST(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
352357
}
353358

354359
static inline void
355360
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(VALUE klass, bool writable)
356361
{
357-
VM_ASSERT(RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS));
358-
362+
VM_ASSERT(klass != 0, "klass should be a valid object");
363+
VM_ASSERT_NAMESPACEABLE_TYPE(klass);
359364
if (writable) {
360365
FL_SET(klass, RCLASS_PRIME_CLASSEXT_WRITABLE);
361366
}
@@ -429,6 +434,7 @@ RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
429434
ext = rb_class_duplicate_classext(RCLASS_EXT_PRIME(obj), obj, ns);
430435
first_set = RCLASS_SET_NAMESPACE_CLASSEXT(obj, ns, ext);
431436
if (first_set) {
437+
// TODO: are there any case that a class/module become non-writable after its birthtime?
432438
RCLASS_SET_PRIME_CLASSEXT_WRITABLE(obj, false);
433439
}
434440
}

namespace.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -845,11 +845,15 @@ rb_namespace_s_main(VALUE recv)
845845
static const char *
846846
classname(VALUE klass)
847847
{
848-
VALUE p = RCLASS_CLASSPATH(klass);
848+
VALUE p;
849+
if (!klass) {
850+
return "Qfalse";
851+
}
852+
p = RCLASSEXT_CLASSPATH(RCLASS_EXT_PRIME(klass));
849853
if (RTEST(p))
850854
return RSTRING_PTR(p);
851855
if (RB_TYPE_P(klass, T_CLASS) || RB_TYPE_P(klass, T_MODULE) || RB_TYPE_P(klass, T_ICLASS))
852-
return RSTRING_PTR(rb_inspect(klass));
856+
return "AnyClassValue";
853857
return "NonClassValue";
854858
}
855859

@@ -973,6 +977,27 @@ rb_f_dump_classext(VALUE recv, VALUE klass)
973977
return res;
974978
}
975979

980+
static VALUE
981+
rb_namespace_root_p(VALUE namespace)
982+
{
983+
const rb_namespace_t *ns = (const rb_namespace_t *)rb_get_namespace_t(namespace);
984+
return RBOOL(NAMESPACE_ROOT_P(ns));
985+
}
986+
987+
static VALUE
988+
rb_namespace_main_p(VALUE namespace)
989+
{
990+
const rb_namespace_t *ns = (const rb_namespace_t *)rb_get_namespace_t(namespace);
991+
return RBOOL(NAMESPACE_MAIN_P(ns));
992+
}
993+
994+
static VALUE
995+
rb_namespace_user_p(VALUE namespace)
996+
{
997+
const rb_namespace_t *ns = (const rb_namespace_t *)rb_get_namespace_t(namespace);
998+
return RBOOL(NAMESPACE_USER_P(ns));
999+
}
1000+
9761001
#endif /* RUBY_DEBUG */
9771002

9781003
/*
@@ -1010,6 +1035,10 @@ Init_Namespace(void)
10101035
rb_define_singleton_method(rb_cNamespace, "root", rb_namespace_s_root, 0);
10111036
rb_define_singleton_method(rb_cNamespace, "main", rb_namespace_s_main, 0);
10121037
rb_define_global_function("dump_classext", rb_f_dump_classext, 1);
1038+
1039+
rb_define_method(rb_cNamespace, "root?", rb_namespace_root_p, 0);
1040+
rb_define_method(rb_cNamespace, "main?", rb_namespace_main_p, 0);
1041+
rb_define_method(rb_cNamespace, "user?", rb_namespace_user_p, 0);
10131042
#endif
10141043
}
10151044

0 commit comments

Comments
 (0)