#BUGFIX
authorStefan Vogel <sv@exept.de>
Mon, 21 Dec 2015 15:02:12 +0100
changeset 18992 5df345494151
parent 18989 2e7fc0e4df9b
child 18993 f0a1ba2be4b0
#BUGFIX class: Block changed: #valueWithOptionalArguments: #valueWithPossibleArguments: Fix bad (copy/pasted) code when argument is a Non-Array
Block.st
--- a/Block.st	Fri Dec 18 13:48:26 2015 +0100
+++ b/Block.st	Mon Dec 21 15:02:12 2015 +0100
@@ -1801,22 +1801,25 @@
     "
 !
 
-valueWithOptionalArguments:argArray
+valueWithOptionalArguments:argArrayIn
     "evaluate the receiver with arguments as required taken from argArray.
      Only the required number of arguments is taken from argArray or nil;
      (i.e. argArray may be larger than the required number).
      If the size of the argArray is smaller than the number of arguments, an error is raised."
 
-    |numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
-
+    |argArray numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
+
+    argArray := argArrayIn.
     (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
-	argArray isCollection ifTrue:[
-	    ^ self valueWithArguments:argArray asArray
-	].
-	^ self badArgumentArray:argArray
+        argArray isCollection ifTrue:[
+            argArray := argArray asArray
+        ] ifFalse:[
+            ^ self badArgumentArray:argArray
+        ].
     ].
-    (argArray size >= nargs) ifFalse:[
-	^ self wrongNumberOfArguments:argArray size
+
+    (argArray size < nargs) ifTrue:[
+        ^ self wrongNumberOfArguments:argArray size
     ].
 %{
     REGISTER OBJFUNC thecode;
@@ -1827,109 +1830,109 @@
 
 #if defined(THIS_CONTEXT)
     if (__ISVALID_ILC_LNO(__pilc))
-	    __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
+            __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
 #endif
     thecode = __BlockInstPtr(self)->b_code;
 
     nA = __INST(nargs);
 
     if (argArray == nil) {
-	ap = 0;
+        ap = 0;
     } else {
-	ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
+        ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
     }
 
 #ifndef NEW_BLOCK_CALL
     home = __BlockInstPtr(self)->b_home;
     if (thecode != (OBJFUNC)nil) {
-	/* the most common case (0 args) here (without a switch) */
-
-	if (nA == __mkSmallInteger(0)) {
-	    RETURN ( (*thecode)(home) );
-	}
-
-	switch ((INT)(nA)) {
-	    default:
-		goto error;
-	    case (INT)__mkSmallInteger(15):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13], ap[14]) );
-	    case (INT)__mkSmallInteger(14):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13]) );
-	    case (INT)__mkSmallInteger(13):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12]) );
-	    case (INT)__mkSmallInteger(12):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11]) );
-	    case (INT)__mkSmallInteger(11):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10]) );
-	    case (INT)__mkSmallInteger(10):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9]) );
-	    case (INT)__mkSmallInteger(9):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) );
-	    case (INT)__mkSmallInteger(8):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) );
-	    case (INT)__mkSmallInteger(7):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) );
-	    case (INT)__mkSmallInteger(6):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) );
-	    case (INT)__mkSmallInteger(5):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4]) );
-	    case (INT)__mkSmallInteger(4):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3]) );
-	    case (INT)__mkSmallInteger(3):
-		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2]) );
-	    case (INT)__mkSmallInteger(2):
-		RETURN ( (*thecode)(home, ap[0], ap[1]) );
-	    case (INT)__mkSmallInteger(1):
-		RETURN ( (*thecode)(home, ap[0]) );
-	    case (INT)__mkSmallInteger(0):
-		RETURN ( (*thecode)(home) );
-		break;
-	}
+        /* the most common case (0 args) here (without a switch) */
+
+        if (nA == __mkSmallInteger(0)) {
+            RETURN ( (*thecode)(home) );
+        }
+
+        switch ((INT)(nA)) {
+            default:
+                goto error;
+            case (INT)__mkSmallInteger(15):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13], ap[14]) );
+            case (INT)__mkSmallInteger(14):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12], ap[13]) );
+            case (INT)__mkSmallInteger(13):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11], ap[12]) );
+            case (INT)__mkSmallInteger(12):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10], ap[11]) );
+            case (INT)__mkSmallInteger(11):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9], ap[10]) );
+            case (INT)__mkSmallInteger(10):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9]) );
+            case (INT)__mkSmallInteger(9):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) );
+            case (INT)__mkSmallInteger(8):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) );
+            case (INT)__mkSmallInteger(7):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) );
+            case (INT)__mkSmallInteger(6):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) );
+            case (INT)__mkSmallInteger(5):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4]) );
+            case (INT)__mkSmallInteger(4):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3]) );
+            case (INT)__mkSmallInteger(3):
+                RETURN ( (*thecode)(home, ap[0], ap[1], ap[2]) );
+            case (INT)__mkSmallInteger(2):
+                RETURN ( (*thecode)(home, ap[0], ap[1]) );
+            case (INT)__mkSmallInteger(1):
+                RETURN ( (*thecode)(home, ap[0]) );
+            case (INT)__mkSmallInteger(0):
+                RETURN ( (*thecode)(home) );
+                break;
+        }
     }
 #endif
 
     if (nA != __mkSmallInteger(0)) {
-	ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
-	switch ((INT)nA) {
-	    default:
-		goto error;
-	    case (INT)__mkSmallInteger(15):
-		a15 = ap[14];
-	    case (INT)__mkSmallInteger(14):
-		a14 = ap[13];
-	    case (INT)__mkSmallInteger(13):
-		a13 = ap[12];
-	    case (INT)__mkSmallInteger(12):
-		a12 = ap[11];
-	    case (INT)__mkSmallInteger(11):
-		a11 = ap[10];
-	    case (INT)__mkSmallInteger(10):
-		a10 = ap[9];
-	    case (INT)__mkSmallInteger(9):
-		a9 = ap[8];
-	    case (INT)__mkSmallInteger(8):
-		a8 = ap[7];
-	    case (INT)__mkSmallInteger(7):
-		a7 = ap[6];
-	    case (INT)__mkSmallInteger(6):
-		a6 = ap[5];
-	    case (INT)__mkSmallInteger(5):
-		a5 = ap[4];
-	    case (INT)__mkSmallInteger(4):
-		a4 = ap[3];
-	    case (INT)__mkSmallInteger(3):
-		a3 = ap[2];
-	    case (INT)__mkSmallInteger(2):
-		a2 = ap[1];
-	    case (INT)__mkSmallInteger(1):
-		a1 = ap[0];
-	    case (INT)__mkSmallInteger(0):
-		break;
-	}
+        ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
+        switch ((INT)nA) {
+            default:
+                goto error;
+            case (INT)__mkSmallInteger(15):
+                a15 = ap[14];
+            case (INT)__mkSmallInteger(14):
+                a14 = ap[13];
+            case (INT)__mkSmallInteger(13):
+                a13 = ap[12];
+            case (INT)__mkSmallInteger(12):
+                a12 = ap[11];
+            case (INT)__mkSmallInteger(11):
+                a11 = ap[10];
+            case (INT)__mkSmallInteger(10):
+                a10 = ap[9];
+            case (INT)__mkSmallInteger(9):
+                a9 = ap[8];
+            case (INT)__mkSmallInteger(8):
+                a8 = ap[7];
+            case (INT)__mkSmallInteger(7):
+                a7 = ap[6];
+            case (INT)__mkSmallInteger(6):
+                a6 = ap[5];
+            case (INT)__mkSmallInteger(5):
+                a5 = ap[4];
+            case (INT)__mkSmallInteger(4):
+                a4 = ap[3];
+            case (INT)__mkSmallInteger(3):
+                a3 = ap[2];
+            case (INT)__mkSmallInteger(2):
+                a2 = ap[1];
+            case (INT)__mkSmallInteger(1):
+                a1 = ap[0];
+            case (INT)__mkSmallInteger(0):
+                break;
+        }
     }
 #ifdef NEW_BLOCK_CALL
     if (thecode != (OBJFUNC)nil) {
-	RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+        RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
     }
 # ifdef PASS_ARG_POINTER
     RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, &a1) );
@@ -1953,11 +1956,17 @@
      the above code only supports up-to 15 arguments
     "
     ^ ArgumentError
-	raiseRequestWith:self
-	errorString:'only blocks with up-to 15 arguments supported'
+        raiseRequestWith:self
+        errorString:'only blocks with up-to 15 arguments supported'
+
+
+    "
+        [:a :b :c | Transcript showCR:a; showCR:b; showCR:c] valueWithOptionalArguments:#(1 2 3 4).
+        [:a :b :c | Transcript showCR:a; showCR:b; showCR:c] valueWithOptionalArguments:#(1 2 3 4) asOrderedCollection.
+    "
 !
 
-valueWithPossibleArguments:argArray
+valueWithPossibleArguments:argArrayIn
     "evaluate the receiver with arguments as required taken from argArray.
      If argArray provides less than the required number of arguments,
      nil is assumed for any remaining argument.
@@ -1965,13 +1974,15 @@
      Only the required number of arguments is taken from argArray or nil;
      (i.e. argArray may be larger than the required number)."
 
-    |numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
-
+    |argArray numArgsProvided a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15|
+
+    argArray := argArrayIn.
     (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
-	argArray isCollection ifTrue:[
-	    ^ self valueWithArguments:argArray asArray
-	].
-	^ self badArgumentArray:argArray
+        argArray isCollection ifTrue:[
+            argArray := argArray asArray
+        ] ifFalse:[
+            ^ self badArgumentArray:argArray
+        ].
     ].
     numArgsProvided := argArray size.
 %{
@@ -1983,89 +1994,89 @@
 
 #if defined(THIS_CONTEXT)
     if (__ISVALID_ILC_LNO(__pilc))
-	    __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
+            __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
 #endif
     thecode = __BlockInstPtr(self)->b_code;
 
     nA = __INST(nargs);
 
     if (argArray == nil) {
-	ap = 0;
+        ap = 0;
     } else {
-	ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
+        ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
     }
     switch (__numArgsProvided) {
-	default:
-	case 15: a15 = ap[14];
-	case 14: a14 = ap[13];
-	case 13: a13 = ap[12];
-	case 12: a12 = ap[11];
-	case 11: a11 = ap[10];
-	case 10: a10 = ap[9];
-	case 9: a9 = ap[8];
-	case 8: a8 = ap[7];
-	case 7: a7 = ap[6];
-	case 6: a6 = ap[5];
-	case 5: a5 = ap[4];
-	case 4: a4 = ap[3];
-	case 3: a3 = ap[2];
-	case 2: a2 = ap[1];
-	case 1: a1 = ap[0];
-	case 0: ;
+        default:
+        case 15: a15 = ap[14];
+        case 14: a14 = ap[13];
+        case 13: a13 = ap[12];
+        case 12: a12 = ap[11];
+        case 11: a11 = ap[10];
+        case 10: a10 = ap[9];
+        case 9: a9 = ap[8];
+        case 8: a8 = ap[7];
+        case 7: a7 = ap[6];
+        case 6: a6 = ap[5];
+        case 5: a5 = ap[4];
+        case 4: a4 = ap[3];
+        case 3: a3 = ap[2];
+        case 2: a2 = ap[1];
+        case 1: a1 = ap[0];
+        case 0: ;
     }
 
 #ifndef NEW_BLOCK_CALL
     home = __BlockInstPtr(self)->b_home;
     if (thecode != (OBJFUNC)nil) {
-	/* the most common case (0 args) here (without a switch) */
-
-	if (nA == __mkSmallInteger(0)) {
-	    RETURN ( (*thecode)(home) );
-	}
-
-	switch ((INT)(nA)) {
-	    default:
-		goto error;
-	    case (INT)__mkSmallInteger(15):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
-	    case (INT)__mkSmallInteger(14):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) );
-	    case (INT)__mkSmallInteger(13):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) );
-	    case (INT)__mkSmallInteger(12):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
-	    case (INT)__mkSmallInteger(11):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) );
-	    case (INT)__mkSmallInteger(10):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) );
-	    case (INT)__mkSmallInteger(9):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9) );
-	    case (INT)__mkSmallInteger(8):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8) );
-	    case (INT)__mkSmallInteger(7):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7) );
-	    case (INT)__mkSmallInteger(6):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6) );
-	    case (INT)__mkSmallInteger(5):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4, a5) );
-	    case (INT)__mkSmallInteger(4):
-		RETURN ( (*thecode)(home, a1, a2, a3, a4) );
-	    case (INT)__mkSmallInteger(3):
-		RETURN ( (*thecode)(home, a1, a2, a3) );
-	    case (INT)__mkSmallInteger(2):
-		RETURN ( (*thecode)(home, a1, a2) );
-	    case (INT)__mkSmallInteger(1):
-		RETURN ( (*thecode)(home, a1) );
-	    case (INT)__mkSmallInteger(0):
-		RETURN ( (*thecode)(home) );
-		break;
-	}
+        /* the most common case (0 args) here (without a switch) */
+
+        if (nA == __mkSmallInteger(0)) {
+            RETURN ( (*thecode)(home) );
+        }
+
+        switch ((INT)(nA)) {
+            default:
+                goto error;
+            case (INT)__mkSmallInteger(15):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+            case (INT)__mkSmallInteger(14):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14) );
+            case (INT)__mkSmallInteger(13):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13) );
+            case (INT)__mkSmallInteger(12):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
+            case (INT)__mkSmallInteger(11):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) );
+            case (INT)__mkSmallInteger(10):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) );
+            case (INT)__mkSmallInteger(9):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8, a9) );
+            case (INT)__mkSmallInteger(8):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7, a8) );
+            case (INT)__mkSmallInteger(7):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6, a7) );
+            case (INT)__mkSmallInteger(6):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5, a6) );
+            case (INT)__mkSmallInteger(5):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4, a5) );
+            case (INT)__mkSmallInteger(4):
+                RETURN ( (*thecode)(home, a1, a2, a3, a4) );
+            case (INT)__mkSmallInteger(3):
+                RETURN ( (*thecode)(home, a1, a2, a3) );
+            case (INT)__mkSmallInteger(2):
+                RETURN ( (*thecode)(home, a1, a2) );
+            case (INT)__mkSmallInteger(1):
+                RETURN ( (*thecode)(home, a1) );
+            case (INT)__mkSmallInteger(0):
+                RETURN ( (*thecode)(home) );
+                break;
+        }
     }
 #endif
 
 #ifdef NEW_BLOCK_CALL
     if (thecode != (OBJFUNC)nil) {
-	RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
+        RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15) );
     }
 # ifdef PASS_ARG_POINTER
     RETURN ( __interpret(self, __intVal(nA), nil, nil, nil, nil, &a1) );
@@ -2089,8 +2100,13 @@
      the above code only supports up-to 15 arguments
     "
     ^ ArgumentError
-	raiseRequestWith:self
-	errorString:'only blocks with up-to 15 arguments supported'
+        raiseRequestWith:self
+        errorString:'only blocks with up-to 15 arguments supported'
+
+    "
+        [:a :b :c :d| Transcript showCR:a; showCR:b; showCR:c; showCR:d] valueWithPossibleArguments:#(1 2 3).
+        [:a :b :c :d| Transcript showCR:a; showCR:b; showCR:c; showCR:d] valueWithPossibleArguments:#(1 2 3) asOrderedCollection.
+    "
 ! !
 
 !Block methodsFor:'exception handling'!