UninterpretedBytes.st
changeset 4019 c9284ca27a4a
parent 3936 dd8cd28d4a9b
child 4275 9fc4a735a1d3
--- 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!