8000 refactoring. common logic into a function. · mrubyc/mrubyc@995fd25 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit 995fd25

Browse files
refactoring. common logic into a function.
1 parent 393d963 commit 995fd25

File tree

3 files changed

+105
-91
lines changed

3 files changed

+105
-91
lines changed

src/c_object.c

Lines changed: 38 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -366,27 +366,42 @@ static void c_object_object_id(struct VM *vm, mrbc_value v[], int argc)
366366

367367
//================================================================
368368
/*! (method - debug) instance_methods
369-
*/
369+
370+
temporary code for operation check.
371+
*/
370372
static void c_object_instance_methods(struct VM *vm, mrbc_value v[], int argc)
371373
{
372-
// TODO: check argument.
373374
if( v[0].tt != MRBC_TT_CLASS ) return;
374375

375-
// temporary code for operation check.
376+
int flag_inherit = !(argc >= 1 && v[1].tt == MRBC_TT_FALSE);
376377
mrbc_value ret = mrbc_array_new( vm, 0 );
377-
const struct RBuiltinClass *cls = (const struct RBuiltinClass *)(v[0].cls);
378+
mrbc_class *cls = v[0].cls;
379+
mrbc_class *nest_buf[MRBC_TRAVERSE_NEST_LEVEL];
380+
int nest_idx = 0;
381+
382+
do {
383+
// builtin method.
384+
for( int i = 0; i < cls->num_builtin_method; i++ ) {
385+
mrbc_array_push( &ret, &mrbc_symbol_value(((struct RBuiltinClass *)cls)->method_symbols[i]) );
386+
}
378387

379-
// builtin method.
380-
for( int i = 0; i < cls->num_builtin_method; i++ ) {
381-
mrbc_array_push( &ret, &mrbc_symbol_value(cls->method_symbols[i]) );
382-
}
388+
// non builtin method.
389+
const mrbc_method *method = cls->method_link;
390+
while( method ) {
391+
mrbc_array_push( &ret, &mrbc_symbol_value(method->sym_id) );
392+
method = method->next;
393+
}
383394

384-
// non builtin method.
385-
const mrbc_method *method = cls->method_link;
386-
while( method ) {
387-
mrbc_array_push( &ret, &mrbc_symbol_value(method->sym_id) );
388-
method = method->next;
389-
}
395+
if( !flag_inherit ) break;
396+
397+
REDO:
398+
cls = mrbc_traverse_class_tree( cls, nest_buf, &nest_idx );
399+
if( cls == MRBC_CLASS(Object) ) {
400+
cls = mrbc_traverse_class_tree_skip( nest_buf, &nest_idx );
401+
if( !cls ) break;
402+
goto REDO;
403+
}
404+
} while( cls );
390405

391406
SET_RETURN(ret);
392407
}
@@ -583,45 +598,26 @@ static void c_object_include(struct VM *vm, mrbc_value v[], int argc)
583598
*/
584599
static void c_object_constants(mrb_vm *vm, mrb_value v[], int argc)
585600
{
586-
int flag_inherit = 1;
587-
588601
if( v[0].tt != MRBC_TT_CLASS ) {
589602
mrbc_raise(vm, MRBC_CLASS(NoMethodError), 0);
590603
return;
591604
}
592-
if( argc >= 1 && v[1].tt == MRBC_TT_FALSE ) flag_inherit = 0;
593605

594-
const mrbc_class *cls = v[0].cls;
606+
int flag_inherit = !(argc >= 1 && v[1].tt == MRBC_TT_FALSE);
595607
mrbc_value ret = mrbc_array_new( vm, 0 );
608+
mrbc_class *cls = v[0].cls;
609+
mrbc_class *nest_buf[MRBC_TRAVERSE_NEST_LEVEL];
610+
int nest_idx = 0;
596611

597612
mrbc_get_all_class_const( cls, &ret );
598613
if( !flag_inherit ) goto RETURN;
599614

600-
// support super class
601-
const mrbc_class *mod_nest[3];
602-
int mod_nest_idx = 0;
603-
604-
while( 1 ) {
605-
cls = cls->super;
606-
if( cls == 0 || cls == MRBC_CLASS(Object) ) {
607-
if( mod_nest_idx == 0 ) break; // does not have super class.
608-
609-
cls = mod_nest[--mod_nest_idx]; // rewind the module search nest.
615+
while( cls ) {
616+
cls = mrbc_traverse_class_tree( cls, nest_buf, &nest_idx );
617+
if( cls == MRBC_CLASS(Object) ) {
618+
cls = mrbc_traverse_class_tree_skip( nest_buf, &nest_idx );
619+
continue;
610620
}
611-
612-
// is the next module alias?
613-
if( cls->flag_alias ) {
614-
// save the super class pointer to mod_nest[]
615-
if( cls->super && cls->super != MRBC_CLASS(Object) ) {
616-
if( mod_nest_idx >= (sizeof(mod_nest) / sizeof(mrbc_class *)) ) {
617-
mrbc_printf("Warning: Module nest exceeds upper limit.\n");
618-
} else {
619-
mod_nest[mod_nest_idx++] = cls->super;
620-
}
621-
}
622-
cls = cls->aliased;
623-
}
624-
625621
mrbc_get_all_class_const( cls, &ret );
626622
}
627623

src/class.c

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,56 @@ mrbc_class * const mrbc_class_tbl[MRBC_TT_MAXVAL+1] = {
5656

5757
/***** Signal catching functions ********************************************/
5858
/***** 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+
59109
/***** Global functions *****************************************************/
60110
//================================================================
61111
/*! define class
@@ -368,29 +418,13 @@ void mrbc_instance_clear_vm_id(mrbc_value *v)
368418
*/
369419
int mrbc_obj_is_kind_of( const mrbc_value *obj, const mrbc_class *tcls )
370420
{
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;
374424

375425
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;
394428
}
395429

396430
return 1;
@@ -407,8 +441,8 @@ int mrbc_obj_is_kind_of( const mrbc_value *obj, const mrbc_class *tcls )
407441
*/
408442
mrbc_method * mrbc_find_method( mrbc_method *r_method, mrbc_class *cls, mrbc_sym sym_id )
409443
{
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;
412446
int flag_module = cls->flag_module;
413447

414448
while( 1 ) {
@@ -445,33 +479,12 @@ mrbc_method * mrbc_find_method( mrbc_method *r_method, mrbc_class *cls, mrbc_sym
445479
}
446480

447481
NEXT:
448-
cls = cls->super;
482+
cls = mrbc_traverse_class_tree( cls, nest_buf, &nest_idx );
449483
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;
463485

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;
475488
}
476489
} // loop next.
477490

src/class.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ extern "C" {
3131
#endif
3232

3333
/***** Constant values ******************************************************/
34+
#define MRBC_TRAVERSE_NEST_LEVEL 3
35+
36+
3437
/***** Macros ***************************************************************/
3538
/*!
3639
Get a built-in class (pointer)
@@ -189,6 +192,8 @@ extern struct RClass * const mrbc_class_tbl[];
189192

190193
/***** Function prototypes **************************************************/
191194
//@cond
195+
mrbc_class *mrbc_traverse_class_tree(mrbc_class *cls, mrbc_class *nest_buf[], int *nest_idx);
196+
mrbc_class *mrbc_traverse_class_tree_skip(mrbc_class *nest_buf[], int *nest_idx);
192197
mrbc_class *mrbc_define_class(struct VM *vm, const char *name, mrbc_class *super);
193198
mrbc_class *mrbc_define_class_under(struct VM *vm, const mrbc_class *outer, const char *name, mrbc_class *super);
194199
mrbc_class *mrbc_define_module(struct VM *vm, const char *name);
@@ -202,7 +207,7 @@ void mrbc_instance_clear_vm_id(mrbc_value *v);
202207
int mrbc_obj_is_kind_of(const mrbc_value *obj, const mrbc_class *tcls);
203208
mrbc_method *mrbc_find_method(mrbc_method *r_method, mrbc_class *cls, mrbc_sym sym_id);
204209
mrbc_class *mrbc_get_class_by_name(const char *name);
205-
mrbc_value mrbc_send(struct VM *vm, mrbc_value *v, int reg_ofs, mrbc_value *recv, const char *method_name, int argc, ...);
210+
mrbc_value mrbc_send(struct VM *vm, mrbc_value *v, int argc, mrbc_value *recv, const char *method_name, int n_params, ...);
206211
void c_ineffect(struct VM *vm, mrbc_value v[], int argc);
207212
int mrbc_run_mrblib(const void *bytecode);
208213
void mrbc_init_class(void);

0 commit comments

Comments
 (0)
0