Array.st
changeset 10 4f1f9a91e406
parent 5 67342904af11
child 11 6bf3080856be
equal deleted inserted replaced
9:b07612967dfa 10:4f1f9a91e406
    25 Arrays store general objects; the size is fixed, so add/remove is not
    25 Arrays store general objects; the size is fixed, so add/remove is not
    26 allowed. Access to the elements is via an Integer index. Since Arrays
    26 allowed. Access to the elements is via an Integer index. Since Arrays
    27 are used very often in the system, some methods have been tuned by
    27 are used very often in the system, some methods have been tuned by
    28 reimplementation as primitive.
    28 reimplementation as primitive.
    29 
    29 
    30 $Header: /cvs/stx/stx/libbasic/Array.st,v 1.4 1993-10-13 02:10:49 claus Exp $
    30 $Header: /cvs/stx/stx/libbasic/Array.st,v 1.5 1993-11-08 02:28:44 claus Exp $
    31 
    31 
    32 written spring 89 by claus
    32 written spring 89 by claus
    33 '!
    33 '!
    34 
    34 
    35 !Array class methodsFor:'queries'!
    35 !Array class methodsFor:'queries'!
   116         mySize = _qSize(self);
   116         mySize = _qSize(self);
   117         _qAlignedNew(nObj, mySize + sizeof(OBJ), __context);
   117         _qAlignedNew(nObj, mySize + sizeof(OBJ), __context);
   118         _InstPtr(nObj)->o_class = Array;
   118         _InstPtr(nObj)->o_class = Array;
   119 
   119 
   120         nIndex = (mySize - OHDR_SIZE) / sizeof(OBJ);
   120         nIndex = (mySize - OHDR_SIZE) / sizeof(OBJ);
   121 #ifdef NOTDEF
   121         /* sorry: must take care of stores ... */
   122 /*
   122         op = _ArrayInstPtr(self)->a_element;
   123  * sorry: store-check needed, elements may be
   123         for (i=0; i<nIndex; i++) {
   124  * contexts ...
   124             _ArrayInstPtr(nObj)->a_element[i] = *op;
   125  */
   125             __STORE(nObj, *op);
   126         /* created object is usually in newspace */
   126             op++;
   127         if (_qSpace(nObj) == newSpace) {
   127         }
   128             /* dont care for store */
   128         _ArrayInstPtr(nObj)->a_element[i] = something;
   129 # ifdef bcopy4
   129         __STORE(nObj, something);
   130             bcopy4(_ArrayInstPtr(self)->a_element, _ArrayInstPtr(nObj)->a_element, nIndex);
       
   131 # else
       
   132             bcopy(_ArrayInstPtr(self)->a_element, _ArrayInstPtr(nObj)->a_element, mySize - OHDR_SIZE);
       
   133 # endif
       
   134             _ArrayInstPtr(nObj)->a_element[nIndex] = something;
       
   135         } else 
       
   136 #endif
       
   137 	{
       
   138             /* must take care of stores ... */
       
   139             op = _ArrayInstPtr(self)->a_element;
       
   140             for (i=0; i<nIndex; i++) {
       
   141                 _ArrayInstPtr(nObj)->a_element[i] = *op;
       
   142                __STORE(nObj, *op);
       
   143                op++;
       
   144             }
       
   145             _ArrayInstPtr(nObj)->a_element[i] = something;
       
   146             __STORE(nObj, something);
       
   147         }
       
   148         RETURN ( nObj );
   130         RETURN ( nObj );
   149     }
   131     }
   150 %}
   132 %}
   151 .
   133 .
   152     ^ super copyWith:something
   134     ^ super copyWith:something
   250                                 *dst++ = *src++;
   232                                 *dst++ = *src++;
   251                             }
   233                             }
   252 # endif
   234 # endif
   253 #endif
   235 #endif
   254                         } else {
   236                         } else {
   255 #ifdef NOTDEF
   237                             while (count-- > 0) {
   256 /*
   238                                 t = *src++;
   257  * sorry, but store-check is needed since elements may be 
   239                                 *dst++ = t;
   258  * contexts etc.
   240                                 __STORE(self, t);
   259  */
       
   260                             /*
       
   261                              * no need for store-check, if dst is in newspace
       
   262                              */
       
   263                             if (_qSpace(self) == newSpace) {
       
   264 # ifdef bcopy4
       
   265                                 bcopy4(src, dst, count);
       
   266 # else
       
   267 #  ifdef FAST_MEMCPY
       
   268                                 bcopy(src, dst, count*sizeof(OBJ));
       
   269 #  else
       
   270                                 while (count--) {
       
   271                                     *dst++ = *src++;
       
   272                                 }
       
   273 #  endif
       
   274 # endif
       
   275                             } else 
       
   276 #endif
       
   277 			    {
       
   278                                 while (count-- > 0) {
       
   279                                     t = *src++;
       
   280                                     *dst++ = t;
       
   281                                     __STORE(self, t);
       
   282                                 }
       
   283                             }
   241                             }
   284                         }
   242                         }
   285                         RETURN ( self );
   243                         RETURN ( self );
   286                     }
   244                     }
   287                 }
   245                 }
   334     /* slow check using = */
   292     /* slow check using = */
   335 
   293 
   336     while (index < nIndex) {
   294     while (index < nIndex) {
   337         element = _InstPtr(self)->i_instvars[index++];
   295         element = _InstPtr(self)->i_instvars[index++];
   338         if (element != nil) {
   296         if (element != nil) {
   339 #ifdef PASS_ARG_REF
   297             if ((*eq.ilc_func)(anObject,__eq, CON_COMMA nil,&eq,element)==true) {
   340             if ((*eq.ilc_func)(anObject,__eq, CON_COMMA nil,&eq,&element)==true)
       
   341 #else
       
   342             if ((*eq.ilc_func)(anObject,__eq, CON_COMMA nil,&eq,element)==true)
       
   343 #endif
       
   344             {
       
   345                 RETURN ( true );
   298                 RETURN ( true );
   346             }
   299             }
   347         }
   300         }
   348     }
   301     }
   349 %}
   302 %}
   371             if (anElement != nil) {
   324             if (anElement != nil) {
   372                 while (index < nIndex) {
   325                 while (index < nIndex) {
   373                     element = _InstPtr(self)->i_instvars[index++];
   326                     element = _InstPtr(self)->i_instvars[index++];
   374                     if (element != nil) {
   327                     if (element != nil) {
   375                         if ((element == anElement) 
   328                         if ((element == anElement) 
   376 #ifdef PASS_ARG_REF
   329                          || ((*eq.ilc_func)(anElement,__eq, CON_COMMA nil,&eq,element) == true)) {
   377                          || ((*eq.ilc_func)(anElement,__eq, CON_COMMA nil,&eq,&element)
       
   378 #else
       
   379                          || ((*eq.ilc_func)(anElement,__eq, CON_COMMA nil,&eq,element)
       
   380 #endif
       
   381                                                                             == true)) {
       
   382                             RETURN ( _MKSMALLINT(index - nInsts) );
   330                             RETURN ( _MKSMALLINT(index - nInsts) );
   383                         }
   331                         }
   384                     }
   332                     }
   385                 }
   333                 }
   386             } else {
   334             } else {
   458 	     * home will not move - keep in a fast register
   406 	     * home will not move - keep in a fast register
   459 	     */
   407 	     */
   460             for (; index < nIndex; index++) {
   408             for (; index < nIndex; index++) {
   461                 if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   409                 if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   462 
   410 
   463 #ifdef PASS_ARG_REF
       
   464                 element = _InstPtr(self)->i_instvars[index];
       
   465                 (*codeVal)(rHome, CON_COMMA  &element);
       
   466 #else
       
   467                 (*codeVal)(rHome, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   411                 (*codeVal)(rHome, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   468 #endif
       
   469             } 
   412             } 
   470 	} else {
   413 	} else {
   471             for (; index < nIndex; index++) {
   414             for (; index < nIndex; index++) {
   472                 if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   415                 if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   473 
   416 
   474 #ifdef PASS_ARG_REF
       
   475                 element = _InstPtr(self)->i_instvars[index];
       
   476                 (*codeVal)(home, CON_COMMA  &element);
       
   477 #else
       
   478                 (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   417                 (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   479 #endif
       
   480             } 
   418             } 
   481         } 
   419         } 
   482     } else {
   420     } else {
   483         for (; index < nIndex; index++) {
   421         for (; index < nIndex; index++) {
   484             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   422             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   485 
   423 
   486 #ifdef PASS_ARG_REF
       
   487             element = _InstPtr(self)->i_instvars[index];
       
   488             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, &element);
       
   489 #else
       
   490             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, 
   424             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, 
   491             				     _InstPtr(self)->i_instvars[index]);
   425             				     _InstPtr(self)->i_instvars[index]);
   492 #endif
       
   493         } 
   426         } 
   494     }
   427     }
   495 %}
   428 %}
   496 .
   429 .
   497     ^ self
   430     ^ self
   515      && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
   448      && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil)
   516      && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
   449      && (_BlockInstPtr(aBlock)->b_nargs == _MKSMALLINT(1))) {
   517         home = _BlockInstPtr(aBlock)->b_home;
   450         home = _BlockInstPtr(aBlock)->b_home;
   518         for (index=nIndex-1; index >= endIndex; index--) {
   451         for (index=nIndex-1; index >= endIndex; index--) {
   519             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   452             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   520 
       
   521 #ifdef PASS_ARG_REF
       
   522             element = _InstPtr(self)->i_instvars[index];
       
   523             (*codeVal)(home, CON_COMMA  &element);
       
   524 #else
       
   525             (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   453             (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   526 #endif
       
   527         } 
   454         } 
   528     } else {
   455     } else {
   529         for (index=nIndex=1; index >= endIndex; index--) {
   456         for (index=nIndex=1; index >= endIndex; index--) {
   530             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   457             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   531 
       
   532 #ifdef PASS_ARG_REF
       
   533             element = _InstPtr(self)->i_instvars[index];
       
   534             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, &element);
       
   535 #else
       
   536             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, 
   458             (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, 
   537             			    _InstPtr(self)->i_instvars[index]);
   459             			    _InstPtr(self)->i_instvars[index]);
   538 #endif
       
   539         } 
   460         } 
   540     }
   461     }
   541 %}
   462 %}
   542 .
   463 .
   543     ^ self
   464     ^ self
   577                     home = _BlockInstPtr(aBlock)->b_home;
   498                     home = _BlockInstPtr(aBlock)->b_home;
   578 		    rHome = home;
   499 		    rHome = home;
   579 		    if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) {
   500 		    if ((rHome == nil) || (_qSpace(rHome) >= STACKSPACE)) {
   580                         for (index=indexLow; index <= indexHigh; index++) {
   501                         for (index=indexLow; index <= indexHigh; index++) {
   581                             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   502                             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   582 
       
   583 #ifdef PASS_ARG_REF
       
   584                             element = _InstPtr(self)->i_instvars[index];
       
   585                             (*codeVal)(rHome, CON_COMMA  &element);
       
   586 #else
       
   587                             (*codeVal)(rHome, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   503                             (*codeVal)(rHome, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   588 #endif
       
   589                         } 
   504                         } 
   590 		    } else {
   505 		    } else {
   591                         for (index=indexLow; index <= indexHigh; index++) {
   506                         for (index=indexLow; index <= indexHigh; index++) {
   592                             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   507                             if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   593 
       
   594 #ifdef PASS_ARG_REF
       
   595                             element = _InstPtr(self)->i_instvars[index];
       
   596                             (*codeVal)(home, CON_COMMA  &element);
       
   597 #else
       
   598                             (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   508                             (*codeVal)(home, CON_COMMA  _InstPtr(self)->i_instvars[index]);
   599 #endif
       
   600                         } 
   509                         } 
   601 		    }
   510 		    }
   602                 } else {
   511                 } else {
   603                     for (index=indexLow; index <= indexHigh; index++) {
   512                     for (index=indexLow; index <= indexHigh; index++) {
   604                         if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   513                         if (InterruptPending != nil) interruptL(__LINE__ COMMA_CON);
   605 
       
   606                         element = _InstPtr(self)->i_instvars[index];
   514                         element = _InstPtr(self)->i_instvars[index];
   607 #ifdef PASS_ARG_REF
       
   608                         (*val.ilc_func) (aBlock, _value_, CON_COMMA  nil, &val, &element);
       
   609 #else
       
   610                         (*val.ilc_func) (aBlock, _value_, CON_COMMA  nil, &val, element);
   515                         (*val.ilc_func) (aBlock, _value_, CON_COMMA  nil, &val, element);
   611 #endif
       
   612                     } 
   516                     } 
   613                 }
   517                 }
   614                 RETURN ( self );
   518                 RETURN ( self );
   615             }
   519             }
   616         }
   520         }
   640         for (; index < nIndex; index++) {
   544         for (; index < nIndex; index++) {
   641             if (InterruptPending != nil) interrupt(CONARG);
   545             if (InterruptPending != nil) interrupt(CONARG);
   642 
   546 
   643             element = _InstPtr(self)->i_instvars[index];
   547             element = _InstPtr(self)->i_instvars[index];
   644             if (element != nil)
   548             if (element != nil)
   645 #ifdef PASS_ARG_REF
       
   646                 (*codeVal)(home, CON_COMMA  &element);
       
   647 #else
       
   648                 (*codeVal)(home, CON_COMMA  element);
   549                 (*codeVal)(home, CON_COMMA  element);
   649 #endif
       
   650         } 
   550         } 
   651     } else {
   551     } else {
   652         for (; index < nIndex; index++) {
   552         for (; index < nIndex; index++) {
   653             if (InterruptPending != nil) interrupt(CONARG);
   553             if (InterruptPending != nil) interrupt(CONARG);
   654 
   554 
   655             element = _InstPtr(self)->i_instvars[index];
   555             element = _InstPtr(self)->i_instvars[index];
   656             if (element != nil)
   556             if (element != nil)
   657 #ifdef PASS_ARG_REF
       
   658                 (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, &element);
       
   659 #else
       
   660                 (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, element);
   557                 (*val.ilc_func)(aBlock, _value_, CON_COMMA  nil, &val, element);
   661 #endif
       
   662         } 
   558         } 
   663     }
   559     }
   664 %}
   560 %}
   665 .
   561 .
   666     ^ self
   562     ^ self