@@ -56,6 +56,56 @@ mrbc_class * const mrbc_class_tbl[MRBC_TT_MAXVAL+1] = {
56
56
57
57
/***** Signal catching functions ********************************************/
58
58
/***** Local functions ******************************************************/
59
+ //================================================================
60
+ /*! (internal use) traverse class tree.
61
+
62
+ @param cls target class
63
+ @param nest_buf nest buffer
64
+ @param nest_idx nest buffer index
65
+ @return mrbc_class * next target class or NULL
66
+ */
67
+ mrbc_class * mrbc_traverse_class_tree ( mrbc_class * cls , mrbc_class * nest_buf [], int * nest_idx )
68
+ {
69
+ cls = cls -> super ;
70
+
71
+ if ( cls == 0 ) {
72
+ if ( * nest_idx == 0 ) return 0 ; // does not have super class.
73
+ cls = nest_buf [-- (* nest_idx )]; // rewind to the saved point.
74
+ cls = cls -> super ;
75
+ }
76
+
77
+ // is the next module alias?
78
+ if ( cls -> flag_alias ) {
79
+ if ( cls -> super ) {
80
+ // save the branch point to nest_buf.
81
+ if ( * nest_idx >= MRBC_TRAVERSE_NEST_LEVEL ) {
82
+ mrbc_printf ("Warning: Module nest exceeds upper limit.\n" );
83
+ } else {
84
+ nest_buf [(* nest_idx )++ ] = cls ;
85
+ }
86
+ }
87
+
88
+ cls = cls -> aliased ;
89
+ }
90
+
91
+ return cls ;
92
+ }
93
+
94
+
95
+ //================================================================
96
+ /*! (internal use) traverse class tree. skip that class.
97
+
98
+ @param nest_buf nest buffer
99
+ @param nest_idx nest buffer index
100
+ @return mrbc_class * previous target class
101
+ */
102
+ mrbc_class * mrbc_traverse_class_tree_skip ( mrbc_class * nest_buf [], int * nest_idx )
103
+ {
104
+ if ( * nest_idx == 0 ) return 0 ; // does not have super class.
105
+ return nest_buf [-- (* nest_idx )]; // rewind to the saved point.
106
+ }
107
+
108
+
59
109
/***** Global functions *****************************************************/
60
110
//================================================================
61
111
/*! define class
@@ -368,29 +418,13 @@ void mrbc_instance_clear_vm_id(mrbc_value *v)
368
418
*/
369
419
int mrbc_obj_is_kind_of ( const mrbc_value * obj , const mrbc_class * tcls )
370
420
{
371
- const mrbc_class * cls = find_class_by_object ( obj );
372
- const mrbc_class * mod_nest [ 3 ];
373
- int mod_nest_idx = 0 ;
421
+ mrbc_class * cls = find_class_by_object ( obj );
422
+ mrbc_class * nest_buf [ MRBC_TRAVERSE_NEST_LEVEL ];
423
+ int nest_idx = 0 ;
374
424
375
425
while ( cls != tcls ) {
376
- cls = cls -> super ;
377
- if ( cls == 0 ) {
378
- if ( mod_nest_idx == 0 ) return 0 ; // does not have super class.
379
- cls = mod_nest [-- mod_nest_idx ];
380
- }
381
-
382
- // is the next alias?
383
- if ( cls -> flag_alias ) {
384
- // save the super for include nesting of modules.
385
- if ( cls -> super ) {
386
- if ( mod_nest_idx >= (sizeof (mod_nest ) / sizeof (mrbc_class * )) ) {
387
- mrbc_printf ("Warning: Module nest exceeds upper limit.\n" );
388
- return 0 ;
389
- }
390
- mod_nest [mod_nest_idx ++ ] = cls -> super ;
391
- }
392
- cls = cls -> aliased ;
393
- }
426
+ cls = mrbc_traverse_class_tree ( cls , nest_buf , & nest_idx );
427
+ if ( ! cls ) return 0 ;
394
428
}
395
429
396
430
return 1 ;
@@ -407,8 +441,8 @@ int mrbc_obj_is_kind_of( const mrbc_value *obj, const mrbc_class *tcls )
407
441
*/
408
442
mrbc_method * mrbc_find_method ( mrbc_method * r_method , mrbc_class * cls , mrbc_sym sym_id )
409
443
{
410
- mrbc_class * mod_nest [ 3 ];
411
- int mod_nest_idx = 0 ;
444
+ mrbc_class * nest_buf [ MRBC_TRAVERSE_NEST_LEVEL ];
445
+ int nest_idx = 0 ;
412
446
int flag_module = cls -> flag_module ;
413
447
414
448
while ( 1 ) {
@@ -445,33 +479,12 @@ mrbc_method * mrbc_find_method( mrbc_method *r_method, mrbc_class *cls, mrbc_sym
445
479
}
446
480
447
481
NEXT :
448
- cls = cls -> super ;
482
+ cls = mrbc_traverse_class_tree ( cls , nest_buf , & nest_idx ) ;
449
483
if ( cls == 0 ) {
450
- // does not have super class.
451
- if ( mod_nest_idx == 0 ) {
452
- if ( flag_module ) {
453
- cls = MRBC_CLASS (Object );
454
- flag_module = 0 ;
455
- continue ;
456
- }
457
- break ;
458
- }
459
-
460
- // rewind the module search nest.
461
- cls = mod_nest [-- mod_nest_idx ];
462
- }
484
+ if ( !flag_module ) break ;
463
485
464
- // is the next alias?
465
- if ( cls -> flag_alias ) {
466
- // save the super for include nesting of modules.
467
- if ( cls -> super ) {
468
- if ( mod_nest_idx >= (sizeof (mod_nest ) / sizeof (mrbc_class * )) ) {
469
- mrbc_printf ("Warning: Module nest exceeds upper limit.\n" );
470
- break ;
471
- }
472
- mod_nest [mod_nest_idx ++ ] = cls -> super ;
473
- }
474
- cls = cls -> aliased ;
486
+ cls = MRBC_CLASS (Object );
487
+ flag_module = 0 ;
475
488
}
476
489
} // loop next.
477
490
0 commit comments