Skip to content

Commit e320547

Browse files
committed
Remove assertion on field in class_duplicate_iclass_classext
`ext` is newly allocated so it shouldn't need an assertion. The class ext (which is always from the module) that we're passing to `class_duplicate_iclass_classext` could legitimately have instance variables on it. We just want to avoid copying them. The assertion was making this crash: ``` $ RUBY_NAMESPACE=1 ./miniruby -e1 ```
1 parent 9583b7a commit e320547

1 file changed

Lines changed: 8 additions & 3 deletions

File tree

class.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ duplicate_classext_subclasses(rb_classext_t *orig, rb_classext_t *copy)
256256
static void
257257
class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_namespace_t *ns)
258258
{
259+
RUBY_ASSERT(RB_TYPE_P(iclass, T_ICLASS));
260+
259261
rb_classext_t *src = RCLASS_EXT_PRIME(iclass);
260262
rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(iclass, ns);
261263
int first_set = 0;
@@ -282,8 +284,6 @@ class_duplicate_iclass_classext(VALUE iclass, rb_classext_t *mod_ext, const rb_n
282284
RCLASSEXT_CONST_TBL(ext) = RCLASSEXT_CONST_TBL(mod_ext);
283285
RCLASSEXT_CVC_TBL(ext) = RCLASSEXT_CVC_TBL(mod_ext);
284286

285-
RUBY_ASSERT(!RCLASSEXT_FIELDS(mod_ext));
286-
287287
// Those are cache and should be recreated when methods are called
288288
// RCLASSEXT_CALLABLE_M_TBL(ext) = NULL;
289289
// RCLASSEXT_CC_TBL(ext) = NULL;
@@ -319,11 +319,14 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace
319319

320320
// TODO: consider shapes for performance
321321
if (RCLASSEXT_FIELDS(orig)) {
322+
RUBY_ASSERT(!RB_TYPE_P(klass, T_ICLASS));
322323
RCLASSEXT_FIELDS(ext) = (VALUE *)st_copy((st_table *)RCLASSEXT_FIELDS(orig));
323324
rb_autoload_copy_table_for_namespace((st_table *)RCLASSEXT_FIELDS(ext), ns);
324325
}
325326
else {
326-
RCLASSEXT_FIELDS(ext) = (VALUE *)st_init_numtable();
327+
if (!RB_TYPE_P(klass, T_ICLASS)) {
328+
RCLASSEXT_FIELDS(ext) = (VALUE *)st_init_numtable();
329+
}
327330
}
328331

329332
if (RCLASSEXT_SHARED_CONST_TBL(orig)) {
@@ -380,6 +383,8 @@ rb_class_duplicate_classext(rb_classext_t *orig, VALUE klass, const rb_namespace
380383
if (subclass_entry->klass && RB_TYPE_P(subclass_entry->klass, T_ICLASS)) {
381384
iclass = subclass_entry->klass;
382385
if (RBASIC_CLASS(iclass) == klass) {
386+
// Is the subclass an ICLASS including this module into another class
387+
// If so we need to re-associate it under our namespace with the new ext
383388
class_duplicate_iclass_classext(iclass, ext, ns);
384389
}
385390
}

0 commit comments

Comments
 (0)