Ejemplo n.º 1
0
Archivo: memory.c Proyecto: 8l/SECD
cell_t *alloc_array(secd_t *secd, size_t size) {
    /* look through the list of arrays */
    cell_t *cur = secd->arrlist;
    while (not_nil(mcons_next(cur))) {
        if (is_array_free(secd, cur)) {
            size_t cursize = arrmeta_size(secd, cur);
            if (cursize >= size) {
                /* allocate this gap */
                if (cursize > size + 1) {
                    /* make a free gap after */
                    cell_t *newmeta = cur + size + 1;
                    cell_t *prevmeta = mcons_prev(cur);
                    init_meta(secd, newmeta, prevmeta, cur);

                    cur->as.mcons.prev = newmeta;
                    prevmeta->as.mcons.next = newmeta;

                    mark_free(newmeta, true);
                }
                mark_free(cur, false);
                return meta_mem(cur);
            }
        }
        cur = mcons_next(cur);
    }

    /* no chunks of sufficient size found, move secd->arrayptr */
    if (secd->arrayptr - secd->fixedptr <= (int)size)
        return &secd_out_of_memory;

    /* create new metadata cons at arrayptr - size - 1 */
    cell_t *oldmeta = secd->arrayptr;

    cell_t *meta = oldmeta - size - 1;
    init_meta(secd, meta, oldmeta, SECD_NIL);

    oldmeta->as.mcons.next = meta;

    secd->arrayptr = meta;

    memdebugf("NEW ARR[%ld], size %zd\n", cell_index(secd, meta), size);
    mark_free(meta, false);
    return meta_mem(meta);
}
Ejemplo n.º 2
0
Archivo: memory.c Proyecto: 8l/SECD
/* Deallocation */
cell_t *drop_dependencies(secd_t *secd, cell_t *c) {
    enum cell_type t = cell_type(c);
    switch (t) {
      case CELL_SYM:
        if (c->as.sym.size != DONT_FREE_THIS)
            free((char *)c->as.sym.data);
            /* TODO: this silently ignores symbol memory corruption */
            c->as.sym.size = DONT_FREE_THIS;
        break;
      case CELL_FRAME:
        drop_cell(secd, c->as.frame.io);
        // fall through
      case CELL_CONS:
        if (not_nil(c)) {
            drop_cell(secd, get_car(c));
            drop_cell(secd, get_cdr(c));
        }
        break;
      case CELL_STR:
      case CELL_ARRAY:
        drop_array(secd, arr_mem(c));
        break;
      case CELL_REF:
        drop_cell(secd, c->as.ref);
        break;
      case CELL_PORT:
        secd_pclose(secd, c);
        break;
      case CELL_ARRMETA:
        if (c->as.mcons.cells) {
            size_t size = arrmeta_size(secd, c);
            size_t i;

            /* free the items */
            for (i = 0; i < size; ++i) {
                /* don't free uninitialized */
                cell_t *ith = meta_mem(c) + i;
                if (cell_type(ith) != CELL_UNDEF)
                    drop_dependencies(secd, ith);
            }
        }
        break;
      case CELL_INT: case CELL_FUNC: case CELL_OP:
      case CELL_ERROR: case CELL_UNDEF:
        return c;
      default:
        return new_error(secd, "drop_dependencies: unknown cell_type 0x%x", t);
    }
    return c;
}
Ejemplo n.º 3
0
int secd_pdump_array(secd_t *secd, cell_t *p, cell_t *mcons) {
    if (mcons->as.mcons.cells) {
        secd_pprintf(secd, p, " #(");
        cell_t *mem = meta_mem(mcons);
        size_t len = arrmeta_size(secd, mcons);
        size_t i;
        for (i = 0; i < len; ++i) {
            cell_t *item_info = serialize_cell(secd, mem + i);
            sexp_pprint(secd, p, item_info);
            free_cell(secd, item_info);
        }
        secd_pprintf(secd, p, ")");
    } else {
        sexp_print_bytes(secd, p, (char *)(mcons + 1),
                                   sizeof(cell_t) * arrmeta_size(secd, mcons));
    }
    return 0;
}