summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--class.c4
-rw-r--r--internal/class.h11
2 files changed, 11 insertions, 4 deletions
diff --git a/class.c b/class.c
index 4ca8c77dee..6d81654142 100644
--- a/class.c
+++ b/class.c
@@ -827,7 +827,9 @@ rb_class_update_superclasses(VALUE klass)
superclasses = class_superclasses_including_self(super);
RCLASS_WRITE_SUPERCLASSES(super, super_depth, superclasses, true, true);
}
- RCLASS_WRITE_SUPERCLASSES(klass, super_depth + 1, superclasses, false, false);
+
+ size_t depth = super_depth == RCLASS_MAX_SUPERCLASS_DEPTH ? super_depth : super_depth + 1;
+ RCLASS_WRITE_SUPERCLASSES(klass, depth, superclasses, false, false);
}
void
diff --git a/internal/class.h b/internal/class.h
index 25b02ca3e0..e83dd31bea 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -85,7 +85,6 @@ struct rb_classext_struct {
struct rb_id_table *callable_m_tbl;
struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
struct rb_id_table *cvc_tbl;
- size_t superclass_depth;
VALUE *superclasses;
/**
* The head of subclasses is a blank (w/o klass) entry to be referred from anchor (and be never deleted).
@@ -121,6 +120,7 @@ struct rb_classext_struct {
} iclass;
} as;
attr_index_t max_iv_count;
+ uint16_t superclass_depth;
unsigned char variation_count;
bool permanent_classpath : 1;
bool cloned : 1;
@@ -145,14 +145,17 @@ struct RClass {
};
// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
-// TODO: restore this assertion after removing several fields from rb_classext_t
-// STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
+// On 32bit platforms there is no variable width allocation so it doesn't matter.
+// TODO: restore this assertion after shrinking rb_classext_t
+// STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE || SIZEOF_VALUE < SIZEOF_LONG_LONG);
struct RClass_and_rb_classext_t {
struct RClass rclass;
rb_classext_t classext;
};
+static const uint16_t RCLASS_MAX_SUPERCLASS_DEPTH = ((uint16_t)-1);
+
static inline bool RCLASS_SINGLETON_P(VALUE klass);
static inline bool RCLASS_PRIME_CLASSEXT_READABLE_P(VALUE obj);
@@ -712,6 +715,8 @@ RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
static inline void
RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self)
{
+ RUBY_ASSERT(depth <= RCLASS_MAX_SUPERCLASS_DEPTH);
+
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
RCLASSEXT_SUPERCLASS_DEPTH(ext) = depth;
RCLASSEXT_SUPERCLASSES(ext) = superclasses;