DUK_LOCAL duk_bool_t duk__insert_hstring_chain(duk_heap *heap, duk_hstring *h) { duk_small_uint_t slotidx; duk_strtab_entry *e; duk_uint16_t *lst; duk_uint16_t *new_lst; duk_size_t i, n; duk_uint16_t null16 = heap->heapptr_null16; duk_uint16_t h16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) h); DUK_ASSERT(heap != NULL); DUK_ASSERT(h != NULL); slotidx = DUK_HSTRING_GET_HASH(h) % DUK_STRTAB_CHAIN_SIZE; DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE); e = heap->strtable + slotidx; if (e->listlen == 0) { if (e->u.str16 == null16) { e->u.str16 = h16; } else { /* Now two entries in the same slot, alloc list */ lst = (duk_uint16_t *) DUK_ALLOC(heap, sizeof(duk_uint16_t) * 2); if (lst == NULL) { return 1; /* fail */ } lst[0] = e->u.str16; lst[1] = h16; e->u.strlist16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) lst); e->listlen = 2; } } else { DUK_ASSERT(e->u.strlist16 != null16); lst = (duk_uint16_t *) DUK_USE_HEAPPTR_DEC16(heap->heap_udata, e->u.strlist16); DUK_ASSERT(lst != NULL); for (i = 0, n = e->listlen; i < n; i++) { if (lst[i] == null16) { lst[i] = h16; return 0; } } if (e->listlen + 1 == 0) { /* Overflow, relevant mainly when listlen is 16 bits. */ return 1; /* fail */ } new_lst = (duk_uint16_t *) DUK_REALLOC(heap, lst, sizeof(duk_uint16_t) * (e->listlen + 1)); if (new_lst == NULL) { return 1; /* fail */ } new_lst[e->listlen++] = h16; e->u.strlist16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) new_lst); } return 0; }
/* Overflow, relevant mainly when listlen is 16 bits. */ return 1; /* fail */ } new_lst = (duk_uint16_t *) DUK_REALLOC(heap, lst, sizeof(duk_uint16_t) * (e->listlen + 1)); if (new_lst == NULL) { return 1; /* fail */ } new_lst[e->listlen++] = h16; e->u.strlist16 = DUK_USE_HEAPPTR_ENC16(heap->heap_udata, (void *) new_lst); } return 0; } #else /* DUK_USE_HEAPPTR16 */ DUK_LOCAL duk_bool_t duk__insert_hstring_chain(duk_heap *heap, duk_hstring *h) { duk_small_uint_t slotidx; duk_strtab_entry *e; duk_hstring **lst; duk_hstring **new_lst; duk_size_t i, n; DUK_ASSERT(heap != NULL); DUK_ASSERT(h != NULL); slotidx = DUK_HSTRING_GET_HASH(h) % DUK_STRTAB_CHAIN_SIZE; DUK_ASSERT(slotidx < DUK_STRTAB_CHAIN_SIZE); e = heap->strtable + slotidx; if (e->listlen == 0) { if (e->u.str == NULL) { e->u.str = h; } else { /* Now two entries in the same slot, alloc list */ lst = (duk_hstring **) DUK_ALLOC(heap, sizeof(duk_hstring *) * 2); if (lst == NULL) { return 1; /* fail */ } lst[0] = e->u.str; lst[1] = h; e->u.strlist = lst; e->listlen = 2; } } else { DUK_ASSERT(e->u.strlist != NULL); lst = e->u.strlist; for (i = 0, n = e->listlen; i < n; i++) { if (lst[i] == NULL) { lst[i] = h; return 0; } } if (e->listlen + 1 == 0) { /* Overflow, relevant mainly when listlen is 16 bits. */ return 1; /* fail */ } new_lst = (duk_hstring **) DUK_REALLOC(heap, e->u.strlist, sizeof(duk_hstring *) * (e->listlen + 1)); if (new_lst == NULL) { return 1; /* fail */ } new_lst[e->listlen++] = h; e->u.strlist = new_lst; } return 0; }
void *duk_realloc(duk_context *ctx, void *ptr, size_t size) { duk_hthread *thr = (duk_hthread *) ctx; DUK_ASSERT(ctx != NULL); /* * Note: since this is an exposed API call, there should be * no way a mark-and-sweep could have a side effect on the * memory allocation behind 'ptr'; the pointer should never * be something that Duktape wants to change. * * Thus, no need to use DUK_REALLOC_INDIRECT (and we don't * have the storage location here anyway). */ return DUK_REALLOC(thr->heap, ptr, size); }
void *duk_heap_mem_realloc_checked(duk_hthread *thr, void *ptr, size_t newsize, const char *filename, int line) { #else void *duk_heap_mem_realloc_checked(duk_hthread *thr, void *ptr, size_t newsize) { #endif void *res; DUK_ASSERT(thr != NULL); /* ptr may be NULL */ DUK_ASSERT_DISABLE(newsize >= 0); res = DUK_REALLOC(thr->heap, ptr, newsize); if (!res) { #ifdef DUK_USE_VERBOSE_ERRORS DUK_ERROR_RAW(filename, line, thr, DUK_ERR_ALLOC_ERROR, "memory realloc failed"); #else DUK_ERROR(thr, DUK_ERR_ALLOC_ERROR, "memory realloc failed"); #endif } return res; }