diff -r 4f1f9a91e406 -r 6bf3080856be Array.st --- a/Array.st Mon Nov 08 03:32:43 1993 +0100 +++ b/Array.st Sat Dec 11 01:42:02 1993 +0100 @@ -27,7 +27,7 @@ are used very often in the system, some methods have been tuned by reimplementation as primitive. -$Header: /cvs/stx/stx/libbasic/Array.st,v 1.5 1993-11-08 02:28:44 claus Exp $ +$Header: /cvs/stx/stx/libbasic/Array.st,v 1.6 1993-12-11 00:39:56 claus Exp $ written spring 89 by claus '! @@ -59,12 +59,14 @@ REGISTER int indx; REGISTER int nIndex; + OBJ cls; if (_isSmallInteger(index)) { indx = _intVal(index) - 1; if (indx >= 0) { nIndex = (_qSize(self) - OHDR_SIZE) / sizeof(OBJ); - indx += _intVal(_ClassInstPtr(_qClass(self))->c_ninstvars); + if ((cls = _qClass(self)) != Array) + indx += _intVal(_ClassInstPtr(cls)->c_ninstvars); if (indx < nIndex) { RETURN ( _InstPtr(self)->i_instvars[indx] ); } @@ -83,12 +85,14 @@ REGISTER int indx; REGISTER int nIndex; + OBJ cls; if (_isSmallInteger(index)) { indx = _intVal(index) - 1; if (indx >= 0) { nIndex = (_qSize(self) - OHDR_SIZE) / sizeof(OBJ); - indx += _intVal(_ClassInstPtr(_qClass(self))->c_ninstvars); + if ((cls = _qClass(self)) != Array) + indx += _intVal(_ClassInstPtr(cls)->c_ninstvars); if (indx < nIndex) { _InstPtr(self)->i_instvars[indx] = anObject; __STORE(self, anObject); @@ -101,33 +105,48 @@ ^ super at:index put:anObject ! ! +!Array methodsFor:'converting'! + +asArray + "return the receiver as an array" + + "could be an instance of a subclass..." + self class == Array ifTrue:[ + ^ self + ]. + ^ super asArray +! ! + !Array methodsFor:'copying'! copyWith:something "reimplemented for speed if receiver is an Array" %{ - OBJ nObj; + OBJ nObj, element; int mySize; - int i, nIndex; - OBJ *op; + int nIndex; + REGISTER OBJ *srcP, *dstP; extern int newSpace; if (_qClass(self) == Array) { mySize = _qSize(self); _qAlignedNew(nObj, mySize + sizeof(OBJ), __context); - _InstPtr(nObj)->o_class = Array; + if (nObj) { + _InstPtr(nObj)->o_class = Array; - nIndex = (mySize - OHDR_SIZE) / sizeof(OBJ); - /* sorry: must take care of stores ... */ - op = _ArrayInstPtr(self)->a_element; - for (i=0; ia_element[i] = *op; - __STORE(nObj, *op); - op++; + nIndex = (mySize - OHDR_SIZE) / sizeof(OBJ); + /* sorry: must take care of stores ... */ + srcP = _ArrayInstPtr(self)->a_element; + dstP = _ArrayInstPtr(nObj)->a_element; + while (nIndex--) { + element = *srcP++; + *dstP++ = element; + __STORE(nObj, element); + } + *dstP = something; + __STORE(nObj, something); + RETURN ( nObj ); } - _ArrayInstPtr(nObj)->a_element[i] = something; - __STORE(nObj, something); - RETURN ( nObj ); } %} . @@ -202,6 +221,9 @@ nIndex = (_qSize(self) - OHDR_SIZE) / sizeof(OBJ); stopIndex = _intVal(stop) - 1; count = stopIndex - startIndex + 1; + if (count == 0) { + RETURN ( self ); + } if ((count > 0) && (stopIndex < nIndex)) { repStartIndex = _intVal(repStart) - 1; if (repStartIndex >= 0) { @@ -379,6 +401,27 @@ ^ super identityIndexOf:anElement startingAt:start ! ! +!Array methodsFor:'printing & storing'! + +isLiteral + "return true, if the receiver can be used as a literal" + + self do:[:element | + element isLiteral ifFalse:[^ false] + ]. + ^ true +! + +storeOn:aStream + self isLiteral ifTrue:[ + aStream nextPutAll:'#('. + self do:[:element | element storeOn:aStream. aStream space]. + aStream nextPutAll:')' + ] ifFalse:[ + super storeOn:aStream + ] +! ! + !Array methodsFor:'enumeration'! do:aBlock @@ -399,30 +442,38 @@ if (__isBlock(aBlock) && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) { +#ifdef NEW_BLOCK_CALL + for (; index < nIndex; index++) { + if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); + + (*codeVal)(aBlock, CON_COMMA _InstPtr(self)->i_instvars[index]); + } +#else home = _BlockInstPtr(aBlock)->b_home; - rHome = home; - if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) { - /* - * home will not move - keep in a fast register - */ + rHome = home; + if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) { + /* + * home will not move - keep in a fast register + */ for (; index < nIndex; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); } - } else { + } else { for (; index < nIndex; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*codeVal)(home, CON_COMMA _InstPtr(self)->i_instvars[index]); } } +#endif } else { for (; index < nIndex; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*val.ilc_func)(aBlock, _value_, CON_COMMA nil, &val, - _InstPtr(self)->i_instvars[index]); + _InstPtr(self)->i_instvars[index]); } } %} @@ -447,16 +498,23 @@ if (__isBlock(aBlock) && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) { +#ifdef NEW_BLOCK_CALL + for (index=nIndex-1; index >= endIndex; index--) { + if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); + (*codeVal)(aBlock, CON_COMMA _InstPtr(self)->i_instvars[index]); + } +#else home = _BlockInstPtr(aBlock)->b_home; for (index=nIndex-1; index >= endIndex; index--) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*codeVal)(home, CON_COMMA _InstPtr(self)->i_instvars[index]); } +#endif } else { for (index=nIndex=1; index >= endIndex; index--) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*val.ilc_func)(aBlock, _value_, CON_COMMA nil, &val, - _InstPtr(self)->i_instvars[index]); + _InstPtr(self)->i_instvars[index]); } } %} @@ -483,11 +541,11 @@ indexLow = _intVal(start); if (indexLow > 0) { indexHigh = _intVal(stop); - if (_qClass(self) != Array) { + if (_qClass(self) != Array) { nInsts = _intVal(_ClassInstPtr(_qClass(self))->c_ninstvars); indexLow += nInsts; indexHigh += nInsts; - } + } nIndex = (_qSize(self) - OHDR_SIZE) / sizeof(OBJ); if (indexHigh <= nIndex) { indexLow--; @@ -495,19 +553,26 @@ if (__isBlock(aBlock) && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) { +#ifdef NEW_BLOCK_CALL + for (index=indexLow; index <= indexHigh; index++) { + if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); + (*codeVal)(aBlock, CON_COMMA _InstPtr(self)->i_instvars[index]); + } +#else home = _BlockInstPtr(aBlock)->b_home; - rHome = home; - if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) { + rHome = home; + if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) { for (index=indexLow; index <= indexHigh; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); } - } else { + } else { for (index=indexLow; index <= indexHigh; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); (*codeVal)(home, CON_COMMA _InstPtr(self)->i_instvars[index]); } - } + } +#endif } else { for (index=indexLow; index <= indexHigh; index++) { if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON); @@ -540,6 +605,15 @@ if (__isBlock(aBlock) && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) { +#ifdef NEW_BLOCK_CALL + for (; index < nIndex; index++) { + if (InterruptPending != nil) interrupt(CONARG); + + element = _InstPtr(self)->i_instvars[index]; + if (element != nil) + (*codeVal)(aBlock, CON_COMMA element); + } +#else home = _BlockInstPtr(aBlock)->b_home; for (; index < nIndex; index++) { if (InterruptPending != nil) interrupt(CONARG); @@ -548,6 +622,7 @@ if (element != nil) (*codeVal)(home, CON_COMMA element); } +#endif } else { for (; index < nIndex; index++) { if (InterruptPending != nil) interrupt(CONARG); @@ -560,4 +635,17 @@ %} . ^ self +! + +addAllTo:aCollection + "add all elements of the receiver to aCollection. + return aCollection." + + |stop "{ Class: SmallInteger }"| + + stop := self size. + 1 to:stop do:[:idx | + aCollection add:(self at:idx) + ]. + ^ aCollection ! !