]>
git.proxmox.com Git - ceph.git/blob - ceph/src/civetweb/src/third_party/duktape-1.8.0/src-separate/duk_hbuffer_alloc.c
2 * duk_hbuffer allocation and freeing.
5 #include "duk_internal.h"
7 /* Allocate a new duk_hbuffer of a certain type and return a pointer to it
8 * (NULL on error). Write buffer data pointer to 'out_bufdata' (only if
9 * allocation successful).
11 DUK_INTERNAL duk_hbuffer
*duk_hbuffer_alloc(duk_heap
*heap
, duk_size_t size
, duk_small_uint_t flags
, void **out_bufdata
) {
12 duk_hbuffer
*res
= NULL
;
13 duk_size_t header_size
;
14 duk_size_t alloc_size
;
16 DUK_ASSERT(heap
!= NULL
);
17 DUK_ASSERT(out_bufdata
!= NULL
);
19 DUK_DDD(DUK_DDDPRINT("allocate hbuffer"));
21 /* Size sanity check. Should not be necessary because caller is
22 * required to check this, but we don't want to cause a segfault
23 * if the size wraps either in duk_size_t computation or when
24 * storing the size in a 16-bit field.
26 if (size
> DUK_HBUFFER_MAX_BYTELEN
) {
27 DUK_D(DUK_DPRINT("hbuffer alloc failed: size too large: %ld", (long) size
));
28 return NULL
; /* no need to write 'out_bufdata' */
31 if (flags
& DUK_BUF_FLAG_EXTERNAL
) {
32 header_size
= sizeof(duk_hbuffer_external
);
33 alloc_size
= sizeof(duk_hbuffer_external
);
34 } else if (flags
& DUK_BUF_FLAG_DYNAMIC
) {
35 header_size
= sizeof(duk_hbuffer_dynamic
);
36 alloc_size
= sizeof(duk_hbuffer_dynamic
);
38 header_size
= sizeof(duk_hbuffer_fixed
);
39 alloc_size
= sizeof(duk_hbuffer_fixed
) + size
;
40 DUK_ASSERT(alloc_size
>= sizeof(duk_hbuffer_fixed
)); /* no wrapping */
43 res
= (duk_hbuffer
*) DUK_ALLOC(heap
, alloc_size
);
48 /* zero everything unless requested not to do so */
49 #if defined(DUK_USE_ZERO_BUFFER_DATA)
50 DUK_MEMZERO((void *) res
,
51 (flags
& DUK_BUF_FLAG_NOZERO
) ? header_size
: alloc_size
);
53 DUK_MEMZERO((void *) res
, header_size
);
56 if (flags
& DUK_BUF_FLAG_EXTERNAL
) {
57 duk_hbuffer_external
*h
;
58 h
= (duk_hbuffer_external
*) res
;
61 #if defined(DUK_USE_EXPLICIT_NULL_INIT)
62 #if defined(DUK_USE_HEAPPTR16)
63 /* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
65 DUK_HBUFFER_EXTERNAL_SET_DATA_PTR(heap
, h
, NULL
);
68 DUK_ASSERT(DUK_HBUFFER_EXTERNAL_GET_DATA_PTR(heap
, h
) == NULL
);
69 } else if (flags
& DUK_BUF_FLAG_DYNAMIC
) {
70 duk_hbuffer_dynamic
*h
= (duk_hbuffer_dynamic
*) res
;
74 DUK_ASSERT(!(flags
& DUK_BUF_FLAG_EXTERNAL
)); /* alloc external with size zero */
75 DUK_DDD(DUK_DDDPRINT("dynamic buffer with nonzero size, alloc actual buffer"));
76 #ifdef DUK_USE_ZERO_BUFFER_DATA
77 ptr
= DUK_ALLOC_ZEROED(heap
, size
);
79 ptr
= DUK_ALLOC(heap
, size
);
82 /* Because size > 0, NULL check is correct */
87 DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap
, h
, ptr
);
90 #if defined(DUK_USE_EXPLICIT_NULL_INIT)
91 #if defined(DUK_USE_HEAPPTR16)
92 /* the compressed pointer is zeroed which maps to NULL, so nothing to do. */
94 DUK_HBUFFER_DYNAMIC_SET_DATA_PTR(heap
, h
, NULL
);
97 DUK_ASSERT(DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap
, h
) == NULL
);
100 *out_bufdata
= (void *) ((duk_hbuffer_fixed
*) res
+ 1);
103 DUK_HBUFFER_SET_SIZE(res
, size
);
105 DUK_HEAPHDR_SET_TYPE(&res
->hdr
, DUK_HTYPE_BUFFER
);
106 if (flags
& DUK_BUF_FLAG_DYNAMIC
) {
107 DUK_HBUFFER_SET_DYNAMIC(res
);
108 if (flags
& DUK_BUF_FLAG_EXTERNAL
) {
109 DUK_HBUFFER_SET_EXTERNAL(res
);
112 DUK_ASSERT(!(flags
& DUK_BUF_FLAG_EXTERNAL
));
114 DUK_HEAP_INSERT_INTO_HEAP_ALLOCATED(heap
, &res
->hdr
);
116 DUK_DDD(DUK_DDDPRINT("allocated hbuffer: %p", (void *) res
));
120 DUK_DD(DUK_DDPRINT("hbuffer allocation failed"));
123 return NULL
; /* no need to write 'out_bufdata' */
126 /* For indirect allocs. */
128 DUK_INTERNAL
void *duk_hbuffer_get_dynalloc_ptr(duk_heap
*heap
, void *ud
) {
129 duk_hbuffer_dynamic
*buf
= (duk_hbuffer_dynamic
*) ud
;
131 return (void *) DUK_HBUFFER_DYNAMIC_GET_DATA_PTR(heap
, buf
);