Box* dictValues(BoxedDict* self) { BoxedList* rtn = new BoxedList(); rtn->ensure(self->d.size()); for (const auto& p : self->d) { listAppendInternal(rtn, p.second); } return rtn; }
Box* JitFragmentWriter::createListHelper(uint64_t num, Box** data) { BoxedList* list = (BoxedList*)createList(); list->ensure(num); for (uint64_t i = 0; i < num; ++i) { assert(gc::isValidGCObject(data[i])); listAppendInternal(list, data[i]); } return list; }
Box* dictKeys(BoxedDict* self) { RELEASE_ASSERT(isSubclass(self->cls, dict_cls), ""); BoxedList* rtn = new BoxedList(); rtn->ensure(self->d.size()); for (const auto& p : self->d) { listAppendInternal(rtn, p.first); } return rtn; }
// TODO the inliner doesn't want to inline these; is there any point to having them in the inline section? extern "C" void listAppendInternal(Box* s, Box* v) { assert(s->cls == list_cls); BoxedList* self = static_cast<BoxedList*>(s); assert(self->size <= self->capacity); self->ensure(1); assert(self->size < self->capacity); self->elts->elts[self->size] = v; self->size++; }
Box* dictItems(BoxedDict* self) { BoxedList* rtn = new BoxedList(); rtn->ensure(self->d.size()); for (const auto& p : self->d) { BoxedTuple* t = BoxedTuple::create({ p.first, p.second }); listAppendInternal(rtn, t); } return rtn; }
extern "C" void listAppendArrayInternal(Box* s, Box** v, int nelts) { assert(s->cls == list_cls); BoxedList* self = static_cast<BoxedList*>(s); assert(self->size <= self->capacity); self->ensure(nelts); assert(self->size <= self->capacity); memcpy(&self->elts->elts[self->size], &v[0], nelts * sizeof(Box*)); self->size += nelts; }
Box* _listSlice(BoxedList* self, i64 start, i64 stop, i64 step, i64 length) { // printf("%ld %ld %ld\n", start, stop, step); assert(step != 0); if (step > 0) { assert(0 <= start); assert(stop <= self->size); } else { assert(start < self->size); assert(-1 <= stop); } BoxedList* rtn = new BoxedList(); if (length > 0) { rtn->ensure(length); copySlice(&rtn->elts->elts[0], &self->elts->elts[0], start, step, length); rtn->size += length; } return rtn; }
Box* listAdd(BoxedList* self, Box* _rhs) { if (_rhs->cls != list_cls) { raiseExcHelper(TypeError, "can only concatenate list (not \"%s\") to list", getTypeName(_rhs)->c_str()); } LOCK_REGION(self->lock.asRead()); BoxedList* rhs = static_cast<BoxedList*>(_rhs); BoxedList* rtn = new BoxedList(); int s1 = self->size; int s2 = rhs->size; rtn->ensure(s1 + s2); memcpy(rtn->elts->elts, self->elts->elts, sizeof(self->elts->elts[0]) * s1); memcpy(rtn->elts->elts + s1, rhs->elts->elts, sizeof(rhs->elts->elts[0]) * s2); rtn->size = s1 + s2; return rtn; }
Box* listMul(BoxedList* self, Box* rhs) { if (rhs->cls != int_cls) { raiseExcHelper(TypeError, "can't multiply sequence by non-int of type '%s'", getTypeName(rhs)->c_str()); } LOCK_REGION(self->lock.asRead()); int n = static_cast<BoxedInt*>(rhs)->n; int s = self->size; BoxedList* rtn = new BoxedList(); rtn->ensure(n * s); if (s == 1) { for (int i = 0; i < n; i++) { listAppendInternal(rtn, self->elts->elts[0]); } } else { for (int i = 0; i < n; i++) { listAppendArrayInternal(rtn, &self->elts->elts[0], s); } } return rtn; }