931 |
931 |
932 %{ /* NOCONTEXT */ |
932 %{ /* NOCONTEXT */ |
933 #ifdef __SCHTEAM__ |
933 #ifdef __SCHTEAM__ |
934 if (start.isSmallInteger() |
934 if (start.isSmallInteger() |
935 && aCharacter.isSTCharacter()) { |
935 && aCharacter.isSTCharacter()) { |
936 int idx1Based = start.intValue(); // st index is 1 based |
936 int idx1Based = start.intValue(); // st index is 1 based |
937 int jIdx = self.asString().indexOf(aCharacter.charValue(), idx1Based-1); |
937 int jIdx = self.asString().indexOf(aCharacter.charValue(), idx1Based-1); |
938 |
938 |
939 return context._RETURN( jIdx+1 ); // st index is 1 based |
939 return context._RETURN( jIdx+1 ); // st index is 1 based |
940 } |
940 } |
941 |
941 |
942 #else |
942 #else |
943 # undef __UNROLL_LOOPS__ |
943 # if defined(__BORLANDC__) || defined(__VISUALC__) |
944 # undef FAST_MEMCHR |
944 # undef __UNROLL_LOOPS__ |
945 # define V2 |
945 # undef FAST_MEMCHR |
|
946 # define V2 |
|
947 # endif |
946 |
948 |
947 REGISTER unsigned char *cp; |
949 REGISTER unsigned char *cp; |
948 # ifdef FAST_MEMCHR |
|
949 REGISTER unsigned char *ncp; |
|
950 # endif |
|
951 REGISTER INT index; |
950 REGISTER INT index; |
952 REGISTER unsigned byteValue; |
951 REGISTER unsigned byteValue; |
953 int last; |
952 int last; |
954 OBJ cls; |
953 OBJ cls; |
955 |
954 |
956 if (__isSmallInteger(start)) { |
955 if (__isSmallInteger(start)) { |
957 index = __intVal(start); |
956 index = __intVal(start); |
958 if (index > 0) { |
957 if (index > 0) { |
959 if (__isCharacter(aCharacter)) { |
958 if (__isCharacter(aCharacter)) { |
960 byteValue = __intVal(__characterVal(aCharacter)); |
959 byteValue = __intVal(__characterVal(aCharacter)); |
961 if (byteValue <= 0xFF) { |
960 if (byteValue <= 0xFF) { |
962 last = __stringSize(self); |
961 last = __stringSize(self); |
963 cp = __stringVal(self); |
962 cp = __stringVal(self); |
964 if ((cls = __qClass(self)) != String) { |
963 if ((cls = __qClass(self)) != String) { |
965 int numInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
964 int numInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars)); |
966 |
965 |
967 cp += numInstBytes; |
966 cp += numInstBytes; |
968 last -= numInstBytes; |
967 last -= numInstBytes; |
969 } |
968 } |
970 if (index <= last) { |
969 if (index <= last) { |
971 # ifdef FAST_MEMCHR |
970 # ifdef FAST_MEMCHR |
972 ncp = (unsigned char *) memchr(cp+index-1, byteValue, last+1-index); |
971 REGISTER unsigned char *ncp; |
973 if (ncp) { |
972 |
974 RETURN ( __mkSmallInteger(ncp - cp + 1) ); |
973 ncp = (unsigned char *) memchr(cp+index-1, byteValue, last+1-index); |
975 } |
974 if (ncp) { |
|
975 RETURN ( __mkSmallInteger(ncp - cp + 1) ); |
|
976 } |
976 # else |
977 # else |
977 # ifdef __UNROLL_LOOPS__ |
978 # ifdef __UNROLL_LOOPS__ |
978 { |
979 { |
979 int last3 = last-3; |
980 int last3 = last-3; |
980 |
981 |
981 for (; index <= last3; index += 4) { |
982 for (; index <= last3; index += 4) { |
982 if (cp[index-1] == byteValue) { RETURN ( __mkSmallInteger(index) ); } |
983 if (cp[index-1] == byteValue) { RETURN ( __mkSmallInteger(index) ); } |
983 if (cp[index-1+1] == byteValue) { RETURN ( __mkSmallInteger(index+1) ); } |
984 if (cp[index-1+1] == byteValue) { RETURN ( __mkSmallInteger(index+1) ); } |
984 if (cp[index-1+2] == byteValue) { RETURN ( __mkSmallInteger(index+2) ); } |
985 if (cp[index-1+2] == byteValue) { RETURN ( __mkSmallInteger(index+2) ); } |
985 if (cp[index-1+3] == byteValue) { RETURN ( __mkSmallInteger(index+3) ); } |
986 if (cp[index-1+3] == byteValue) { RETURN ( __mkSmallInteger(index+3) ); } |
986 } |
987 } |
987 } |
988 } |
988 # endif |
989 # endif |
989 # ifdef V1 |
990 # ifdef V1 |
990 for (; index <= last; index++) { |
991 for (; index <= last; index++) { |
991 if (cp[index-1] == byteValue) { |
992 if (cp[index-1] == byteValue) { |
992 RETURN ( __mkSmallInteger(index) ); |
993 RETURN ( __mkSmallInteger(index) ); |
993 } |
994 } |
994 } |
995 } |
995 # endif |
996 # endif |
996 # ifdef V2 |
997 # ifdef V2 |
997 { |
998 { |
998 // see bit twiddling hacks |
999 // see bit twiddling hacks |
999 # define hasZeroByte(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL) |
1000 # define hasZeroByte(v) (((v) - 0x01010101UL) & ~(v) & 0x80808080UL) |
1000 # define hasByteM(v,m) hasZeroByte( (v) ^ m) |
1001 # define hasByteM(v,m) hasZeroByte( (v) ^ m) |
1001 # if __POINTER_SIZE__ == 8 |
1002 # if __POINTER_SIZE__ == 8 |
1002 # define hasZeroByte8(v) (((v) - 0x0101010101010101ULL) & ~(v) & 0x8080808080808080ULL) |
1003 # define hasZeroByte8(v) (((v) - 0x0101010101010101ULL) & ~(v) & 0x8080808080808080ULL) |
1003 # define hasByteM8(v,m) hasZeroByte8( (v) ^ m) |
1004 # define hasByteM8(v,m) hasZeroByte8( (v) ^ m) |
1004 // the following loop checks eight bytes at once |
1005 // the following loop checks eight bytes at once |
1005 if (((index-1) & 0x7) == 0) { |
1006 if (((index-1) & 0x7) == 0) { |
1006 int last8 = last-8; |
1007 int last8 = last-8; |
1007 INT m = (~0ULL/255 * (byteValue)); |
1008 INT m = (~0ULL/255 * (byteValue)); |
1008 |
1009 |
1009 while (index <= last8) { |
1010 while (index <= last8) { |
1010 unsigned INT v = *(unsigned INT *)(cp+index-1); |
1011 unsigned INT v = *(unsigned INT *)(cp+index-1); |
1011 |
1012 |
1012 if (hasByteM8(v,m)) break; |
1013 if (hasByteM8(v,m)) break; |
1013 index += 8; |
1014 index += 8; |
1014 } |
1015 } |
1015 } |
1016 } |
1016 # endif |
1017 # endif |
1017 // the following loop checks four bytes at once |
1018 // the following loop checks four bytes at once |
1018 if (((index-1) & 0x3) == 0) { |
1019 if (((index-1) & 0x3) == 0) { |
1019 int last4 = last-4; |
1020 int last4 = last-4; |
1020 int m = (~0UL/255 * (byteValue)); |
1021 int m = (~0UL/255 * (byteValue)); |
1021 |
1022 |
1022 while (index <= last4) { |
1023 while (index <= last4) { |
1023 unsigned int v = *(unsigned int *)(cp+index-1); |
1024 unsigned int v = *(unsigned int *)(cp+index-1); |
1024 |
1025 |
1025 if (hasByteM(v,m)) break; |
1026 if (hasByteM(v,m)) break; |
1026 index += 4; |
1027 index += 4; |
1027 } |
1028 } |
1028 } |
1029 } |
1029 while (index <= last) { |
1030 while (index <= last) { |
1030 if (cp[index-1] == byteValue) { |
1031 if (cp[index-1] == byteValue) { |
1031 RETURN ( __mkSmallInteger(index) ); |
1032 RETURN ( __mkSmallInteger(index) ); |
1032 } |
1033 } |
1033 index++; |
1034 index++; |
1034 } |
1035 } |
1035 } |
1036 } |
1036 # endif |
1037 # endif |
1037 # endif |
1038 # endif |
1038 } |
1039 } |
1039 } |
1040 } |
1040 } |
1041 } |
1041 RETURN ( __mkSmallInteger(0) ); |
1042 RETURN ( __mkSmallInteger(0) ); |
1042 } |
1043 } |
1043 } |
1044 } |
1044 # undef V2 |
1045 # undef V2 |
1045 #endif /* not SCHTEAM */ |
1046 #endif /* not SCHTEAM */ |
1046 %}. |
1047 %}. |
1047 ^ super indexOf:aCharacter startingAt:start |
1048 ^ super indexOf:aCharacter startingAt:start |