/* * Get a list of our properties */ void CVmObjClass::build_prop_list(VMG_ vm_obj_id_t self, vm_val_t *retval) { vm_obj_id_t mod_obj; vm_meta_entry_t *entry; size_t my_prop_cnt; size_t mod_prop_cnt; vm_val_t mod_val; CVmObjList *lst; CVmObjList *mod_lst; /* presume we won't find any static properties of our own */ my_prop_cnt = 0; /* get my metaclass table entry */ entry = get_meta_entry(vmg0_); /* if we have an entry, count the properties */ if (entry != 0) my_prop_cnt = list_class_props(vmg_ self, entry, 0, 0, FALSE); /* if we have a modifier object, get its property list */ if ((mod_obj = get_mod_obj()) != VM_INVALID_OBJ) { /* get the modifier's property list - we'll add it to our own */ vm_objp(vmg_ mod_obj)->build_prop_list(vmg_ self, &mod_val); /* get the result as a list object, properly cast */ mod_lst = (CVmObjList *)vm_objp(vmg_ mod_val.val.obj); /* * As an optimization, if we don't have any properties of our own * to add to the modifier list, just return the modifier list * directly (thus avoiding unnecessarily creating another copy of * the list with no changes). */ if (my_prop_cnt == 0) { /* the modifier list is the entire return value */ *retval = mod_val; return; } /* get the size of the modifier list */ mod_prop_cnt = vmb_get_len(mod_lst->get_as_list()); } else { /* * we have no modifier object - for the result list, we simply * need our own list, so set the modifier list to nil */ mod_val.set_nil(); mod_prop_cnt = 0; mod_lst = 0; } /* for gc protection, push the modifier's list */ G_stk->push(&mod_val); /* * Allocate a list big enough to hold the modifier's list plus our own * list. */ retval->set_obj(CVmObjList:: create(vmg_ FALSE, my_prop_cnt + mod_prop_cnt)); /* push the return value list for gc protection */ G_stk->push(retval); /* get it as a list object, properly cast */ lst = (CVmObjList *)vm_objp(vmg_ retval->val.obj); lst->cons_clear(); /* start the list with our own properties */ if (entry != 0) list_class_props(vmg_ self, entry, lst, 0, FALSE); /* copy the modifier list into the results, if there is a modifier list */ if (mod_prop_cnt != 0) lst->cons_copy_elements(my_prop_cnt, mod_lst->get_as_list()); /* done with the gc protection */ G_stk->discard(2); }