287 } |
300 } |
288 %}. |
301 %}. |
289 ^ super at:index put:anObject |
302 ^ super at:index put:anObject |
290 ! |
303 ! |
291 |
304 |
292 size |
305 basicSize |
293 "return the number of indexed elements in the receiver. |
306 "return the number of indexed elements in the receiver" |
294 Reimplemented here to avoid the additional size->basicSize send |
|
295 (which we can do here, since size is obviously not redefined in a subclass). |
|
296 This method is the same as basicSize." |
|
297 |
307 |
298 %{ /* NOCONTEXT */ |
308 %{ /* NOCONTEXT */ |
299 |
309 |
300 RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) )); |
310 RETURN ( __MKSMALLINT(_arraySize(self) - _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars) )); |
301 %} |
311 %} |
302 ! |
312 ! |
303 |
313 |
304 at:index |
314 basicAt:index |
305 "return the indexed instance variable with index, anInteger. |
315 "return the indexed instance variable with index, anInteger |
306 Reimplemented here to avoid the additional at:->basicAt: send |
316 - added here for speed" |
307 (which we can do here, since at: is obviously not redefined in a subclass). |
|
308 This method is the same as at:." |
|
309 |
317 |
310 %{ /* NOCONTEXT */ |
318 %{ /* NOCONTEXT */ |
311 |
319 |
312 REGISTER int indx; |
320 REGISTER int indx; |
313 REGISTER unsigned int nIndex; |
321 REGISTER unsigned int nIndex; |
451 ^ super copyWith:something |
451 ^ super copyWith:something |
452 ! ! |
452 ! ! |
453 |
453 |
454 !Array methodsFor:'enumerating'! |
454 !Array methodsFor:'enumerating'! |
455 |
455 |
456 do:aBlock |
|
457 "evaluate the argument, aBlock for each element in the collection. |
|
458 - reimplemented for speed" |
|
459 |
|
460 |home| |
|
461 %{ |
|
462 REGISTER OBJFUNC codeVal; |
|
463 REGISTER int index; |
|
464 unsigned int nIndex; |
|
465 extern OBJ Block; |
|
466 static struct inlineCache val = _ILC1; |
|
467 REGISTER OBJ rHome; |
|
468 |
|
469 index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars); |
|
470 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
471 if (__isBlockLike(aBlock) |
|
472 && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) |
|
473 && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) { |
|
474 #ifdef NEW_BLOCK_CALL |
|
475 for (; index < nIndex; index++) { |
|
476 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
477 |
|
478 (*codeVal)(aBlock, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
479 } |
|
480 #else |
|
481 home = _BlockInstPtr(aBlock)->b_home; |
|
482 rHome = home; |
|
483 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) { |
|
484 /* |
|
485 * home will not move - keep in a fast register |
|
486 */ |
|
487 #if defined(UNROLL_LOOPS) |
|
488 { |
|
489 int i4; |
|
490 |
|
491 while ((i4 = index+4) < nIndex) { |
|
492 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
493 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
494 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
495 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+1]); |
|
496 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
497 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+2]); |
|
498 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
499 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+3]); |
|
500 index = i4; |
|
501 } |
|
502 } |
|
503 #endif |
|
504 for (; index < nIndex; index++) { |
|
505 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
506 |
|
507 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
508 } |
|
509 } else { |
|
510 for (; index < nIndex; index++) { |
|
511 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
512 |
|
513 (*codeVal)(home, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
514 } |
|
515 } |
|
516 #endif |
|
517 } else { |
|
518 for (; index < nIndex; index++) { |
|
519 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
520 |
|
521 (*val.ilc_func)(aBlock, |
|
522 @symbol(value:), |
|
523 CON_COMMA nil, &val, |
|
524 _InstPtr(self)->i_instvars[index]); |
|
525 } |
|
526 } |
|
527 %} |
|
528 . |
|
529 ^ self |
|
530 ! |
|
531 |
|
532 keysAndValuesDo:aBlock |
|
533 "evaluate the argument, aBlock for each element in the collection. |
|
534 Pass both index and element to the block. |
|
535 - reimplemented for speed" |
|
536 |
|
537 |home| |
|
538 %{ |
|
539 REGISTER OBJFUNC codeVal; |
|
540 REGISTER int index; |
|
541 unsigned int nIndex; |
|
542 extern OBJ Block; |
|
543 static struct inlineCache val2 = _ILC2; |
|
544 REGISTER OBJ rHome; |
|
545 |
|
546 index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars); |
|
547 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
548 if (__isBlockLike(aBlock) |
|
549 && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) |
|
550 && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(2))) { |
|
551 #ifdef NEW_BLOCK_CALL |
|
552 for (; index < nIndex; index++) { |
|
553 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
554 |
|
555 (*codeVal)(aBlock, CON_COMMA __MKSMALLINT(index+1), |
|
556 _InstPtr(self)->i_instvars[index]); |
|
557 } |
|
558 #else |
|
559 home = _BlockInstPtr(aBlock)->b_home; |
|
560 rHome = home; |
|
561 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) { |
|
562 /* |
|
563 * home will not move - keep in a fast register |
|
564 */ |
|
565 while (index < nIndex) { |
|
566 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
567 |
|
568 index++; |
|
569 (*codeVal)(rHome, CON_COMMA __MKSMALLINT(index), |
|
570 _InstPtr(self)->i_instvars[index-1]); |
|
571 } |
|
572 } else { |
|
573 while (index < nIndex) { |
|
574 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
575 |
|
576 index++; |
|
577 (*codeVal)(home, CON_COMMA __MKSMALLINT(index), |
|
578 _InstPtr(self)->i_instvars[index-1]); |
|
579 } |
|
580 } |
|
581 #endif |
|
582 } else { |
|
583 while (index < nIndex) { |
|
584 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
585 |
|
586 index++; |
|
587 (*val2.ilc_func)(aBlock, |
|
588 @symbol(value:value:), |
|
589 CON_COMMA nil, &val2, |
|
590 __MKSMALLINT(index), |
|
591 _InstPtr(self)->i_instvars[index-1]); |
|
592 } |
|
593 } |
|
594 %} |
|
595 . |
|
596 ^ self |
|
597 ! |
|
598 |
|
599 from:start to:stop do:aBlock |
456 from:start to:stop do:aBlock |
600 "evaluate the argument, aBlock for the elements starting at index start |
457 "evaluate the argument, aBlock for the elements starting at index start |
601 up to (and including) stop in the collection. |
458 up to (and including) stop in the collection. |
602 - reimplemented for speed" |
459 - reimplemented for speed" |
603 |
460 |
681 %} |
538 %} |
682 . |
539 . |
683 ^ super from:start to:stop do:aBlock |
540 ^ super from:start to:stop do:aBlock |
684 ! |
541 ! |
685 |
542 |
|
543 do:aBlock |
|
544 "evaluate the argument, aBlock for each element in the collection. |
|
545 - reimplemented for speed" |
|
546 |
|
547 |home| |
|
548 %{ |
|
549 REGISTER OBJFUNC codeVal; |
|
550 REGISTER int index; |
|
551 unsigned int nIndex; |
|
552 extern OBJ Block; |
|
553 static struct inlineCache val = _ILC1; |
|
554 REGISTER OBJ rHome; |
|
555 |
|
556 index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars); |
|
557 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
558 if (__isBlockLike(aBlock) |
|
559 && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) |
|
560 && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(1))) { |
|
561 #ifdef NEW_BLOCK_CALL |
|
562 for (; index < nIndex; index++) { |
|
563 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
564 |
|
565 (*codeVal)(aBlock, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
566 } |
|
567 #else |
|
568 home = _BlockInstPtr(aBlock)->b_home; |
|
569 rHome = home; |
|
570 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) { |
|
571 /* |
|
572 * home will not move - keep in a fast register |
|
573 */ |
|
574 #if defined(UNROLL_LOOPS) |
|
575 { |
|
576 int i4; |
|
577 |
|
578 while ((i4 = index+4) < nIndex) { |
|
579 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
580 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
581 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
582 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+1]); |
|
583 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
584 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+2]); |
|
585 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
586 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index+3]); |
|
587 index = i4; |
|
588 } |
|
589 } |
|
590 #endif |
|
591 for (; index < nIndex; index++) { |
|
592 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
593 |
|
594 (*codeVal)(rHome, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
595 } |
|
596 } else { |
|
597 for (; index < nIndex; index++) { |
|
598 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
599 |
|
600 (*codeVal)(home, CON_COMMA _InstPtr(self)->i_instvars[index]); |
|
601 } |
|
602 } |
|
603 #endif |
|
604 } else { |
|
605 for (; index < nIndex; index++) { |
|
606 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
607 |
|
608 (*val.ilc_func)(aBlock, |
|
609 @symbol(value:), |
|
610 CON_COMMA nil, &val, |
|
611 _InstPtr(self)->i_instvars[index]); |
|
612 } |
|
613 } |
|
614 %} |
|
615 . |
|
616 ^ self |
|
617 ! |
|
618 |
686 nonNilElementsDo:aBlock |
619 nonNilElementsDo:aBlock |
687 "evaluate the argument, aBlock for each non-nil element" |
620 "evaluate the argument, aBlock for each non-nil element" |
688 |
621 |
689 |home| |
622 |home| |
690 %{ |
623 %{ |
741 if (element != nil) |
674 if (element != nil) |
742 (*val.ilc_func)(aBlock, |
675 (*val.ilc_func)(aBlock, |
743 @symbol(value:), |
676 @symbol(value:), |
744 CON_COMMA nil, &val, |
677 CON_COMMA nil, &val, |
745 element); |
678 element); |
|
679 } |
|
680 } |
|
681 %} |
|
682 . |
|
683 ^ self |
|
684 ! |
|
685 |
|
686 keysAndValuesDo:aBlock |
|
687 "evaluate the argument, aBlock for each element in the collection. |
|
688 Pass both index and element to the block. |
|
689 - reimplemented for speed" |
|
690 |
|
691 |home| |
|
692 %{ |
|
693 REGISTER OBJFUNC codeVal; |
|
694 REGISTER int index; |
|
695 unsigned int nIndex; |
|
696 extern OBJ Block; |
|
697 static struct inlineCache val2 = _ILC2; |
|
698 REGISTER OBJ rHome; |
|
699 |
|
700 index = _intVal(_ClassInstPtr(__qClass(self))->c_ninstvars); |
|
701 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
702 if (__isBlockLike(aBlock) |
|
703 && ((codeVal = _BlockInstPtr(aBlock)->b_code) != (OBJFUNC)nil) |
|
704 && (_BlockInstPtr(aBlock)->b_nargs == __MKSMALLINT(2))) { |
|
705 #ifdef NEW_BLOCK_CALL |
|
706 for (; index < nIndex; index++) { |
|
707 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
708 |
|
709 (*codeVal)(aBlock, CON_COMMA __MKSMALLINT(index+1), |
|
710 _InstPtr(self)->i_instvars[index]); |
|
711 } |
|
712 #else |
|
713 home = _BlockInstPtr(aBlock)->b_home; |
|
714 rHome = home; |
|
715 if ((rHome == nil) || (__qSpace(rHome) >= STACKSPACE)) { |
|
716 /* |
|
717 * home will not move - keep in a fast register |
|
718 */ |
|
719 while (index < nIndex) { |
|
720 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
721 |
|
722 index++; |
|
723 (*codeVal)(rHome, CON_COMMA __MKSMALLINT(index), |
|
724 _InstPtr(self)->i_instvars[index-1]); |
|
725 } |
|
726 } else { |
|
727 while (index < nIndex) { |
|
728 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
729 |
|
730 index++; |
|
731 (*codeVal)(home, CON_COMMA __MKSMALLINT(index), |
|
732 _InstPtr(self)->i_instvars[index-1]); |
|
733 } |
|
734 } |
|
735 #endif |
|
736 } else { |
|
737 while (index < nIndex) { |
|
738 if (InterruptPending != nil) __interruptL(@line COMMA_CON); |
|
739 |
|
740 index++; |
|
741 (*val2.ilc_func)(aBlock, |
|
742 @symbol(value:value:), |
|
743 CON_COMMA nil, &val2, |
|
744 __MKSMALLINT(index), |
|
745 _InstPtr(self)->i_instvars[index-1]); |
746 } |
746 } |
747 } |
747 } |
748 %} |
748 %} |
749 . |
749 . |
750 ^ self |
750 ^ self |
899 s contents |
899 s contents |
900 " |
900 " |
901 ! ! |
901 ! ! |
902 |
902 |
903 !Array methodsFor:'filling & replacing'! |
903 !Array methodsFor:'filling & replacing'! |
|
904 |
|
905 from:index1 to:index2 put:anObject |
|
906 "reimplemented for speed if receiver is an Array" |
|
907 |
|
908 %{ /* NOCONTEXT */ |
|
909 |
|
910 REGISTER int index; |
|
911 unsigned int nIndex; |
|
912 unsigned int endIndex; |
|
913 REGISTER OBJ *dst; |
|
914 |
|
915 if ((__qClass(self) == Array) |
|
916 && __bothSmallInteger(index1, index2)) { |
|
917 index = _intVal(index1) - 1; |
|
918 if (index >= 0) { |
|
919 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
920 endIndex = _intVal(index2) - 1; |
|
921 if (endIndex < nIndex) { |
|
922 dst = &(_InstPtr(self)->i_instvars[index]); |
|
923 #ifdef memset4 |
|
924 memset4(dst, anObject, (endIndex-index+1)); |
|
925 __STORE(self, anObject); |
|
926 #else |
|
927 if ((INT)anObject == 0) { |
|
928 memset(dst, 0, __OBJS2BYTES__(endIndex-index+1)); |
|
929 } else { |
|
930 #if defined(UNROLL_LOOPS) |
|
931 { |
|
932 int i8; |
|
933 |
|
934 while ((i8 = index + 8) <= endIndex) { |
|
935 dst[0] = anObject; |
|
936 dst[1] = anObject; |
|
937 dst[2] = anObject; |
|
938 dst[3] = anObject; |
|
939 dst[4] = anObject; |
|
940 dst[5] = anObject; |
|
941 dst[6] = anObject; |
|
942 dst[7] = anObject; |
|
943 dst += 8; |
|
944 index = i8; |
|
945 } |
|
946 } |
|
947 #endif |
|
948 for (; index <= endIndex; index++) { |
|
949 *dst++ = anObject; |
|
950 } |
|
951 __STORE(self, anObject); |
|
952 } |
|
953 #endif |
|
954 RETURN ( self ); |
|
955 } |
|
956 } |
|
957 } |
|
958 %} |
|
959 . |
|
960 ^ super from:index1 to:index2 put:anObject |
|
961 ! |
904 |
962 |
905 replaceFrom:start to:stop with:aCollection startingAt:repStart |
963 replaceFrom:start to:stop with:aCollection startingAt:repStart |
906 "reimplemented for speed if both receiver and aCollection are Arrays" |
964 "reimplemented for speed if both receiver and aCollection are Arrays" |
907 |
965 |
908 %{ /* NOCONTEXT */ |
966 %{ /* NOCONTEXT */ |
1007 } |
1065 } |
1008 } |
1066 } |
1009 } |
1067 } |
1010 %}. |
1068 %}. |
1011 ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart |
1069 ^ super replaceFrom:start to:stop with:aCollection startingAt:repStart |
1012 ! |
|
1013 |
|
1014 from:index1 to:index2 put:anObject |
|
1015 "reimplemented for speed if receiver is an Array" |
|
1016 |
|
1017 %{ /* NOCONTEXT */ |
|
1018 |
|
1019 REGISTER int index; |
|
1020 unsigned int nIndex; |
|
1021 unsigned int endIndex; |
|
1022 REGISTER OBJ *dst; |
|
1023 |
|
1024 if ((__qClass(self) == Array) |
|
1025 && __bothSmallInteger(index1, index2)) { |
|
1026 index = _intVal(index1) - 1; |
|
1027 if (index >= 0) { |
|
1028 nIndex = __BYTES2OBJS__(__qSize(self) - OHDR_SIZE); |
|
1029 endIndex = _intVal(index2) - 1; |
|
1030 if (endIndex < nIndex) { |
|
1031 dst = &(_InstPtr(self)->i_instvars[index]); |
|
1032 #ifdef memset4 |
|
1033 memset4(dst, anObject, (endIndex-index+1)); |
|
1034 __STORE(self, anObject); |
|
1035 #else |
|
1036 if ((INT)anObject == 0) { |
|
1037 memset(dst, 0, __OBJS2BYTES__(endIndex-index+1)); |
|
1038 } else { |
|
1039 #if defined(UNROLL_LOOPS) |
|
1040 { |
|
1041 int i8; |
|
1042 |
|
1043 while ((i8 = index + 8) <= endIndex) { |
|
1044 dst[0] = anObject; |
|
1045 dst[1] = anObject; |
|
1046 dst[2] = anObject; |
|
1047 dst[3] = anObject; |
|
1048 dst[4] = anObject; |
|
1049 dst[5] = anObject; |
|
1050 dst[6] = anObject; |
|
1051 dst[7] = anObject; |
|
1052 dst += 8; |
|
1053 index = i8; |
|
1054 } |
|
1055 } |
|
1056 #endif |
|
1057 for (; index <= endIndex; index++) { |
|
1058 *dst++ = anObject; |
|
1059 } |
|
1060 __STORE(self, anObject); |
|
1061 } |
|
1062 #endif |
|
1063 RETURN ( self ); |
|
1064 } |
|
1065 } |
|
1066 } |
|
1067 %} |
|
1068 . |
|
1069 ^ super from:index1 to:index2 put:anObject |
|
1070 ! ! |
1070 ! ! |
1071 |
1071 |
1072 !Array methodsFor:'printing & storing'! |
1072 !Array methodsFor:'printing & storing'! |
1073 |
1073 |
1074 displayString |
1074 displayString |