Esempio n. 1
0
File: dbpack.c Progetto: braddr/cold
static cDict *unpack_dict(cBuf *buf, Long *buf_pos)
{
    cDict *dict;
    cList *keys, *values;
    Int i;

    keys = unpack_list(buf, buf_pos);
    values = unpack_list(buf, buf_pos);
    if (keys->len <= 64) {
        dict = dict_new(keys, values);
        list_discard(keys);
        list_discard(values);
        return dict;
    } else {
        dict = EMALLOC(cDict, 1);
        dict->keys = keys;
        dict->values = values;
        dict->hashtab_size = read_long(buf, buf_pos);
        dict->links = EMALLOC(Int, dict->hashtab_size);
        dict->hashtab = EMALLOC(Int, dict->hashtab_size);
        for (i = 0; i < dict->hashtab_size; i++) {
            dict->links[i] = read_long(buf, buf_pos);
            dict->hashtab[i] = read_long(buf, buf_pos);
        }
        dict->refs = 1;
        return dict;
    }
}
Esempio n. 2
0
cDict *dict_from_slices(cList *slices)
{
    cList *keys, *values;
    cDict *dict;
    cData *d;

    /* Make lists for keys and values. */
    keys = list_new(list_length(slices));
    values = list_new(list_length(slices));

    for (d = list_first(slices); d; d = list_next(slices, d)) {
        if (d->type != LIST || list_length(d->u.list) != 2) {
            /* Invalid slice.  Throw away what we had and return NULL. */
            list_discard(keys);
            list_discard(values);
            return NULL;
        }
        keys = list_add(keys, list_elem(d->u.list, 0));
        values = list_add(values, list_elem(d->u.list, 1));
    }

    /* Slices were all valid; return new dict. */
    dict = dict_new(keys, values);
    list_discard(keys);
    list_discard(values);
    return dict;
}
Esempio n. 3
0
void dict_discard(cDict *dict)
{
    dict->refs--;
    if (!dict->refs) {
        list_discard(dict->keys);
        list_discard(dict->values);
        tfree(dict->links, sizeof(Int) * dict->hashtab_size);
        tfree(dict->hashtab, sizeof(Int) * dict->hashtab_size);
        tfree(dict, sizeof(cDict));
    }
}
Esempio n. 4
0
cDict *dict_new_empty(void)
{
    if (!generic_empty_dict) {
        cList *l1, *l2;

        l1 = list_new(0);
        l2 = list_new(0);
        generic_empty_dict = dict_new(l1, l2);
        list_discard(l1);
        list_discard(l2);
    }

    return dict_dup(generic_empty_dict);
}
Esempio n. 5
0
void hash_discard(Hash * hash)
{
    hash->refs--;
    if (!hash->refs) {
	list_discard(hash->keys);
	efree(hash->links);
	efree(hash->hashtab);
	efree(hash);
    }
}
Esempio n. 6
0
Hash * hash_new(int size)
{
    cList * keys;
    Hash  * out;

    keys = list_new(size);
    out = hash_new_with(keys);
    list_discard(keys);
    return out;
}
Esempio n. 7
0
File: dict.c Progetto: whilke/ColdC
void func_dict_values(void) {
    cData * args;
    cList * values;

    if (!func_init_1(&args, DICT))
	return;

    values = dict_values(DICT1);
    pop(1);
    push_list(values);
    list_discard(values);
}
Esempio n. 8
0
File: dict.c Progetto: whilke/ColdC
void func_dict_keys(void) {
    cData * args;
    cList * keys;

    if (!func_init_1(&args, DICT))
	return;

    keys = dict_keys(DICT1);
    pop(1);
    push_list(keys);
    list_discard(keys);
}
Esempio n. 9
0
File: list.c Progetto: nrhtr/genesis
cList *list_prep(cList * list, Int start, Int len)
{
    cList *cnew;
    Int i, resize, size;

    /* Figure out if we need to resize the list or move its contents.  Moving
     * contents takes precedence. */
#if DISABLED
    resize = (len - start) * 4 < list->size;
    resize = resize && list->size > STARTING_SIZE;
    resize = resize || (list->size < len);
#endif
    resize = list->size < len + start;


    /* Move the list contents into a new list. */
    if ((list->refs > 1) || (resize && start > 0)) {
        cnew = list_new(len);
        cnew->len = len;
        len = (list->len < len) ? list->len : len;
        for (i = 0; i < len; i++)
            data_dup(&cnew->el[i], &list->el[start + i]);
        list_discard(list);
        return cnew;
    }

    /* Resize the list.  We can assume that list->start == start == 0. */
    else if (resize) {
        for (; list->len > len; list->len--)
            data_discard(&list->el[list->len - 1]);
        list->len = len;
        size = len;
        list = (cList *) erealloc(list, sizeof(cList) + (size * sizeof(cData)));
        list->size = size;
        return list;
    }

    else {
        for (; list->start < start; list->start++, list->len--)
            data_discard(&list->el[list->start]);
        for (; list->len > len; list->len--)
            data_discard(&list->el[list->start + list->len - 1]);
        list->start = start;
        list->len = len;
        return list;
    }
}
Esempio n. 10
0
File: list.c Progetto: nrhtr/genesis
cList *list_union(cList * list1, cList * list2)
{
    cData *start, *end, *d;

    start = list2->el + list2->start;
    end = start + list2->len;
    if (list1->len + list2->len < 12) {
        for (d = start; d < end; d++) {
            if (list_search(list1, d) == -1)
                list1 = list_add(list1, d);
        }
    } else {
        Hash *tmp;

        tmp = hash_new_with(list1);
        list_discard(list1);
        for (d = start; d < end; d++) {
            tmp = hash_add(tmp, d);
        }
        list1 = list_dup(tmp->keys);
        hash_discard(tmp);
    }
    return list1;
}
Esempio n. 11
0
INTERNAL cList *add_op_arg(cList * out, Int type, Long op, Method * method)
{
    Obj *obj = method->object;
    cData d;

    switch (type) {
    case INTEGER:
        d.type = INTEGER;
        d.u.val = op;
        break;
    case FLOAT:
        d.type = FLOAT;
        d.u.fval = *((Float *) (&op));
        break;
    case T_ERROR:
        if (op == -1) {
            d.type = INTEGER;
            d.u.val = -1;
        } else {
            d.type = T_ERROR;
            d.u.error = object_get_ident(obj, op);
        }
        break;
    case IDENT:
        d.type = SYMBOL;
        d.u.symbol = object_get_ident(obj, op);
        break;
    case VAR:
        {
            Long id;

            d.type = SYMBOL;

            if (op < method->num_args) {
                op = method->num_args - op - 1;
                id = object_get_ident(obj, method->argnames[op]);
                d.u.symbol = id;
                break;
            }
            op -= method->num_args;

            if (method->rest != -1) {
                if (op == 0) {
                    id = object_get_ident(obj, method->rest);
                    d.u.symbol = id;
                    break;
                }
                op--;
            }

            id = object_get_ident(obj, method->varnames[op]);
            d.u.symbol = id;
            break;
        }
    case STRING:
        d.type = STRING;
        d.u.str = object_get_string(obj, op);
        break;
        /* case JUMP: *//* ignore JUMP */
    default:
        return out;
#if DISABLED                    /* none of these are used as args in op_table */
    case LIST:
    case FROB:
    case DICT:
    case BUFFER:
#endif
    }

    out = list_add(out, &d);
    /* do not discard, we were not using duped data */

    return out;
}

COLDC_FUNC(method_bytecode)
{
    cData *args, d;
    Method *method;
    cList *list;
    register Int x;
    Long *ops;
    Op_info *info;
    Long opcode;

    /* Accept a list of lines of code and a symbol for the name. */
    if (!func_init_1(&args, SYMBOL))
        return;

    method = object_find_method(cur_frame->object->objnum, args[0].u.symbol, FROB_ANY);

    /* keep these for later reference, if its already around */
    if (!method)
        THROW((methodnf_id, "Method %D not found.", &args[0]))

    list = list_new(method->num_opcodes);
    d.type = SYMBOL;
    ops = method->opcodes;
    x = 0;
    while (x < method->num_opcodes) {
        opcode = ops[x];
        info = &op_table[opcode];
        d.type = SYMBOL;
        d.u.symbol = info->symbol;
        list = list_add(list, &d);
        /* dont bother discarding, we didnt dup twice */
        x++;

        if (info->arg1) {
            list = add_op_arg(list, info->arg1, ops[x], method);
            x++;
        }

        if (info->arg2) {
            list = add_op_arg(list, info->arg1, ops[x], method);
            x++;
        }
    }

    pop(1);
    push_list(list);
    list_discard(list);
}
Esempio n. 12
0
File: sig.c Progetto: nrhtr/genesis
/* void catch_signal(int sig, int code, struct sigcontext *scp) { */
void catch_signal(int sig)
{
    char *sptr;
    cStr *sigstr;
    cData arg1;
    Bool do_shutdown = NO;

    signal(sig, catch_signal);

    sptr = sig_name(sig);
    sigstr = string_from_chars(sptr, strlen(sptr));

    write_err("Caught signal %d: %S", sig, sigstr);

    string_discard(sigstr);


    /* figure out what to do */
    switch (sig) {
#ifdef __UNIX__
    case SIGHUP:
        atomic = NO;
        handle_connection_output();
        flush_files();
#endif
#ifndef __MSVC__
    case SIGUSR2:
        /* let the db do what it wants from here */
        break;
    case SIGUSR1:
        {
            cData *d;
            cList *l;

            /* First cancel all preempted and suspended tasks */
            l = vm_list();
            for (d = list_first(l); d; d = list_next(l, d)) {
                /* boggle */
                if (d->type != INTEGER)
                    continue;
                vm_cancel(d->u.val);
            }
            list_discard(l);

            /* now cancel the current task if it is valid */
            if (vm_lookup(task_id) != NULL) {
                vm_cancel(task_id);
            }

            /* jump back to the main loop */
            longjmp(main_jmp, 1);
            break;
        }
#endif
    case SIGILL:
        /* lets panic and hopefully shutdown without frobbing the db */
        panic(sig_name(sig));
        break;
    case SIGTERM:
        if (running) {
            write_err("*** Attempting normal shutdown ***");
            running = NO;

            /* jump back to the main loop, ignore any current tasks;
             *drip*, *drip*, leaky */
            longjmp(main_jmp, 1);
        } else {
            panic(sig_name(sig));
        }
        break;
    default:
        do_shutdown = YES;
        break;
    }

    /* only pass onto the db if we are 'executing' */
    if (!running)
        return;

    /* send a message to the system object */
    arg1.type = SYMBOL;
    arg1.u.symbol = ident_get(sptr);
    vm_task(SYSTEM_OBJNUM, signal_id, 1, &arg1);

    if (do_shutdown)
        running = NO;
}