#OTHER
authorStefan Vogel <sv@exept.de>
Sat, 12 Mar 2016 17:35:13 +0100
changeset 19348 9342f3d5cf15
parent 19347 c9a24d38a8ea
child 19349 d10a0648ff0f
#OTHER class: Behavior changed: #basicNew: fixed BAD BUG variableByte instances with named instvars were not initialized with 0 correctly. (Try BitArray new:10 with old code and see the garbage bits)
Behavior.st
--- a/Behavior.st	Fri Mar 11 17:28:03 2016 +0100
+++ b/Behavior.st	Sat Mar 12 17:35:13 2016 +0100
@@ -2529,13 +2529,14 @@
 %{  /* NOCONTEXT */
 #ifdef __SCHTEAM__
     if (anInteger.isSmallInteger()) {
-	return __c__._RETURN( self.basicNew( anInteger.intValue()) );
+        return __c__._RETURN( self.basicNew( anInteger.intValue()) );
     }
 #else
     OBJ newobj;
     unsigned INT nInstVars;
     unsigned INT instsize;
-    INT nindexedinstvars;
+    unsigned INT nindexedinstvars;
+    unsigned INT nBytes;
     unsigned INT flags;
 # if ! defined(FAST_ARRAY_MEMSET)
     REGISTER char *cp;
@@ -2547,303 +2548,295 @@
     double *dp;
 
     if (__isSmallInteger(anInteger)) {
-	nindexedinstvars = __intVal(anInteger);
-	if (nindexedinstvars >= 0) {
-	    nInstVars = __intVal(__INST(instSize));
-	    flags = __intVal(__INST(flags)) & ARRAYMASK;
-	    switch (flags) {
-		case BYTEARRAY:
-		    instsize = OHDR_SIZE + nindexedinstvars;
-		    instsize += __OBJS2BYTES__(nInstVars);
-		    if (__CanDoQuickNew(instsize)) {        /* OBJECT ALLOCATION */
-			/*
-			 * the most common case
-			 */
-			__qCheckedNew(newobj, instsize);
-			__InstPtr(newobj)->o_class = self;
-			__qSTORE(newobj, self);
-		nilIt:
-			cp = (char *)__InstPtr(newobj)->i_instvars;
+        nindexedinstvars = __intVal(anInteger);
+        if (nindexedinstvars >= 0) {
+            nInstVars = __intVal(__INST(instSize));
+            flags = __intVal(__INST(flags)) & ARRAYMASK;
+            switch (flags) {
+                case BYTEARRAY:
+                    nBytes = nindexedinstvars + __OBJS2BYTES__(nInstVars);
+                    instsize = OHDR_SIZE + nBytes;
+                    if (__CanDoQuickNew(instsize)) {        /* OBJECT ALLOCATION */
+                        /*
+                         * the most common case
+                         */
+                        __qCheckedNew(newobj, instsize);
+                        __InstPtr(newobj)->o_class = self;
+                        __qSTORE(newobj, self);
+                nilIt:
+                        cp = (char *)__InstPtr(newobj)->i_instvars;
 # if defined(memset4) && defined(FAST_ARRAY_MEMSET4) || defined(FAST_MEMSET4)
-			{
-			    INT nInts = nindexedinstvars >> 2;
-
-			    if (nindexedinstvars & 3) nInts++;
-			    memset4(cp, 0, nInts);
-			}
+                        memset4(cp, 0, (nBytes+3) >> 2);
+# elif defined(FAST_ARRAY_MEMSET)
+                        memset(cp, 0, nBytes);
 # else
-#  if defined(FAST_ARRAY_MEMSET)
-			memset(cp, 0, nindexedinstvars);
-#  else
-			while (nindexedinstvars >= (sizeof(INT) * 8L)) {
-			    ((INT *)cp)[0] = (INT)0;
-			    ((INT *)cp)[1] = (INT)0;
-			    ((INT *)cp)[2] = (INT)0;
-			    ((INT *)cp)[3] = (INT)0;
-			    ((INT *)cp)[4] = (INT)0;
-			    ((INT *)cp)[5] = (INT)0;
-			    ((INT *)cp)[6] = (INT)0;
-			    ((INT *)cp)[7] = (INT)0;
-			    cp += (sizeof(INT) * 8L);
-			    nindexedinstvars -= (sizeof(INT) * 8L);
-			}
-			while (nindexedinstvars >= sizeof(INT)) {
-			    *(INT *)cp = (INT)0;
-			    cp += sizeof(INT);
-			    nindexedinstvars -= sizeof(INT);
-			}
-			while (nindexedinstvars--)
-			    *cp++ = 0;
-#  endif
+                        while (nBytes >= (sizeof(INT) * 8L)) {
+                            ((INT *)cp)[0] = (INT)0;
+                            ((INT *)cp)[1] = (INT)0;
+                            ((INT *)cp)[2] = (INT)0;
+                            ((INT *)cp)[3] = (INT)0;
+                            ((INT *)cp)[4] = (INT)0;
+                            ((INT *)cp)[5] = (INT)0;
+                            ((INT *)cp)[6] = (INT)0;
+                            ((INT *)cp)[7] = (INT)0;
+                            cp += (sizeof(INT) * 8L);
+                            nBytes -= (sizeof(INT) * 8L);
+                        }
+                        while (nBytes >= sizeof(INT)) {
+                            *(INT *)cp = (INT)0;
+                            cp += sizeof(INT);
+                            nBytes -= sizeof(INT);
+                        }
+                        while (nBytes--)
+                            *cp++ = 0;
 # endif
-			RETURN ( newobj );
-		    }
-		    __PROTECT_CONTEXT__
-		    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
-		    goto nilIt;
-		    break;
-
-		case WORDARRAY:
-		case SWORDARRAY:
-		    instsize = OHDR_SIZE +
-			       __OBJS2BYTES__(nInstVars) +
-			       nindexedinstvars * 2;
-		    __PROTECT_CONTEXT__
-		    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
-		    goto nilIt;
-
-	       case LONGARRAY:
-	       case SLONGARRAY:
-		    instsize = OHDR_SIZE +
-			       __OBJS2BYTES__(nInstVars) +
-			       nindexedinstvars * 4;
-		    __PROTECT_CONTEXT__
-		    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
-		    goto nilIt;
-
-	       case LONGLONGARRAY:
-	       case SLONGLONGARRAY:
-		    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
-
+                        RETURN ( newobj );
+                    }
+                    __PROTECT_CONTEXT__
+                    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
+                    goto nilIt;
+                    break;
+
+                case WORDARRAY:
+                case SWORDARRAY:
+                    nBytes = __OBJS2BYTES__(nInstVars) + nindexedinstvars * 2;
+                    instsize = OHDR_SIZE + nBytes;
+                    __PROTECT_CONTEXT__
+                    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
+                    goto nilIt;
+
+               case LONGARRAY:
+               case SLONGARRAY:
+                    nBytes = __OBJS2BYTES__(nInstVars) + nindexedinstvars * 4;
+                    instsize = OHDR_SIZE + nBytes;
+                    __PROTECT_CONTEXT__
+                    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
+                    goto nilIt;
+
+               case LONGLONGARRAY:
+               case SLONGLONGARRAY:
+                    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 # ifdef __NEED_LONGLONG_ALIGN
-		    instsize = ((instsize-1) + __LONGLONG_ALIGN) & ~(__LONGLONG_ALIGN-1);
+                    instsize = ((instsize-1) + __LONGLONG_ALIGN) & ~(__LONGLONG_ALIGN-1);
 # endif
-		    instsize += nindexedinstvars * 8;
-
-		    __PROTECT_CONTEXT__
-		    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
-		    goto nilIt;
-		    break;
-
-	       case FLOATARRAY:
-		    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
-		    instsize += nindexedinstvars * sizeof(float);
-
-		    __PROTECT_CONTEXT__
-		    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
+                    instsize += nindexedinstvars * 8;
+                    nBytes = instsize - OHDR_SIZE;
+
+                    __PROTECT_CONTEXT__
+                    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
+                    goto nilIt;
+                    break;
+
+               case FLOATARRAY:
+                    nBytes = __OBJS2BYTES__(nInstVars) + nindexedinstvars * sizeof(float);
+                    instsize = OHDR_SIZE + nBytes;
+
+                    __PROTECT_CONTEXT__
+                    __qNew(newobj, instsize);   /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
 
 # if defined(__FLOAT0_IS_INT0) /* knowin that float 0.0 is all-zeros */
-		    goto nilIt;
+                    goto nilIt;
 # else
-		    op = __InstPtr(newobj)->i_instvars;
-		    while (nInstVars--)
-			*op++ = nil;
-		    fp = (float *)op;
-		    while (nindexedinstvars--)
-			*fp++ = 0.0;
+                    op = __InstPtr(newobj)->i_instvars;
+                    while (nInstVars--)
+                        *op++ = nil;
+                    fp = (float *)op;
+                    while (nindexedinstvars--)
+                        *fp++ = 0.0;
 # endif
-		    RETURN ( newobj );
-		    break;
-
-	       case DOUBLEARRAY:
-		    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
+                    RETURN ( newobj );
+                    break;
+
+               case DOUBLEARRAY:
+                    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
 # ifdef __NEED_DOUBLE_ALIGN
-		    instsize = ((instsize-1) + __DOUBLE_ALIGN) & ~(__DOUBLE_ALIGN-1);
+                    instsize = ((instsize-1) + __DOUBLE_ALIGN) & ~(__DOUBLE_ALIGN-1);
 # endif
-		    instsize += nindexedinstvars * sizeof(double);
-
-		    __PROTECT_CONTEXT__
-		    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
+                    instsize += nindexedinstvars * sizeof(double);
+                    nBytes = instsize - OHDR_SIZE;
+
+                    __PROTECT_CONTEXT__
+                    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
 
 # if defined(__DOUBLE0_IS_INT0) /* knowin that double 0.0 is all-zeros */
-		    goto nilIt;
+                    goto nilIt;
 # else
-		    op = __InstPtr(newobj)->i_instvars;
-		    while (nInstVars--)
-			*op++ = nil;
+                    op = __InstPtr(newobj)->i_instvars;
+                    while (nInstVars--)
+                        *op++ = nil;
 
 #  ifdef __NEED_DOUBLE_ALIGN
-		    /*
-		     * care for double alignment
-		     * add filler.
-		     */
-		    if ((INT)op & (__DOUBLE_ALIGN-1)) {
-			*op++ = nil;
-		    }
+                    /*
+                     * care for double alignment
+                     * add filler.
+                     */
+                    if ((INT)op & (__DOUBLE_ALIGN-1)) {
+                        *op++ = nil;
+                    }
 #  endif
-		    dp = (double *)op;
-		    while (nindexedinstvars--)
-			*dp++ = 0.0;
+                    dp = (double *)op;
+                    while (nindexedinstvars--)
+                        *dp++ = 0.0;
 # endif
-		    RETURN ( newobj );
-		    break;
-
-		case WKPOINTERARRAY:
-		case POINTERARRAY:
-		    nInstVars += nindexedinstvars;
-		    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
-		    __PROTECT_CONTEXT__
-		    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
-		    __UNPROTECT_CONTEXT__
-		    if (newobj == nil) {
-			break;
-		    }
-		    __InstPtr(newobj)->o_class = self;
-		    __qSTORE(newobj, self);
+                    RETURN ( newobj );
+                    break;
+
+                case WKPOINTERARRAY:
+                case POINTERARRAY:
+                    nInstVars += nindexedinstvars;
+                    instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
+                    __PROTECT_CONTEXT__
+                    __qAlignedNew(newobj, instsize);    /* OBJECT ALLOCATION */
+                    __UNPROTECT_CONTEXT__
+                    if (newobj == nil) {
+                        break;
+                    }
+                    __InstPtr(newobj)->o_class = self;
+                    __qSTORE(newobj, self);
 
 # if defined(memset4) && defined(FAST_ARRAY_MEMSET4) || defined(FAST_MEMSET4)
-		    memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
+                    memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
 # else
-		    /*
-		     * knowing that nil is 0
-		     */
+                    /*
+                     * knowing that nil is 0
+                     */
 #  ifdef sparc
 #   define FAST_ARRAY_MEMSET_DOUBLES_UNROLLED
 #  endif
 
 #  if defined(FAST_ARRAY_MEMSET_DOUBLES_UNROLLED)
-		    op = __InstPtr(newobj)->i_instvars;
-		    if (nInstVars > 8) {
-			*op++ = nil;    /* for alignment */
-			nInstVars--;
-			while (nInstVars >= 8) {
-			    *(double *)op = 0.0;
-			    ((double *)op)[1] = 0.0;
-			    ((double *)op)[2] = 0.0;
-			    ((double *)op)[3] = 0.0;
-			    op += 8;
-			    nInstVars -= 8;
-			}
-		    }
-		    while (nInstVars) {
-			*op++ = 0;
-			nInstVars--;
-		    }
+                    op = __InstPtr(newobj)->i_instvars;
+                    if (nInstVars > 8) {
+                        *op++ = nil;    /* for alignment */
+                        nInstVars--;
+                        while (nInstVars >= 8) {
+                            *(double *)op = 0.0;
+                            ((double *)op)[1] = 0.0;
+                            ((double *)op)[2] = 0.0;
+                            ((double *)op)[3] = 0.0;
+                            op += 8;
+                            nInstVars -= 8;
+                        }
+                    }
+                    while (nInstVars) {
+                        *op++ = 0;
+                        nInstVars--;
+                    }
 #  else
 #   if defined(FAST_ARRAY_MEMSET_LONGLONG_UNROLLED)
-		    op = __InstPtr(newobj)->i_instvars;
-		    if (nInstVars > 8) {
-			*op++ = nil;    /* for alignment */
-			nInstVars--;
-			while (nInstVars >= 8) {
-			    *(long long *)op = 0;
-			    ((long long *)op)[1] = 0;
-			    ((long long *)op)[2] = 0;
-			    ((long long *)op)[3] = 0;
-			    op += 8;
-			    nInstVars -= 8;
-			}
-		    }
-		    while (nInstVars) {
-			*op++ = 0;
-			nInstVars--;
-		    }
+                    op = __InstPtr(newobj)->i_instvars;
+                    if (nInstVars > 8) {
+                        *op++ = nil;    /* for alignment */
+                        nInstVars--;
+                        while (nInstVars >= 8) {
+                            *(long long *)op = 0;
+                            ((long long *)op)[1] = 0;
+                            ((long long *)op)[2] = 0;
+                            ((long long *)op)[3] = 0;
+                            op += 8;
+                            nInstVars -= 8;
+                        }
+                    }
+                    while (nInstVars) {
+                        *op++ = 0;
+                        nInstVars--;
+                    }
 #   else
 #    if defined(FAST_ARRAY_MEMSET)
-		    memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
+                    memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
 #    else
-		    op = __InstPtr(newobj)->i_instvars;
-		    while (nInstVars >= 8) {
-			nInstVars -= 8;
-			op[0] = nil; op[1] = nil;
-			op[2] = nil; op[3] = nil;
-			op[4] = nil; op[5] = nil;
-			op[6] = nil; op[7] = nil;
-			op += 8;
-		    }
-		    while (nInstVars--)
-			*op++ = nil;
+                    op = __InstPtr(newobj)->i_instvars;
+                    while (nInstVars >= 8) {
+                        nInstVars -= 8;
+                        op[0] = nil; op[1] = nil;
+                        op[2] = nil; op[3] = nil;
+                        op[4] = nil; op[5] = nil;
+                        op[6] = nil; op[7] = nil;
+                        op += 8;
+                    }
+                    while (nInstVars--)
+                        *op++ = nil;
 #    endif
 #   endif
 #  endif
 # endif
-		    RETURN ( newobj );
-		    break;
-
-		default:
-		    /*
-		     * new:n for non-variable classes only allowed if
-		     * n == 0
-		     */
-		    if (nindexedinstvars == 0) {
-			instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
-			__PROTECT_CONTEXT__
-			__qAlignedNew(newobj, instsize);        /* OBJECT ALLOCATION */
-			__UNPROTECT_CONTEXT__
-			if (newobj == nil) {
-			    break;
-			}
-			__InstPtr(newobj)->o_class = self;
-			__qSTORE(newobj, self);
-
-			if (nInstVars) {
+                    RETURN ( newobj );
+                    break;
+
+                default:
+                    /*
+                     * new:n for non-variable classes only allowed if
+                     * n == 0
+                     */
+                    if (nindexedinstvars == 0) {
+                        instsize = OHDR_SIZE + __OBJS2BYTES__(nInstVars);
+                        __PROTECT_CONTEXT__
+                        __qAlignedNew(newobj, instsize);        /* OBJECT ALLOCATION */
+                        __UNPROTECT_CONTEXT__
+                        if (newobj == nil) {
+                            break;
+                        }
+                        __InstPtr(newobj)->o_class = self;
+                        __qSTORE(newobj, self);
+
+                        if (nInstVars) {
 # if defined(memset4) && defined(FAST_OBJECT_MEMSET4) || defined(FAST_MEMSET4)
-			    memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
+                            memset4(__InstPtr(newobj)->i_instvars, nil, nInstVars);
 # else
 #  if defined(FAST_MEMSET)
-			    /*
-			     * knowing that nil is 0
-			     */
-			    memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
+                            /*
+                             * knowing that nil is 0
+                             */
+                            memset(__InstPtr(newobj)->i_instvars, 0, instsize - OHDR_SIZE);
 #  else
-			    op = __InstPtr(newobj)->i_instvars;
-			    do {
-				*op++ = nil;
-			    } while (--nInstVars);
+                            op = __InstPtr(newobj)->i_instvars;
+                            do {
+                                *op++ = nil;
+                            } while (--nInstVars);
 #  endif
 # endif
-			}
-			RETURN ( newobj );
-		    }
-		    break;
-	    }
-	}
+                        }
+                        RETURN ( newobj );
+                    }
+                    break;
+            }
+        }
     }
 #endif /* not SCHTEAM */
 %}.
@@ -2853,26 +2846,26 @@
     "
 
     (anInteger isMemberOf:SmallInteger) ifFalse:[
-	"
-	 the argument is either not an integer,
-	 or a LargeInteger (which means that its definitely too big)
-	"
-	self error:'argument to new: must be Integer' mayProceed:true.
-	^ nil
+        "
+         the argument is either not an integer,
+         or a LargeInteger (which means that its definitely too big)
+        "
+        self error:'argument to new: must be Integer' mayProceed:true.
+        ^ nil
     ].
     (anInteger < 0) ifTrue:[
-	"
-	 the argument is negative,
-	"
-	self error:'bad (negative) argument to new:'.
-	^ nil
+        "
+         the argument is negative,
+        "
+        self error:'bad (negative) argument to new:'.
+        ^ nil
     ].
     self isVariable ifFalse:[
-	"
-	 this class does not have any indexed instance variables
-	"
-	self error:'class has no indexed instvars - cannot create with new:'.
-	^ nil
+        "
+         this class does not have any indexed instance variables
+        "
+        self error:'class has no indexed instvars - cannot create with new:'.
+        ^ nil
     ].
     "
      memory allocation failed.
@@ -5272,3 +5265,4 @@
 version_CVS
     ^ '$Header$'
 ! !
+