static void caml_ba_serialize(value v, uintnat * wsize_32, uintnat * wsize_64) { struct caml_ba_array * b = Caml_ba_array_val(v); intnat num_elts; int i; /* Serialize header information */ caml_serialize_int_4(b->num_dims); caml_serialize_int_4(b->flags & (CAML_BA_KIND_MASK | CAML_BA_LAYOUT_MASK)); /* On a 64-bit machine, if any of the dimensions is >= 2^32, the size of the marshaled data will be >= 2^32 and extern_value() will fail. So, it is safe to write the dimensions as 32-bit unsigned integers. */ for (i = 0; i < b->num_dims; i++) caml_serialize_int_4(b->dim[i]); /* Compute total number of elements */ num_elts = 1; for (i = 0; i < b->num_dims; i++) num_elts = num_elts * b->dim[i]; /* Serialize elements */ switch (b->flags & CAML_BA_KIND_MASK) { case CAML_BA_SINT8: case CAML_BA_UINT8: caml_serialize_block_1(b->data, num_elts); break; case CAML_BA_SINT16: case CAML_BA_UINT16: caml_serialize_block_2(b->data, num_elts); break; #ifdef _KERNEL #else case CAML_BA_FLOAT32: #endif case CAML_BA_INT32: caml_serialize_block_4(b->data, num_elts); break; #ifdef _KERNEL #else case CAML_BA_COMPLEX32: caml_serialize_block_4(b->data, num_elts * 2); break; case CAML_BA_FLOAT64: case CAML_BA_INT64: caml_serialize_block_8(b->data, num_elts); break; case CAML_BA_COMPLEX64: caml_serialize_block_8(b->data, num_elts * 2); break; #endif case CAML_BA_CAML_INT: caml_ba_serialize_longarray(b->data, num_elts, -0x40000000, 0x3FFFFFFF); break; case CAML_BA_NATIVE_INT: caml_ba_serialize_longarray(b->data, num_elts, -0x80000000, 0x7FFFFFFF); break; } /* Compute required size in Caml heap. Assumes struct caml_ba_array is exactly 4 + num_dims words */ Assert(sizeof(struct caml_ba_array) == 5 * sizeof(value)); *wsize_32 = (4 + b->num_dims) * 4; *wsize_64 = (4 + b->num_dims) * 8; }
static void caml_ba_serialize_longarray(void * data, intnat num_elts, intnat min_val, intnat max_val) { #ifdef ARCH_SIXTYFOUR int overflow_32 = 0; intnat * p, n; for (n = 0, p = data; n < num_elts; n++, p++) { if (*p < min_val || *p > max_val) { overflow_32 = 1; break; } } if (overflow_32) { caml_serialize_int_1(1); caml_serialize_block_8(data, num_elts); } else { caml_serialize_int_1(0); for (n = 0, p = data; n < num_elts; n++, p++) caml_serialize_int_4((int32) *p); } #else caml_serialize_int_1(0); caml_serialize_block_4(data, num_elts); #endif }