Example #1
0
/*
 *   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);
}