/* [caml_ba_alloc] will allocate a new bigarray object in the heap. If [data] is NULL, the memory for the contents is also allocated (with [malloc]) by [caml_ba_alloc]. [data] cannot point into the OCaml heap. [dim] may point into an object in the OCaml heap. */ CAMLexport value caml_ba_alloc(int flags, int num_dims, void * data, intnat * dim) { uintnat num_elts, asize, size; int overflow, i; value res; struct caml_ba_array * b; intnat dimcopy[CAML_BA_MAX_NUM_DIMS]; #if defined(__FreeBSD__) && defined(_KERNEL) struct caml_ba_proxy *proxy; #endif Assert(num_dims >= 1 && num_dims <= CAML_BA_MAX_NUM_DIMS); Assert((flags & CAML_BA_KIND_MASK) <= CAML_BA_COMPLEX64); for (i = 0; i < num_dims; i++) dimcopy[i] = dim[i]; size = 0; if (data == NULL) { overflow = 0; num_elts = 1; for (i = 0; i < num_dims; i++) { num_elts = caml_ba_multov(num_elts, dimcopy[i], &overflow); } size = caml_ba_multov(num_elts, caml_ba_element_size[flags & CAML_BA_KIND_MASK], &overflow); if (overflow) caml_raise_out_of_memory(); data = __malloc(size); if (data == NULL && size != 0) caml_raise_out_of_memory(); flags |= CAML_BA_MANAGED; } asize = SIZEOF_BA_ARRAY + num_dims * sizeof(intnat); res = caml_alloc_custom(&caml_ba_ops, asize, size, CAML_BA_MAX_MEMORY); b = Caml_ba_array_val(res); #if defined(__FreeBSD__) && defined(_KERNEL) if ((flags & CAML_BA_MANAGED_MASK) != CAML_BA_MANAGED) { b->proxy = __malloc(sizeof(struct caml_ba_proxy)); if (b->proxy == NULL) caml_raise_out_of_memory(); proxy = b->proxy; for (proxy->size = 0, i = 0; i < num_dims; i++) proxy->size += dim[i]; proxy->refcount = 1; if ((flags & CAML_BA_MANAGED_MASK) == CAML_BA_FBSD_MBUF) { proxy->type = CAML_FREEBSD_MBUF; proxy->data = data; b->data = mtod((struct mbuf *) proxy->data, void *); }
/* [caml_ba_alloc] will allocate a new bigarray object in the heap. If [data] is NULL, the memory for the contents is also allocated (with [malloc]) by [caml_ba_alloc]. [data] cannot point into the OCaml heap. [dim] may point into an object in the OCaml heap. */ CAMLexport value caml_ba_alloc(int flags, int num_dims, void * data, intnat * dim) { uintnat num_elts, asize, size; int overflow, i; value res; struct caml_ba_array * b; intnat dimcopy[CAML_BA_MAX_NUM_DIMS]; Assert(num_dims >= 1 && num_dims <= CAML_BA_MAX_NUM_DIMS); Assert((flags & CAML_BA_KIND_MASK) <= CAML_BA_COMPLEX64); for (i = 0; i < num_dims; i++) dimcopy[i] = dim[i]; size = 0; if (data == NULL) { overflow = 0; num_elts = 1; for (i = 0; i < num_dims; i++) { num_elts = caml_ba_multov(num_elts, dimcopy[i], &overflow); } size = caml_ba_multov(num_elts, caml_ba_element_size[flags & CAML_BA_KIND_MASK], &overflow); if (overflow) caml_raise_out_of_memory(); data = malloc(size); if (data == NULL && size != 0) caml_raise_out_of_memory(); flags |= CAML_BA_MANAGED; } /* PR#5516: use C99's flexible array types if possible */ #if (__STDC_VERSION__ >= 199901L) asize = sizeof(struct caml_ba_array) + num_dims * sizeof(intnat); #else asize = sizeof(struct caml_ba_array) + (num_dims - 1) * sizeof(intnat); #endif res = caml_alloc_custom(&caml_ba_ops, asize, size, CAML_BA_MAX_MEMORY); b = Caml_ba_array_val(res); b->data = data; b->num_dims = num_dims; b->flags = flags; b->proxy = NULL; for (i = 0; i < num_dims; i++) b->dim[i] = dimcopy[i]; return res; }