endmethod // --- alloc struct Array* Array_alloc(U32 size) { enum { N = 10 }; static struct Class* cls[] = { classref(Array0, Array1, Array2, Array3, Array4, Array5, Array6, Array7, Array8, Array9, ArrayN) }; size_t extra = size * sizeof(OBJ); // check for overflow if (extra/sizeof(OBJ) < size) THROW(gnewWithStr(ExOverflow, "size is too large")); OBJ _cls = (OBJ)cls[size > N ? N : size]; OBJ _arr = gallocWithSize(_cls, extra); struct ArrayN *arrn = CAST(struct ArrayN*, _arr); struct Array *arr = &arrn->ArrayBlk.Array; arr->object = arrn->_object; arr->size = 0; arr->stride = 1; return arr; }
endmethod // ----- U32 Sequence_enlargeCapacity(U32 capacity, U32 extra) { U32 size = capacity + extra; U32 last = U32_MAX/SEQUENCE_GROWTH_RATE; // overflow if (capacity > U32_MAX-extra) THROW(gnewWithStr(ExOverflow, "extra size is too large")); // starting point if (capacity < SEQUENCE_MIN_SIZE) capacity = SEQUENCE_MIN_SIZE; // growth rate while (capacity < size && capacity <= last) capacity *= SEQUENCE_GROWTH_RATE; // round last growth if (capacity < size) capacity = size; return capacity; }
endmethod // ----- allocator struct String* String_alloc(U32 size) { useclass(StringN); if (size == U32_MAX) THROW(gnewWithStr(ExOverflow, "size is too large")); OBJ _str = gallocWithSize(StringN, size+1); struct StringN *strn = CAST(struct StringN*, _str); struct String *str = &strn->String; str->value = strn->_value; str->size = 0; return str; }