@@ -302,6 +302,7 @@ struct rb_callcache {
302302#define VM_CALLCACHE_REFINEMENT IMEMO_FL_USER3
303303#define VM_CALLCACHE_UNMARKABLE IMEMO_FL_USER4
304304#define VM_CALLCACHE_ON_STACK IMEMO_FL_USER5
305+ #define VM_CALLCACHE_INVALID_SUPER IMEMO_FL_USER6
305306
306307enum vm_cc_type {
307308 cc_type_normal , // chained from ccs
@@ -344,8 +345,6 @@ vm_cc_new(VALUE klass,
344345 * ((struct rb_callable_method_entry_struct * * )& cc -> cme_ ) = (struct rb_callable_method_entry_struct * )cme ;
345346 * ((vm_call_handler * )& cc -> call_ ) = call ;
346347
347- VM_ASSERT (RB_TYPE_P (klass , T_CLASS ) || RB_TYPE_P (klass , T_ICLASS ));
348-
349348 switch (type ) {
350349 case cc_type_normal :
351350 break ;
@@ -358,8 +357,13 @@ vm_cc_new(VALUE klass,
358357 break ;
359358 }
360359
361- if (cme -> def -> type == VM_METHOD_TYPE_ATTRSET || cme -> def -> type == VM_METHOD_TYPE_IVAR ) {
362- vm_cc_attr_index_initialize (cc , INVALID_SHAPE_ID );
360+ if (cme ) {
361+ if (cme -> def -> type == VM_METHOD_TYPE_ATTRSET || cme -> def -> type == VM_METHOD_TYPE_IVAR ) {
362+ vm_cc_attr_index_initialize (cc , INVALID_SHAPE_ID );
363+ }
364+ }
365+ else {
366+ * (VALUE * )& cc -> flags |= VM_CALLCACHE_INVALID_SUPER ;
363367 }
364368
365369 RB_DEBUG_COUNTER_INC (cc_new );
@@ -405,6 +409,14 @@ vm_cc_markable(const struct rb_callcache *cc)
405409 return FL_TEST_RAW ((VALUE )cc , VM_CALLCACHE_UNMARKABLE ) == 0 ;
406410}
407411
412+ static inline bool
413+ vm_cc_invalid_super (const struct rb_callcache * cc )
414+ {
415+ VM_ASSERT (IMEMO_TYPE_P (cc , imemo_callcache ));
416+ // Set when calling super and there is no superclass.
417+ return FL_TEST_RAW ((VALUE )cc , VM_CALLCACHE_INVALID_SUPER );
418+ }
419+
408420static inline bool
409421vm_cc_valid (const struct rb_callcache * cc )
410422{
@@ -418,10 +430,11 @@ static inline const struct rb_callable_method_entry_struct *
418430vm_cc_cme (const struct rb_callcache * cc )
419431{
420432 VM_ASSERT (IMEMO_TYPE_P (cc , imemo_callcache ));
421- VM_ASSERT (cc -> klass != Qundef || !vm_cc_markable (cc ));
433+ VM_ASSERT (cc -> klass != Qundef || !vm_cc_markable (cc ) || vm_cc_invalid_super ( cc ) );
422434 VM_ASSERT (cc_check_class (cc -> klass ));
423435 VM_ASSERT (cc -> call_ == NULL || // not initialized yet
424436 !vm_cc_markable (cc ) ||
437+ vm_cc_invalid_super (cc ) ||
425438 cc -> cme_ != NULL );
426439
427440 return cc -> cme_ ;
@@ -432,7 +445,7 @@ vm_cc_call(const struct rb_callcache *cc)
432445{
433446 VM_ASSERT (IMEMO_TYPE_P (cc , imemo_callcache ));
434447 VM_ASSERT (cc -> call_ != NULL );
435- VM_ASSERT (cc -> klass != Qundef || !vm_cc_markable (cc ));
448+ VM_ASSERT (cc -> klass != Qundef || !vm_cc_markable (cc ) || vm_cc_invalid_super ( cc ) );
436449 VM_ASSERT (cc_check_class (cc -> klass ));
437450 return cc -> call_ ;
438451}
0 commit comments