]> gitweb.factorcode.org Git - factor.git/blob - vm/generic_arrays.hpp
VM: Refactor generic_arrays.hpp to Factor style
[factor.git] / vm / generic_arrays.hpp
1 namespace factor {
2
3 template <typename Array> cell array_capacity(const Array* array) {
4 #ifdef FACTOR_DEBUG
5   FACTOR_ASSERT(array->type() == Array::type_number);
6 #endif
7   return array->capacity >> TAG_BITS;
8 }
9
10 template <typename Array> cell array_size(cell capacity) {
11   return sizeof(Array) + capacity * Array::element_size;
12 }
13
14 template <typename Array> cell array_size(Array* array) {
15   return array_size<Array>(array_capacity(array));
16 }
17
18 /* Allocates memory */
19 template <typename Array>
20 Array* factor_vm::allot_uninitialized_array(cell capacity) {
21   Array* array = allot<Array>(array_size<Array>(capacity));
22   array->capacity = tag_fixnum(capacity);
23   return array;
24 }
25
26 template <typename Array>
27 bool factor_vm::reallot_array_in_place_p(Array* array, cell capacity) {
28   return nursery.contains_p(array) && capacity <= array_capacity(array);
29 }
30
31 /* Allocates memory (sometimes) */
32 template <typename Array>
33 Array* factor_vm::reallot_array(Array* array_, cell capacity) {
34   data_root<Array> array(array_, this);
35
36   if (array_capacity(array.untagged()) == capacity)
37     return array.untagged();
38
39   if (reallot_array_in_place_p(array.untagged(), capacity)) {
40     array->capacity = tag_fixnum(capacity);
41     return array.untagged();
42   } else {
43     cell to_copy = array_capacity(array.untagged());
44     if (capacity < to_copy)
45       to_copy = capacity;
46
47     Array* new_array = allot_uninitialized_array<Array>(capacity);
48
49     memcpy(new_array + 1, array.untagged() + 1, to_copy * Array::element_size);
50     memset((char*)(new_array + 1) + to_copy * Array::element_size, 0,
51            (capacity - to_copy) * Array::element_size);
52
53     return new_array;
54   }
55 }
56
57 }