diff -r b4bb0f43d6a7 -r c9284ca27a4a UninterpretedBytes.st --- a/UninterpretedBytes.st Mon Mar 01 23:51:44 1999 +0100 +++ b/UninterpretedBytes.st Wed Mar 03 16:11:12 1999 +0100 @@ -99,39 +99,6 @@ " ! ! -!UninterpretedBytes class methodsFor:'initialization'! - -checkByteOrder - "initialize our current byteOrder. - Must be called at system init time and on snapshot restart" - - IsBigEndian := self isBigEndian. - - "Created: / 5.3.1998 / 14:51:41 / stefan" -! - -initialize - "get the byte order" - - self checkByteOrder. - - "want to be informed when returning from snapshot" - ObjectMemory dependents addDependent:self - - "Created: / 5.3.1998 / 14:46:31 / stefan" - "Modified: / 5.3.1998 / 14:53:28 / stefan" -! - -update:something with:aParameter from:changedObject - "handle image restarts and reget the byte order" - - (something == #returnFromSnapshot) ifTrue:[ - self checkByteOrder. - ] - - "Created: / 5.3.1998 / 14:55:13 / stefan" -! ! - !UninterpretedBytes class methodsFor:'instance creation'! from:aCollection @@ -146,7 +113,10 @@ isBigEndian "return true, if words/shorts store the most-significant byte first (MSB), false if least-sign.-first (LSB). - I.e. false for vax, intel; true for m68k, sun." + I.e. false for vax, intel; true for m68k, sun. + + Notice: UninterpretedBytes isBigEndian + this is inlined both by stc and the jit compiler" %{ /* NOCONTEXT */ @@ -164,8 +134,8 @@ * constant for systems where this is known. */ union { - unsigned int u_l; - char u_c[sizeof(int)]; + unsigned int u_l; + char u_c[sizeof(int)]; } u; u.u_l = 0x87654321; @@ -634,7 +604,7 @@ |w| - w := self unsignedLongLongAt:index bigEndian:IsBigEndian. + w := self unsignedLongLongAt:index bigEndian:(UninterpretedBytes isBigEndian). (w > (16r7FFFFFFFFFFFFFFF)) ifTrue:[ ^ w - (16r10000000000000000) ]. @@ -717,15 +687,15 @@ l := LargeInteger basicNew numberOfDigits:8. msb ifTrue:[ - bIdx := index + 7. - delta := -1 + bIdx := index + 7. + delta := -1 ] ifFalse:[ - bIdx := index. - delta := 1 + bIdx := index. + delta := 1 ]. 1 to:8 do:[:i | - l digitAt:i put:(self basicAt:bIdx). - bIdx := bIdx + delta + l digitAt:i put:(self basicAt:bIdx). + bIdx := bIdx + delta ]. ^ l compressed @@ -813,7 +783,7 @@ The value must be in the range 0 to 16rFFFFFFFFFFFFFFFF. The value is stored in natural byte order." - ^ self unsignedLongLongAt:index put:anInteger bigEndian:IsBigEndian + ^ self unsignedLongLongAt:index put:anInteger bigEndian:(UninterpretedBytes isBigEndian) "Created: / 5.3.1998 / 14:44:00 / stefan" "Modified: / 5.3.1998 / 15:02:32 / stefan" @@ -876,23 +846,44 @@ __fetchBytePointerAndSize__(self, &cp, &sz); if (cp) { unsigned INT idx = ((unsigned INT)__intVal(index)) - 1; + int iVal; if ((idx+(sizeof(int)-1)) < sz) { cp += idx; - /* - * aligned + +#if defined(i386) || defined(UNALIGNED_FETCH_OK) + /* aligned or not - we dont care + * (i386 can fetch unaligned) */ + iVal = ((int *)cp)[0]; +#else if (((INT)cp & (sizeof(int)-1)) == 0) { - int iVal = ((int *)cp)[0]; - - RETURN (__MKUINT(iVal)); + /* + * aligned + */ + iVal = ((int *)cp)[0]; + } else { + union { + char c[4]; + int i; + } u; + u.c[0] = cp[0]; + u.c[1] = cp[1]; + u.c[2] = cp[2]; + u.c[3] = cp[3]; + iVal = u.i; } +#endif + if ((iVal >= 0) && (iVal <= _MAX_INT)) { + RETURN ( __MKSMALLINT(iVal) ); + } + RETURN ( __MKULARGEINT(iVal) ); } } } %}. - ^ self doubleWordAt:index MSB:IsBigEndian + ^ self doubleWordAt:index MSB:(UninterpretedBytes isBigEndian) " |b| @@ -912,41 +903,102 @@ Subclasses may redefine this for better performance." |val - ival "{ XXClass: SmallInteger }" + ival "{ Class: SmallInteger }" + t "{ Class: SmallInteger }" i "{ Class: SmallInteger }" b1 "{ Class: SmallInteger }" b2 "{ Class: SmallInteger }" b3 "{ Class: SmallInteger }" b4 "{ Class: SmallInteger }"| +%{ + /* + * handle the most common cases fast ... + */ + if (__isSmallInteger(index)) { + unsigned char *cp; + int sz; + + __fetchBytePointerAndSize__(self, &cp, &sz); + if (cp) { + unsigned INT idx = ((unsigned INT)__intVal(index)) - 1; + int iVal; + + if ((idx+(sizeof(int)-1)) < sz) { + cp += idx; + + if (msb == true) { +#ifdef __MSBFIRST + if (((INT)cp & (sizeof(int)-1))== 0) { + /* + * aligned + */ + iVal = ((int *)cp)[0]; + } else +#endif + { + iVal = cp[0]; + iVal = (iVal << 8) | cp[1]; + iVal = (iVal << 8) | cp[2]; + iVal = (iVal << 8) | cp[3]; + } + } else { +#ifdef i386 + /* + * aligned or not - we dont care + * (i386 can fetch unaligned) + */ + iVal = ((int *)cp)[0]; +#else +# ifdef __LSBFIRST + if (((INT)cp & (sizeof(int)-1))== 0) { + /* + * aligned + */ + iVal = ((int *)cp)[0]; + } else +# endif + { + iVal = cp[3]; + iVal = (iVal << 8) | cp[2]; + iVal = (iVal << 8) | cp[1]; + iVal = (iVal << 8) | cp[0]; + } +#endif + } + RETURN (__MKUINT(iVal)); + } + } + } +%}. + + "/ fallBack code - non ByteArray-like receiver + "/ or funny index + i := index. b1 := self at:i. b2 := self at:(i+1). b3 := self at:(i+2). b4 := self at:(i+3). - msb ifTrue:[ - ival := b1. - ival := (ival bitShift:8) + b2. - ival := (ival bitShift:8) + b3. - val := (ival bitShift:8) + b4. - ] ifFalse:[ - ival := b4. - ival := (ival bitShift:8) + b3. - ival := (ival bitShift:8) + b2. - val := (ival bitShift:8) + b1. + msb ifFalse:[ + t := b4. b4 := b1. b1 := t. + t := b3. b3 := b2. b2 := t. ]. + ival := b1. + ival := (ival bitShift:8) + b2. + ival := (ival bitShift:8) + b3. + val := (ival bitShift:8) + b4. ^ val " |b| b := ByteArray withAll:#(1 2 3 4). - (b doubleWordAt:1 MSB:true) printStringRadix:16. - (b doubleWordAt:1 MSB:false) printStringRadix:16 + (b doubleWordAt:1 MSB:true) printStringRadix:16. + (b doubleWordAt:1 MSB:false) printStringRadix:16 " - "Modified: / 21.1.1998 / 17:42:30 / cg" ! doubleWordAt:index put:value @@ -957,7 +1009,7 @@ The value is stored in the machines natural byte order. Subclasses may redefine this for better performance." - ^ self doubleWordAt:index put:value MSB:IsBigEndian + ^ self doubleWordAt:index put:value MSB:(UninterpretedBytes isBigEndian) " |b| @@ -1015,7 +1067,7 @@ accessing the memory as an array of doubleWord entries. (i.e. indices are 1, 2, ...)" - ^ self doubleWordAtDoubleWordIndex:index MSB:IsBigEndian + ^ self doubleWordAtDoubleWordIndex:index MSB:(UninterpretedBytes isBigEndian) "Created: / 21.1.1998 / 17:43:53 / cg" "Modified: / 5.3.1998 / 14:58:06 / stefan" @@ -1040,7 +1092,7 @@ accessing the memory as an array of doubleWord entries. (i.e. indices are 1, 2, ...)" - ^ self doubleWordAtDoubleWordIndex:index put:value MSB:IsBigEndian + ^ self doubleWordAtDoubleWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian) "Created: / 21.1.1998 / 17:44:13 / cg" "Modified: / 5.3.1998 / 14:58:19 / stefan" @@ -1319,9 +1371,10 @@ "return the 4-bytes starting at index as an (unsigned) Integer. The index is a smalltalk index (i.e. 1-based). The value is retrieved in the machines natural byte order. - Subclasses may redefine this for better performance." + Subclasses may redefine this for better performance. + Same as doubleWordAt: for protocol completeness" - ^ self unsignedLongAt:index bigEndian:IsBigEndian + ^ self doubleWordAt:index " |b| @@ -1339,34 +1392,10 @@ The index is a smalltalk index (i.e. 1-based). The value is retrieved MSB-first, if the msb-arg is true; LSB-first otherwise. - Subclasses may redefine this for better performance." - - |val - ival "{ Class: SmallInteger }" - i "{ Class: SmallInteger }" - b1 "{ Class: SmallInteger }" - b2 "{ Class: SmallInteger }" - b3 "{ Class: SmallInteger }" - b4 "{ Class: SmallInteger }"| + Subclasses may redefine this for better performance. + Same as doubleWordAt:MSB: for protocol completeness" - i := index. - b1 := self at:i. - b2 := self at:(i+1). - b3 := self at:(i+2). - b4 := self at:(i+3). - - msb ifTrue:[ - ival := b1. - ival := (ival bitShift:8) + b2. - ival := (ival bitShift:8) + b3. - val := (ival * 256) + b4. - ] ifFalse:[ - ival := b4. - ival := (ival bitShift:8) + b3. - ival := (ival bitShift:8) + b2. - val := (ival * 256) + b1. - ]. - ^ val + ^ self doubleWordAt:index MSB:msb " |b| @@ -1386,9 +1415,10 @@ The value should be in the range 0 to 16rFFFFFFFF (for negative values, the stored value is not defined). The value is stored in the machines natural byte order. - Subclasses may redefine this for better performance." + Subclasses may redefine this for better performance. + Same as doubleWordAt:put: for protocol completeness" - ^ self unsignedLongAt:index put:value bigEndian:IsBigEndian + ^ self doubleWordAt:index put:value " |b| @@ -1406,27 +1436,10 @@ The index is a smalltalk index (i.e. 1-based). The value must be in the range 0 to 16rFFFFFFFF. The value is stored MSB-first if msb is true; LSB-first otherwise. - Subclasses may redefine this for better performance." - - |i "{ Class: SmallInteger }" | - - ((aNumber < 0) or:[aNumber > 16rFFFFFFFF]) ifTrue:[ - ^ self elementBoundsError - ]. + Subclasses may redefine this for better performance. + Same as doubleWordAt:put:MSB: for protocol completeness" - i := index. - msb ifTrue:[ - self at:i put:(aNumber digitAt:4). - self at:(i+1) put:(aNumber digitAt:3). - self at:(i+2) put:(aNumber digitAt:2). - self at:(i+3) put:(aNumber digitAt:1). - ] ifFalse:[ - self at:i put:(aNumber digitAt:1). - self at:(i+1) put:(aNumber digitAt:2). - self at:(i+2) put:(aNumber digitAt:3). - self at:(i+3) put:(aNumber digitAt:4). - ]. - ^ aNumber + ^ self doubleWordAt:index put:aNumber MSB:msb " |b| @@ -1622,7 +1635,7 @@ This is the ST80 equivalent of #wordAt:" - ^ self unsignedShortAt:index bigEndian:IsBigEndian + ^ self unsignedShortAt:index bigEndian:(UninterpretedBytes isBigEndian) "Created: / 5.3.1998 / 11:38:25 / stefan" "Modified: / 5.3.1998 / 14:59:25 / stefan" @@ -1654,7 +1667,7 @@ The stored value must be in the range 0 .. 16rFFFF. The value is stored in the machines natural byteorder." - ^ self unsignedShortAt:index put:value bigEndian:IsBigEndian + ^ self unsignedShortAt:index put:value bigEndian:(UninterpretedBytes isBigEndian) " |b| @@ -1713,7 +1726,7 @@ The value is retrieved in the machines natural byte order Subclasses may redefine this for better performance." - ^ self wordAt:index MSB:IsBigEndian + ^ self wordAt:index MSB:(UninterpretedBytes isBigEndian) "Modified: / 5.3.1998 / 14:59:51 / stefan" ! @@ -1745,7 +1758,7 @@ The value is stored in the machines natural byteorder. Question: should it accept signed values ? (see ByteArray>>signedWordAt:put:)" - ^ self wordAt:index put:value MSB:IsBigEndian + ^ self wordAt:index put:value MSB:(UninterpretedBytes isBigEndian) " |b| @@ -1803,7 +1816,7 @@ accessing the memory as an array of word entries. (i.e. indices are 1, 2, ...)" - ^ self wordAtWordIndex:index MSB:IsBigEndian + ^ self wordAtWordIndex:index MSB:(UninterpretedBytes isBigEndian) "Created: / 21.1.1998 / 17:48:26 / cg" "Modified: / 5.3.1998 / 15:00:16 / stefan" @@ -1828,7 +1841,7 @@ accessing the memory as an array of word entries. (i.e. indices are 1, 2, ...)" - ^ self wordAtWordIndex:index put:value MSB:IsBigEndian + ^ self wordAtWordIndex:index put:value MSB:(UninterpretedBytes isBigEndian) "Created: / 21.1.1998 / 17:48:34 / cg" "Modified: / 5.3.1998 / 15:00:27 / stefan" @@ -1958,6 +1971,5 @@ !UninterpretedBytes class methodsFor:'documentation'! version - ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.31 1998-11-24 17:04:36 cg Exp $' + ^ '$Header: /cvs/stx/stx/libbasic/UninterpretedBytes.st,v 1.32 1999-03-03 15:10:51 cg Exp $' ! ! -UninterpretedBytes initialize!