Add a function for computing the pointer to a row-major-aref item.

This is necessary for open-coding the actual array access, while
keeping the array object type and index bound check. The array
element type is not checked; instead the function ensures that the
specified number of bytes at the returned ptr are within bounds.
This commit is contained in:
Alexander Gavrilov 2010-08-08 14:39:10 +04:00 committed by Juan Jose Garcia Ripoll
parent dcf08cd6c0
commit 7c7a40e4bd
2 changed files with 31 additions and 0 deletions

View file

@ -231,6 +231,33 @@ ecl_aref1(cl_object x, cl_index index)
return ecl_aref_unsafe(x, index);
}
void *
ecl_row_major_ptr(cl_object x, cl_index index, cl_index bytes)
{
cl_index idx, elt_size, offset;
cl_elttype elt_type;
if (ecl_unlikely(!ECL_ARRAYP(x))) {
FEwrong_type_nth_arg(@[aref], 1, x, @[array]);
}
elt_type = x->array.elttype;
if (ecl_unlikely(elt_type == aet_bit || elt_type == aet_object))
FEerror("In ecl_row_major_ptr: Specialized array expected, element type ~S found.",
1,ecl_elttype_to_symbol(elt_type));
elt_size = ecl_aet_size[elt_type];
offset = index*elt_size;
/* don't check bounds if bytes == 0 */
if (ecl_unlikely(bytes > 0 && offset + bytes > x->array.dim*elt_size)) {
FEwrong_index(@[row-major-aref], x, -1, MAKE_FIXNUM(index),
x->array.dim);
}
return x->array.self.b8 + offset;
}
/*
Internal function for setting array elements:

View file

@ -324,6 +324,10 @@ extern ECL_API cl_object APPLY(cl_narg n, cl_objectfn, cl_object *x);
extern ECL_API cl_object cl_row_major_aref(cl_object x, cl_object i);
extern ECL_API cl_object si_row_major_aset(cl_object x, cl_object i, cl_object v);
extern ECL_API cl_object si_make_vector(cl_object etype, cl_object dim, cl_object adj, cl_object fillp, cl_object displ, cl_object disploff);
/* for open-coding the access while preserving the bounds and type check: */
extern ECL_API void *ecl_row_major_ptr(cl_object arr, cl_index index, cl_index bytes);
extern ECL_API cl_object cl_array_element_type(cl_object a);
extern ECL_API cl_object cl_array_rank(cl_object a);
extern ECL_API cl_object cl_array_dimension(cl_object a, cl_object index);