summaryrefslogtreecommitdiff
path: root/otherlibs/bigarray/bigarray_stubs.c
diff options
context:
space:
mode:
Diffstat (limited to 'otherlibs/bigarray/bigarray_stubs.c')
-rw-r--r--otherlibs/bigarray/bigarray_stubs.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/otherlibs/bigarray/bigarray_stubs.c b/otherlibs/bigarray/bigarray_stubs.c
index 8afdc0df6e..4021b74aee 100644
--- a/otherlibs/bigarray/bigarray_stubs.c
+++ b/otherlibs/bigarray/bigarray_stubs.c
@@ -160,8 +160,8 @@ caml_ba_alloc(int flags, int num_dims, void * data, intnat * dim)
if (data == NULL && size != 0) caml_raise_out_of_memory();
flags |= CAML_BA_MANAGED;
}
- /* PR#5516: use C99's / gcc's flexible array types if possible */
-#if (__STDC_VERSION__ >= 199901L) || defined(__GNUC__)
+ /* 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);
@@ -496,18 +496,19 @@ CAMLprim value caml_ba_layout(value vb)
return Val_int(Caml_ba_array_val(vb)->flags & CAML_BA_LAYOUT_MASK);
}
-/* Finalization of a big array */
+/* Finalization / release of a big array */
static void caml_ba_finalize(value v)
{
struct caml_ba_array * b = Caml_ba_array_val(v);
+ intnat i;
switch (b->flags & CAML_BA_MANAGED_MASK) {
case CAML_BA_EXTERNAL:
break;
case CAML_BA_MANAGED:
if (b->proxy == NULL) {
- free(b->data);
+ free(b->data); /* no op if b->data = NULL */
} else {
if (-- b->proxy->refcount == 0) {
free(b->proxy->data);
@@ -526,6 +527,17 @@ static void caml_ba_finalize(value v)
}
break;
}
+ /* Make sure that subsequent accesses to the bigarray fail (empty bounds)
+ and that subsequent calls to caml_ba_finalize do nothing. */
+ for (i = 0; i < b->num_dims; i++) b->dim[i] = 0;
+ b->data = NULL;
+ b->proxy = NULL;
+}
+
+CAMLprim value caml_ba_release(value v)
+{
+ caml_ba_finalize(v);
+ return Val_unit;
}
/* Comparison of two big arrays */