JL_DLLEXPORT void jl_arrayunset(jl_array_t *a, size_t i) { if (i >= jl_array_len(a)) jl_bounds_error_int((jl_value_t*)a, i+1); char *ptail = (char*)a->data + i*a->elsize; if (a->flags.ptrarray) memset(ptail, 0, a->elsize); }
JL_DLLEXPORT void jl_array_del_end(jl_array_t *a, size_t dec) { size_t n = jl_array_nrows(a); if (__unlikely(n < dec)) jl_bounds_error_int((jl_value_t*)a, 0); if (__unlikely(a->flags.isshared)) array_try_unshare(a); jl_array_del_at_end(a, n - dec, dec, n); }
JL_DLLEXPORT void jl_array_del_at(jl_array_t *a, ssize_t idx, size_t dec) { size_t n = jl_array_nrows(a); size_t last = idx + dec; if (__unlikely(idx < 0)) jl_bounds_error_int((jl_value_t*)a, idx + 1); if (__unlikely(last > n)) jl_bounds_error_int((jl_value_t*)a, last); // The unsharing needs to happen before we modify the buffer if (__unlikely(a->flags.isshared)) array_try_unshare(a); if (idx < n - last) { jl_array_del_at_beg(a, idx, dec, n); } else { jl_array_del_at_end(a, idx, dec, n); } }
JL_DLLEXPORT void jl_array_grow_at(jl_array_t *a, ssize_t idx, size_t inc) { // No need to explicitly unshare. // Shared arrays are guaranteed to trigger the slow path for growing. size_t n = jl_array_nrows(a); if (idx < 0 || idx > n) jl_bounds_error_int((jl_value_t*)a, idx + 1); if (idx + 1 < n / 2) { jl_array_grow_at_beg(a, idx, inc, n); } else { jl_array_grow_at_end(a, idx, inc, n); } }
JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); if (i >= jl_datatype_nfields(st)) jl_bounds_error_int(v, i+1); size_t offs = jl_field_offset(st,i); if (jl_field_isptr(st,i)) { jl_value_t *fval = *(jl_value_t**)((char*)v + offs); if (fval == NULL) jl_throw(jl_undefref_exception); return fval; } return jl_new_bits(jl_field_type(st,i), (char*)v + offs); }
void jl_array_del_end(jl_array_t *a, size_t dec) { if (dec == 0) return; if (dec > a->nrows) jl_bounds_error_int((jl_value_t*)a, a->nrows - dec); if (a->isshared) array_try_unshare(a); if (a->elsize > 0) { char *ptail = (char*)a->data + (a->nrows-dec)*a->elsize; assert(ptail < (char*)a->data + (a->length*a->elsize)); if (a->ptrarray) memset(ptail, 0, dec*a->elsize); else ptail[0] = 0; } #ifdef STORE_ARRAY_LEN a->length -= dec; #endif a->nrows -= dec; }
JL_DLLEXPORT jl_value_t *jl_get_nth_field_checked(jl_value_t *v, size_t i) { jl_datatype_t *st = (jl_datatype_t*)jl_typeof(v); if (i >= jl_datatype_nfields(st)) jl_bounds_error_int(v, i + 1); size_t offs = jl_field_offset(st, i); if (jl_field_isptr(st, i)) { jl_value_t *fval = *(jl_value_t**)((char*)v + offs); if (fval == NULL) jl_throw(jl_undefref_exception); return fval; } jl_value_t *ty = jl_field_type(st, i); if (jl_is_uniontype(ty)) { size_t fsz = jl_field_size(st, i); uint8_t sel = ((uint8_t*)v)[offs + fsz - 1]; ty = jl_nth_union_component(ty, sel); if (jl_is_datatype_singleton((jl_datatype_t*)ty)) return ((jl_datatype_t*)ty)->instance; } return jl_new_bits(ty, (char*)v + offs); }
void jl_array_del_beg(jl_array_t *a, size_t dec) { if (dec == 0) return; if (dec > a->nrows) jl_bounds_error_int((jl_value_t*)a, dec); if (a->isshared) array_try_unshare(a); size_t es = a->elsize; size_t nb = dec*es; memset(a->data, 0, nb); size_t offset = a->offset; offset += dec; a->data = (char*)a->data + nb; #ifdef STORE_ARRAY_LEN a->length -= dec; #endif a->nrows -= dec; // make sure offset doesn't grow forever due to deleting at beginning // and growing at end size_t newoffs = offset; if (offset >= 13*a->maxsize/20) { newoffs = 17*(a->maxsize - a->nrows)/100; } #ifdef _P64 while (newoffs > (size_t)((uint32_t)-1)) { newoffs = newoffs/2; } #endif if (newoffs != offset) { size_t anb = a->nrows*es; size_t delta = (offset - newoffs)*es; a->data = (char*)a->data - delta; memmove(a->data, (char*)a->data + delta, anb); } a->offset = newoffs; }
JL_DLLEXPORT void JL_NORETURN jl_bounds_error_tuple_int(jl_value_t **v, size_t nv, size_t i) { // values in v are expected to already be gc-rooted jl_bounds_error_int(jl_f_tuple(NULL, v, nv), i); }
JL_DLLEXPORT size_t jl_get_field_offset(jl_datatype_t *ty, int field) { if (ty->layout == NULL || field > jl_datatype_nfields(ty) || field < 1) jl_bounds_error_int((jl_value_t*)ty, field); return jl_field_offset(ty, field - 1); }