diff --git a/include/deemon/alloc.h b/include/deemon/alloc.h index 2f6dd8cd4..5a6dab638 100644 --- a/include/deemon/alloc.h +++ b/include/deemon/alloc.h @@ -219,6 +219,7 @@ DFUNDEF ATTR_COLD bool DCALL Dee_TryCollectMemory(size_t req_bytes); /* Same as `Dee_TryCollectMemory()', but raise an * `Error.NoMemory' if memory could not be collected. */ DFUNDEF WUNUSED ATTR_COLD bool DCALL Dee_CollectMemory(size_t req_bytes); +#define Dee_CollectMemoryc(elem_count, elem_size) Dee_CollectMemory((elem_count) * (elem_size)) /* Throw a bad-allocation error for `req_bytes' bytes. * @return: -1: Always returns -1. */ diff --git a/include/deemon/cxx/object.h b/include/deemon/cxx/object.h index 2bc46c148..5582bd5b0 100644 --- a/include/deemon/cxx/object.h +++ b/include/deemon/cxx/object.h @@ -2131,10 +2131,10 @@ class RangeProxyObjBase { class RangeProxyIdxObjBase { private: DeeObject *m_ptr; - size_t m_bgn; + Dee_ssize_t m_bgn; DeeObject *m_end; public: - RangeProxyIdxObjBase(DeeObject *ptr, size_t bgn, DeeObject *end) DEE_CXX_NOTHROW + RangeProxyIdxObjBase(DeeObject *ptr, Dee_ssize_t bgn, DeeObject *end) DEE_CXX_NOTHROW : m_ptr(ptr) , m_bgn(bgn) , m_end(end) {} @@ -2149,12 +2149,7 @@ class RangeProxyIdxObjBase { return DeeObject_SetRangeBeginIndex(m_ptr, m_bgn, m_end, value); } void del() const { - int error; - DREF DeeObject *begin_ob; - begin_ob = throw_if_null(DeeInt_NewSize(m_bgn)); - error = DeeObject_DelRange(m_ptr, begin_ob, m_end); - Dee_Decref(begin_ob); - throw_if_nonzero(error); + throw_if_nonzero(DeeObject_DelRangeBeginIndex(m_ptr, m_bgn, m_end)); } }; @@ -2162,9 +2157,9 @@ class RangeProxyObjIdxBase { private: DeeObject *m_ptr; DeeObject *m_bgn; - size_t m_end; + Dee_ssize_t m_end; public: - RangeProxyObjIdxBase(DeeObject *ptr, DeeObject *bgn, size_t end) DEE_CXX_NOTHROW + RangeProxyObjIdxBase(DeeObject *ptr, DeeObject *bgn, Dee_ssize_t end) DEE_CXX_NOTHROW : m_ptr(ptr) , m_bgn(bgn) , m_end(end) {} @@ -2179,22 +2174,17 @@ class RangeProxyObjIdxBase { return DeeObject_SetRangeEndIndex(m_ptr, m_bgn, m_end, value); } void del() const { - int error; - DREF DeeObject *end_ob; - end_ob = throw_if_null(DeeInt_NewSize(m_end)); - error = DeeObject_DelRange(m_ptr, m_bgn, end_ob); - Dee_Decref(end_ob); - throw_if_nonzero(error); + throw_if_nonzero(DeeObject_DelRangeEndIndex(m_ptr, m_bgn, m_end)); } }; class RangeProxyIdxBase { private: DeeObject *m_ptr; - size_t m_bgn; - size_t m_end; + Dee_ssize_t m_bgn; + Dee_ssize_t m_end; public: - RangeProxyIdxBase(DeeObject *ptr, size_t bgn, size_t end) DEE_CXX_NOTHROW + RangeProxyIdxBase(DeeObject *ptr, Dee_ssize_t bgn, Dee_ssize_t end) DEE_CXX_NOTHROW : m_ptr(ptr) , m_bgn(bgn) , m_end(end) {} @@ -2209,18 +2199,7 @@ class RangeProxyIdxBase { return DeeObject_SetRangeIndex(m_ptr, m_bgn, m_end, value); } void del() const { - int error; - DREF DeeObject *begin_ob, *end_ob; - begin_ob = throw_if_null(DeeInt_NewSize(m_bgn)); - end_ob = DeeInt_NewSize(m_end); - if unlikely(!end_ob) { - Dee_Decref(begin_ob); - throw_last_deemon_exception(); - } - error = DeeObject_DelRange(m_ptr, begin_ob, end_ob); - Dee_Decref(end_ob); - Dee_Decref(begin_ob); - throw_if_nonzero(error); + throw_if_nonzero(DeeObject_DelRangeIndex(m_ptr, m_bgn, m_end)); } }; @@ -2244,7 +2223,7 @@ class RangeProxyIdxObj { public: using ConstGetAndSetRefProxyWithDefault, RangeSeqType>::operator=; - RangeProxyIdxObj(DeeObject *ptr, size_t bgn, DeeObject *end) DEE_CXX_NOTHROW + RangeProxyIdxObj(DeeObject *ptr, Dee_ssize_t bgn, DeeObject *end) DEE_CXX_NOTHROW : RangeProxyIdxObjBase(ptr, bgn, end) {} RangeProxyIdxObj(RangeProxyIdxObj const &right) DEE_CXX_NOTHROW : RangeProxyIdxObjBase(static_cast(right)) {} @@ -2257,7 +2236,7 @@ class RangeProxyObjIdx { public: using ConstGetAndSetRefProxyWithDefault, RangeSeqType>::operator=; - RangeProxyObjIdx(DeeObject *ptr, DeeObject *bgn, size_t end) DEE_CXX_NOTHROW + RangeProxyObjIdx(DeeObject *ptr, DeeObject *bgn, Dee_ssize_t end) DEE_CXX_NOTHROW : RangeProxyObjIdxBase(ptr, bgn, end) {} RangeProxyObjIdx(RangeProxyObjIdx const &right) DEE_CXX_NOTHROW : RangeProxyObjIdxBase(static_cast(right)) {} @@ -2270,7 +2249,7 @@ class RangeProxyIdx { public: using ConstGetAndSetRefProxyWithDefault, RangeSeqType>::operator=; - RangeProxyIdx(DeeObject *ptr, size_t bgn, size_t end) DEE_CXX_NOTHROW + RangeProxyIdx(DeeObject *ptr, Dee_ssize_t bgn, Dee_ssize_t end) DEE_CXX_NOTHROW : RangeProxyIdxBase(ptr, bgn, end) {} RangeProxyIdx(RangeProxyIdx const &right) DEE_CXX_NOTHROW : RangeProxyIdxBase(static_cast(right)) {} @@ -2648,73 +2627,52 @@ class RangeProxyAccessor { NONNULL_CXX((1, 2)) RangeProxyObj range(DeeObject *begin, DeeObject *end) { return RangeProxyObj(((ProxyType *)this)->ptr(), begin, end); } - NONNULL_CXX((1)) RangeProxyObjIdx range(DeeObject *begin, size_t end) { + NONNULL_CXX((1)) RangeProxyObjIdx range(DeeObject *begin, Dee_ssize_t end) { return RangeProxyObjIdx(((ProxyType *)this)->ptr(), begin, end); } - NONNULL_CXX((2)) RangeProxyIdxObj range(size_t begin, DeeObject *end) { + NONNULL_CXX((2)) RangeProxyIdxObj range(Dee_ssize_t begin, DeeObject *end) { return RangeProxyIdxObj(((ProxyType *)this)->ptr(), begin, end); } - RangeProxyIdx range(size_t begin, size_t end) { + RangeProxyIdx range(Dee_ssize_t begin, Dee_ssize_t end) { return RangeProxyIdx(((ProxyType *)this)->ptr(), begin, end); } NONNULL_CXX((1, 2)) Ref getrange(DeeObject *begin, DeeObject *end) { return inherit(DeeObject_GetRange(((ProxyType *)this)->ptr(), begin, end)); } - NONNULL_CXX((1)) Ref getrange(DeeObject *begin, size_t end) { + NONNULL_CXX((1)) Ref getrange(DeeObject *begin, Dee_ssize_t end) { return inherit(DeeObject_GetRangeEndIndex(((ProxyType *)this)->ptr(), begin, end)); } - NONNULL_CXX((2)) Ref getrange(size_t begin, DeeObject *end) { + NONNULL_CXX((2)) Ref getrange(Dee_ssize_t begin, DeeObject *end) { return inherit(DeeObject_GetRangeBeginIndex(((ProxyType *)this)->ptr(), begin, end)); } - Ref getrange(size_t begin, size_t end) { + Ref getrange(Dee_ssize_t begin, Dee_ssize_t end) { return inherit(DeeObject_GetRangeIndex(((ProxyType *)this)->ptr(), begin, end)); } NONNULL_CXX((1, 2)) void delrange(DeeObject *begin, DeeObject *end) { throw_if_nonzero(DeeObject_DelRange(((ProxyType *)this)->ptr(), begin, end)); } - NONNULL_CXX((1)) void delrange(DeeObject *begin, size_t end) { - int error; - DREF DeeObject *end_ob; - end_ob = throw_if_null(DeeInt_NewSize(end)); - error = DeeObject_DelRange(((ProxyType *)this)->ptr(), begin, end_ob); - Dee_Decref(end_ob); - throw_if_nonzero(error); + NONNULL_CXX((1)) void delrange(DeeObject *begin, Dee_ssize_t end) { + throw_if_nonzero(DeeObject_DelRangeEndIndex(((ProxyType *)this)->ptr(), begin, end)); } - NONNULL_CXX((2)) void delrange(size_t begin, DeeObject *end) { - int error; - DREF DeeObject *begin_ob; - begin_ob = throw_if_null(DeeInt_NewSize(begin)); - error = DeeObject_DelRange(((ProxyType *)this)->ptr(), begin_ob, end); - Dee_Decref(begin_ob); - throw_if_nonzero(error); + NONNULL_CXX((2)) void delrange(Dee_ssize_t begin, DeeObject *end) { + throw_if_nonzero(DeeObject_DelRangeBeginIndex(((ProxyType *)this)->ptr(), begin, end)); } - void delrange(size_t begin, size_t end) { - int error; - DREF DeeObject *begin_ob, *end_ob; - begin_ob = throw_if_null(DeeInt_NewSize(begin)); - end_ob = DeeInt_NewSize(end); - if unlikely(!end_ob) { - Dee_Decref(begin_ob); - throw_last_deemon_exception(); - } - error = DeeObject_DelRange(((ProxyType *)this)->ptr(), begin_ob, end_ob); - Dee_Decref(end_ob); - Dee_Decref(begin_ob); - throw_if_nonzero(error); + void delrange(Dee_ssize_t begin, Dee_ssize_t end) { + throw_if_nonzero(DeeObject_DelRangeIndex(((ProxyType *)this)->ptr(), begin, end)); } NONNULL_CXX((1, 2, 3)) void setrange(DeeObject *begin, DeeObject *end, DeeObject *value) { return inherit(DeeObject_SetRange(((ProxyType *)this)->ptr(), begin, end, value)); } - NONNULL_CXX((1, 3)) void setrange(DeeObject *begin, size_t end, DeeObject *value) { + NONNULL_CXX((1, 3)) void setrange(DeeObject *begin, Dee_ssize_t end, DeeObject *value) { return inherit(DeeObject_SetRangeEndIndex(((ProxyType *)this)->ptr(), begin, end, value)); } - NONNULL_CXX((2, 3)) void setrange(size_t begin, DeeObject *end, DeeObject *value) { + NONNULL_CXX((2, 3)) void setrange(Dee_ssize_t begin, DeeObject *end, DeeObject *value) { return inherit(DeeObject_SetRangeBeginIndex(((ProxyType *)this)->ptr(), begin, end, value)); } - NONNULL_CXX((3)) void setrange(size_t begin, size_t end, DeeObject *value) { + NONNULL_CXX((3)) void setrange(Dee_ssize_t begin, Dee_ssize_t end, DeeObject *value) { return inherit(DeeObject_SetRangeIndex(((ProxyType *)this)->ptr(), begin, end, value)); } }; diff --git a/include/deemon/object.h b/include/deemon/object.h index e17ca973f..2950b3b6d 100644 --- a/include/deemon/object.h +++ b/include/deemon/object.h @@ -3364,10 +3364,13 @@ DFUNDEF WUNUSED NONNULL((1, 3)) DREF DeeObject *(DCALL DeeObject_GetRangeBeginIn DFUNDEF WUNUSED NONNULL((1, 2)) DREF DeeObject *(DCALL DeeObject_GetRangeEndIndex)(DeeObject *self, DeeObject *begin, Dee_ssize_t end); DFUNDEF WUNUSED NONNULL((1)) DREF DeeObject *(DCALL DeeObject_GetRangeIndex)(DeeObject *__restrict self, Dee_ssize_t begin, Dee_ssize_t end); DFUNDEF WUNUSED NONNULL((1, 2, 3)) int (DCALL DeeObject_DelRange)(DeeObject *self, DeeObject *begin, DeeObject *end); -DFUNDEF WUNUSED NONNULL((1, 2, 3, 4)) int (DCALL DeeObject_SetRange)(DeeObject *self, DeeObject *begin, DeeObject *end, DeeObject *value); -DFUNDEF WUNUSED NONNULL((1, 3, 4)) int (DCALL DeeObject_SetRangeBeginIndex)(DeeObject *self, Dee_ssize_t begin, DeeObject *end, DeeObject *value); -DFUNDEF WUNUSED NONNULL((1, 2, 4)) int (DCALL DeeObject_SetRangeEndIndex)(DeeObject *self, DeeObject *begin, Dee_ssize_t end, DeeObject *value); -DFUNDEF WUNUSED NONNULL((1, 4)) int (DCALL DeeObject_SetRangeIndex)(DeeObject *self, Dee_ssize_t begin, Dee_ssize_t end, DeeObject *value); +DFUNDEF WUNUSED NONNULL((1, 3)) int (DCALL DeeObject_DelRangeBeginIndex)(DeeObject *self, Dee_ssize_t begin, DeeObject *end); +DFUNDEF WUNUSED NONNULL((1, 2)) int (DCALL DeeObject_DelRangeEndIndex)(DeeObject *self, DeeObject *begin, Dee_ssize_t end); +DFUNDEF WUNUSED NONNULL((1)) int (DCALL DeeObject_DelRangeIndex)(DeeObject *self, Dee_ssize_t begin, Dee_ssize_t end); +DFUNDEF WUNUSED NONNULL((1, 2, 3, 4)) int (DCALL DeeObject_SetRange)(DeeObject *self, DeeObject *begin, DeeObject *end, DeeObject *values); +DFUNDEF WUNUSED NONNULL((1, 3, 4)) int (DCALL DeeObject_SetRangeBeginIndex)(DeeObject *self, Dee_ssize_t begin, DeeObject *end, DeeObject *values); +DFUNDEF WUNUSED NONNULL((1, 2, 4)) int (DCALL DeeObject_SetRangeEndIndex)(DeeObject *self, DeeObject *begin, Dee_ssize_t end, DeeObject *values); +DFUNDEF WUNUSED NONNULL((1, 4)) int (DCALL DeeObject_SetRangeIndex)(DeeObject *self, Dee_ssize_t begin, Dee_ssize_t end, DeeObject *values); #define DeeObject_GetItemString(self, key) DeeObject_GetItemStringHash(self, key, Dee_HashStr(key)) #define DeeObject_GetItemStringLen(self, key, keylen) DeeObject_GetItemStringLenHash(self, key, keylen, Dee_HashPtr(key, keylen)) #define DeeObject_GetItemStringDef(self, key, def) DeeObject_GetItemStringHashDef(self, key, Dee_HashStr(key), def) diff --git a/include/deemon/seq.h b/include/deemon/seq.h index 1851714c4..07d6c0d76 100644 --- a/include/deemon/seq.h +++ b/include/deemon/seq.h @@ -348,7 +348,7 @@ struct Dee_type_nsi { __UINTPTR_HALF_TYPE__ nsi_class; /* Sequence class (One of `TYPE_SEQX_CLASS_*') */ __UINTPTR_HALF_TYPE__ nsi_flags; /* Sequence flags (Set of `TYPE_SEQX_F*') */ union { - Dee_funptr_t _nsi_class_functions[22]; + Dee_funptr_t _nsi_class_functions[24]; struct { /* [1..1] ERROR: (size_t)-1 */ @@ -383,6 +383,8 @@ struct Dee_type_nsi { WUNUSED_T NONNULL_T((1)) DREF DeeObject *(DCALL *nsi_getrange)(DeeObject *__restrict self, Dee_ssize_t start, Dee_ssize_t end); WUNUSED_T NONNULL_T((1)) DREF DeeObject *(DCALL *nsi_getrange_n)(DeeObject *__restrict self, Dee_ssize_t start); /* end: Dee_None */ + WUNUSED_T NONNULL_T((1)) int (DCALL *nsi_delrange)(DeeObject *self, Dee_ssize_t start, Dee_ssize_t end); + WUNUSED_T NONNULL_T((1)) int (DCALL *nsi_delrange_n)(DeeObject *self, Dee_ssize_t start); /* end: Dee_None */ WUNUSED_T NONNULL_T((1, 4)) int (DCALL *nsi_setrange)(DeeObject *self, Dee_ssize_t start, Dee_ssize_t end, DeeObject *values); WUNUSED_T NONNULL_T((1, 3)) int (DCALL *nsi_setrange_n)(DeeObject *self, Dee_ssize_t start, DeeObject *values); /* end: Dee_None */ @@ -486,6 +488,55 @@ struct Dee_type_nsi { }; +struct Dee_seq_range { + union { +#undef sr_start +#undef sr_istart + size_t sr_start; /* Start index (clamped) */ + Dee_ssize_t sr_istart; /* Start index (input) */ + } +#ifndef __COMPILER_HAVE_TRANSPARENT_UNION + _dee_aunion_s +#define sr_start _dee_aunion_s.sr_start +#define sr_istart _dee_aunion_s.sr_istart +#endif /* !__COMPILER_HAVE_TRANSPARENT_UNION */ + ; + union { +#undef sr_end +#undef sr_iend + size_t sr_end; /* End index (clamped) */ + Dee_ssize_t sr_iend; /* End index (input) */ + } +#ifndef __COMPILER_HAVE_TRANSPARENT_UNION + _dee_aunion_e +#define sr_end _dee_aunion_e.sr_end +#define sr_iend _dee_aunion_e.sr_iend +#endif /* !__COMPILER_HAVE_TRANSPARENT_UNION */ + ; +}; + + +/* Clamp a range, as given to `operator [:]' & friends to the bounds + * accepted by the associated sequence. This handles stuff like negative + * index over-roll and past-the-end truncation. */ +#define DeeSeqRange_Clamp(prange, istart, iend, size) \ + ((prange)->sr_istart = (istart), \ + (prange)->sr_iend = (iend), \ + _DeeSeqRange_Clamp(prange, size)) +#define _DeeSeqRange_Clamp(prange, size) \ + (void)(((prange)->sr_start <= (prange)->sr_end && \ + (prange)->sr_end <= (size)) || \ + (DeeSeqRange_DoClamp(prange, size), 0)) +DFUNDEF ATTR_INOUT(1) void DCALL +DeeSeqRange_DoClamp(struct Dee_seq_range *__restrict self, + size_t size); + +/* Specialized version of `DeeSeqRange_DoClamp()' for `[istart:none]' range expressions. */ +#define DeeSeqRange_Clamp_n(istart, size) \ + ((size_t)(istart) <= (size) ? (size_t)(istart) : DeeSeqRange_DoClamp_n(istart, size)) +DFUNDEF ATTR_CONST WUNUSED size_t DCALL +DeeSeqRange_DoClamp_n(Dee_ssize_t start, size_t size); + /* Lookup the closest NSI descriptor for `tp', or return `NULL' * if the top-most type implementing any sequence operator doesn't diff --git a/src/deemon/compiler/asm/util.c b/src/deemon/compiler/asm/util.c index 38139a4d5..3591674d3 100644 --- a/src/deemon/compiler/asm/util.c +++ b/src/deemon/compiler/asm/util.c @@ -138,47 +138,38 @@ asm_gpush_s32(int32_t value) { INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL tuple_getrange_i(DeeTupleObject *__restrict self, - dssize_t begin, dssize_t end); + dssize_t i_begin, dssize_t i_end); INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL list_getrange_as_tuple(DeeListObject *__restrict self, - dssize_t begin, dssize_t end) { + dssize_t i_begin, dssize_t i_end) { DREF DeeTupleObject *result; - size_t i; + struct Dee_seq_range range; + size_t range_size; again: DeeList_LockRead(self); - if unlikely(begin < 0) - begin += DeeList_SIZE(self); - if unlikely(end < 0) - end += DeeList_SIZE(self); - if unlikely((size_t)begin >= DeeList_SIZE(self) || - (size_t)begin >= (size_t)end) { + DeeSeqRange_Clamp(&range, i_begin, i_end, DeeList_SIZE(self)); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) { /* Empty list. */ DeeList_LockEndRead(self); - return DeeList_New(); + return_empty_tuple; } - if unlikely((size_t)end > DeeList_SIZE(self)) - end = (dssize_t)DeeList_SIZE(self); - end -= begin; - ASSERT(end != 0); - result = (DREF DeeTupleObject *)DeeObject_TryMalloc(offsetof(DeeTupleObject, t_elem) + - (size_t)end * sizeof(DREF DeeObject *)); + result = (DREF DeeTupleObject *)DeeObject_TryMalloc(DeeTuple_SIZEOF(range_size)); if unlikely(!result) { DeeList_LockEndRead(self); - if (Dee_CollectMemory(offsetof(DeeTupleObject, t_elem) + - (size_t)end * sizeof(DREF DeeObject *))) + if (Dee_CollectMemory(DeeTuple_SIZEOF(range_size))) goto again; goto err; } /* Copy vector elements. */ - for (i = 0; i < (size_t)end; ++i) { - result->t_elem[i] = DeeList_GET(self, (size_t)begin + i); - Dee_Incref(result->t_elem[i]); - } + Dee_Movrefv(DeeTuple_ELEM(result), + DeeList_ELEM(self) + range.sr_start, + range_size); DeeList_LockEndRead(self); DeeObject_Init(result, &DeeTuple_Type); - result->t_size = (size_t)end; + result->t_size = range_size; return (DREF DeeObject *)result; err: return NULL; diff --git a/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def b/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def index fcf256c52..e86655eeb 100644 --- a/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def +++ b/src/deemon/linker-scripts/link-deemon-gcc-i386-cygwin.def @@ -564,6 +564,9 @@ EXPORTS _DeeObject_DelItemStringHash@12=DeeObject_DelItemStringHash@12 _DeeObject_DelItemStringLenHash@16=DeeObject_DelItemStringLenHash@16 _DeeObject_DelRange@12=DeeObject_DelRange@12 + _DeeObject_DelRangeBeginIndex@12=DeeObject_DelRangeBeginIndex@12 + _DeeObject_DelRangeEndIndex@12=DeeObject_DelRangeEndIndex@12 + _DeeObject_DelRangeIndex@12=DeeObject_DelRangeIndex@12 _DeeObject_Destroy@4=DeeObject_Destroy@4 _DeeObject_Destroy_d@12=DeeObject_Destroy_d@12 _DeeObject_Div@8=DeeObject_Div@8 @@ -743,6 +746,8 @@ EXPORTS _DeeRoSet_Insert@8=DeeRoSet_Insert@8 _DeeRoSet_New@0=DeeRoSet_New@0 _DeeRoSet_NewWithHint@4=DeeRoSet_NewWithHint@4 + _DeeSeqRange_DoClamp@8=DeeSeqRange_DoClamp@8 + _DeeSeqRange_DoClamp_n@8=DeeSeqRange_DoClamp_n@8 _DeeSeq_All@4=DeeSeq_All@4 _DeeSeq_Any@4=DeeSeq_Any@4 _DeeSeq_AsHeapVector@8=DeeSeq_AsHeapVector@8 diff --git a/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def b/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def index ef6f0c0ff..0f91632d4 100644 --- a/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def +++ b/src/deemon/linker-scripts/link-deemon-msvc-i386-win32.def @@ -564,6 +564,9 @@ EXPORTS DeeObject_DelItemStringHash@12=_DeeObject_DelItemStringHash@12 DeeObject_DelItemStringLenHash@16=_DeeObject_DelItemStringLenHash@16 DeeObject_DelRange@12=_DeeObject_DelRange@12 + DeeObject_DelRangeBeginIndex@12=_DeeObject_DelRangeBeginIndex@12 + DeeObject_DelRangeEndIndex@12=_DeeObject_DelRangeEndIndex@12 + DeeObject_DelRangeIndex@12=_DeeObject_DelRangeIndex@12 DeeObject_Destroy@4=_DeeObject_Destroy@4 DeeObject_Destroy_d@12=_DeeObject_Destroy_d@12 DeeObject_Div@8=_DeeObject_Div@8 @@ -743,6 +746,8 @@ EXPORTS DeeRoSet_Insert@8=_DeeRoSet_Insert@8 DeeRoSet_New@0=_DeeRoSet_New@0 DeeRoSet_NewWithHint@4=_DeeRoSet_NewWithHint@4 + DeeSeqRange_DoClamp@8=_DeeSeqRange_DoClamp@8 + DeeSeqRange_DoClamp_n@8=_DeeSeqRange_DoClamp_n@8 DeeSeq_All@4=_DeeSeq_All@4 DeeSeq_Any@4=_DeeSeq_Any@4 DeeSeq_AsHeapVector@8=_DeeSeq_AsHeapVector@8 diff --git a/src/deemon/objects/bytes.c b/src/deemon/objects/bytes.c index c07bf249f..30c9b7a6f 100644 --- a/src/deemon/objects/bytes.c +++ b/src/deemon/objects/bytes.c @@ -37,6 +37,7 @@ #include #include +#include #include #include #include @@ -45,6 +46,9 @@ #include "../runtime/runtime_error.h" #include "../runtime/strings.h" +#undef SSIZE_MAX +#define SSIZE_MAX __SSIZE_MAX__ + DECL_BEGIN #undef byte_t @@ -1267,87 +1271,117 @@ bytes_nsi_setitem(Bytes *self, size_t index, DeeObject *value) { } PRIVATE WUNUSED NONNULL((1)) DREF Bytes *DCALL -bytes_nsi_getrange_i(Bytes *__restrict self, - dssize_t start_index, - dssize_t end_index) { - if unlikely(start_index < 0) - start_index += DeeBytes_SIZE(self); - if unlikely(end_index < 0) - end_index += DeeBytes_SIZE(self); - if ((size_t)end_index > DeeBytes_SIZE(self)) - end_index = (dssize_t)DeeBytes_SIZE(self); - if ((size_t)start_index >= (size_t)end_index) +bytes_nsi_getrange(Bytes *__restrict self, + dssize_t i_begin, + dssize_t i_end) { + struct Dee_seq_range range; + size_t range_size; + DeeSeqRange_Clamp(&range, i_begin, i_end, DeeBytes_SIZE(self)); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) return_reference_((Bytes *)Dee_EmptyBytes); - if ((size_t)start_index == 0 && - (size_t)end_index == DeeBytes_SIZE(self)) + if unlikely(range_size == DeeBytes_SIZE(self)) return_reference_(self); return (DREF Bytes *)DeeBytes_NewView(self->b_orig, - self->b_base + (size_t)start_index, - (size_t)(end_index - start_index), + self->b_base + range.sr_start, + range_size, self->b_flags); } PRIVATE WUNUSED NONNULL((1)) DREF Bytes *DCALL -bytes_nsi_getrange_in(Bytes *__restrict self, - dssize_t start_index) { - if unlikely(start_index < 0) - start_index += DeeBytes_SIZE(self); - if ((size_t)start_index >= DeeBytes_SIZE(self)) - return_reference_((Bytes *)Dee_EmptyBytes); - if (start_index == 0) +bytes_nsi_getrange_n(Bytes *__restrict self, + dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return bytes_nsi_getrange(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; + start = DeeSeqRange_Clamp_n(i_begin, DeeBytes_SIZE(self)); + if unlikely(start == 0) return_reference_(self); + range_size = DeeBytes_SIZE(self) - start; + if unlikely(range_size <= 0) + return_reference_((Bytes *)Dee_EmptyBytes); return (DREF Bytes *)DeeBytes_NewView(self->b_orig, - self->b_base + (size_t)start_index, - (size_t)(DeeBytes_SIZE(self) - start_index), + self->b_base + start, + range_size, self->b_flags); +#endif /* !__OPTIMIZE_SIZE__ */ } - - PRIVATE WUNUSED NONNULL((1, 4)) int DCALL -bytes_nsi_setrange_i(Bytes *self, - dssize_t start_index, - dssize_t end_index, - DeeObject *value) { +bytes_nsi_setrange(Bytes *self, + dssize_t i_begin, + dssize_t i_end, + DeeObject *value) { + struct Dee_seq_range range; + size_t range_size; byte_t *dst; - size_t size; if unlikely(!DeeBytes_WRITABLE(self)) goto err_readonly; - if unlikely(start_index < 0) - start_index += DeeBytes_SIZE(self); - if unlikely(end_index < 0) - end_index += DeeBytes_SIZE(self); - if unlikely((size_t)start_index >= DeeBytes_SIZE(self) || - (size_t)start_index >= (size_t)end_index) { - start_index = 0; - end_index = 0; - } else if unlikely((size_t)end_index > DeeBytes_SIZE(self)) { - end_index = (dssize_t)DeeBytes_SIZE(self); - } - size = (size_t)(end_index - start_index); - dst = DeeBytes_DATA(self) + (size_t)start_index; - return DeeSeq_ItemsToBytes(dst, size, value); + DeeSeqRange_Clamp(&range, i_begin, i_end, DeeBytes_SIZE(self)); + range_size = range.sr_end - range.sr_start; + dst = DeeBytes_DATA(self) + range.sr_start; + return DeeSeq_ItemsToBytes(dst, range_size, value); err_readonly: return err_bytes_not_writable((DeeObject *)self); } PRIVATE WUNUSED NONNULL((1, 3)) int DCALL -bytes_nsi_setrange_in(Bytes *self, - dssize_t start_index, - DeeObject *value) { +bytes_nsi_setrange_n(Bytes *self, dssize_t i_begin, + DeeObject *value) { +#ifdef __OPTIMIZE_SIZE__ + return bytes_nsi_setrange(self, i_begin, SSIZE_MAX, value); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; byte_t *dst; - size_t size; if unlikely(!DeeBytes_WRITABLE(self)) goto err_readonly; - if unlikely(start_index < 0) - start_index += DeeBytes_SIZE(self); - if unlikely((size_t)start_index >= DeeBytes_SIZE(self)) - start_index = DeeBytes_SIZE(self); - size = (size_t)(DeeBytes_SIZE(self) - start_index); - dst = DeeBytes_DATA(self) + (size_t)start_index; - return DeeSeq_ItemsToBytes(dst, size, value); + start = DeeSeqRange_Clamp_n(i_begin, DeeBytes_SIZE(self)); + range_size = DeeBytes_SIZE(self) - start; + dst = DeeBytes_DATA(self) + start; + return DeeSeq_ItemsToBytes(dst, range_size, value); err_readonly: return err_bytes_not_writable((DeeObject *)self); +#endif /* !__OPTIMIZE_SIZE__ */ +} + +PRIVATE WUNUSED NONNULL((1)) int DCALL +bytes_nsi_delrange(Bytes *self, dssize_t i_begin, dssize_t i_end) { +#ifdef __OPTIMIZE_SIZE__ + return bytes_nsi_setrange(self, i_begin, i_end, Dee_None); +#else /* __OPTIMIZE_SIZE__ */ + struct Dee_seq_range range; + size_t range_size; + byte_t *dst; + if unlikely(!DeeBytes_WRITABLE(self)) + goto err_readonly; + DeeSeqRange_Clamp(&range, i_begin, i_end, DeeBytes_SIZE(self)); + range_size = range.sr_end - range.sr_start; + dst = DeeBytes_DATA(self) + range.sr_start; + bzero(dst, range_size); + return 0; +err_readonly: + return err_bytes_not_writable((DeeObject *)self); +#endif /* !__OPTIMIZE_SIZE__ */ +} + +PRIVATE WUNUSED NONNULL((1)) int DCALL +bytes_nsi_delrange_n(Bytes *self, dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return bytes_nsi_delrange(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; + byte_t *dst; + if unlikely(!DeeBytes_WRITABLE(self)) + goto err_readonly; + start = DeeSeqRange_Clamp_n(i_begin, DeeBytes_SIZE(self)); + range_size = DeeBytes_SIZE(self) - start; + dst = DeeBytes_DATA(self) + start; + bzero(dst, range_size); + return 0; +err_readonly: + return err_bytes_not_writable((DeeObject *)self); +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 3)) DREF DeeObject *DCALL @@ -1381,10 +1415,12 @@ PRIVATE struct type_nsi tpconst bytes_nsi = { /* .nsi_delitem = */ (dfunptr_t)&bytes_nsi_delitem, /* .nsi_setitem = */ (dfunptr_t)&bytes_nsi_setitem, /* .nsi_getitem_fast = */ (dfunptr_t)NULL, - /* .nsi_getrange = */ (dfunptr_t)&bytes_nsi_getrange_i, - /* .nsi_getrange_n = */ (dfunptr_t)&bytes_nsi_getrange_in, - /* .nsi_setrange = */ (dfunptr_t)&bytes_nsi_setrange_i, - /* .nsi_setrange_n = */ (dfunptr_t)&bytes_nsi_setrange_in, + /* .nsi_getrange = */ (dfunptr_t)&bytes_nsi_getrange, + /* .nsi_getrange_n = */ (dfunptr_t)&bytes_nsi_getrange_n, + /* .nsi_delrange = */ (dfunptr_t)&bytes_nsi_delrange, + /* .nsi_delrange_n = */ (dfunptr_t)&bytes_nsi_delrange_n, + /* .nsi_setrange = */ (dfunptr_t)&bytes_nsi_setrange, + /* .nsi_setrange_n = */ (dfunptr_t)&bytes_nsi_setrange_n, /* .nsi_find = */ (dfunptr_t)NULL, /* .nsi_rfind = */ (dfunptr_t)NULL, /* .nsi_xch = */ (dfunptr_t)&bytes_nsi_xch, diff --git a/src/deemon/objects/class_desc.c b/src/deemon/objects/class_desc.c index d41540d76..dee544cb4 100644 --- a/src/deemon/objects/class_desc.c +++ b/src/deemon/objects/class_desc.c @@ -2405,6 +2405,8 @@ PRIVATE struct type_nsi tpconst ot_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&ot_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/list.c b/src/deemon/objects/list.c index b8ad66861..f77b982e0 100644 --- a/src/deemon/objects/list.c +++ b/src/deemon/objects/list.c @@ -38,6 +38,7 @@ #include #include +#include #include #include @@ -45,7 +46,6 @@ #include "../runtime/strings.h" #undef SSIZE_MAX -#include #define SSIZE_MAX __SSIZE_MAX__ DECL_BEGIN @@ -162,7 +162,7 @@ list_copy(List *__restrict me, new_elemv = (DREF DeeObject **)Dee_TryMallocc(count, sizeof(DREF DeeObject *)); if unlikely(!new_elemv) { DeeList_LockEndRead(other); - if (Dee_CollectMemory(count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(count, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -244,7 +244,7 @@ list_init_iterator(List *__restrict me, new_elema = elemc + 1; goto do_realloc; } - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto do_realloc; Dee_Decref(elem); goto err; @@ -534,7 +534,7 @@ DeeList_ExtendInherited(/*inherit(on_success)*/ DREF DeeObject *self, size_t arg new_elema = req_alloc; goto do_realloc_vector; } - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto do_realloc_vector; goto err; } @@ -634,10 +634,10 @@ DeeList_Erase(DeeObject *__restrict self, max_count = me->l_list.ol_elemc - index; if (count > max_count) count = max_count; - delobv = (DREF DeeObject **)Dee_TryMalloca(count * sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(count, sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (!Dee_CollectMemory(count * sizeof(DREF DeeObject *))) + if (!Dee_CollectMemoryc(count, sizeof(DREF DeeObject *))) return (size_t)-1; goto again; } @@ -1009,7 +1009,7 @@ PUBLIC WUNUSED NONNULL((1)) int DeeList_LockEndWrite(me); /* Try to collect some memory, then try again. */ - if (Dee_CollectMemory(objc * sizeof(DeeObject *))) + if (Dee_CollectMemoryc(objc, sizeof(DeeObject *))) goto retry; goto err; } @@ -1099,7 +1099,7 @@ PUBLIC WUNUSED NONNULL((1, 3)) int new_elema = me->l_list.ol_elemc + 1; goto do_realloc; } - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto do_realloc; DeeList_LockEndWrite(me); goto err; @@ -1151,7 +1151,7 @@ PUBLIC WUNUSED NONNULL((1)) int new_elema = me->l_list.ol_elemc + objc; goto do_realloc; } - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto do_realloc; DeeList_LockEndWrite(me); goto err; @@ -1436,36 +1436,32 @@ list_getitem(List *me, DeeObject *index) { } INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL -list_getrange_i(List *__restrict me, - dssize_t begin, dssize_t end) { +list_nsi_getrange(List *__restrict me, dssize_t i_begin, dssize_t i_end) { + struct Dee_seq_range range; + size_t range_size; DREF DeeObject **new_elemv; DREF List *result; again: DeeList_LockRead(me); - if unlikely(begin < 0) - begin += me->l_list.ol_elemc; - if unlikely(end < 0) - end += me->l_list.ol_elemc; - if unlikely((size_t)begin >= me->l_list.ol_elemc || - (size_t)begin >= (size_t)end) { + DeeSeqRange_Clamp(&range, i_begin, i_end, me->l_list.ol_elemc); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) { /* Empty list. */ DeeList_LockEndRead(me); return DeeList_New(); } - if unlikely((size_t)end > me->l_list.ol_elemc) - end = (dssize_t)me->l_list.ol_elemc; - end -= begin; - ASSERT(end != 0); - new_elemv = (DREF DeeObject **)Dee_TryMallocc((size_t)end, sizeof(DREF DeeObject *)); + new_elemv = (DREF DeeObject **)Dee_TryMallocc(range_size, sizeof(DREF DeeObject *)); if unlikely(!new_elemv) { DeeList_LockEndRead(me); - if (Dee_CollectMemory((size_t)end * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; return NULL; } /* Copy vector elements. */ - Dee_Movrefv(new_elemv, me->l_list.ol_elemv + begin, (size_t)end); + Dee_Movrefv(new_elemv, + me->l_list.ol_elemv + range.sr_start, + range_size); DeeList_LockEndRead(me); /* Create the new list descriptor. */ @@ -1475,8 +1471,8 @@ list_getrange_i(List *__restrict me, /* Fill in the descriptor. */ DeeObject_Init(result, &DeeList_Type); - result->l_list.ol_elemc = (size_t)end; - _DeeList_SetAlloc(result, (size_t)end); + result->l_list.ol_elemc = range_size; + _DeeList_SetAlloc(result, range_size); weakref_support_init(result); Dee_atomic_rwlock_init(&result->l_lock); result->l_list.ol_elemv = new_elemv; @@ -1487,40 +1483,39 @@ list_getrange_i(List *__restrict me, err_elemv: /* Cleanup on error. */ - Dee_Decrefv(new_elemv, (size_t)end); + Dee_Decrefv(new_elemv, range_size); Dee_Free(new_elemv); return NULL; } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL -list_getrange_in(List *__restrict me, dssize_t begin) { +list_nsi_getrange_n(List *__restrict me, dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return list_nsi_getrange(me, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ DREF DeeObject **new_elemv; DREF List *result; - size_t new_size; + size_t start, range_size; again: DeeList_LockRead(me); - if unlikely(begin < 0) - begin += me->l_list.ol_elemc; - if unlikely((size_t)begin >= me->l_list.ol_elemc) { + start = DeeSeqRange_Clamp_n(i_begin, me->l_list.ol_elemc); + range_size = me->l_list.ol_elemc - start; + if unlikely(range_size <= 0) { /* Empty list. */ DeeList_LockEndRead(me); return DeeList_New(); } - - new_size = me->l_list.ol_elemc - begin; - ASSERT(new_size != 0); - new_elemv = (DREF DeeObject **)Dee_TryMallocc((size_t)new_size, - sizeof(DREF DeeObject *)); + ASSERT(range_size != 0); + new_elemv = (DREF DeeObject **)Dee_TryMallocc(range_size, sizeof(DREF DeeObject *)); if unlikely(!new_elemv) { DeeList_LockEndRead(me); - if (Dee_CollectMemory((size_t)new_size * - sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; return NULL; } /* Copy vector elements. */ - Dee_Movrefv(new_elemv, me->l_list.ol_elemv + (size_t)begin, (size_t)new_size); + Dee_Movrefv(new_elemv, me->l_list.ol_elemv + start, range_size); DeeList_LockEndRead(me); /* Create the new list descriptor. */ @@ -1530,8 +1525,8 @@ list_getrange_in(List *__restrict me, dssize_t begin) { /* Fill in the descriptor. */ DeeObject_Init(result, &DeeList_Type); - result->l_list.ol_elemc = (size_t)new_size; - _DeeList_SetAlloc(result, (size_t)new_size); + result->l_list.ol_elemc = range_size; + _DeeList_SetAlloc(result, range_size); weakref_support_init(result); Dee_atomic_rwlock_init(&result->l_lock); result->l_list.ol_elemv = new_elemv; @@ -1542,21 +1537,22 @@ list_getrange_in(List *__restrict me, dssize_t begin) { err_elemv: /* Cleanup on error. */ - Dee_Decrefv(new_elemv, (size_t)new_size); + Dee_Decrefv(new_elemv, range_size); Dee_Free(new_elemv); return NULL; +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL list_getrange(List *me, DeeObject *begin, DeeObject *end) { - dssize_t i_begin, i_end = SSIZE_MAX; + dssize_t i_begin, i_end; if (DeeObject_AsSSize(begin, &i_begin)) goto err; if (DeeNone_Check(end)) - return list_getrange_in(me, i_begin); + return list_nsi_getrange_n(me, i_begin); if (DeeObject_AsSSize(end, &i_end)) goto err; - return list_getrange_i(me, i_begin, i_end); + return list_nsi_getrange(me, i_begin, i_end); err: return NULL; } @@ -1646,50 +1642,37 @@ list_iter(List *__restrict me) { } PRIVATE WUNUSED NONNULL((1)) int DCALL -list_delrange_i(List *__restrict me, - dssize_t start, - dssize_t end) { +list_nsi_delrange(List *__restrict me, dssize_t i_begin, dssize_t i_end) { DREF DeeObject **delobv; - size_t count; - dssize_t start_index, end_index; + struct Dee_seq_range range; + size_t range_size; again: - start_index = start; - end_index = end; DeeList_LockWrite(me); - if (end_index < 0) { - end_index += DeeList_SIZE(me); - } else if ((size_t)end_index > DeeList_SIZE(me)) { - end_index = (dssize_t)DeeList_SIZE(me); - } - if (start_index < 0) { - start_index += DeeList_SIZE(me); - } else if ((size_t)start_index >= DeeList_SIZE(me)) { + DeeSeqRange_Clamp(&range, i_begin, i_end, DeeList_SIZE(me)); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) goto done_noop; - } - if ((size_t)start_index >= (size_t)end_index) - goto done_noop; - count = (size_t)end_index - (size_t)start_index; - delobv = (DREF DeeObject **)Dee_TryMalloca((size_t)count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, + sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory((size_t)count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - (size_t)count, sizeof(DREF DeeObject *)); - memmovedownc(DeeList_ELEM(me) + (size_t)start_index, - DeeList_ELEM(me) + (size_t)end_index, - DeeList_SIZE(me) - (size_t)end_index, + memcpyc(delobv, DeeList_ELEM(me) + range.sr_start, + range_size, sizeof(DREF DeeObject *)); + memmovedownc(DeeList_ELEM(me) + range.sr_start, + DeeList_ELEM(me) + range.sr_end, + DeeList_SIZE(me) - range.sr_end, sizeof(DREF DeeObject *)); - me->l_list.ol_elemc -= count; + me->l_list.ol_elemc -= range_size; DeeList_LockEndWrite(me); /* Drop object references. */ - Dee_Decrefv(delobv, count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -1703,39 +1686,34 @@ list_delrange_i(List *__restrict me, } PRIVATE WUNUSED NONNULL((1)) int DCALL -list_delrange_in(List *__restrict me, - dssize_t start) { +list_nsi_delrange_n(List *__restrict me, dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return list_nsi_delrange(me, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ DREF DeeObject **delobv; - size_t count; - dssize_t start_index; + size_t start, range_size; again: - start_index = start; DeeList_LockWrite(me); - if (start_index < 0) { - start_index += DeeList_SIZE(me); - } else if ((size_t)start_index >= DeeList_SIZE(me)) { - goto done_noop; - } - if ((size_t)start_index >= DeeList_SIZE(me)) + start = DeeSeqRange_Clamp_n(i_begin, DeeList_SIZE(me)); + range_size = DeeList_SIZE(me) - start; + if unlikely(range_size <= 0) goto done_noop; - count = DeeList_SIZE(me) - (size_t)start_index; - delobv = (DREF DeeObject **)Dee_TryMalloca((size_t)count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory((size_t)count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - (size_t)count, sizeof(DREF DeeObject *)); - me->l_list.ol_elemc -= count; + memcpyc(delobv, DeeList_ELEM(me) + start, + range_size, sizeof(DREF DeeObject *)); + me->l_list.ol_elemc -= range_size; DeeList_LockEndWrite(me); /* Drop object references. */ - Dee_Decrefv(delobv, count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -1746,37 +1724,25 @@ list_delrange_in(List *__restrict me, done_noop: DeeList_LockEndWrite(me); goto done; +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 4)) int DCALL -list_setrange_fast_i(List *me, - dssize_t start, dssize_t end, - DeeObject *items, - size_t insert_count) { +list_setrange_fast(List *me, dssize_t i_begin, dssize_t i_end, + DeeObject *items, size_t insert_count) { DREF DeeObject **delobv; - size_t delete_count, i; - dssize_t start_index, end_index; + struct Dee_seq_range range; + size_t range_size, i; if unlikely(!insert_count) - return list_delrange_i(me, start, end); + return list_nsi_delrange(me, i_begin, i_end); again: DeeList_LockWrite(me); - start_index = start; - end_index = end; - if (start_index < 0) { - start_index += DeeList_SIZE(me); - } else if ((size_t)start_index > DeeList_SIZE(me)) { - start_index = (dssize_t)DeeList_SIZE(me); - } - if ((size_t)start_index >= (size_t)end_index) { - /* Insert-only */ - delete_count = 0; - } else { - delete_count = (size_t)end_index - (size_t)start_index; - } - ASSERT(delete_count <= DeeList_SIZE(me)); - if (insert_count > delete_count) { + DeeSeqRange_Clamp(&range, i_begin, i_end, me->l_list.ol_elemc); + range_size = range.sr_end - range.sr_start; + ASSERT(range_size <= DeeList_SIZE(me)); + if (insert_count > range_size) { /* Make sure the list has enough available memory. */ - size_t min_elema = (DeeList_SIZE(me) - delete_count) + insert_count; + size_t min_elema = (DeeList_SIZE(me) - range_size) + insert_count; size_t old_elema = DeeList_GetAlloc(me); if (min_elema > old_elema) { size_t new_elema = old_elema; @@ -1795,7 +1761,7 @@ list_setrange_fast_i(List *me, if unlikely(!new_elemv) { DeeList_LockEndWrite(me); /* Collect memory and try again. */ - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -1804,49 +1770,49 @@ list_setrange_fast_i(List *me, _DeeList_SetAlloc(me, new_elema); } } - if (!delete_count) { + if (range_size <= 0) { /* Move following items to their proper places. */ - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)start_index, - DeeList_SIZE(me) - (size_t)start_index, + memmoveupc(DeeList_ELEM(me) + range.sr_start + insert_count, + DeeList_ELEM(me) + range.sr_start, + DeeList_SIZE(me) - range.sr_start, sizeof(DREF DeeObject *)); /* Fill in the new items. */ for (i = 0; i < insert_count; ++i) - DeeList_SET(me, (size_t)start_index + i, DeeFastSeq_GetItemNB(items, i)); + DeeList_SET(me, range.sr_start + i, DeeFastSeq_GetItemNB(items, i)); me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); } else { - delobv = (DREF DeeObject **)Dee_TryMalloca(delete_count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, + sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(delete_count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - delete_count, sizeof(DREF DeeObject *)); + memcpyc(delobv, DeeList_ELEM(me) + range.sr_start, + range_size, sizeof(DREF DeeObject *)); /* Move following items to their proper places. */ - if ((size_t)start_index + insert_count != (size_t)end_index) { - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)end_index, - DeeList_SIZE(me) - (size_t)end_index, + if (range.sr_start + insert_count != range.sr_end) { + memmoveupc(DeeList_ELEM(me) + range.sr_start + insert_count, + DeeList_ELEM(me) + range.sr_end, + DeeList_SIZE(me) - range.sr_end, sizeof(DREF DeeObject *)); } /* Fill in the new items. */ for (i = 0; i < insert_count; ++i) - DeeList_SET(me, (size_t)start_index + i, DeeFastSeq_GetItemNB(items, i)); - me->l_list.ol_elemc -= delete_count; + DeeList_SET(me, range.sr_start + i, DeeFastSeq_GetItemNB(items, i)); + me->l_list.ol_elemc -= range_size; me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); /* Drop object references. */ - Dee_Decrefv(delobv, delete_count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -1857,29 +1823,21 @@ list_setrange_fast_i(List *me, } PRIVATE WUNUSED NONNULL((1, 3)) int DCALL -list_setrange_fast_in(List *me, - dssize_t start, - DeeObject *items, - size_t insert_count) { +list_setrange_fast_n(List *me, dssize_t i_begin, + DeeObject *items, size_t insert_count) { +#ifdef __OPTIMIZE_SIZE__ + return list_setrange_fast(me, i_begin, SSIZE_MAX, items, insert_count); +#else /* __OPTIMIZE_SIZE__ */ DREF DeeObject **delobv; - size_t delete_count, i; - dssize_t start_index; + size_t range_size, i, start; again: DeeList_LockWrite(me); - start_index = start; - if (start_index < 0) - start_index += DeeList_SIZE(me); - if ((size_t)start_index >= DeeList_SIZE(me)) { - /* Insert-only */ - start_index = (dssize_t)DeeList_SIZE(me); - delete_count = 0; - } else { - delete_count = DeeList_SIZE(me) - (size_t)start_index; - } - ASSERT(delete_count <= DeeList_SIZE(me)); - if (insert_count > delete_count) { + start = DeeSeqRange_Clamp_n(i_begin, me->l_list.ol_elemc); + range_size = me->l_list.ol_elemc - start; + ASSERT(range_size <= DeeList_SIZE(me)); + if (insert_count > range_size) { /* Make sure the list has enough available memory. */ - size_t min_elema = (DeeList_SIZE(me) - delete_count) + insert_count; + size_t min_elema = (DeeList_SIZE(me) - range_size) + insert_count; size_t old_elema = DeeList_GetAlloc(me); if (min_elema > old_elema) { size_t new_elema = old_elema; @@ -1898,7 +1856,7 @@ list_setrange_fast_in(List *me, if unlikely(!new_elemv) { DeeList_LockEndWrite(me); /* Collect memory and try again. */ - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -1907,41 +1865,40 @@ list_setrange_fast_in(List *me, _DeeList_SetAlloc(me, new_elema); } } - if (!delete_count) { + if (!range_size) { /* Move following items to their proper places. */ - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)start_index, - DeeList_SIZE(me) - (size_t)start_index, + memmoveupc(DeeList_ELEM(me) + start + insert_count, + DeeList_ELEM(me) + start, + DeeList_SIZE(me) - start, sizeof(DREF DeeObject *)); /* Fill in the new items. */ for (i = 0; i < insert_count; ++i) - DeeList_SET(me, (size_t)start_index + i, DeeFastSeq_GetItemNB(items, i)); + DeeList_SET(me, start + i, DeeFastSeq_GetItemNB(items, i)); me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); } else { - delobv = (DREF DeeObject **)Dee_TryMalloca(delete_count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(delete_count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - delete_count, sizeof(DREF DeeObject *)); + memcpyc(delobv, DeeList_ELEM(me) + start, + range_size, sizeof(DREF DeeObject *)); /* Fill in the new items. */ for (i = 0; i < insert_count; ++i) - DeeList_SET(me, (size_t)start_index + i, DeeFastSeq_GetItemNB(items, i)); - me->l_list.ol_elemc -= delete_count; + DeeList_SET(me, start + i, DeeFastSeq_GetItemNB(items, i)); + me->l_list.ol_elemc -= range_size; me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); /* Drop object references. */ - Dee_Decrefv(delobv, delete_count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -1949,65 +1906,50 @@ list_setrange_fast_in(List *me, return 0; err: return -1; +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 4)) int DCALL -list_setrange_i(List *me, - dssize_t start, dssize_t end, - DeeObject *items) { +list_nsi_setrange(List *me, dssize_t i_begin, + dssize_t i_end, DeeObject *items) { DREF DeeObject **delobv, **insertv; - size_t delete_count, insert_count; - dssize_t start_index, end_index; - - /* Special case: none -> delrange. */ - if (DeeNone_Check(items)) - return list_delrange_i(me, start, end); + size_t range_size, insert_count; + struct Dee_seq_range range; /* Check for special case: Fast-insert */ insert_count = DeeFastSeq_GetSizeNB(items); if (insert_count != DEE_FASTSEQ_NOTFAST) - return list_setrange_fast_i(me, start, end, items, insert_count); + return list_setrange_fast(me, i_begin, i_end, items, insert_count); insertv = DeeSeq_AsHeapVector(items, &insert_count); if unlikely(!insertv) goto err; if unlikely(!insert_count) { Dee_Free(insertv); - return list_delrange_i(me, start, end); + return list_nsi_delrange(me, i_begin, i_end); } again: - start_index = start; - end_index = end; DeeList_LockWrite(me); - if (end_index < 0) { - end_index += DeeList_SIZE(me); - } else if ((size_t)end_index > DeeList_SIZE(me)) { - end_index = (dssize_t)DeeList_SIZE(me); - } - if (start_index < 0) { - start_index += DeeList_SIZE(me); - } else if ((size_t)start_index > DeeList_SIZE(me)) { - start_index = (dssize_t)DeeList_SIZE(me); - } - if ((size_t)start_index >= (size_t)end_index) { - if (!me->l_list.ol_elemc) { - /* Special case: The list didn't contain anything, yet - * -> Here, we can simply invert the insert-vector and call it a day! */ - Dee_Free(me->l_list.ol_elemv); - me->l_list.ol_elemv = insertv; /* Inherit */ - me->l_list.ol_elemc = insert_count; - _DeeList_SetAlloc(me, insert_count); - DeeList_LockEndWrite(me); - goto done; - } - /* Insert-only */ - delete_count = 0; - } else { - delete_count = (size_t)end_index - (size_t)start_index; + DeeSeqRange_Clamp(&range, i_begin, i_end, me->l_list.ol_elemc); + range_size = range.sr_end - range.sr_start; + ASSERT(range_size <= DeeList_SIZE(me)); + if (range_size == me->l_list.ol_elemc) { + /* Special case: assign to the entirety of the list + * -> Here, we can simply swap vectors. */ + DeeObject **old_elemv; + size_t old_elemc; + old_elemv = me->l_list.ol_elemv; + old_elemc = me->l_list.ol_elemc; + me->l_list.ol_elemv = insertv; /* Inherit */ + me->l_list.ol_elemc = insert_count; + _DeeList_SetAlloc(me, insert_count); + DeeList_LockEndWrite(me); + old_elemv = Dee_Decrefv(old_elemv, old_elemc); + Dee_Free(old_elemv); + goto done; } - ASSERT(delete_count <= DeeList_SIZE(me)); - if (insert_count > delete_count) { + if (insert_count > range_size) { /* Make sure the list has enough available memory. */ - size_t min_elema = (DeeList_SIZE(me) - delete_count) + insert_count; + size_t min_elema = (DeeList_SIZE(me) - range_size) + insert_count; size_t old_elema = DeeList_GetAlloc(me); if (min_elema > old_elema) { size_t new_elema = old_elema; @@ -2026,7 +1968,7 @@ list_setrange_i(List *me, if unlikely(!new_elemv) { DeeList_LockEndWrite(me); /* Collect memory and try again. */ - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto again; goto err_insertv; } @@ -2035,51 +1977,50 @@ list_setrange_i(List *me, _DeeList_SetAlloc(me, new_elema); } } - if (!delete_count) { + if (!range_size) { /* Move following items to their proper places. */ - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)start_index, - DeeList_SIZE(me) - (size_t)start_index, + memmoveupc(DeeList_ELEM(me) + range.sr_start + insert_count, + DeeList_ELEM(me) + range.sr_start, + DeeList_SIZE(me) - range.sr_start, sizeof(DREF DeeObject *)); /* Copy new items into the list. */ - memcpyc(DeeList_ELEM(me) + (size_t)start_index, insertv, + memcpyc(DeeList_ELEM(me) + range.sr_start, insertv, insert_count, sizeof(DREF DeeObject *)); me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); Dee_Free(insertv); } else { - delobv = (DREF DeeObject **)Dee_TryMalloca(delete_count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(delete_count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err_insertv; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - delete_count, sizeof(DREF DeeObject *)); + memcpyc(delobv, DeeList_ELEM(me) + range.sr_start, + range_size, sizeof(DREF DeeObject *)); /* Move following items to their proper places. */ - if ((size_t)start_index + insert_count != (size_t)end_index) { - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)end_index, - DeeList_SIZE(me) - (size_t)end_index, + if (range.sr_start + insert_count != range.sr_end) { + memmoveupc(DeeList_ELEM(me) + range.sr_start + insert_count, + DeeList_ELEM(me) + range.sr_end, + DeeList_SIZE(me) - range.sr_end, sizeof(DREF DeeObject *)); } /* Copy new items into the list. */ - memcpyc(DeeList_ELEM(me) + (size_t)start_index, insertv, + memcpyc(DeeList_ELEM(me) + range.sr_start, insertv, insert_count, sizeof(DREF DeeObject *)); - me->l_list.ol_elemc -= delete_count; + me->l_list.ol_elemc -= range_size; me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); Dee_Free(insertv); /* Drop object references. */ - Dee_Decrefv(delobv, delete_count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -2094,55 +2035,50 @@ list_setrange_i(List *me, } PRIVATE WUNUSED NONNULL((1, 3)) int DCALL -list_setrange_in(List *me, dssize_t start, DeeObject *items) { +list_nsi_setrange_n(List *me, dssize_t i_begin, DeeObject *items) { +#ifdef __OPTIMIZE_SIZE__ + return list_nsi_setrange(me, i_begin, SSIZE_MAX, items); +#else /* __OPTIMIZE_SIZE__ */ DREF DeeObject **delobv, **insertv; - size_t delete_count, insert_count; - dssize_t start_index; - - /* Special case: none -> delrange. */ - if (DeeNone_Check(items)) - return list_delrange_in(me, start); + size_t range_size, insert_count, start; /* Check for special case: Fast-insert */ insert_count = DeeFastSeq_GetSizeNB(items); if (insert_count != DEE_FASTSEQ_NOTFAST) { if (!insert_count) - return list_delrange_in(me, start); - return list_setrange_fast_in(me, start, items, insert_count); + return list_nsi_delrange_n(me, i_begin); + return list_setrange_fast_n(me, i_begin, items, insert_count); } insertv = DeeSeq_AsHeapVector(items, &insert_count); if unlikely(!insertv) goto err; if unlikely(!insert_count) { Dee_Free(insertv); - return list_delrange_in(me, start); + return list_nsi_delrange_n(me, i_begin); } again: - start_index = start; DeeList_LockWrite(me); - if (start_index < 0) - start_index += DeeList_SIZE(me); - if ((size_t)start_index >= DeeList_SIZE(me)) { - start_index = (dssize_t)DeeList_SIZE(me); - if (!me->l_list.ol_elemc) { - /* Special case: The list didn't contain anything, yet - * -> Here, we can simply invert the insert-vector and call it a day! */ - Dee_Free(me->l_list.ol_elemv); - me->l_list.ol_elemv = insertv; /* Inherit */ - me->l_list.ol_elemc = insert_count; - _DeeList_SetAlloc(me, insert_count); - DeeList_LockEndWrite(me); - goto done; - } - /* Insert-only */ - delete_count = 0; - } else { - delete_count = DeeList_SIZE(me) - (size_t)start_index; + start = DeeSeqRange_Clamp_n(i_begin, me->l_list.ol_elemc); + if (start == 0) { + /* Special case: assign to the entirety of the list + * -> Here, we can simply swap vectors. */ + DeeObject **old_elemv; + size_t old_elemc; + old_elemv = me->l_list.ol_elemv; + old_elemc = me->l_list.ol_elemc; + me->l_list.ol_elemv = insertv; /* Inherit */ + me->l_list.ol_elemc = insert_count; + _DeeList_SetAlloc(me, insert_count); + DeeList_LockEndWrite(me); + old_elemv = Dee_Decrefv(old_elemv, old_elemc); + Dee_Free(old_elemv); + goto done; } - ASSERT(delete_count <= DeeList_SIZE(me)); - if (insert_count > delete_count) { + range_size = me->l_list.ol_elemc - start; + ASSERT(range_size <= DeeList_SIZE(me)); + if (insert_count > range_size) { /* Make sure the list has enough available memory. */ - size_t min_elema = (DeeList_SIZE(me) - delete_count) + insert_count; + size_t min_elema = (DeeList_SIZE(me) - range_size) + insert_count; size_t old_elema = DeeList_GetAlloc(me); if (min_elema > old_elema) { size_t new_elema = old_elema; @@ -2161,7 +2097,7 @@ list_setrange_in(List *me, dssize_t start, DeeObject *items) { if unlikely(!new_elemv) { DeeList_LockEndWrite(me); /* Collect memory and try again. */ - if (Dee_CollectMemory(new_elema * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elema, sizeof(DREF DeeObject *))) goto again; goto err_insertv; } @@ -2170,43 +2106,42 @@ list_setrange_in(List *me, dssize_t start, DeeObject *items) { _DeeList_SetAlloc(me, new_elema); } } - if (!delete_count) { + if (!range_size) { /* Move following items to their proper places. */ - memmoveupc(DeeList_ELEM(me) + (size_t)start_index + insert_count, - DeeList_ELEM(me) + (size_t)start_index, - DeeList_SIZE(me) - (size_t)start_index, + memmoveupc(DeeList_ELEM(me) + start + insert_count, + DeeList_ELEM(me) + start, + DeeList_SIZE(me) - start, sizeof(DREF DeeObject *)); /* Copy new items into the list. */ - memcpyc(DeeList_ELEM(me) + (size_t)start_index, insertv, + memcpyc(DeeList_ELEM(me) + start, insertv, insert_count, sizeof(DREF DeeObject *)); me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); Dee_Free(insertv); } else { - delobv = (DREF DeeObject **)Dee_TryMalloca(delete_count * - sizeof(DREF DeeObject *)); + delobv = (DREF DeeObject **)Dee_TryMallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!delobv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(delete_count * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(range_size, sizeof(DREF DeeObject *))) goto again; goto err_insertv; } /* Move all items to-be deleted into the delete-vector. */ - memcpyc(delobv, DeeList_ELEM(me) + (size_t)start_index, - delete_count, sizeof(DREF DeeObject *)); + memcpyc(delobv, DeeList_ELEM(me) + start, + range_size, sizeof(DREF DeeObject *)); /* Copy new items into the list. */ - memcpyc(DeeList_ELEM(me) + (size_t)start_index, insertv, + memcpyc(DeeList_ELEM(me) + start, insertv, insert_count, sizeof(DREF DeeObject *)); - me->l_list.ol_elemc -= delete_count; + me->l_list.ol_elemc -= range_size; me->l_list.ol_elemc += insert_count; DeeList_LockEndWrite(me); Dee_Free(insertv); /* Drop object references. */ - Dee_Decrefv(delobv, delete_count); + Dee_Decrefv(delobv, range_size); /* Free the temporary del-item vector. */ Dee_Freea(delobv); @@ -2218,35 +2153,36 @@ list_setrange_in(List *me, dssize_t start, DeeObject *items) { Dee_Free(insertv); err: return -1; +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL -list_delrange(List *me, DeeObject *start_ob, DeeObject *end_ob) { - dssize_t start_index, end_index; - if (DeeObject_AsSSize(start_ob, &start_index)) +list_delrange(List *me, DeeObject *begin, DeeObject *end) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (DeeNone_Check(end_ob)) - return list_delrange_in(me, start_index); - if (DeeObject_AsSSize(end_ob, &end_index)) + if (DeeNone_Check(end)) + return list_nsi_delrange_n(me, i_begin); + if (DeeObject_AsSSize(end, &i_end)) goto err; - return list_delrange_i(me, start_index, end_index); + return list_nsi_delrange(me, i_begin, i_end); err: return -1; } PRIVATE WUNUSED NONNULL((1, 2, 3, 4)) int DCALL -list_setrange(List *me, DeeObject *start_ob, - DeeObject *end_ob, DeeObject *items) { - dssize_t start_index, end_index; - if (DeeObject_AsSSize(start_ob, &start_index)) +list_setrange(List *me, DeeObject *begin, + DeeObject *end, DeeObject *items) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (DeeNone_Check(end_ob)) - return list_setrange_in(me, start_index, items); - if (DeeObject_AsSSize(end_ob, &end_index)) + if (DeeNone_Check(end)) + return list_nsi_setrange_n(me, i_begin, items); + if (DeeObject_AsSSize(end, &i_end)) goto err; - return list_setrange_i(me, start_index, end_index, items); + return list_nsi_setrange(me, i_begin, i_end, items); err: return -1; } @@ -2363,10 +2299,12 @@ PRIVATE struct type_nsi tpconst list_nsi = { /* .nsi_delitem = */ (dfunptr_t)&list_delitem_index, /* .nsi_setitem = */ (dfunptr_t)&list_setitem_index, /* .nsi_getitem_fast = */ (dfunptr_t)NULL, - /* .nsi_getrange = */ (dfunptr_t)&list_getrange_i, - /* .nsi_getrange_n = */ (dfunptr_t)&list_getrange_in, - /* .nsi_setrange = */ (dfunptr_t)&list_setrange_i, - /* .nsi_setrange_n = */ (dfunptr_t)&list_setrange_in, + /* .nsi_getrange = */ (dfunptr_t)&list_nsi_getrange, + /* .nsi_getrange_n = */ (dfunptr_t)&list_nsi_getrange_n, + /* .nsi_delrange = */ (dfunptr_t)&list_nsi_delrange, + /* .nsi_delrange_n = */ (dfunptr_t)&list_nsi_delrange_n, + /* .nsi_setrange = */ (dfunptr_t)&list_nsi_setrange, + /* .nsi_setrange_n = */ (dfunptr_t)&list_nsi_setrange_n, /* .nsi_find = */ (dfunptr_t)&list_nsi_find, /* .nsi_rfind = */ (dfunptr_t)&list_nsi_rfind, /* .nsi_xch = */ (dfunptr_t)&list_nsi_xch, @@ -3008,7 +2946,7 @@ list_resize(List *me, size_t argc, sizeof(DREF DeeObject *)); if unlikely(!new_elemv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(new_elemc * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elemc, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -3061,10 +2999,10 @@ list_resize(List *me, size_t argc, DREF DeeObject **old_obj; size_t num_del; num_del = me->l_list.ol_elemc - new_elemc; - old_obj = (DREF DeeObject **)Dee_TryMalloca(num_del * sizeof(DREF DeeObject *)); + old_obj = (DREF DeeObject **)Dee_TryMallocac(num_del, sizeof(DREF DeeObject *)); if unlikely(!old_obj) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(new_elemc * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(new_elemc, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -3277,7 +3215,7 @@ list_mul(List *me, DeeObject *other) { res_elemv = (DREF DeeObject **)Dee_TryMallocc(res_elemc, sizeof(DREF DeeObject *)); if unlikely(!res_elemv) { DeeList_LockEndRead(me); - if (Dee_CollectMemory(res_elemc * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(res_elemc, sizeof(DREF DeeObject *))) goto again; goto err; } @@ -3348,7 +3286,7 @@ list_inplace_mul(List **__restrict p_self, sizeof(DREF DeeObject *)); if unlikely(!elemv) { DeeList_LockEndWrite(me); - if (Dee_CollectMemory(result_length * sizeof(DREF DeeObject *))) + if (Dee_CollectMemoryc(result_length, sizeof(DREF DeeObject *))) goto again; goto err; } diff --git a/src/deemon/objects/seq.c b/src/deemon/objects/seq.c index d3525b6d6..e50bac4b2 100644 --- a/src/deemon/objects/seq.c +++ b/src/deemon/objects/seq.c @@ -50,6 +50,76 @@ DECL_BEGIN +#define do_fix_negative_range_index(index, size) \ + ((size) - ((size_t)(-(index)) % (size))) + +/* Clamp a range, as given to `operator [:]' & friends to the bounds + * accepted by the associated sequence. This handles stuff like negative + * index over-roll and past-the-end truncation. */ +PUBLIC ATTR_INOUT(1) void DCALL +DeeSeqRange_DoClamp(struct Dee_seq_range *__restrict self, + size_t size) { + /* Fix invalid start indices. */ + if (self->sr_start >= size) { + if (self->sr_istart >= 0) + goto empty_range; /* Range starts at too great of an index. */ + + /* Fast-case for when `-1' is used (or anything with an + * absolute value less than the sequence's size) */ + self->sr_istart += size; + if unlikely(self->sr_istart < 0) { + /* Check for special case: empty sequence (else the mod will + * fault due to divide-by-zero) -> only valid range is [0:0] */ + if unlikely(size == 0) + goto empty_range; + self->sr_start = do_fix_negative_range_index(self->sr_istart, size); + } + } + ASSERT(self->sr_start <= size); + + /* Fix invalid end indices. */ + if (self->sr_end > size) { + if (self->sr_iend < 0) { + self->sr_iend += size; + if unlikely(self->sr_iend < 0) { + /* Check for special case: empty sequence (else the mod will + * fault due to divide-by-zero) -> only valid range is [0:0] */ + if unlikely(size == 0) + goto empty_range; + self->sr_end = do_fix_negative_range_index(self->sr_iend, size); + } + } else { + self->sr_end = size; + } + } + ASSERT(self->sr_end <= size); + + /* Fix range-end happening before range-start. */ + if unlikely(self->sr_end < self->sr_start) + self->sr_end = self->sr_start; + return; +empty_range: + self->sr_start = size; + self->sr_end = size; +} + +/* Specialized version of `DeeSeqRange_DoClamp()' for `[istart:none]' range expressions. */ +PUBLIC ATTR_CONST WUNUSED size_t DCALL +DeeSeqRange_DoClamp_n(Dee_ssize_t start, size_t size) { + if likely((size_t)start >= size) { + if (start >= 0) + goto empty_range; + start += size; + if unlikely((size_t)start >= size) { + if unlikely(size == 0) + goto empty_range; + start = (Dee_ssize_t)do_fix_negative_range_index(start, size); + } + } + return (size_t)start; +empty_range: + return 0; +} /* Lookup the closest NSI descriptor for `tp', or return `NULL' * if the top-most type implementing any sequence operator doesn't @@ -107,8 +177,11 @@ seq_getrange(DeeObject *self, DeeObject *start, DeeObject *end) { size_t seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (i_begin < 0) + if (i_begin < 0) { i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } } return DeeSeq_GetRangeN(self, (size_t)i_begin); } @@ -118,10 +191,16 @@ seq_getrange(DeeObject *self, DeeObject *start, DeeObject *end) { size_t seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (i_begin < 0) + if (i_begin < 0) { i_begin += seq_len; - if (i_end < 0) + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + if (i_end < 0) { i_end += seq_len; + if unlikely(i_end < 0) + i_end = (dssize_t)do_fix_negative_range_index(i_end, seq_len); + } } return DeeSeq_GetRange(self, (size_t)i_begin, @@ -137,10 +216,16 @@ seq_nsi_getrange(DeeObject *__restrict self, dssize_t i_begin, dssize_t i_end) { seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (i_begin < 0) + if (i_begin < 0) { i_begin += seq_len; - if (i_end < 0) + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + if (i_end < 0) { i_end += seq_len; + if unlikely(i_end < 0) + i_end = (dssize_t)do_fix_negative_range_index(i_end, seq_len); + } } return DeeSeq_GetRange(self, (size_t)i_begin, @@ -156,8 +241,11 @@ seq_nsi_getrange_n(DeeObject *__restrict self, dssize_t i_begin) { seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (i_begin < 0) + if (i_begin < 0) { i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } } return DeeSeq_GetRangeN(self, (size_t)i_begin); err: @@ -603,6 +691,30 @@ seq_iterself(DeeObject *__restrict self) { } +PRIVATE WUNUSED NONNULL((1)) int DCALL +seq_nsi_delrange(DeeObject *self, dssize_t i_begin, dssize_t i_end) { + if unlikely(i_begin < 0 || i_end < 0) { + size_t seq_len = DeeObject_Size(self); + if unlikely(seq_len == (size_t)-1) + goto err; + if (i_begin < 0) { + i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + if (i_end < 0) { + i_end += seq_len; + if unlikely(i_end < 0) + i_end = (dssize_t)do_fix_negative_range_index(i_end, seq_len); + } + } + return DeeSeq_DelRange(self, + (size_t)i_begin, + (size_t)i_end); +err: + return -1; +} + PRIVATE WUNUSED NONNULL((1, 4)) int DCALL seq_nsi_setrange(DeeObject *self, dssize_t i_begin, dssize_t i_end, DeeObject *values) { @@ -610,15 +722,16 @@ seq_nsi_setrange(DeeObject *self, dssize_t i_begin, dssize_t i_end, size_t seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (i_begin < 0) + if (i_begin < 0) { i_begin += seq_len; - if (i_end < 0) + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + if (i_end < 0) { i_end += seq_len; - } - if (DeeNone_Check(values)) { - return DeeSeq_DelRange(self, - (size_t)i_begin, - (size_t)i_end); + if unlikely(i_end < 0) + i_end = (dssize_t)do_fix_negative_range_index(i_end, seq_len); + } } return DeeSeq_SetRange(self, (size_t)i_begin, @@ -628,6 +741,21 @@ seq_nsi_setrange(DeeObject *self, dssize_t i_begin, dssize_t i_end, return -1; } +PRIVATE WUNUSED NONNULL((1)) int DCALL +seq_nsi_delrange_n(DeeObject *self, dssize_t i_begin) { + if unlikely(i_begin < 0) { + size_t seq_len = DeeObject_Size(self); + if unlikely(seq_len == (size_t)-1) + goto err; + i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + return DeeSeq_DelRangeN(self, (size_t)i_begin); +err: + return -1; +} + PRIVATE WUNUSED NONNULL((1, 3)) int DCALL seq_nsi_setrange_n(DeeObject *self, dssize_t i_begin, DeeObject *values) { @@ -636,9 +764,9 @@ seq_nsi_setrange_n(DeeObject *self, dssize_t i_begin, if unlikely(seq_len == (size_t)-1) goto err; i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); } - if (DeeNone_Check(values)) - return DeeSeq_DelRangeN(self, (size_t)i_begin); return DeeSeq_SetRangeN(self, (size_t)i_begin, values); err: return -1; @@ -646,32 +774,40 @@ seq_nsi_setrange_n(DeeObject *self, dssize_t i_begin, PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL seq_delrange(DeeObject *self, DeeObject *start, DeeObject *end) { - dssize_t start_index, end_index; - if (DeeObject_AsSSize(start, &start_index)) + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(start, &i_begin)) goto err; if (DeeNone_Check(end)) { - if unlikely(start_index < 0) { + if unlikely(i_begin < 0) { size_t seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - start_index += seq_len; + i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); } - return DeeSeq_DelRangeN(self, (size_t)start_index); + return DeeSeq_DelRangeN(self, (size_t)i_begin); } - if (DeeObject_AsSSize(end, &end_index)) + if (DeeObject_AsSSize(end, &i_end)) goto err; - if unlikely(start_index < 0 || end_index < 0) { + if unlikely(i_begin < 0 || i_end < 0) { size_t seq_len = DeeObject_Size(self); if unlikely(seq_len == (size_t)-1) goto err; - if (start_index < 0) - start_index += seq_len; - if (end_index < 0) - end_index += seq_len; + if (i_begin < 0) { + i_begin += seq_len; + if unlikely(i_begin < 0) + i_begin = (dssize_t)do_fix_negative_range_index(i_begin, seq_len); + } + if (i_end < 0) { + i_end += seq_len; + if unlikely(i_end < 0) + i_end = (dssize_t)do_fix_negative_range_index(i_end, seq_len); + } } return DeeSeq_DelRange(self, - (size_t)start_index, - (size_t)end_index); + (size_t)i_begin, + (size_t)i_end); err: return -1; } @@ -720,6 +856,8 @@ PRIVATE struct type_nsi tpconst seq_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)&seq_nsi_getrange, /* .nsi_getrange_n = */ (dfunptr_t)&seq_nsi_getrange_n, + /* .nsi_delrange = */ (dfunptr_t)&seq_nsi_delrange, + /* .nsi_delrange_n = */ (dfunptr_t)&seq_nsi_delrange_n, /* .nsi_setrange = */ (dfunptr_t)&seq_nsi_setrange, /* .nsi_setrange_n = */ (dfunptr_t)&seq_nsi_setrange_n, /* .nsi_find = */ (dfunptr_t)&DeeSeq_Find, @@ -4853,9 +4991,9 @@ PUBLIC DeeTypeObject DeeSeq_Type = { /**/ " if (start < 0 || end < 0) {\n" /**/ " local mylen = ##this;\n" /**/ " if (start < 0)\n" - /**/ " start += mylen;\n" + /**/ " start += mylen;\n" /* TODO: Incorrect! */ /**/ " if (end < 0)\n" - /**/ " end += mylen;\n" + /**/ " end += mylen;\n" /* TODO: Incorrect! */ /**/ " }\n" /**/ " if (start >= end)\n" /**/ " return Sequence(); /* Empty Sequence */\n" @@ -5117,9 +5255,9 @@ PUBLIC DeeTypeObject DeeSeq_Type = { /**/ " if (start < 0 || end < 0) {\n" /**/ " local mylen = (##this).operator int();\n" /**/ " if (start < 0)\n" - /**/ " start += mylen;\n" + /**/ " start += mylen;\n" /* TODO: Incorrect! */ /**/ " if (end < 0)\n" - /**/ " end += mylen;\n" + /**/ " end += mylen;\n" /* TODO: Incorrect! */ /**/ " }\n" /**/ " for (local tp: type(this).__mro__) {\n" /**/ " if (tp === Sequence)\n" @@ -5175,7 +5313,7 @@ PUBLIC DeeTypeObject DeeSeq_Type = { /**/ " if (end is none) {\n" /**/ " end = mylen;\n" /**/ " } else if (end < 0) {\n" - /**/ " end += mylen;\n" + /**/ " end += mylen;\n" /* TODO: Incorrect! */ /**/ " }\n" /**/ " }\n" /**/ " if (start >= end) {\n" diff --git a/src/deemon/objects/seq/concat.c b/src/deemon/objects/seq/concat.c index 2bd96825b..ff9a1c21a 100644 --- a/src/deemon/objects/seq/concat.c +++ b/src/deemon/objects/seq/concat.c @@ -742,6 +742,8 @@ PRIVATE struct type_nsi tpconst cat_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&cat_nsi_find, diff --git a/src/deemon/objects/seq/each-fastpass.c.inl b/src/deemon/objects/seq/each-fastpass.c.inl index 31be638b8..40a37ef95 100644 --- a/src/deemon/objects/seq/each-fastpass.c.inl +++ b/src/deemon/objects/seq/each-fastpass.c.inl @@ -312,6 +312,8 @@ PRIVATE struct type_nsi tpconst F(nsi) = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/seq/each.c b/src/deemon/objects/seq/each.c index 246a1769f..bd1ef2bea 100644 --- a/src/deemon/objects/seq/each.c +++ b/src/deemon/objects/seq/each.c @@ -1199,6 +1199,8 @@ PRIVATE struct type_nsi tpconst seo_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/seq/range.c b/src/deemon/objects/seq/range.c index aa309b0ae..cf4334294 100644 --- a/src/deemon/objects/seq/range.c +++ b/src/deemon/objects/seq/range.c @@ -1381,30 +1381,26 @@ intrange_getitem(IntRange *self, PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL intrange_nsi_getrange(IntRange *__restrict self, - dssize_t start, dssize_t end) { + dssize_t begin, dssize_t end) { + struct Dee_seq_range range; size_t mylen = intrange_nsi_getsize(self); - if (start < 0) - start += mylen; - if (end < 0) - end += mylen; - if ((size_t)end > mylen) - end = (dssize_t)mylen; - if ((size_t)start >= (size_t)end) + DeeSeqRange_Clamp(&range, begin, end, mylen); + if (range.sr_end <= range.sr_start) return_reference_(Dee_EmptySeq); - return DeeRange_NewInt(self->ir_start + ((size_t)start * self->ir_step), - self->ir_end - ((mylen - (size_t)end) * self->ir_step), + return DeeRange_NewInt(self->ir_start + (range.sr_start * self->ir_step), + self->ir_end - ((mylen - range.sr_end) * self->ir_step), self->ir_step); } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL intrange_nsi_getrange_n(IntRange *__restrict self, - dssize_t start) { + dssize_t begin) { + size_t start; size_t mylen = intrange_nsi_getsize(self); - if (start < 0) - start += mylen; - if ((size_t)start >= mylen) + start = DeeSeqRange_Clamp_n(begin, mylen); + if (start >= mylen) return_reference_(Dee_EmptySeq); - return DeeRange_NewInt(self->ir_start + ((size_t)start * self->ir_step), + return DeeRange_NewInt(self->ir_start + (start * self->ir_step), self->ir_end, self->ir_step); } @@ -1441,6 +1437,8 @@ PRIVATE struct type_nsi tpconst intrange_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)&intrange_nsi_getrange, /* .nsi_getrange_n = */ (dfunptr_t)&intrange_nsi_getrange_n, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/seq/repeat.c b/src/deemon/objects/seq/repeat.c index 4d0545401..7dc0fa0e8 100644 --- a/src/deemon/objects/seq/repeat.c +++ b/src/deemon/objects/seq/repeat.c @@ -34,12 +34,16 @@ #include #include +#include #include #include "../../runtime/runtime_error.h" #include "../../runtime/strings.h" #include "../gc_inspect.h" +#undef SSIZE_MAX +#define SSIZE_MAX __SSIZE_MAX__ + DECL_BEGIN #define REPEATITER_READ_NUM(x) atomic_read(&(x)->rpi_num) @@ -571,6 +575,8 @@ PRIVATE struct type_nsi tpconst repeat_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&repeat_nsi_find, @@ -1013,35 +1019,6 @@ repeatitem_get(RepeatItem *self, return NULL; } -PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL -repeatitem_getrange(RepeatItem *self, - DeeObject *start_ob, - DeeObject *end_ob) { - dssize_t start, end; - if (DeeObject_AsSSize(start_ob, &start)) - goto err; - if (DeeNone_Check(end_ob)) { - end = self->rpit_num; - } else if (DeeObject_AsSSize(end_ob, &end)) { - goto err; - } - if unlikely(start < 0) - start += self->rpit_num; - if unlikely(end < 0) - end += self->rpit_num; - if unlikely((size_t)start >= self->rpit_num || - (size_t)start >= (size_t)end) - return_reference_(Dee_EmptySeq); - if unlikely((size_t)end > self->rpit_num) - end = (dssize_t)self->rpit_num; - end -= start; - ASSERT(end != 0); - return DeeSeq_RepeatItem(self->rpit_obj, (size_t)end); -err: - return NULL; -} - - PRIVATE WUNUSED NONNULL((1)) size_t DCALL repeatitem_nsi_getsize(RepeatItem *__restrict self) { if unlikely(self->rpit_num == (size_t)-1) @@ -1071,39 +1048,54 @@ repeatitem_nsi_getitem_fast(RepeatItem *__restrict self, size_t UNUSED(index)) { } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL -repeatitem_nsi_getrange(RepeatItem *__restrict self, - dssize_t start, - dssize_t end) { - if unlikely(start < 0) - start += self->rpit_num; - if unlikely(end < 0) - end += self->rpit_num; - if unlikely((size_t)start >= self->rpit_num || - (size_t)start >= (size_t)end) - return_reference_(Dee_EmptySeq); - if unlikely((size_t)end > self->rpit_num) - end = (dssize_t)self->rpit_num; - end -= start; - ASSERT(end != 0); - return DeeSeq_RepeatItem(self->rpit_obj, (size_t)end); +repeatitem_nsi_getrange_i(RepeatItem *__restrict self, + dssize_t i_begin, + dssize_t i_end) { + struct Dee_seq_range range; + size_t range_size; + DeeSeqRange_Clamp(&range, i_begin, i_end, self->rpit_num); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) + return_reference_(Dee_EmptySeq); + return DeeSeq_RepeatItem(self->rpit_obj, range_size); } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL -repeatitem_nsi_getrange_n(RepeatItem *__restrict self, - dssize_t start) { - if unlikely(start < 0) - start += self->rpit_num; - if unlikely((size_t)start >= self->rpit_num) +repeatitem_nsi_getrange_in(RepeatItem *__restrict self, + dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return repeatitem_nsi_getrange_i(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; + start = DeeSeqRange_Clamp_n(i_begin, self->rpit_num); + range_size = self->rpit_num - start; + if unlikely(range_size <= 0) return_reference_(Dee_EmptySeq); - ASSERT(self->rpit_num != 0); - return DeeSeq_RepeatItem(self->rpit_obj, - self->rpit_num - (size_t)start); + return DeeSeq_RepeatItem(self->rpit_obj, range_size); +#endif /* !__OPTIMIZE_SIZE__ */ } -PRIVATE size_t DCALL -repeatitem_nsi_find(RepeatItem *__restrict self, +PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL +repeatitem_getrange(RepeatItem *self, + DeeObject *begin, + DeeObject *end) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) + goto err; + if (DeeNone_Check(end)) + return repeatitem_nsi_getrange_in(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) + goto err; + return repeatitem_nsi_getrange_i(self, i_begin, i_end); +err: + return NULL; +} + + +PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL +repeatitem_nsi_find(RepeatItem *self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, + DeeObject *keyed_search_item, DeeObject *key) { int error; if (start >= self->rpit_num || start >= end) @@ -1116,10 +1108,10 @@ repeatitem_nsi_find(RepeatItem *__restrict self, return start; } -PRIVATE size_t DCALL -repeatitem_nsi_rfind(RepeatItem *__restrict self, +PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL +repeatitem_nsi_rfind(RepeatItem *self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, + DeeObject *keyed_search_item, DeeObject *key) { size_t result; result = repeatitem_nsi_find(self, start, end, keyed_search_item, key); @@ -1143,8 +1135,10 @@ PRIVATE struct type_nsi tpconst repeatitem_nsi = { /* .nsi_delitem = */ (dfunptr_t)NULL, /* .nsi_setitem = */ (dfunptr_t)NULL, /* .nsi_getitem_fast = */ (dfunptr_t)&repeatitem_nsi_getitem_fast, - /* .nsi_getrange = */ (dfunptr_t)&repeatitem_nsi_getrange, - /* .nsi_getrange_n = */ (dfunptr_t)&repeatitem_nsi_getrange_n, + /* .nsi_getrange = */ (dfunptr_t)&repeatitem_nsi_getrange_i, + /* .nsi_getrange_n = */ (dfunptr_t)&repeatitem_nsi_getrange_in, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&repeatitem_nsi_find, diff --git a/src/deemon/objects/seq/segments.c b/src/deemon/objects/seq/segments.c index e99b9c695..290e39e75 100644 --- a/src/deemon/objects/seq/segments.c +++ b/src/deemon/objects/seq/segments.c @@ -398,6 +398,8 @@ PRIVATE struct type_nsi tpconst seg_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/seq/simpleproxy.c b/src/deemon/objects/seq/simpleproxy.c index 3df4574a1..f9dd36226 100644 --- a/src/deemon/objects/seq/simpleproxy.c +++ b/src/deemon/objects/seq/simpleproxy.c @@ -449,6 +449,8 @@ PRIVATE struct type_nsi tpconst ids_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, /* TODO */ @@ -480,6 +482,8 @@ PRIVATE struct type_nsi tpconst types_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, /* TODO */ @@ -511,6 +515,8 @@ PRIVATE struct type_nsi tpconst classes_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, /* TODO */ diff --git a/src/deemon/objects/seq/subrange.c b/src/deemon/objects/seq/subrange.c index 6c9a72095..2cb78effd 100644 --- a/src/deemon/objects/seq/subrange.c +++ b/src/deemon/objects/seq/subrange.c @@ -420,6 +420,8 @@ PRIVATE struct type_nsi tpconst subrange_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&subrange_nsi_find, @@ -566,6 +568,7 @@ DeeSeq_GetRange(DeeObject *__restrict self, DREF SubRange *result; if unlikely(begin >= end) return_reference_(Dee_EmptySeq); + /* Create a sub-range sequence. */ result = DeeObject_MALLOC(SubRange); if unlikely(!result) @@ -738,6 +741,8 @@ PRIVATE struct type_nsi tpconst subrangen_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&subrangen_nsi_find, diff --git a/src/deemon/objects/seq/svec.c b/src/deemon/objects/seq/svec.c index 9fbf089c1..dbba66cbe 100644 --- a/src/deemon/objects/seq/svec.c +++ b/src/deemon/objects/seq/svec.c @@ -38,6 +38,9 @@ #include "../../runtime/runtime_error.h" #include "../../runtime/strings.h" +#undef SSIZE_MAX +#define SSIZE_MAX __SSIZE_MAX__ + DECL_BEGIN #define RVI_GETPOS(x) atomic_read(&(x)->rvi_pos) @@ -296,8 +299,7 @@ rvec_contains(RefVector *self, } PRIVATE WUNUSED NONNULL((1, 2)) DREF DeeObject *DCALL -rvec_getitem(RefVector *self, - DeeObject *index_ob) { +rvec_getitem(RefVector *self, DeeObject *index_ob) { size_t index; DREF DeeObject *result; if (DeeObject_AsSize(index_ob, &index)) @@ -328,9 +330,9 @@ PRIVATE ATTR_COLD int DCALL err_readonly_rvec(void) { } -PRIVATE int DCALL -rvec_setitem(RefVector *__restrict self, - DeeObject *__restrict index_ob, +PRIVATE WUNUSED NONNULL((1, 2)) int DCALL +rvec_setitem(RefVector *self, + DeeObject *index_ob, DeeObject *value) { size_t index; DREF DeeObject *old_item; @@ -358,8 +360,7 @@ rvec_setitem(RefVector *__restrict self, } PRIVATE WUNUSED NONNULL((1, 2)) int DCALL -rvec_delitem(RefVector *__restrict self, - DeeObject *__restrict index_ob) { +rvec_delitem(RefVector *self, DeeObject *index_ob) { return rvec_setitem(self, index_ob, NULL); } @@ -426,9 +427,9 @@ rvec_nsi_delitem_fast(RefVector *__restrict self, size_t index) { Dee_XDecref(oldobj); } -PRIVATE void DCALL -rvec_nsi_setitem_fast(RefVector *__restrict self, size_t index, - /*inherit(always)*/ DREF DeeObject *__restrict value) { +PRIVATE NONNULL((1, 3)) void DCALL +rvec_nsi_setitem_fast(RefVector *self, size_t index, + /*inherit(always)*/ DREF DeeObject *value) { DREF DeeObject *oldobj; ASSERT(index < self->rv_length); ASSERT(RefVector_IsWritable(self)); @@ -439,9 +440,9 @@ rvec_nsi_setitem_fast(RefVector *__restrict self, size_t index, Dee_XDecref(oldobj); } -PRIVATE int DCALL -rvec_nsi_setitem(RefVector *__restrict self, size_t index, - DeeObject *__restrict value) { +PRIVATE NONNULL((1, 3)) int DCALL +rvec_nsi_setitem(RefVector *self, size_t index, + DeeObject *value) { DREF DeeObject *oldobj; if unlikely(index >= self->rv_length) return err_index_out_of_bounds((DeeObject *)self, index, self->rv_length); @@ -467,9 +468,9 @@ rvec_nsi_getitem_fast(RefVector *__restrict self, size_t index) { return result; } -PRIVATE WUNUSED DREF DeeObject *DCALL -rvec_nsi_xchitem(RefVector *__restrict self, size_t index, - DeeObject *__restrict value) { +PRIVATE WUNUSED NONNULL((1, 3)) DREF DeeObject *DCALL +rvec_nsi_xchitem(RefVector *self, size_t index, + DeeObject *value) { DREF DeeObject *result; if unlikely(index >= self->rv_length) { err_index_out_of_bounds((DeeObject *)self, index, self->rv_length); @@ -494,9 +495,9 @@ rvec_nsi_xchitem(RefVector *__restrict self, size_t index, return NULL; } -PRIVATE bool DCALL -rvec_nsi_cmpdelitem(RefVector *__restrict self, size_t index, - DeeObject *__restrict old_value) { +PRIVATE WUNUSED NONNULL((1, 3)) bool DCALL +rvec_nsi_cmpdelitem(RefVector *self, size_t index, + DeeObject *old_value) { ASSERT(index < self->rv_length); ASSERT(RefVector_IsWritable(self)); RefVector_LockWrite(self); @@ -510,9 +511,9 @@ rvec_nsi_cmpdelitem(RefVector *__restrict self, size_t index, return true; } -PRIVATE size_t DCALL -rvec_nsi_find(RefVector *__restrict self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, DeeObject *key) { +PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL +rvec_nsi_find(RefVector *self, size_t start, size_t end, + DeeObject *keyed_search_item, DeeObject *key) { size_t i; DREF DeeObject *item; int temp; @@ -535,9 +536,9 @@ rvec_nsi_find(RefVector *__restrict self, size_t start, size_t end, return (size_t)-2; } -PRIVATE size_t DCALL -rvec_nsi_rfind(RefVector *__restrict self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, DeeObject *key) { +PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL +rvec_nsi_rfind(RefVector *self, size_t start, size_t end, + DeeObject *keyed_search_item, DeeObject *key) { size_t i; DREF DeeObject *item; int temp; @@ -563,9 +564,9 @@ rvec_nsi_rfind(RefVector *__restrict self, size_t start, size_t end, } -PRIVATE int DCALL -rvec_nsi_remove(RefVector *__restrict self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, DeeObject *key) { +PRIVATE WUNUSED NONNULL((1, 4)) int DCALL +rvec_nsi_remove(RefVector *self, size_t start, size_t end, + DeeObject *keyed_search_item, DeeObject *key) { size_t i; DREF DeeObject *item; int temp; @@ -594,9 +595,9 @@ rvec_nsi_remove(RefVector *__restrict self, size_t start, size_t end, return -1; } -PRIVATE int DCALL -rvec_nsi_rremove(RefVector *__restrict self, size_t start, size_t end, - DeeObject *__restrict keyed_search_item, DeeObject *key) { +PRIVATE WUNUSED NONNULL((1, 4)) int DCALL +rvec_nsi_rremove(RefVector *self, size_t start, size_t end, + DeeObject *keyed_search_item, DeeObject *key) { size_t i; DREF DeeObject *item; int temp; @@ -627,11 +628,9 @@ rvec_nsi_rremove(RefVector *__restrict self, size_t start, size_t end, return -1; } -PRIVATE size_t DCALL -rvec_nsi_removeall(RefVector *__restrict self, - size_t start, size_t end, - DeeObject *__restrict keyed_search_item, - DeeObject *key) { +PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL +rvec_nsi_removeall(RefVector *self, size_t start, size_t end, + DeeObject *keyed_search_item, DeeObject *key) { size_t i; size_t result = 0; DREF DeeObject *item; @@ -664,9 +663,8 @@ rvec_nsi_removeall(RefVector *__restrict self, } PRIVATE WUNUSED NONNULL((1, 4)) size_t DCALL -rvec_nsi_removeif(RefVector *__restrict self, - size_t start, size_t end, - DeeObject *__restrict should_remove) { +rvec_nsi_removeif(RefVector *self, size_t start, size_t end, + DeeObject *should_remove) { size_t i; size_t result = 0; int temp; @@ -704,59 +702,50 @@ rvec_nsi_removeif(RefVector *__restrict self, PRIVATE WUNUSED NONNULL((1)) int DCALL rvec_nsi_delrange(RefVector *__restrict self, - dssize_t start, dssize_t end) { + dssize_t i_begin, dssize_t i_end) { + struct Dee_seq_range range; size_t i; if (!RefVector_IsWritable(self)) return err_readonly_rvec(); - if (start < 0) - start += self->rv_length; - if (end < 0) - end += self->rv_length; - if ((size_t)end > self->rv_length) - end = (dssize_t)self->rv_length; - for (i = (size_t)start; i < (size_t)end; ++i) + DeeSeqRange_Clamp(&range, i_begin, i_end, self->rv_length); + for (i = range.sr_start; i < range.sr_end; ++i) rvec_nsi_delitem_fast(self, i); return 0; } PRIVATE WUNUSED NONNULL((1)) int DCALL rvec_nsi_delrange_n(RefVector *__restrict self, - dssize_t start) { - size_t i, end = self->rv_length; + dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return rvec_nsi_delrange(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t i, start; if (!RefVector_IsWritable(self)) return err_readonly_rvec(); - if (start < 0) - start += end; - for (i = (size_t)start; i < end; ++i) + start = DeeSeqRange_Clamp_n(i_begin, self->rv_length); + for (i = start; i < self->rv_length; ++i) rvec_nsi_delitem_fast(self, i); return 0; +#endif /* !__OPTIMIZE_SIZE__ */ } -PRIVATE int DCALL -rvec_nsi_setrange(RefVector *__restrict self, - dssize_t start, dssize_t end, - DeeObject *__restrict values) { +PRIVATE WUNUSED NONNULL((1, 4)) int DCALL +rvec_nsi_setrange(RefVector *self, dssize_t i_begin, + dssize_t i_end, DeeObject *values) { + struct Dee_seq_range range; + size_t range_size; size_t i, fast_length; DREF DeeObject *elem; - if (DeeNone_Check(values)) - return rvec_nsi_delrange(self, start, end); if (!RefVector_IsWritable(self)) return err_readonly_rvec(); - if (start < 0) - start += self->rv_length; - if (end < 0) - end += self->rv_length; - if ((size_t)end > self->rv_length) - end = (dssize_t)self->rv_length; + DeeSeqRange_Clamp(&range, i_begin, i_end, self->rv_length); + range_size = range.sr_end - range.sr_start; fast_length = DeeFastSeq_GetSize(values); if (fast_length != DEE_FASTSEQ_NOTFAST) { - if (fast_length != ((size_t)end - (size_t)start)) { - return err_invalid_unpack_size(values, - (size_t)end - (size_t)start, - fast_length); - } - for (i = (size_t)start; i < (size_t)end; ++i) { - elem = DeeFastSeq_GetItem(values, i - (size_t)start); + if (fast_length != range_size) + return err_invalid_unpack_size(values, range_size, fast_length); + for (i = range.sr_start; i < range.sr_end; ++i) { + elem = DeeFastSeq_GetItem(values, i - range.sr_start); if unlikely(!elem) goto err; rvec_nsi_setitem_fast(self, i, elem); /* Inherit reference. */ @@ -766,13 +755,13 @@ rvec_nsi_setrange(RefVector *__restrict self, iterator = DeeObject_IterSelf(values); if unlikely(!iterator) goto err; - for (i = (size_t)start; i < (size_t)end; ++i) { + for (i = range.sr_start; i < range.sr_end; ++i) { elem = DeeObject_IterNext(iterator); if unlikely(!ITER_ISOK(elem)) { if unlikely(elem == ITER_DONE) { err_invalid_unpack_size(values, - (size_t)end - (size_t)start, - i - (size_t)start); + range_size, + i - range.sr_start); } err_iterator: Dee_Decref(iterator); @@ -784,7 +773,7 @@ rvec_nsi_setrange(RefVector *__restrict self, elem = DeeObject_IterNext(iterator); if unlikely(elem != ITER_DONE) { if (elem) { - err_invalid_unpack_iter_size(values, iterator, (size_t)end - (size_t)start); + err_invalid_unpack_iter_size(values, iterator, range_size); Dee_Decref(elem); } goto err_iterator; @@ -796,42 +785,33 @@ rvec_nsi_setrange(RefVector *__restrict self, return -1; } -PRIVATE int DCALL -rvec_nsi_setrange_n(RefVector *__restrict self, - dssize_t start, - DeeObject *__restrict values) { - if (DeeNone_Check(values)) - return rvec_nsi_delrange_n(self, start); - return rvec_nsi_setrange(self, start, - (size_t)self->rv_length, - values); +PRIVATE WUNUSED NONNULL((1, 3)) int DCALL +rvec_nsi_setrange_n(RefVector *self, dssize_t start, + DeeObject *values) { + return rvec_nsi_setrange(self, start, SSIZE_MAX, values); } PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL -rvec_delrange(RefVector *__restrict self, - DeeObject *__restrict start, - DeeObject *__restrict end) { - dssize_t start_index; - dssize_t end_index; - if (DeeObject_AsSSize(start, &start_index)) +rvec_delrange(RefVector *self, DeeObject *begin, DeeObject *end) { + dssize_t i_begin; + dssize_t i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; if (DeeNone_Check(end)) - return rvec_nsi_delrange_n(self, start_index); - if (DeeObject_AsSSize(end, &end_index)) + return rvec_nsi_delrange_n(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) goto err; - return rvec_nsi_delrange(self, start_index, end_index); + return rvec_nsi_delrange(self, i_begin, i_end); err: return -1; } PRIVATE WUNUSED NONNULL((1, 2, 3, 4)) int DCALL -rvec_setrange(RefVector *__restrict self, - DeeObject *__restrict start, - DeeObject *__restrict end, - DeeObject *__restrict values) { +rvec_setrange(RefVector *self, DeeObject *begin, + DeeObject *end, DeeObject *values) { dssize_t start_index; dssize_t end_index; - if (DeeObject_AsSSize(start, &start_index)) + if (DeeObject_AsSSize(begin, &start_index)) goto err; if (DeeNone_Check(end)) return rvec_nsi_setrange_n(self, start_index, values); @@ -856,6 +836,8 @@ PRIVATE struct type_nsi tpconst rvec_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&rvec_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)&rvec_nsi_delrange, + /* .nsi_delrange_n = */ (dfunptr_t)&rvec_nsi_delrange_n, /* .nsi_setrange = */ (dfunptr_t)&rvec_nsi_setrange, /* .nsi_setrange_n = */ (dfunptr_t)&rvec_nsi_setrange_n, /* .nsi_find = */ (dfunptr_t)&rvec_nsi_find, @@ -942,7 +924,7 @@ INTERN DeeTypeObject RefVector_Type = { OBJECT_HEAD_INIT(&DeeType_Type), /* .tp_name = */ "_RefVector", /* .tp_doc = */ NULL, - /* .tp_flags = */ TP_FNORMAL | TP_FFINAL, + /* .tp_flags = */ TP_FNORMAL | TP_FFINAL, /* TODO: This needs to become a GC object (since it can reference itself) */ /* .tp_weakrefs = */ 0, /* .tp_features = */ TF_NONE, /* .tp_base = */ &DeeSeq_Type, @@ -1438,6 +1420,8 @@ PRIVATE struct type_nsi tpconst svec_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&svec_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&svec_nsi_find, diff --git a/src/deemon/objects/seq/transform.c b/src/deemon/objects/seq/transform.c index e28dc31f5..f45991bd5 100644 --- a/src/deemon/objects/seq/transform.c +++ b/src/deemon/objects/seq/transform.c @@ -355,6 +355,8 @@ PRIVATE struct type_nsi tpconst trans_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* TODO */ /* .nsi_getrange_n = */ (dfunptr_t)NULL, /* TODO */ + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/seq/typemro.c b/src/deemon/objects/seq/typemro.c index 28b6b5fac..746f49f14 100644 --- a/src/deemon/objects/seq/typemro.c +++ b/src/deemon/objects/seq/typemro.c @@ -799,6 +799,8 @@ PRIVATE struct type_nsi tpconst typemro_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&typemro_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&typemro_nsi_find, @@ -830,6 +832,8 @@ PRIVATE struct type_nsi tpconst typebases_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&typebases_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&typebases_nsi_find, diff --git a/src/deemon/objects/seq_mutable.c b/src/deemon/objects/seq_mutable.c index 5e76e619c..4b9441dca 100644 --- a/src/deemon/objects/seq_mutable.c +++ b/src/deemon/objects/seq_mutable.c @@ -670,8 +670,8 @@ DeeSeq_DelRange(DeeObject *__restrict self, size_t start, size_t end) { if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ && is_noninherited_nsi(tp_self, seq, nsi)) { /* Check for NSI-optimized variants */ - if (nsi->nsi_seqlike.nsi_setrange) - return (*nsi->nsi_seqlike.nsi_setrange)(self, start, end, Dee_None); + if (nsi->nsi_seqlike.nsi_delrange) + return (*nsi->nsi_seqlike.nsi_delrange)(self, start, end); if (nsi->nsi_seqlike.nsi_erase) { size_t temp, mylen; mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); @@ -718,9 +718,8 @@ DeeSeq_DelRange(DeeObject *__restrict self, size_t start, size_t end) { return 0; } } - if (has_noninherited_delrange(tp_self, seq) || - has_noninherited_setrange(tp_self, seq)) { - /* Try to implement delitem using delrange or setrange. */ + if (has_noninherited_delrange(tp_self, seq)) { + /* Try to implement delitem using delrange. */ DREF DeeObject *start_index, *end_index; start_index = DeeInt_NewSize(start); if unlikely(!start_index) @@ -730,11 +729,7 @@ DeeSeq_DelRange(DeeObject *__restrict self, size_t start, size_t end) { Dee_Decref(start_index); goto err; } - if (has_noninherited_delrange(tp_self, seq)) { - result = (*seq->tp_range_del)(self, start_index, end_index); - } else { - result = (*seq->tp_range_set)(self, start_index, end_index, Dee_None); - } + result = (*seq->tp_range_del)(self, start_index, end_index); Dee_Decref(end_index); Dee_Decref(start_index); return result; @@ -817,14 +812,10 @@ DeeSeq_DelRangeN(DeeObject *__restrict self, size_t start) { if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ && is_noninherited_nsi(tp_self, seq, nsi)) { /* Check for NSI-optimized variants */ - if (nsi->nsi_seqlike.nsi_setrange_n) - return (*nsi->nsi_seqlike.nsi_setrange_n)(self, start, Dee_None); - if (nsi->nsi_seqlike.nsi_setrange) { - size_t mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); - if unlikely(mylen == (size_t)-1) - goto err; - return (*nsi->nsi_seqlike.nsi_setrange)(self, start, mylen, Dee_None); - } + if (nsi->nsi_seqlike.nsi_delrange_n) + return (*nsi->nsi_seqlike.nsi_delrange_n)(self, start); + if (nsi->nsi_seqlike.nsi_delrange) + return (*nsi->nsi_seqlike.nsi_delrange)(self, start, SSIZE_MAX); if (nsi->nsi_seqlike.nsi_erase) { size_t temp, mylen; mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); @@ -865,18 +856,13 @@ DeeSeq_DelRangeN(DeeObject *__restrict self, size_t start) { return 0; } } - if (has_noninherited_delrange(tp_self, seq) || - has_noninherited_setrange(tp_self, seq)) { - /* Try to implement delitem using delrange or setrange. */ + if (has_noninherited_delrange(tp_self, seq)) { + /* Try to implement delitem using delrange. */ DREF DeeObject *start_index; start_index = DeeInt_NewSize(start); if unlikely(!start_index) goto err; - if (seq->tp_range_del) { - result = (*seq->tp_range_del)(self, start_index, Dee_None); - } else { - result = (*seq->tp_range_set)(self, start_index, Dee_None, Dee_None); - } + result = (*seq->tp_range_del)(self, start_index, Dee_None); Dee_Decref(start_index); return result; } @@ -1266,23 +1252,6 @@ DeeSeq_SetRange(DeeObject *self, size_t start, size_t end, Dee_Decref(start_ob); return result; } -#if 0 - if (has_noninherited_setrange(tp_self, seq)) { - DREF DeeObject *start_ob, *end_ob; - start_ob = DeeInt_NewSize(start); - if unlikely(!start_ob) - goto err; - end_ob = DeeInt_NewSize(end); - if unlikely(!end_ob) { - Dee_Decref(start_ob); - goto err; - } - result = (*seq->tp_range_set)(self, start_ob, end_ob, Dee_None); - Dee_Decref(end_ob); - Dee_Decref(start_ob); - return result; - } -#endif if (has_noninherited_delitem(tp_self, seq)) { do { DREF DeeObject *index_ob; @@ -2391,7 +2360,7 @@ DeeSeq_Erase(DeeObject *__restrict self, /* Check for NSI-optimized variants */ if (nsi->nsi_seqlike.nsi_erase) return (*nsi->nsi_seqlike.nsi_erase)(self, index, count); - if (nsi->nsi_seqlike.nsi_setrange) { + if (nsi->nsi_seqlike.nsi_delrange) { size_t mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); if unlikely(mylen == (size_t)-1) goto err; @@ -2401,7 +2370,7 @@ DeeSeq_Erase(DeeObject *__restrict self, } else if (index + count > mylen) { count = mylen - index; } - if ((*nsi->nsi_seqlike.nsi_setrange)(self, index, index + count, Dee_None)) + if ((*nsi->nsi_seqlike.nsi_delrange)(self, index, index + count)) goto err; return count; } @@ -2426,8 +2395,7 @@ DeeSeq_Erase(DeeObject *__restrict self, return count; } } - if (has_noninherited_delrange(tp_self, seq) || - has_noninherited_setrange(tp_self, seq)) { + if (has_noninherited_delrange(tp_self, seq)) { DREF DeeObject *start_index, *end_index; size_t mylen = DeeObject_Size(self); if unlikely(mylen == (size_t)-1) @@ -2446,9 +2414,7 @@ DeeSeq_Erase(DeeObject *__restrict self, Dee_Decref(start_index); goto err; } - error = has_noninherited_delrange(tp_self, seq) - ? (*seq->tp_range_del)(self, start_index, end_index) - : (*seq->tp_range_set)(self, start_index, end_index, Dee_None); + error = (*seq->tp_range_del)(self, start_index, end_index); Dee_Decref(end_index); Dee_Decref(start_index); if unlikely(error) @@ -2576,7 +2542,7 @@ DeeSeq_PopItem(DeeObject *__restrict self, dssize_t index) { return result; } } - if (nsi->nsi_seqlike.nsi_setrange) { + if (nsi->nsi_seqlike.nsi_delrange) { if (nsi->nsi_seqlike.nsi_getitem) { if (index < 0) { size_t mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); @@ -2587,7 +2553,7 @@ DeeSeq_PopItem(DeeObject *__restrict self, dssize_t index) { result = (*nsi->nsi_seqlike.nsi_getitem)(self, (size_t)index); if unlikely(!result) goto err; - if unlikely((*nsi->nsi_seqlike.nsi_setrange)(self, (size_t)index, (size_t)index + 1, Dee_None)) + if unlikely((*nsi->nsi_seqlike.nsi_delrange)(self, (size_t)index, (size_t)index + 1)) goto err_r; return result; } @@ -2606,7 +2572,7 @@ DeeSeq_PopItem(DeeObject *__restrict self, dssize_t index) { err_unbound_index(self, (size_t)index); goto err; } - if unlikely((*nsi->nsi_seqlike.nsi_setrange)(self, (size_t)index, (size_t)index + 1, Dee_None)) + if unlikely((*nsi->nsi_seqlike.nsi_delrange)(self, (size_t)index, (size_t)index + 1)) goto err_r; return result; } @@ -2634,8 +2600,7 @@ DeeSeq_PopItem(DeeObject *__restrict self, dssize_t index) { goto err_r; return result; } - if (has_noninherited_delrange(tp_self, seq) || - has_noninherited_setrange(tp_self, seq)) { + if (has_noninherited_delrange(tp_self, seq)) { DREF DeeObject *index_ob, *index_plus1_ob; if (index < 0) { size_t mylen = DeeObject_Size(self); @@ -2656,9 +2621,7 @@ DeeSeq_PopItem(DeeObject *__restrict self, dssize_t index) { Dee_Decref(index_ob); goto err_r; } - error = has_noninherited_delrange(tp_self, seq) - ? (*seq->tp_range_del)(self, index_ob, index_plus1_ob) - : (*seq->tp_range_set)(self, index_ob, index_plus1_ob, Dee_None); + error = (*seq->tp_range_del)(self, index_ob, index_plus1_ob); Dee_Decref(index_plus1_ob); Dee_Decref(index_ob); if unlikely(error) @@ -2705,7 +2668,7 @@ DeeSeq_Remove(DeeObject *self, size_t start, size_t end, if (nsi->nsi_seqlike.nsi_getitem && (nsi->nsi_seqlike.nsi_delitem || nsi->nsi_seqlike.nsi_erase || - nsi->nsi_seqlike.nsi_setrange)) { + nsi->nsi_seqlike.nsi_delrange)) { size_t i, mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); if (end > mylen) end = mylen; @@ -2744,8 +2707,8 @@ DeeSeq_Remove(DeeObject *self, size_t start, size_t end, if ((*nsi->nsi_seqlike.nsi_erase)(self, i, 1) == (size_t)-1) goto err; } else { - ASSERT(nsi->nsi_seqlike.nsi_setrange); - if ((*nsi->nsi_seqlike.nsi_setrange)(self, i, i + 1, Dee_None)) + ASSERT(nsi->nsi_seqlike.nsi_delrange); + if ((*nsi->nsi_seqlike.nsi_delrange)(self, i, i + 1)) goto err; } return 1; @@ -2991,7 +2954,7 @@ DeeSeq_RRemove(DeeObject *self, size_t start, size_t end, if (nsi->nsi_seqlike.nsi_getitem && (nsi->nsi_seqlike.nsi_delitem || nsi->nsi_seqlike.nsi_erase || - nsi->nsi_seqlike.nsi_setrange)) { + nsi->nsi_seqlike.nsi_delrange)) { size_t i, mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); if (end > mylen) end = mylen; @@ -3033,8 +2996,8 @@ DeeSeq_RRemove(DeeObject *self, size_t start, size_t end, if ((*nsi->nsi_seqlike.nsi_erase)(self, i, 1) == (size_t)-1) goto err; } else { - ASSERT(nsi->nsi_seqlike.nsi_setrange); - if ((*nsi->nsi_seqlike.nsi_setrange)(self, i, i + 1, Dee_None)) + ASSERT(nsi->nsi_seqlike.nsi_delrange); + if ((*nsi->nsi_seqlike.nsi_delrange)(self, i, i + 1)) goto err; } return 1; @@ -3487,7 +3450,7 @@ DeeSeq_RemoveAll(DeeObject *self, size_t start, size_t end, if (nsi->nsi_seqlike.nsi_getitem && (nsi->nsi_seqlike.nsi_delitem || nsi->nsi_seqlike.nsi_erase || - nsi->nsi_seqlike.nsi_setrange)) { + nsi->nsi_seqlike.nsi_delrange)) { size_t i, mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); if (end > mylen) end = mylen; @@ -3514,8 +3477,8 @@ DeeSeq_RemoveAll(DeeObject *self, size_t start, size_t end, if ((*nsi->nsi_seqlike.nsi_erase)(self, i, 1) == (size_t)-1) goto err_keyed_search_item; } else { - ASSERT(nsi->nsi_seqlike.nsi_setrange); - if ((*nsi->nsi_seqlike.nsi_setrange)(self, i, i + 1, Dee_None)) + ASSERT(nsi->nsi_seqlike.nsi_delrange); + if ((*nsi->nsi_seqlike.nsi_delrange)(self, i, i + 1)) goto err_keyed_search_item; } if unlikely(count == (size_t)-2) @@ -3542,8 +3505,8 @@ DeeSeq_RemoveAll(DeeObject *self, size_t start, size_t end, if ((*nsi->nsi_seqlike.nsi_erase)(self, i, 1) == (size_t)-1) goto err; } else { - ASSERT(nsi->nsi_seqlike.nsi_setrange); - if ((*nsi->nsi_seqlike.nsi_setrange)(self, i, i + 1, Dee_None)) + ASSERT(nsi->nsi_seqlike.nsi_delrange); + if ((*nsi->nsi_seqlike.nsi_delrange)(self, i, i + 1)) goto err; } if unlikely(count == (size_t)-2) @@ -3961,7 +3924,7 @@ DeeSeq_RemoveIf(DeeObject *self, size_t start, if (nsi->nsi_seqlike.nsi_getitem && (nsi->nsi_seqlike.nsi_delitem || nsi->nsi_seqlike.nsi_erase || - nsi->nsi_seqlike.nsi_setrange)) { + nsi->nsi_seqlike.nsi_delrange)) { size_t i, mylen = (*nsi->nsi_seqlike.nsi_getsize)(self); if (end > mylen) end = mylen; @@ -3988,8 +3951,8 @@ DeeSeq_RemoveIf(DeeObject *self, size_t start, if ((*nsi->nsi_seqlike.nsi_erase)(self, i, 1) == (size_t)-1) goto err; } else { - ASSERT(nsi->nsi_seqlike.nsi_setrange); - if ((*nsi->nsi_seqlike.nsi_setrange)(self, i, i + 1, Dee_None)) + ASSERT(nsi->nsi_seqlike.nsi_delrange); + if ((*nsi->nsi_seqlike.nsi_delrange)(self, i, i + 1)) goto err; } if unlikely(count == (size_t)-2) diff --git a/src/deemon/objects/string.c b/src/deemon/objects/string.c index e1e5e266e..6d2800af9 100644 --- a/src/deemon/objects/string.c +++ b/src/deemon/objects/string.c @@ -33,11 +33,13 @@ #include #include #include -#include #include /* memmem() */ +#include #include +#include #include +#include #include @@ -45,9 +47,9 @@ #include "../runtime/strings.h" #undef SSIZE_MAX -#include #define SSIZE_MAX __SSIZE_MAX__ - +#undef byte_t +#define byte_t __BYTE_TYPE__ DECL_BEGIN @@ -584,10 +586,10 @@ compare_string_bytes(String *__restrict lhs, size_t rhs_len; if (!lhs->s_data || lhs->s_data->u_width == STRING_WIDTH_1BYTE) { - uint8_t *lhs_str; + uint8_t const *lhs_str; int result; /* Compare against single-byte string. */ - lhs_str = (uint8_t *)lhs->s_str; + lhs_str = (uint8_t const *)lhs->s_str; lhs_len = lhs->s_len; rhs_len = DeeBytes_SIZE(rhs); /* Most simple case: compare ascii/single-byte strings. */ @@ -595,7 +597,7 @@ compare_string_bytes(String *__restrict lhs, if (result != 0) return fix_memcmp_return(result); } else { - uint8_t *rhs_str; + byte_t const *rhs_str; struct string_utf *lhs_utf; /* Compare against single-byte string. */ rhs_str = DeeBytes_DATA(rhs); @@ -660,9 +662,9 @@ compare_strings(String *__restrict lhs, size_t rhs_len; if (!lhs->s_data || lhs->s_data->u_width == STRING_WIDTH_1BYTE) { - uint8_t *lhs_str; + uint8_t const *lhs_str; /* Compare against single-byte string. */ - lhs_str = (uint8_t *)lhs->s_str; + lhs_str = (uint8_t const *)lhs->s_str; lhs_len = lhs->s_len; if (!rhs->s_data || rhs->s_data->u_width == STRING_WIDTH_1BYTE) { @@ -707,18 +709,18 @@ compare_strings(String *__restrict lhs, } } else if (!rhs->s_data || rhs->s_data->u_width == STRING_WIDTH_1BYTE) { - uint8_t *rhs_str; + uint8_t const *rhs_str; struct string_utf *lhs_utf; /* Compare against single-byte string. */ - rhs_str = (uint8_t *)rhs->s_str; + rhs_str = (uint8_t const *)rhs->s_str; rhs_len = rhs->s_len; lhs_utf = lhs->s_data; switch (lhs_utf->u_width) { CASE_WIDTH_2BYTE: { - uint16_t *lhs_str; + uint16_t const *lhs_str; size_t i, common_len; - lhs_str = (uint16_t *)lhs_utf->u_data[lhs_utf->u_width]; + lhs_str = (uint16_t const *)lhs_utf->u_data[lhs_utf->u_width]; lhs_len = WSTR_LENGTH(lhs_str); common_len = MIN(rhs_len, lhs_len); for (i = 0; i < common_len; ++i) { @@ -729,9 +731,9 @@ compare_strings(String *__restrict lhs, } break; CASE_WIDTH_4BYTE: { - uint32_t *lhs_str; + uint32_t const *lhs_str; size_t i, common_len; - lhs_str = (uint32_t *)lhs_utf->u_data[lhs_utf->u_width]; + lhs_str = (uint32_t const *)lhs_utf->u_data[lhs_utf->u_width]; lhs_len = WSTR_LENGTH(lhs_str); common_len = MIN(rhs_len, lhs_len); for (i = 0; i < common_len; ++i) { @@ -744,8 +746,8 @@ compare_strings(String *__restrict lhs, default: __builtin_unreachable(); } } else { - struct string_utf *lhs_utf; - struct string_utf *rhs_utf; + struct string_utf const *lhs_utf; + struct string_utf const *rhs_utf; lhs_utf = lhs->s_data; rhs_utf = rhs->s_data; ASSERT(lhs_utf != NULL); @@ -756,16 +758,16 @@ compare_strings(String *__restrict lhs, switch (lhs_utf->u_width) { CASE_WIDTH_2BYTE: { - uint16_t *lhs_str; - lhs_str = (uint16_t *)lhs_utf->u_data[lhs_utf->u_width]; + uint16_t const *lhs_str; + lhs_str = (uint16_t const *)lhs_utf->u_data[lhs_utf->u_width]; lhs_len = WSTR_LENGTH(lhs_str); switch (rhs_utf->u_width) { CASE_WIDTH_2BYTE: { int result; - uint16_t *rhs_str; + uint16_t const *rhs_str; size_t common_len; - rhs_str = (uint16_t *)rhs_utf->u_data[rhs_utf->u_width]; + rhs_str = (uint16_t const *)rhs_utf->u_data[rhs_utf->u_width]; rhs_len = WSTR_LENGTH(rhs_str); common_len = MIN(lhs_len, rhs_len); result = memcmpw(lhs_str, rhs_str, common_len); @@ -774,9 +776,9 @@ compare_strings(String *__restrict lhs, } break; CASE_WIDTH_4BYTE: { - uint32_t *rhs_str; + uint32_t const *rhs_str; size_t i, common_len; - rhs_str = (uint32_t *)rhs_utf->u_data[rhs_utf->u_width]; + rhs_str = (uint32_t const *)rhs_utf->u_data[rhs_utf->u_width]; rhs_len = WSTR_LENGTH(rhs_str); common_len = MIN(lhs_len, rhs_len); for (i = 0; i < common_len; ++i) { @@ -791,15 +793,15 @@ compare_strings(String *__restrict lhs, } break; CASE_WIDTH_4BYTE: { - uint32_t *lhs_str; - lhs_str = (uint32_t *)lhs_utf->u_data[lhs_utf->u_width]; + uint32_t const *lhs_str; + lhs_str = (uint32_t const *)lhs_utf->u_data[lhs_utf->u_width]; lhs_len = WSTR_LENGTH(lhs_str); switch (rhs_utf->u_width) { CASE_WIDTH_2BYTE: { - uint16_t *rhs_str; + uint16_t const *rhs_str; size_t i, common_len; - rhs_str = (uint16_t *)rhs_utf->u_data[rhs_utf->u_width]; + rhs_str = (uint16_t const *)rhs_utf->u_data[rhs_utf->u_width]; rhs_len = WSTR_LENGTH(rhs_str); common_len = MIN(lhs_len, rhs_len); for (i = 0; i < common_len; ++i) { @@ -811,9 +813,9 @@ compare_strings(String *__restrict lhs, CASE_WIDTH_4BYTE: { int result; - uint32_t *rhs_str; + uint32_t const *rhs_str; size_t common_len; - rhs_str = (uint32_t *)rhs_utf->u_data[rhs_utf->u_width]; + rhs_str = (uint32_t const *)rhs_utf->u_data[rhs_utf->u_width]; rhs_len = WSTR_LENGTH(rhs_str); common_len = MIN(lhs_len, rhs_len); result = memcmpl(lhs_str, rhs_str, common_len); @@ -1073,7 +1075,7 @@ PRIVATE WUNUSED NONNULL((1)) size_t DCALL stringiter_nii_getindex(StringIterator *__restrict self) { union dcharptr pos; pos.ptr = READ_ITER_PTR(self); - return (size_t)(pos.cp8 - (uint8_t *)DeeString_WSTR(self->si_string)) / + return (size_t)(pos.cp8 - (byte_t const *)DeeString_WSTR(self->si_string)) / STRING_SIZEOF_WIDTH(self->si_width); } @@ -1081,7 +1083,7 @@ PRIVATE WUNUSED NONNULL((1)) int DCALL stringiter_nii_setindex(StringIterator *__restrict self, size_t index) { if (index > DeeString_WLEN(self->si_string)) index = DeeString_WLEN(self->si_string); - self->si_iter.cp8 = (uint8_t *)DeeString_WSTR(self->si_string) + + self->si_iter.cp8 = (byte_t *)DeeString_WSTR(self->si_string) + (index * STRING_SIZEOF_WIDTH(self->si_width)); return 0; } @@ -1282,33 +1284,54 @@ string_get(String *self, return NULL; } +PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL +string_getrange_i(String *__restrict self, + dssize_t begin, dssize_t end) { + struct Dee_seq_range range; + size_t range_size; + void *str = DeeString_WSTR(self); + int width = DeeString_WIDTH(self); + size_t len = WSTR_LENGTH(str); + DeeSeqRange_Clamp(&range, begin, end, len); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) + return_empty_string; + return DeeString_NewWithWidth((byte_t *)str + + (range.sr_start * STRING_SIZEOF_WIDTH(width)), + range_size, width); +} + +PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL +string_getrange_in(String *__restrict self, dssize_t begin) { +#ifdef __OPTIMIZE_SIZE__ + return string_getrange_i(self, begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t range_size, start; + void *str = DeeString_WSTR(self); + int width = DeeString_WIDTH(self); + size_t len = WSTR_LENGTH(str); + start = DeeSeqRange_Clamp_n(begin, len); + range_size = len - start; + if unlikely(range_size <= 0) + return_empty_string; + return DeeString_NewWithWidth((byte_t *)str + + (start * STRING_SIZEOF_WIDTH(width)), + range_size, width); +#endif /* !__OPTIMIZE_SIZE__ */ +} + INTERN WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL string_range_get(String *__restrict self, DeeObject *__restrict begin, DeeObject *__restrict end) { - void *str = DeeString_WSTR(self); - int width = DeeString_WIDTH(self); - size_t len = WSTR_LENGTH(str); - dssize_t i_begin, i_end = (dssize_t)len; + dssize_t i_begin, i_end; if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (!DeeNone_Check(end)) { - if (DeeObject_AsSSize(end, &i_end)) - goto err; - } - if (i_begin < 0) - i_begin += len; - if (i_end < 0) - i_end += len; - if unlikely((size_t)i_begin >= len || - (size_t)i_begin >= (size_t)i_end) - return_empty_string; - if unlikely((size_t)i_end > len) - i_end = (dssize_t)len; - return DeeString_NewWithWidth((uint8_t *)str + - ((size_t)i_begin * STRING_SIZEOF_WIDTH(width)), - (size_t)i_end - (size_t)i_begin, - width); + if (DeeNone_Check(end)) + return string_getrange_in(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) + goto err; + return string_getrange_i(self, i_begin, i_end); err: return NULL; } @@ -1351,8 +1374,10 @@ PRIVATE struct type_nsi tpconst string_nsi = { /* .nsi_delitem = */ (dfunptr_t)NULL, /* .nsi_setitem = */ (dfunptr_t)NULL, /* .nsi_getitem_fast = */ (dfunptr_t)NULL, - /* .nsi_getrange = */ (dfunptr_t)NULL, - /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_getrange = */ (dfunptr_t)&string_getrange_i, + /* .nsi_getrange_n = */ (dfunptr_t)&string_getrange_in, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/tuple.c b/src/deemon/objects/tuple.c index f8fb5e1b0..6a1d19086 100644 --- a/src/deemon/objects/tuple.c +++ b/src/deemon/objects/tuple.c @@ -73,6 +73,10 @@ #include #endif /* CONFIG_TUPLE_CACHE_MAXCOUNT && !CONFIG_NO_THREADS */ +#undef SSIZE_MAX +#include +#define SSIZE_MAX __SSIZE_MAX__ + DECL_BEGIN #ifndef NDEBUG @@ -1477,38 +1481,40 @@ tuple_getitem(Tuple *self, DeeObject *index) { INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL tuple_getrange_i(Tuple *__restrict self, dssize_t begin, dssize_t end) { - if unlikely(begin < 0) - begin += DeeTuple_SIZE(self); - if unlikely(end < 0) - end += DeeTuple_SIZE(self); - if unlikely((size_t)begin >= DeeTuple_SIZE(self) || - (size_t)begin >= (size_t)end) - return_empty_tuple; - if unlikely((size_t)end > DeeTuple_SIZE(self)) - end = (dssize_t)DeeTuple_SIZE(self); - return DeeTuple_NewVector((size_t)(end - begin), - DeeTuple_ELEM(self) + begin); + size_t range_size; + struct Dee_seq_range range; + DeeSeqRange_Clamp(&range, begin, end, self->t_size); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size == self->t_size) + return_reference((DeeObject *)self); + return DeeTuple_NewVector(range_size, self->t_elem + range.sr_start); } INTERN WUNUSED NONNULL((1)) DREF DeeObject *DCALL tuple_getrange_in(Tuple *__restrict self, dssize_t begin) { - if unlikely(begin < 0) - begin += DeeTuple_SIZE(self); - if unlikely((size_t)begin >= DeeTuple_SIZE(self)) - return_empty_tuple; - return DeeTuple_NewVector(DeeTuple_SIZE(self) - (size_t)begin, - DeeTuple_ELEM(self) + (size_t)begin); +#ifdef __OPTIMIZE_SIZE__ + return tuple_getrange_i(self, begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; + start = DeeSeqRange_Clamp_n(begin, self->t_size); + if unlikely(start == 0) + return_reference((DeeObject *)self); + return DeeTuple_NewVector(DeeTuple_SIZE(self) - start, + DeeTuple_ELEM(self) + start); +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL tuple_getrange(Tuple *__restrict self, DeeObject *__restrict begin, DeeObject *__restrict end) { - dssize_t i_begin, i_end = DeeTuple_SIZE(self); + dssize_t i_begin, i_end; if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (!DeeNone_Check(end) && DeeObject_AsSSize(end, &i_end)) + if (DeeNone_Check(end)) + return tuple_getrange_in(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) goto err; return tuple_getrange_i(self, i_begin, i_end); err: @@ -1597,6 +1603,8 @@ PRIVATE struct type_nsi tpconst tuple_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&tuple_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)&tuple_getrange_i, /* .nsi_getrange_n = */ (dfunptr_t)&tuple_getrange_in, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)&tuple_nsi_find, diff --git a/src/deemon/objects/unicode/regroups.c b/src/deemon/objects/unicode/regroups.c index 1938330e0..41fa80bd9 100644 --- a/src/deemon/objects/unicode/regroups.c +++ b/src/deemon/objects/unicode/regroups.c @@ -470,6 +470,8 @@ PRIVATE struct type_nsi tpconst rg_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&rg_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, @@ -593,6 +595,8 @@ PRIVATE struct type_nsi tpconst rss_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&rss_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, @@ -623,6 +627,8 @@ PRIVATE struct type_nsi tpconst rsb_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&rsb_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/objects/unicode/reproxy.c.inl b/src/deemon/objects/unicode/reproxy.c.inl index da4b8d051..c8bb4e408 100644 --- a/src/deemon/objects/unicode/reproxy.c.inl +++ b/src/deemon/objects/unicode/reproxy.c.inl @@ -1284,6 +1284,8 @@ PRIVATE struct type_nsi tpconst refa_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, @@ -1895,6 +1897,8 @@ PRIVATE struct type_nsi tpconst resp_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/deemon/runtime/operator.c b/src/deemon/runtime/operator.c index 92d54303d..890fef02f 100644 --- a/src/deemon/runtime/operator.c +++ b/src/deemon/runtime/operator.c @@ -277,7 +277,7 @@ DeeSystem_DEFINE_memsetp(dee_memsetp) #define DeeType_INVOKE_SETITEM(tp_self, self, index, value) (*(tp_self)->tp_seq->tp_set)(self, index, value) #define DeeType_INVOKE_GETRANGE(tp_self, self, start, end) (*(tp_self)->tp_seq->tp_range_get)(self, start, end) #define DeeType_INVOKE_DELRANGE(tp_self, self, start, end) (*(tp_self)->tp_seq->tp_range_del)(self, start, end) -#define DeeType_INVOKE_SETRANGE(tp_self, self, start, end, values) (*(tp_self)->tp_seq->tp_range_set)(self, start, end, value) +#define DeeType_INVOKE_SETRANGE(tp_self, self, start, end, values) (*(tp_self)->tp_seq->tp_range_set)(self, start, end, values) #define DeeType_INVOKE_GETATTR(tp_self, self, name) (*(tp_self)->tp_attr->tp_getattr)(self, name) #define DeeType_INVOKE_DELATTR(tp_self, self, name) (*(tp_self)->tp_attr->tp_delattr)(self, name) #define DeeType_INVOKE_SETATTR(tp_self, self, name, value) (*(tp_self)->tp_attr->tp_setattr)(self, name, value) @@ -4061,15 +4061,118 @@ PUBLIC WUNUSED NONNULL((1)) DREF DeeObject * return NULL; } +PUBLIC WUNUSED NONNULL((1)) int +(DCALL DeeObject_DelRangeBeginIndex)(DeeObject *self, + dssize_t begin, DeeObject *end) { + LOAD_TP_SELF; + ASSERT_OBJECT(end); + do { + if (tp_self->tp_seq && tp_self->tp_seq->tp_range_del) { + int result; + DREF DeeObject *begin_ob; + struct type_nsi const *nsi; + /* NSI optimizations. */ + nsi = tp_self->tp_seq->tp_nsi; + if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ) { + if (DeeNone_Check(end)) { + if (nsi->nsi_seqlike.nsi_delrange_n) + return (*nsi->nsi_seqlike.nsi_delrange_n)(self, begin); + } else if (nsi->nsi_seqlike.nsi_delrange) { + dssize_t end_index; + if (DeeObject_AsSSize(end, &end_index)) + goto err; + return (*nsi->nsi_seqlike.nsi_delrange)(self, begin, end_index); + } + } + begin_ob = DeeInt_NewSSize(begin); + if unlikely(!begin_ob) + goto err; + result = DeeType_INVOKE_DELRANGE(tp_self, self, begin_ob, end); + Dee_Decref(begin_ob); + return result; + } + } while (type_inherit_setrange(tp_self)); + err_unimplemented_operator(tp_self, OPERATOR_SETRANGE); +err: + return -1; +} + +PUBLIC WUNUSED NONNULL((1, 2)) int +(DCALL DeeObject_DelRangeEndIndex)(DeeObject *self, + DeeObject *begin, dssize_t end) { + LOAD_TP_SELF; + ASSERT_OBJECT(begin); + do { + if (tp_self->tp_seq && tp_self->tp_seq->tp_range_del) { + int result; + DREF DeeObject *end_ob; + struct type_nsi const *nsi; + /* NSI optimizations. */ + nsi = tp_self->tp_seq->tp_nsi; + if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ) { + if (nsi->nsi_seqlike.nsi_delrange) { + dssize_t start_index; + if (DeeObject_AsSSize(begin, &start_index)) + goto err; + return (*nsi->nsi_seqlike.nsi_delrange)(self, start_index, end); + } + } + end_ob = DeeInt_NewSSize(end); + if unlikely(!end_ob) + goto err; + result = DeeType_INVOKE_DELRANGE(tp_self, self, begin, end_ob); + Dee_Decref(end_ob); + return result; + } + } while (type_inherit_setrange(tp_self)); + err_unimplemented_operator(tp_self, OPERATOR_SETRANGE); +err: + return -1; +} + +PUBLIC WUNUSED NONNULL((1)) int +(DCALL DeeObject_DelRangeIndex)(DeeObject *self, + dssize_t begin, dssize_t end) { + LOAD_TP_SELF; + do { + if (tp_self->tp_seq && tp_self->tp_seq->tp_range_del) { + DREF DeeObject *begin_ob, *end_ob; + int result; + struct type_nsi const *nsi; + /* NSI optimizations. */ + nsi = tp_self->tp_seq->tp_nsi; + if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ) { + if (nsi->nsi_seqlike.nsi_delrange) + return (*nsi->nsi_seqlike.nsi_delrange)(self, begin, end); + } + begin_ob = DeeInt_NewSSize(begin); + if unlikely(!begin_ob) + goto err; + end_ob = DeeInt_NewSSize(end); + if unlikely(!end_ob) { + Dee_Decref(begin_ob); + goto err; + } + result = DeeType_INVOKE_DELRANGE(tp_self, self, begin_ob, end_ob); + Dee_Decref(end_ob); + Dee_Decref(begin_ob); + return result; + } + } while (type_inherit_setrange(tp_self)); + err_unimplemented_operator(tp_self, OPERATOR_SETRANGE); +err: + return -1; +} + PUBLIC WUNUSED NONNULL((1, 3, 4)) int (DCALL DeeObject_SetRangeBeginIndex)(DeeObject *self, dssize_t begin, DeeObject *end, - DeeObject *value) { + DeeObject *values) { LOAD_TP_SELF; ASSERT_OBJECT(end); - ASSERT_OBJECT(value); + ASSERT_OBJECT(values); do { - if (tp_self->tp_seq && tp_self->tp_seq->tp_range_get) { + if (tp_self->tp_seq && tp_self->tp_seq->tp_range_set) { int result; DREF DeeObject *begin_ob; struct type_nsi const *nsi; @@ -4078,18 +4181,18 @@ PUBLIC WUNUSED NONNULL((1, 3, 4)) int if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ) { if (DeeNone_Check(end)) { if (nsi->nsi_seqlike.nsi_setrange_n) - return (*nsi->nsi_seqlike.nsi_setrange_n)(self, begin, value); + return (*nsi->nsi_seqlike.nsi_setrange_n)(self, begin, values); } else if (nsi->nsi_seqlike.nsi_setrange) { dssize_t end_index; if (DeeObject_AsSSize(end, &end_index)) goto err; - return (*nsi->nsi_seqlike.nsi_setrange)(self, begin, end_index, value); + return (*nsi->nsi_seqlike.nsi_setrange)(self, begin, end_index, values); } } begin_ob = DeeInt_NewSSize(begin); if unlikely(!begin_ob) goto err; - result = DeeType_INVOKE_SETRANGE(tp_self, self, begin_ob, end, value); + result = DeeType_INVOKE_SETRANGE(tp_self, self, begin_ob, end, values); Dee_Decref(begin_ob); return result; } @@ -4102,12 +4205,12 @@ PUBLIC WUNUSED NONNULL((1, 3, 4)) int PUBLIC WUNUSED NONNULL((1, 2, 4)) int (DCALL DeeObject_SetRangeEndIndex)(DeeObject *self, DeeObject *begin, dssize_t end, - DeeObject *value) { + DeeObject *values) { LOAD_TP_SELF; ASSERT_OBJECT(begin); - ASSERT_OBJECT(value); + ASSERT_OBJECT(values); do { - if (tp_self->tp_seq && tp_self->tp_seq->tp_range_get) { + if (tp_self->tp_seq && tp_self->tp_seq->tp_range_set) { int result; DREF DeeObject *end_ob; struct type_nsi const *nsi; @@ -4118,13 +4221,13 @@ PUBLIC WUNUSED NONNULL((1, 2, 4)) int dssize_t start_index; if (DeeObject_AsSSize(begin, &start_index)) goto err; - return (*nsi->nsi_seqlike.nsi_setrange)(self, start_index, end, value); + return (*nsi->nsi_seqlike.nsi_setrange)(self, start_index, end, values); } } end_ob = DeeInt_NewSSize(end); if unlikely(!end_ob) goto err; - result = DeeType_INVOKE_SETRANGE(tp_self, self, begin, end_ob, value); + result = DeeType_INVOKE_SETRANGE(tp_self, self, begin, end_ob, values); Dee_Decref(end_ob); return result; } @@ -4137,9 +4240,9 @@ PUBLIC WUNUSED NONNULL((1, 2, 4)) int PUBLIC WUNUSED NONNULL((1, 4)) int (DCALL DeeObject_SetRangeIndex)(DeeObject *self, dssize_t begin, dssize_t end, - DeeObject *value) { + DeeObject *values) { LOAD_TP_SELF; - ASSERT_OBJECT(value); + ASSERT_OBJECT(values); do { if (tp_self->tp_seq && tp_self->tp_seq->tp_range_set) { DREF DeeObject *begin_ob, *end_ob; @@ -4149,7 +4252,7 @@ PUBLIC WUNUSED NONNULL((1, 4)) int nsi = tp_self->tp_seq->tp_nsi; if (nsi && nsi->nsi_class == TYPE_SEQX_CLASS_SEQ) { if (nsi->nsi_seqlike.nsi_setrange) - return (*nsi->nsi_seqlike.nsi_setrange)(self, begin, end, value); + return (*nsi->nsi_seqlike.nsi_setrange)(self, begin, end, values); } begin_ob = DeeInt_NewSSize(begin); if unlikely(!begin_ob) @@ -4159,7 +4262,7 @@ PUBLIC WUNUSED NONNULL((1, 4)) int Dee_Decref(begin_ob); goto err; } - result = DeeType_INVOKE_SETRANGE(tp_self, self, begin_ob, end_ob, value); + result = DeeType_INVOKE_SETRANGE(tp_self, self, begin_ob, end_ob, values); Dee_Decref(end_ob); Dee_Decref(begin_ob); return result; diff --git a/src/dex/collections/deque.c b/src/dex/collections/deque.c index 3d912d6d9..9c2d36df3 100644 --- a/src/dex/collections/deque.c +++ b/src/dex/collections/deque.c @@ -1195,6 +1195,8 @@ PRIVATE struct type_nsi tpconst deq_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/dex/collections/fixedlist.c b/src/dex/collections/fixedlist.c index 0644bff6c..8eebf0be4 100644 --- a/src/dex/collections/fixedlist.c +++ b/src/dex/collections/fixedlist.c @@ -40,8 +40,12 @@ #include #include +#include #include +#undef SSIZE_MAX +#define SSIZE_MAX __SSIZE_MAX__ + DECL_BEGIN #ifndef CONFIG_HAVE_memsetp @@ -658,26 +662,24 @@ fl_iter(FixedList *__restrict self) { } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL -fl_nsi_getrange(FixedList *__restrict self, dssize_t start, dssize_t end) { - size_t count; +fl_nsi_getrange(FixedList *__restrict self, dssize_t i_begin, dssize_t i_end) { DREF FixedList *result; - if (start < 0) - start += self->fl_size; - if (end < 0) - end += self->fl_size; - if ((size_t)end > self->fl_size) - end = (dssize_t)self->fl_size; - if ((size_t)start >= (size_t)end) + struct Dee_seq_range range; + size_t range_size; + DeeSeqRange_Clamp(&range, i_begin, i_end, self->fl_size); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) return_reference_(Dee_EmptySeq); - count = (size_t)end - (size_t)start; result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + - count * sizeof(DREF DeeObject *)); + range_size * sizeof(DREF DeeObject *)); if unlikely(!result) goto done; Dee_atomic_rwlock_init(&result->fl_lock); - result->fl_size = count; + result->fl_size = range_size; FixedList_LockRead(self); - Dee_XMovrefv(result->fl_elem, self->fl_elem + (size_t)start, count); + Dee_XMovrefv(result->fl_elem, + self->fl_elem + range.sr_start, + range_size); FixedList_LockEndRead(self); weakref_support_init(result); DeeObject_Init(result, &FixedList_Type); @@ -687,135 +689,202 @@ fl_nsi_getrange(FixedList *__restrict self, dssize_t start, dssize_t end) { } PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL -fl_nsi_getrange_n(FixedList *__restrict self, dssize_t start) { - return fl_nsi_getrange(self, start, (dssize_t)self->fl_size); +fl_nsi_getrange_n(FixedList *__restrict self, dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return fl_nsi_getrange(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + DREF FixedList *result; + size_t start, range_size; + start = DeeSeqRange_Clamp_n(i_begin, self->fl_size); + range_size = self->fl_size - start; + if unlikely(range_size <= 0) + return_reference_(Dee_EmptySeq); + result = (DREF FixedList *)DeeGCObject_Malloc(offsetof(FixedList, fl_elem) + + range_size * sizeof(DREF DeeObject *)); + if unlikely(!result) + goto done; + Dee_atomic_rwlock_init(&result->fl_lock); + result->fl_size = range_size; + FixedList_LockRead(self); + Dee_XMovrefv(result->fl_elem, + self->fl_elem + start, + range_size); + FixedList_LockEndRead(self); + weakref_support_init(result); + DeeObject_Init(result, &FixedList_Type); + DeeGC_Track((DeeObject *)result); +done: + return (DREF DeeObject *)result; +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1)) int DCALL -fl_nsi_delrange(FixedList *__restrict self, dssize_t start, dssize_t end) { - size_t i, count; +fl_nsi_delrange(FixedList *__restrict self, dssize_t i_begin, dssize_t i_end) { + struct Dee_seq_range range; + size_t range_size; + DeeSeqRange_Clamp(&range, i_begin, i_end, self->fl_size); + range_size = range.sr_end - range.sr_start; + if (range_size > 0) { + size_t i; + DREF DeeObject **values_buf; + values_buf = (DREF DeeObject **)Dee_Mallocac(range_size, sizeof(DREF DeeObject *)); + if unlikely(!values_buf) + goto err; + FixedList_LockWrite(self); + for (i = 0; i < range_size; ++i) { + DREF DeeObject **p_slot; + p_slot = &self->fl_elem[(size_t)i_begin + i]; + /* Exchange objects. */ + values_buf[i] = *p_slot; + *p_slot = NULL; + } + FixedList_LockEndWrite(self); + Dee_XDecrefv(values_buf, range_size); + Dee_Freea(values_buf); + } + return 0; +err: + return -1; +} + +PRIVATE WUNUSED NONNULL((1)) int DCALL +fl_nsi_delrange_n(FixedList *__restrict self, dssize_t i_begin) { +#ifdef __OPTIMIZE_SIZE__ + return fl_nsi_delrange(self, i_begin, SSIZE_MAX); +#else /* __OPTIMIZE_SIZE__ */ + size_t start, range_size; + start = DeeSeqRange_Clamp_n(i_begin, self->fl_size); + range_size = self->fl_size - start; + if (range_size > 0) { + size_t i; + DREF DeeObject **values_buf; + values_buf = (DREF DeeObject **)Dee_Mallocac(range_size, sizeof(DREF DeeObject *)); + if unlikely(!values_buf) + goto err; + FixedList_LockWrite(self); + for (i = 0; i < range_size; ++i) { + DREF DeeObject **p_slot; + p_slot = &self->fl_elem[(size_t)i_begin + i]; + /* Exchange objects. */ + values_buf[i] = *p_slot; + *p_slot = NULL; + } + FixedList_LockEndWrite(self); + Dee_XDecrefv(values_buf, range_size); + Dee_Freea(values_buf); + } + return 0; +err: + return -1; +#endif /* !__OPTIMIZE_SIZE__ */ +} + +PRIVATE WUNUSED NONNULL((1, 4)) int DCALL +fl_nsi_setrange(FixedList *self, dssize_t i_begin, + dssize_t i_end, DeeObject *values) { + struct Dee_seq_range range; + size_t i, range_size; DREF DeeObject **values_buf; - if (start < 0) - start += self->fl_size; - if (end < 0) - end += self->fl_size; - if ((size_t)end > self->fl_size) - end = (dssize_t)self->fl_size; - count = (size_t)end - (size_t)start; - values_buf = (DREF DeeObject **)Dee_Mallocac(count, sizeof(DREF DeeObject *)); + DeeSeqRange_Clamp(&range, i_begin, i_end, self->fl_size); + range_size = range.sr_end - range.sr_start; + values_buf = (DREF DeeObject **)Dee_Mallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!values_buf) goto err; + if (DeeObject_UnpackWithUnbound(values, range_size, values_buf)) + goto err_values_buf; FixedList_LockWrite(self); - for (i = 0; i < count; ++i) { - DREF DeeObject **p_slot; - p_slot = &self->fl_elem[(size_t)start + i]; + for (i = 0; i < range_size; ++i) { + DREF DeeObject **p_slot, *temp; + p_slot = &self->fl_elem[(size_t)i_begin + i]; /* Exchange objects. */ - values_buf[i] = *p_slot; - *p_slot = NULL; + temp = *p_slot; + *p_slot = values_buf[i]; + values_buf[i] = temp; } FixedList_LockEndWrite(self); - Dee_XDecrefv(values_buf, count); + Dee_XDecrefv(values_buf, range_size); Dee_Freea(values_buf); return 0; +err_values_buf: + Dee_Freea(values_buf); err: return -1; } -PRIVATE WUNUSED NONNULL((1, 4)) int DCALL -fl_nsi_setrange(FixedList *self, dssize_t start, dssize_t end, DeeObject *values) { - size_t i, count; +PRIVATE WUNUSED NONNULL((1, 3)) int DCALL +fl_nsi_setrange_n(FixedList *self, dssize_t i_begin, DeeObject *values) { +#ifdef __OPTIMIZE_SIZE__ + return fl_nsi_setrange(self, i_begin, SSIZE_MAX, values); +#else /* __OPTIMIZE_SIZE__ */ + size_t i, start, range_size; DREF DeeObject **values_buf; - if (DeeNone_Check(values)) - return fl_nsi_delrange(self, start, end); - if (start < 0) - start += self->fl_size; - if (end < 0) - end += self->fl_size; - if ((size_t)end > self->fl_size) - end = (dssize_t)self->fl_size; - count = (size_t)end - (size_t)start; - values_buf = (DREF DeeObject **)Dee_Mallocac(count, sizeof(DREF DeeObject *)); + start = DeeSeqRange_Clamp_n(i_begin, self->fl_size); + range_size = self->fl_size - start; + values_buf = (DREF DeeObject **)Dee_Mallocac(range_size, sizeof(DREF DeeObject *)); if unlikely(!values_buf) goto err; - if (DeeObject_UnpackWithUnbound(values, count, values_buf)) + if (DeeObject_UnpackWithUnbound(values, range_size, values_buf)) goto err_values_buf; FixedList_LockWrite(self); - for (i = 0; i < count; ++i) { + for (i = 0; i < range_size; ++i) { DREF DeeObject **p_slot, *temp; - p_slot = &self->fl_elem[(size_t)start + i]; + p_slot = &self->fl_elem[(size_t)i_begin + i]; /* Exchange objects. */ temp = *p_slot; *p_slot = values_buf[i]; values_buf[i] = temp; } FixedList_LockEndWrite(self); - Dee_XDecrefv(values_buf, count); + Dee_XDecrefv(values_buf, range_size); Dee_Freea(values_buf); return 0; err_values_buf: Dee_Freea(values_buf); err: return -1; -} - -PRIVATE WUNUSED NONNULL((1, 3)) int DCALL -fl_nsi_setrange_n(FixedList *self, dssize_t start, DeeObject *values) { - return fl_nsi_setrange(self, start, (dssize_t)self->fl_size, values); +#endif /* !__OPTIMIZE_SIZE__ */ } PRIVATE WUNUSED NONNULL((1, 2, 3)) DREF DeeObject *DCALL -fl_getrange(FixedList *__restrict self, - DeeObject *__restrict start, - DeeObject *__restrict end) { - dssize_t start_index; - dssize_t end_index; - if (DeeObject_AsSSize(start, &start_index)) +fl_getrange(FixedList *self, DeeObject *begin, DeeObject *end) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (DeeNone_Check(end)) { - end_index = (dssize_t)self->fl_size; - } else { - if (DeeObject_AsSSize(end, &end_index)) - goto err; - } - return fl_nsi_getrange(self, start_index, end_index); + if (DeeNone_Check(end)) + return fl_nsi_getrange_n(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) + goto err; + return fl_nsi_getrange(self, i_begin, i_end); err: return NULL; } PRIVATE WUNUSED NONNULL((1, 2, 3)) int DCALL -fl_delrange(FixedList *__restrict self, - DeeObject *__restrict start, - DeeObject *__restrict end) { - dssize_t start_index; - dssize_t end_index; - if (DeeObject_AsSSize(start, &start_index)) +fl_delrange(FixedList *self, DeeObject *begin, DeeObject *end) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; - if (DeeNone_Check(end)) { - end_index = (dssize_t)self->fl_size; - } else { - if (DeeObject_AsSSize(end, &end_index)) - goto err; - } - return fl_nsi_delrange(self, start_index, end_index); + if (DeeNone_Check(end)) + return fl_nsi_delrange_n(self, i_begin); + if (DeeObject_AsSSize(end, &i_end)) + goto err; + return fl_nsi_delrange(self, i_begin, i_end); err: return -1; } PRIVATE WUNUSED NONNULL((1, 2, 3, 4)) int DCALL -fl_setrange(FixedList *__restrict self, - DeeObject *__restrict start, - DeeObject *__restrict end, - DeeObject *__restrict values) { - dssize_t start_index; - dssize_t end_index; - if (DeeObject_AsSSize(start, &start_index)) +fl_setrange(FixedList *self, DeeObject *begin, + DeeObject *end, DeeObject *values) { + dssize_t i_begin, i_end; + if (DeeObject_AsSSize(begin, &i_begin)) goto err; if (DeeNone_Check(end)) - return fl_nsi_setrange_n(self, start_index, values); - if (DeeObject_AsSSize(end, &end_index)) + return fl_nsi_setrange_n(self, i_begin, values); + if (DeeObject_AsSSize(end, &i_end)) goto err; - return fl_nsi_setrange(self, start_index, end_index, values); + return fl_nsi_setrange(self, i_begin, i_end, values); err: return -1; } @@ -1073,6 +1142,8 @@ PRIVATE struct type_nsi tpconst fl_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)&fl_nsi_getitem_fast, /* .nsi_getrange = */ (dfunptr_t)&fl_nsi_getrange, /* .nsi_getrange_n = */ (dfunptr_t)&fl_nsi_getrange_n, + /* .nsi_delrange = */ (dfunptr_t)&fl_nsi_delrange, + /* .nsi_delrange_n = */ (dfunptr_t)&fl_nsi_delrange_n, /* .nsi_setrange = */ (dfunptr_t)&fl_nsi_setrange, /* .nsi_setrange_n = */ (dfunptr_t)&fl_nsi_setrange_n, /* .nsi_find = */ (dfunptr_t)&fl_nsi_find, diff --git a/src/dex/ctypes/array.c b/src/dex/ctypes/array.c index 9ea83cd31..219ccbbef 100644 --- a/src/dex/ctypes/array.c +++ b/src/dex/ctypes/array.c @@ -37,11 +37,14 @@ #include /* bzero() */ #include +#include #include +#include #undef SSIZE_MAX -#include #define SSIZE_MAX __SSIZE_MAX__ +#undef byte_t +#define byte_t __BYTE_TYPE__ DECL_BEGIN @@ -67,7 +70,7 @@ aiter_visit(ArrayIterator *__restrict self, dvisit_t proc, void *arg) { } -PRIVATE WUNUSED DREF struct lvalue_object *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF struct lvalue_object *DCALL aiter_next(ArrayIterator *__restrict self) { DREF struct lvalue_object *result; union pointer result_pointer; @@ -96,7 +99,7 @@ aiter_bool(ArrayIterator *__restrict self) { return atomic_read(&self->ai_pos.ptr) >= self->ai_end.ptr; } -PRIVATE WUNUSED DREF struct lvalue_object *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF struct lvalue_object *DCALL aiter_getseq(ArrayIterator *__restrict self) { DREF struct lvalue_object *result; DREF DeeArrayTypeObject *atype; @@ -182,7 +185,7 @@ PRIVATE DeeTypeObject ArrayIterator_Type = { }; -PRIVATE WUNUSED DREF ArrayIterator *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF ArrayIterator *DCALL array_iter(DeeArrayTypeObject *tp_self, void *base) { DREF ArrayIterator *result; @@ -207,12 +210,12 @@ array_iter(DeeArrayTypeObject *tp_self, void *base) { return NULL; } -PRIVATE WUNUSED DREF DeeObject *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL array_size(DeeArrayTypeObject *tp_self, void *UNUSED(base)) { return DeeInt_NewSize(tp_self->at_count); } -PRIVATE WUNUSED DREF DeeObject *DCALL +PRIVATE WUNUSED NONNULL((1, 3)) DREF DeeObject *DCALL array_contains(DeeArrayTypeObject *tp_self, void *base, DeeObject *other) { DREF struct lvalue_object *temp = NULL; DREF DeeLValueTypeObject *lval_type; @@ -256,7 +259,7 @@ array_contains(DeeArrayTypeObject *tp_self, void *base, DeeObject *other) { return NULL; } -PRIVATE WUNUSED DREF DeeObject *DCALL +PRIVATE WUNUSED NONNULL((1, 3)) DREF DeeObject *DCALL array_get(DeeArrayTypeObject *tp_self, void *base, DeeObject *index_ob) { DREF struct lvalue_object *result; DREF DeeLValueTypeObject *lval_type; @@ -290,7 +293,7 @@ array_get(DeeArrayTypeObject *tp_self, void *base, DeeObject *index_ob) { return NULL; } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1, 3, 4)) int DCALL array_set(DeeArrayTypeObject *tp_self, void *base, DeeObject *index_ob, DeeObject *value) { int result; @@ -307,37 +310,31 @@ array_set(DeeArrayTypeObject *tp_self, void *base, return -1; } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1, 3)) int DCALL array_del(DeeArrayTypeObject *tp_self, void *base, DeeObject *index_ob) { return array_set(tp_self, base, index_ob, Dee_None); } -PRIVATE WUNUSED DREF DeeObject *DCALL +PRIVATE WUNUSED NONNULL((1, 3, 4)) DREF DeeObject *DCALL array_getrange(DeeArrayTypeObject *tp_self, void *base, DeeObject *begin_ob, DeeObject *end_ob) { DREF struct lvalue_object *result; DREF DeeLValueTypeObject *lval_type; DREF DeeArrayTypeObject *array_type; - dssize_t begin, end = -1; - if (DeeObject_AsSSize(begin_ob, &begin)) + dssize_t i_begin, i_end = (dssize_t)tp_self->at_count; + struct Dee_seq_range range; + size_t range_size; + if (DeeObject_AsSSize(begin_ob, &i_begin)) goto err; if (!DeeNone_Check(end_ob)) { - if (DeeObject_AsSSize(end_ob, &end)) + if (DeeObject_AsSSize(end_ob, &i_end)) goto err; } - if unlikely(begin < 0) - begin += tp_self->at_count; - if unlikely(end < 0) - end += tp_self->at_count; - if unlikely((size_t)begin >= tp_self->at_count || - (size_t)begin >= (size_t)end) - begin = end = 0; /* Empty array. */ - if unlikely((size_t)end > tp_self->at_count) - end = (dssize_t)tp_self->at_count; + DeeSeqRange_Clamp(&range, i_begin, i_end, tp_self->at_count); + range_size = range.sr_end - range.sr_start; /* Construct a sub-array type. */ - array_type = DeeSType_Array(tp_self->at_orig, - (size_t)(end - begin)); + array_type = DeeSType_Array(tp_self->at_orig, range_size); if unlikely(!array_type) goto err; @@ -353,7 +350,7 @@ array_getrange(DeeArrayTypeObject *tp_self, void *base, /* Set the base pointer to the start of the requested sub-range. */ result->l_ptr.uint = ((uintptr_t)base) + - ((size_t)begin * DeeSType_Sizeof(tp_self->at_orig)); + (range.sr_start * DeeSType_Sizeof(tp_self->at_orig)); return (DREF DeeObject *)result; err_lval_type: Dee_Decref(DeeLValueType_AsType(lval_type)); @@ -361,34 +358,31 @@ array_getrange(DeeArrayTypeObject *tp_self, void *base, return NULL; } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1, 3, 4)) int DCALL array_delrange(DeeArrayTypeObject *tp_self, void *base, DeeObject *begin_ob, DeeObject *end_ob) { - dssize_t begin, end = -1; - if (DeeObject_AsSSize(begin_ob, &begin)) + dssize_t i_begin, i_end = (dssize_t)tp_self->at_count; + struct Dee_seq_range range; + size_t range_size; + if (DeeObject_AsSSize(begin_ob, &i_begin)) goto err; if (!DeeNone_Check(end_ob)) { - if (DeeObject_AsSSize(end_ob, &end)) + if (DeeObject_AsSSize(end_ob, &i_end)) goto err; } - if unlikely(begin < 0) - begin += tp_self->at_count; - if unlikely(end < 0) - end += tp_self->at_count; - if unlikely((size_t)begin >= tp_self->at_count || - (size_t)begin >= (size_t)end) { + DeeSeqRange_Clamp(&range, i_begin, i_end, tp_self->at_count); + range_size = range.sr_end - range.sr_start; + if unlikely(range_size <= 0) { /* Empty range . */ } else { size_t item_size; - uint8_t *del_begin; + byte_t *del_begin; size_t del_size; - if unlikely((size_t)end > tp_self->at_count) - end = (dssize_t)tp_self->at_count; /* Simply zero out the described memory range. */ item_size = DeeSType_Sizeof(tp_self->at_orig); - del_size = (size_t)(end - begin) * item_size; - del_begin = (uint8_t *)((uintptr_t)base + ((size_t)begin * item_size)); + del_size = range_size * item_size; + del_begin = (byte_t *)((uintptr_t)base + (range.sr_start * item_size)); CTYPES_FAULTPROTECT(bzero(del_begin, del_size), goto err); } return 0; @@ -396,45 +390,44 @@ array_delrange(DeeArrayTypeObject *tp_self, void *base, return -1; } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1, 3, 4, 5)) int DCALL array_setrange(DeeArrayTypeObject *tp_self, void *base, DeeObject *begin_ob, DeeObject *end_ob, DeeObject *value) { - dssize_t begin, end = SSIZE_MAX; + dssize_t i_begin, i_end; + struct Dee_seq_range range; + size_t range_size; DREF DeeObject *iter, *elem; /* When `none' is passed, simply clear out affected memory. */ if (DeeNone_Check(value)) return array_delrange(tp_self, base, begin_ob, end_ob); - if (DeeObject_AsSSize(begin_ob, &begin)) + i_end = (dssize_t)tp_self->at_count; + if (DeeObject_AsSSize(begin_ob, &i_begin)) goto err; if (!DeeNone_Check(end_ob)) { - if (DeeObject_AsSSize(end_ob, &end)) + if (DeeObject_AsSSize(end_ob, &i_end)) goto err; } - if unlikely(begin < 0) - begin += tp_self->at_count; - if unlikely(end < 0) - end += tp_self->at_count; + DeeSeqRange_Clamp(&range, i_begin, i_end, tp_self->at_count); + range_size = range.sr_end - range.sr_start; iter = DeeObject_IterSelf(value); if unlikely(!iter) goto err; - if unlikely((size_t)begin >= tp_self->at_count || - (size_t)begin >= (size_t)end) { + if unlikely(range_size <= 0) { /* Empty range. */ } else { size_t item_size; union pointer array_iter, array_end; - if unlikely((size_t)end > tp_self->at_count) - end = (dssize_t)tp_self->at_count; - item_size = DeeSType_Sizeof(tp_self->at_orig); - array_iter.uint = (uintptr_t)base + (size_t)begin * item_size; - array_end.uint = (uintptr_t)base + (size_t)end * item_size; - while (array_iter.uint < array_end.uint) { + item_size = DeeSType_Sizeof(tp_self->at_orig); + array_iter.ptr = (byte_t *)base + range.sr_start * item_size; + array_end.ptr = (byte_t *)base + range.sr_end * item_size; + while (array_iter.ptr < array_end.ptr) { int error; elem = DeeObject_IterNext(iter); if unlikely(!ITER_ISOK(elem)) { if (elem) { /* Unexpected end of sequence. */ - size_t given_count = array_iter.uint - ((uintptr_t)base + (size_t)begin * item_size); + size_t given_count; + given_count = array_iter.uint - ((uintptr_t)base + range.sr_start * item_size); if (item_size) given_count /= item_size; DeeError_Throwf(&DeeError_UnpackError, @@ -476,12 +469,12 @@ array_setrange(DeeArrayTypeObject *tp_self, void *base, return -1; } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1, 3)) int DCALL array_assign(DeeArrayTypeObject *tp_self, void *base, DeeObject *value) { return array_setrange(tp_self, base, Dee_None, Dee_None, value); } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1)) int DCALL array_init(DeeArrayTypeObject *tp_self, void *base, size_t argc, DeeObject *const *argv) { DeeObject *arg; @@ -492,7 +485,7 @@ array_init(DeeArrayTypeObject *tp_self, void *base, return -1; } -PRIVATE WUNUSED DREF struct pointer_object *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF struct pointer_object *DCALL array_adddiff(DeeArrayTypeObject *tp_self, void *base, ptrdiff_t diff) { /* Follow C-conventions and return a pointer to the `diff's element. */ @@ -519,7 +512,7 @@ array_adddiff(DeeArrayTypeObject *tp_self, return NULL; } -PRIVATE WUNUSED DREF struct pointer_object *DCALL +PRIVATE WUNUSED NONNULL((1, 3)) DREF struct pointer_object *DCALL array_add(DeeArrayTypeObject *tp_self, void *base, DeeObject *value) { ptrdiff_t diff; if (DeeObject_AsPtrdiff(value, &diff)) @@ -529,7 +522,7 @@ array_add(DeeArrayTypeObject *tp_self, void *base, DeeObject *value) { return NULL; } -PRIVATE WUNUSED DREF struct pointer_object *DCALL +PRIVATE WUNUSED NONNULL((1, 3)) DREF struct pointer_object *DCALL array_sub(DeeArrayTypeObject *tp_self, void *base, DeeObject *value) { ptrdiff_t diff; if (DeeObject_AsPtrdiff(value, &diff)) @@ -539,7 +532,7 @@ array_sub(DeeArrayTypeObject *tp_self, void *base, DeeObject *value) { return NULL; } -PRIVATE WUNUSED DREF DeeObject *DCALL +PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL array_repr(DeeArrayTypeObject *tp_self, void *base) { union pointer iter, end; size_t item_size; @@ -576,14 +569,14 @@ array_repr(DeeArrayTypeObject *tp_self, void *base) { } -PRIVATE int DCALL +PRIVATE WUNUSED NONNULL((1)) int DCALL array_bool(DeeArrayTypeObject *tp_self, void *UNUSED(base)) { return tp_self->at_count != 0; } -PRIVATE WUNUSED DREF DeeObject *DCALL -array_call(DeeArrayTypeObject *tp_self, - void *base, size_t argc, DeeObject *const *argv) { +PRIVATE WUNUSED NONNULL((1)) DREF DeeObject *DCALL +array_call(DeeArrayTypeObject *tp_self, void *base, + size_t argc, DeeObject *const *argv) { /* Because arrays must behave compatible to pointers, * calling an array will call its first element. */ return DeeStruct_Call(tp_self->at_orig, base, argc, argv); diff --git a/src/dex/json/libjson.c b/src/dex/json/libjson.c index 66abaa104..96c192e52 100644 --- a/src/dex/json/libjson.c +++ b/src/dex/json/libjson.c @@ -1067,6 +1067,8 @@ PRIVATE struct type_nsi tpconst jseq_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL, diff --git a/src/dex/rt/slab.c b/src/dex/rt/slab.c index 7b5cb5c4b..31efd3a19 100644 --- a/src/dex/rt/slab.c +++ b/src/dex/rt/slab.c @@ -189,6 +189,8 @@ PRIVATE struct type_nsi tpconst ss_nsi = { /* .nsi_getitem_fast = */ (dfunptr_t)NULL, /* .nsi_getrange = */ (dfunptr_t)NULL, /* .nsi_getrange_n = */ (dfunptr_t)NULL, + /* .nsi_delrange = */ (dfunptr_t)NULL, + /* .nsi_delrange_n = */ (dfunptr_t)NULL, /* .nsi_setrange = */ (dfunptr_t)NULL, /* .nsi_setrange_n = */ (dfunptr_t)NULL, /* .nsi_find = */ (dfunptr_t)NULL,