Пример #1
0
/*
 *   allocate a new page 
 */
void CTcDataStream::alloc_page()
{
    /* 
     *   if we're coming back to a page that was previously allocated, we
     *   need merely re-establish the existing page 
     */
    if (page_cur_ + 1 < page_cnt_)
    {
        /* move to the next page */
        ++page_cur_;

        /* start writing at the start of the page */
        wp_ = pages_[page_cur_];
        rem_ = TCCS_PAGE_SIZE;

        /* we're done */
        return;
    }

    /* 
     *   if we don't have room for a new page in the page array, expand
     *   the page array 
     */
    if (page_cnt_ >= page_slots_)
    {
        /* increase the page slot count */
        page_slots_ += 100;

        /* allocate or reallocate the page array */
        if (pages_ == 0)
            pages_ = (char **)t3malloc(page_slots_ * sizeof(pages_[0]));
        else
            pages_ = (char **)t3realloc(pages_,
                                        page_slots_ * sizeof(pages_[0]));

        /* if that failed, throw an error */
        if (pages_ == 0)
            err_throw(TCERR_CODEGEN_NO_MEM);
    }

    /* allocate the new page */
    pages_[page_cnt_] = (char *)t3malloc(TCCS_PAGE_SIZE);

    /* throw an error if we couldn't allocate the page */
    if (pages_[page_cnt_] == 0)
        err_throw(TCERR_CODEGEN_NO_MEM);

    /* start writing at the start of the new page */
    wp_ = pages_[page_cnt_];

    /* the entire page is free */
    rem_ = TCCS_PAGE_SIZE;

    /* make the new page the current page */
    page_cur_ = page_cnt_;

    /* count the new page */
    ++page_cnt_;
}
Пример #2
0
 const char *vmpbs_alloc_and_load_page(pool_ofs_t ofs, size_t page_size,
                                       size_t load_size)
 {
     char *mem = (char *)t3malloc(load_size);
     vmpbs_load_page(ofs, page_size, load_size, mem);
     return mem;
 }
Пример #3
0
/*
 *   allocate 
 */
CTcSrcMemory::CTcSrcMemory(const char *buf, CCharmapToUni *mapper)
{
    size_t len;
    size_t alo_len;
    char *p;

    /* get the length of the null-terminated source string */
    len = strlen(buf);

    /* 
     *   Allocate a buffer for a UTF8-encoded copy of the buffer -
     *   allocate three bytes per byte of the original, since this is the
     *   worst case for expansion of the encoding.  Allocate one extra
     *   byte to ensure we have space for a null terminator.  
     */
    alo_len = len*3;
    buf_alo_ = (char *)t3malloc(alo_len + 1);

    /* map the buffer */
    p = buf_alo_;
    mapper->map(&p, &alo_len, buf, len);

    /* null-terminate the translated buffer */
    *p = '\0';

    /* start reading at the start of the translated buffer */
    buf_ = buf_alo_;
}
Пример #4
0
/*
 *   Ensure that we have space for a given number of entries 
 */
void CVmMetaTable::ensure_space(size_t entries, size_t increment)
{
    /* if we don't have enough space, allocate more */
    if (entries >= alloc_)
    {
        size_t new_size;
        
        /* increase the allocation size by the given increment */
        alloc_ += increment;

        /* if it's still too small, bump it up to the required size */
        if (alloc_ < entries)
            alloc_ = entries;

        /* compute the new size */
        new_size = alloc_ * sizeof(table_[0]);
        
        /* 
         *   if we have a table already, reallocate it at the larger size;
         *   otherwise, allocate a new table 
         */
        if (table_ != 0)
            table_ = (vm_meta_entry_t *)t3realloc(table_, new_size);
        else
            table_ = (vm_meta_entry_t *)t3malloc(new_size);
    }
}
Пример #5
0
/*
 *   add a symbol
 */
void CVmRuntimeSymbols::add_sym(const char *sym, size_t len,
                                const vm_val_t *val)
{
    vm_runtime_sym *new_sym;

    /* allocate a new structure */
    new_sym = (vm_runtime_sym *)t3malloc(sizeof(vm_runtime_sym) + len - 1);

    /* copy the data */
    new_sym->val = *val;
    new_sym->len = len;
    memcpy(new_sym->sym, sym, len);

    /* link it into our list */
    new_sym->nxt = 0;
    if (tail_ == 0)
        head_ = new_sym;
    else
        tail_->nxt = new_sym;

    /* it's the new tail */
    tail_ = new_sym;

    /* count it */
    ++cnt_;
}
Пример #6
0
 void init(size_t initsize)
 {
     buf = (char *)t3malloc(initsize);
     buf[0] = '\0';
     len = initsize;
     inc = (initsize > 128 ? initsize / 2 : 128);
     wrtidx = 0;
 }
Пример #7
0
/*
 *   Create the metaclass dependency table with a given number of initial
 *   entries 
 */
CVmMetaTable::CVmMetaTable(size_t init_entries)
{
    vm_meta_reg_t *entry;
    uint cnt;
    uint i;

    /* allocate space for our entries */
    if (init_entries != 0)
    {
        /* allocate the space */
        table_ = (vm_meta_entry_t *)
                 t3malloc(init_entries * sizeof(table_[0]));
    }
    else
    {
        /* we have no entries */
        table_ = 0;
    }

    /* no entries are defined yet */
    count_ = 0;

    /* remember the allocation size */
    alloc_ = init_entries;

    /* count the number of registered metaclasses */
    for (entry = G_meta_reg_table, cnt = 0 ; entry->meta != 0 ;
         ++entry, ++cnt) ;

    /* 
     *   allocate the reverse dependency table -- this table lets us get
     *   the dependency index of a metaclass given its registration table
     *   index 
     */
    reverse_map_ = (int *)t3malloc(cnt * sizeof(reverse_map_[0]));

    /* 
     *   set each element of the table to -1, since we have no dependency
     *   table entries yet 
     */
    for (i = 0 ; i < cnt ; ++i)
        reverse_map_[i] = -1;
}
Пример #8
0
/*
 *   Allocate space for a string of a given length.  We'll add in space
 *   for the null terminator.  
 */
char *lib_alloc_str(size_t len)
{
    char *buf;

    /* allocate the space */
    buf = (char *)t3malloc(len + 1);

    /* make sure it's initially null-terminated */
    buf[0] = '\0';

    /* return the space */
    return buf;
}
Пример #9
0
/*
 *   Allocate line record pages 
 */
void CTcCodeStream::alloc_line_pages(size_t number_to_add)
{
    size_t siz;
    size_t i;

    /* create or expand the master page array */
    siz = (line_pages_alloc_ + number_to_add) * sizeof(tcgen_line_page_t *);
    if (line_pages_ == 0)
        line_pages_ = (tcgen_line_page_t **)t3malloc(siz);
    else
        line_pages_ = (tcgen_line_page_t **)t3realloc(line_pages_, siz);

    /* allocate the new pages */
    for (i = line_pages_alloc_ ; i < line_pages_alloc_ + number_to_add ; ++i)
    {
        /* allocate this page */
        line_pages_[i] = (tcgen_line_page_t *)
                         t3malloc(sizeof(tcgen_line_page_t));
    }

    /* remember the new allocation */
    line_pages_alloc_ += number_to_add;
}
Пример #10
0
/*
 *   allocating vsprintf implementation 
 */
char *t3vsprintf_alloc(const char *fmt, va_list args)
{
    /* measure the required space - add in a byte for null termination */
    size_t len = t3vsprintf(0, 0, fmt, args) + 1;

    /* allocate space */
    char *buf = (char *)t3malloc(len);
    if (buf == 0)
        return 0;

    /* do the actual formatting */
    t3vsprintf(buf, len, fmt, args);

    /* return the allocated buffer */
    return buf;
}
Пример #11
0
/*
 *   Create an application/x-www-form-urlencoded buffer from the payload. 
 */
char *OS_HttpPayload::urlencode(size_t &len) const
{
    /* 
     *   start by scanning the fields to figure the total buffer length we'll
     *   need 
     */
    OS_HttpPayloadItem *item;
    for (len = 0, item = first_item ; item != 0 ; item = item->nxt)
    {
        /* 
         *   if this isn't the first item, we'll need a '&' to separate it
         *   from the prior item 
         */
        if (item != first_item)
            len += 1;
        
        /* 
         *   add the item's length: "name=value", with url encoding for both
         *   strings 
         */
        len += urlencodestr(0, item->name) + 1 + urlencodestr(0, item->val);
    }
    
    /* allocate the buffer */
    char *putdata = (char *)t3malloc(len + 1);
    if (putdata == 0)
        return 0;
    
    /* build the buffer */
    char *p;
    for (p = putdata, item = first_item ; item != 0 ; item = item->nxt)
    {
        /* if this isn't the first item, add the '&' */
        if (item != first_item)
            *p++ = '&';
        
        /* add "name=urlencodestr(value)" */
        p += urlencodestr(p, item->name);
        *p++ = '=';
        p += urlencodestr(p, item->val);
    }

    /* return the allocated buffer */
    return putdata;
}
Пример #12
0
/*
 *   allocate the stack 
 */
CVmStack::CVmStack(size_t max_depth, size_t reserve)
{
    /* 
     *   Allocate the array of stack elements.  Allocate the requested
     *   maximum depth plus the requested reserve space.  Overallocate by a
     *   few elements to leave ourselves a little buffer against mild
     *   overages - for the most part, we count on the compiler to check for
     *   proper stack usage at entry to each function, but intrinsics
     *   sometimes push a few elements without checking.  
     */
    arr_ = (vm_val_t *)t3malloc((max_depth + reserve + 25) * sizeof(arr_[0]));
    
    /* remember the maximum depth and the reserve depth */
    max_depth_ = max_depth;
    reserve_depth_ = reserve;

    /* the reserve is not yet in use */
    reserve_in_use_ = FALSE;

    /* initialize the stack pointer */
    init();
}
Пример #13
0
/*
 *   Allocate space in the dynamic pool 
 */
CVmPoolDynObj *CVmPoolInMem::dynpool_alloc(size_t len)
{
    CVmPoolDynObj *cur;

    /* 
     *   if the requested size exceeds the page size, we can't allocate
     *   it, since each request must fit within a single page 
     */
    if (len > page_size_)
        return 0;
    
    /*
     *   First, see if we can find a free pool object that we've already
     *   allocated that will fill the request 
     */
    for (cur = dyn_head_ ; cur != 0 ; cur = cur->get_next())
    {
        /* if this object is free, and it's big enough, use it */
        if (cur->is_free() && cur->get_len() >= len)
        {
            /* 
             *   if this object is at least a little bigger than the
             *   request, create a new object to hold the balance of this
             *   object, so that the balance can be allocated separately 
             */
            if (cur->get_len() > len + 63)
            {
                CVmPoolDynObj *new_obj;

                /* 
                 *   create a new object, using the space remaining in the
                 *   old object after the requested amount of space 
                 */
                new_obj = new CVmPoolDynObj(cur->get_ofs() + len,
                                            cur->get_len() - len);

                /* reduce the old object to the requested size */
                cur->set_len(len);

                /* link the new object in after the old object */
                insert_dyn(cur, new_obj);

                /* the new object is free */
                new_obj->set_free(TRUE);
            }

            /* this object is now in use */
            cur->set_free(FALSE);

            /* return the object we found */
            return cur;
        }
    }

    /*
     *   We didn't find any free memory in any existing pages where we
     *   could fill the request.  So, we must allocate a new page.  First,
     *   allocate a new page slot.  
     */
    alloc_page_slots(page_slots_ + 1);

    /* allocate space for the page data */
    pages_[page_slots_ - 1].mem = (char *)t3malloc(page_size_);

    /* 
     *   if the requested size wouldn't leave much additional space on the
     *   page, simply give the entire page to the new object 
     */
    if (len + 63 >= page_size_)
        len = page_size_;

    /* create a new dynamic pool handle for the new object */
    cur = new CVmPoolDynObj(get_page_start_ofs(page_slots_ - 1), len);

    /* link it in at the end of the list */
    append_dyn(cur);

    /* 
     *   if there's any space left over, create yet another object to
     *   cover the free space remaining on the page 
     */
    if (len < page_size_)
    {
        CVmPoolDynObj *f;
        
        /* create a new dynamic pool handle for the new object */
        f = new CVmPoolDynObj(get_page_start_ofs(page_slots_ - 1) + len,
                              page_size_ - len);

        /* mark it as free */
        f->set_free(TRUE);

        /* link it in at the end of the list */
        append_dyn(f);
    }

    /* return the new object */
    return cur;
}
Пример #14
0
/*
 *   Add an entry to the table for a given registration table index
 */
void CVmMetaTable::add_entry(const char *metaclass_id,
                             uint idx, size_t func_cnt,
                             vm_prop_id_t min_prop, vm_prop_id_t max_prop)
{
    vm_meta_reg_t *entry;
    size_t prop_xlat_cnt;

    /* get the registration table entry from the index */
    entry = &G_meta_reg_table[idx];
    
    /* remember the defining class object */
    table_[count_].meta_ = *entry->meta;

    /* save the name */
    table_[count_].set_meta_name(metaclass_id);

    /* calculate the number of entries in the table */
    if (min_prop == VM_INVALID_PROP || max_prop == VM_INVALID_PROP)
        prop_xlat_cnt = 0;
    else
        prop_xlat_cnt = max_prop - min_prop + 1;

    /* set the property count */
    table_[count_].min_prop_ = min_prop;
    table_[count_].prop_xlat_cnt_ = prop_xlat_cnt;

    /* set the function count */
    table_[count_].func_xlat_cnt_ = func_cnt;

    /* we don't know the intrinsic class's representative object yet */
    table_[count_].class_obj_ = VM_INVALID_OBJ;

    /* allocate space for the property table, if we have any translations */
    if (prop_xlat_cnt != 0)
    {
        size_t siz;

        /* calculate the table size */
        siz = prop_xlat_cnt * sizeof(table_[count_].prop_xlat_[0]);
        
        /* allocate the table */
        table_[count_].prop_xlat_ = (unsigned short *)t3malloc(siz);

        /* 
         *   initialize each entry in the table to zero - this will ensure
         *   that each entry that is never set to a valid function index
         *   will properly yield function index zero, which is defined as
         *   the "not found" invalid function index 
         */
        memset(table_[count_].prop_xlat_, 0, siz);
    }
    else
    {
        /* there are no properties to translate, so we don't need a table */
        table_[count_].prop_xlat_ = 0;
    }

    /* allocate the function-to-property translation table */
    if (func_cnt != 0)
    {
        size_t i;
        vm_prop_id_t *prop_ptr;
        
        /* allocate the table */
        table_[count_].func_xlat_ =
            (vm_prop_id_t *)t3malloc(func_cnt * sizeof(vm_prop_id_t));

        /* clear the table - mark each entry as an invalid property ID */
        for (i = 0, prop_ptr = table_[count_].func_xlat_ ;
             i < func_cnt ; ++i, ++prop_ptr)
            *prop_ptr = VM_INVALID_PROP;
    }
    else
    {
        /* no properties, so we don't need a table */
        table_[count_].func_xlat_ = 0;
    }

    /* 
     *   store the reverse mapping for this entry, so that we can find the
     *   dependency entry given the registration index 
     */
    reverse_map_[idx] = count_;

    /* count the new entry */
    ++count_;
}