Block.st
changeset 6498 3db82d6e6146
parent 6320 0db3f79930a9
child 6512 f015412236b3
equal deleted inserted replaced
6497:786812ab9bb3 6498:3db82d6e6146
   321 byteCode:bCode numArgs:numArgs numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   321 byteCode:bCode numArgs:numArgs numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   322     "create a new cheap (homeless) block.
   322     "create a new cheap (homeless) block.
   323      Not for public use - this is a special hook for the compiler."
   323      Not for public use - this is a special hook for the compiler."
   324 
   324 
   325     ^ self
   325     ^ self
   326         byteCode:bCode numArgs:numArgs numVars:0 numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   326 	byteCode:bCode numArgs:numArgs numVars:0 numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   327 !
   327 !
   328 
   328 
   329 byteCode:bCode numArgs:numArgs numVars:numVars numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   329 byteCode:bCode numArgs:numArgs numVars:numVars numStack:nStack sourcePosition:sourcePos initialPC:initialPC literals:literals
   330     "create a new cheap (homeless) block.
   330     "create a new cheap (homeless) block.
   331      Not for public use - this is a special hook for the compiler."
   331      Not for public use - this is a special hook for the compiler."
   332 
   332 
   333     |newBlock|
   333     |newBlock|
   334 
   334 
   335     newBlock := (super basicNew:(literals size)) 
   335     newBlock := (super basicNew:(literals size)) 
   336                            byteCode:bCode
   336 			   byteCode:bCode
   337                            numArgs:numArgs
   337 			   numArgs:numArgs
   338                            numVars:numVars
   338 			   numVars:numVars
   339                            numStack:nStack
   339 			   numStack:nStack
   340                      sourcePosition:sourcePos
   340 		     sourcePosition:sourcePos
   341                           initialPC:initialPC
   341 			  initialPC:initialPC
   342                            literals:literals.
   342 			   literals:literals.
   343     ^ newBlock
   343     ^ newBlock
   344 
   344 
   345     "Modified: 24.6.1996 / 12:36:48 / stefan"
   345     "Modified: 24.6.1996 / 12:36:48 / stefan"
   346     "Created: 13.4.1997 / 00:04:09 / cg"
   346     "Created: 13.4.1997 / 00:04:09 / cg"
   347 !
   347 !
   401     "/ (actually, the previous implementation was:
   401     "/ (actually, the previous implementation was:
   402     "/ ^ self valueNowOrOnUnwindDo:aBlock
   402     "/ ^ self valueNowOrOnUnwindDo:aBlock
   403 
   403 
   404     "
   404     "
   405      [
   405      [
   406         [
   406 	[
   407             Transcript showCR:'one'.
   407 	    Transcript showCR:'one'.
   408             Processor activeProcess terminate.
   408 	    Processor activeProcess terminate.
   409             Transcript showCR:'two'.
   409 	    Transcript showCR:'two'.
   410         ] ensure:[
   410 	] ensure:[
   411             Transcript showCR:'three'.
   411 	    Transcript showCR:'three'.
   412         ].
   412 	].
   413      ] fork.
   413      ] fork.
   414     "
   414     "
   415 
   415 
   416     "
   416     "
   417      [
   417      [
   418         [
   418 	[
   419             Transcript showCR:'one'.
   419 	    Transcript showCR:'one'.
   420             Transcript showCR:'two'.
   420 	    Transcript showCR:'two'.
   421         ] ensure:[
   421 	] ensure:[
   422             Transcript showCR:'three'.
   422 	    Transcript showCR:'three'.
   423         ].
   423 	].
   424      ] fork.
   424      ] fork.
   425     "
   425     "
   426 !
   426 !
   427 
   427 
   428 ifCurtailed:aBlock
   428 ifCurtailed:aBlock
   444     "
   444     "
   445      |s|
   445      |s|
   446 
   446 
   447      s := 'Makefile' asFilename readStream.
   447      s := 'Makefile' asFilename readStream.
   448      [
   448      [
   449         ^ self
   449 	^ self
   450      ] ifCurtailed:[
   450      ] ifCurtailed:[
   451         Transcript showCR:'closing the stream - even though a return occurred'.
   451 	Transcript showCR:'closing the stream - even though a return occurred'.
   452         s close
   452 	s close
   453      ]
   453      ]
   454     "
   454     "
   455     "
   455     "
   456      [
   456      [
   457          |s|
   457 	 |s|
   458 
   458 
   459          s := 'Makefile' asFilename readStream.
   459 	 s := 'Makefile' asFilename readStream.
   460          [
   460 	 [
   461             Processor activeProcess terminate
   461 	    Processor activeProcess terminate
   462          ] ifCurtailed:[
   462 	 ] ifCurtailed:[
   463             Transcript showCR:'closing the stream - even though process was terminated'.
   463 	    Transcript showCR:'closing the stream - even though process was terminated'.
   464             s close
   464 	    s close
   465          ]
   465 	 ]
   466      ] fork
   466      ] fork
   467     "
   467     "
   468 ! !
   468 ! !
   469 
   469 
   470 !Block methodsFor:'Compatibility - Squeak'!
   470 !Block methodsFor:'Compatibility - Squeak'!
   474      Notice, that the handlerBlock may take 0,1 or 2 args.
   474      Notice, that the handlerBlock may take 0,1 or 2 args.
   475      (1 arg  -> the exception;
   475      (1 arg  -> the exception;
   476       2 args -> the errorString and the erronous receiver)"
   476       2 args -> the errorString and the erronous receiver)"
   477 
   477 
   478     handlerBlock numArgs == 1 ifTrue:[
   478     handlerBlock numArgs == 1 ifTrue:[
   479         ^ self on:Error do:handlerBlock
   479 	^ self on:Error do:handlerBlock
   480     ].
   480     ].
   481 
   481 
   482     ^ self 
   482     ^ self 
   483         on:Error 
   483 	on:Error 
   484         do:[:ex | 
   484 	do:[:ex | 
   485             |errString errReceiver|
   485 	    |errString errReceiver|
   486 
   486 
   487             handlerBlock numArgs == 0 ifTrue:[
   487 	    handlerBlock numArgs == 0 ifTrue:[
   488                 ex return:handlerBlock value
   488 		ex return:handlerBlock value
   489             ].
   489 	    ].
   490             errString := ex description.
   490 	    errString := ex description.
   491             errReceiver := ex suspendedContext receiver.
   491 	    errReceiver := ex suspendedContext receiver.
   492             ex return:(handlerBlock value:errString value:errReceiver)
   492 	    ex return:(handlerBlock value:errString value:errReceiver)
   493         ]
   493 	]
   494 
   494 
   495     "
   495     "
   496      |a|
   496      |a|
   497 
   497 
   498      a := 0.
   498      a := 0.
   522      (i.e. does a long return), evaluate the argument, aBlock.
   522      (i.e. does a long return), evaluate the argument, aBlock.
   523      This is used to make certain that cleanup actions 
   523      This is used to make certain that cleanup actions 
   524      (for example closing files etc.) are executed regardless of error actions.
   524      (for example closing files etc.) are executed regardless of error actions.
   525 
   525 
   526      Q: is this the exact semantics of V'Ages method ?
   526      Q: is this the exact semantics of V'Ages method ?
   527         the documentation is unclean; it could be a valueNowOrOnUnwindDo: ..."
   527 	the documentation is unclean; it could be a valueNowOrOnUnwindDo: ..."
   528 
   528 
   529     ^ self ifCurtailed:aBlock
   529     ^ self ifCurtailed:aBlock
   530 
   530 
   531     "Created: 15.11.1996 / 11:38:37 / cg"
   531     "Created: 15.11.1996 / 11:38:37 / cg"
   532 ! !
   532 ! !
   543 homeMethod
   543 homeMethod
   544     "return the receivers home method.
   544     "return the receivers home method.
   545      Thats the method where the block was created."
   545      Thats the method where the block was created."
   546 
   546 
   547     home notNil ifTrue:[
   547     home notNil ifTrue:[
   548         ^ home method
   548 	^ home method
   549     ].
   549     ].
   550     ^ nil
   550     ^ nil
   551 
   551 
   552     "Created: 19.6.1997 / 16:14:57 / cg"
   552     "Created: 19.6.1997 / 16:14:57 / cg"
   553 !
   553 !
   580 
   580 
   581 !Block methodsFor:'binary storage'!
   581 !Block methodsFor:'binary storage'!
   582 
   582 
   583 storeBinaryDefinitionOn:stream manager:manager
   583 storeBinaryDefinitionOn:stream manager:manager
   584     byteCode isNil ifTrue:[
   584     byteCode isNil ifTrue:[
   585         self error:'cannot preserve semantics of block'.
   585 	self error:'cannot preserve semantics of block'.
   586     ].
   586     ].
   587     ^ super storeBinaryDefinitionOn:stream manager:manager
   587     ^ super storeBinaryDefinitionOn:stream manager:manager
   588 ! !
   588 ! !
   589 
   589 
   590 !Block methodsFor:'conversion'!
   590 !Block methodsFor:'conversion'!
   593     "convert myself into a varArg block;
   593     "convert myself into a varArg block;
   594      this one has 1 formal argument, which gets the list
   594      this one has 1 formal argument, which gets the list
   595      of actual arguments when evaluated."
   595      of actual arguments when evaluated."
   596 
   596 
   597     nargs ~~ 1 ifTrue:[
   597     nargs ~~ 1 ifTrue:[
   598         self error:'vararg blocks must take exactly 1 argument - the arg list'.
   598 	self error:'vararg blocks must take exactly 1 argument - the arg list'.
   599         ^ nil
   599 	^ nil
   600     ].
   600     ].
   601 
   601 
   602     self changeClassTo:VarArgBlock.
   602     self changeClassTo:VarArgBlock.
   603     ^ self
   603     ^ self
   604 
   604 
   605     "
   605     "
   606      |b|
   606      |b|
   607 
   607 
   608      b := [:argList | Transcript 
   608      b := [:argList | Transcript 
   609                         show:'invoked with args:'; 
   609 			show:'invoked with args:'; 
   610                         showCR:argList
   610 			showCR:argList
   611           ] asVarArgBlock.
   611 	  ] asVarArgBlock.
   612      b value.
   612      b value.
   613      b value:'arg1'.
   613      b value:'arg1'.
   614      b value:'arg1' value:'arg2' value:'arg3' value:'arg4'
   614      b value:'arg1' value:'arg2' value:'arg3' value:'arg4'
   615     "
   615     "
   616 
   616 
  1040 
  1040 
  1041     |oldPrio retVal|
  1041     |oldPrio retVal|
  1042 
  1042 
  1043     oldPrio := Processor activePriority.
  1043     oldPrio := Processor activePriority.
  1044     [
  1044     [
  1045         Processor activeProcess priority:priority.
  1045 	Processor activeProcess priority:priority.
  1046         retVal := self value.
  1046 	retVal := self value.
  1047     ] ensure:[
  1047     ] ensure:[
  1048         Processor activeProcess priority:oldPrio
  1048 	Processor activeProcess priority:oldPrio
  1049     ].
  1049     ].
  1050     ^ retVal
  1050     ^ retVal
  1051 
  1051 
  1052     "
  1052     "
  1053      [
  1053      [
  1054          1000 timesRepeat:[
  1054 	 1000 timesRepeat:[
  1055              1000 factorial
  1055 	     1000 factorial
  1056          ]
  1056 	 ]
  1057      ] valueAt:3
  1057      ] valueAt:3
  1058     "
  1058     "
  1059 
  1059 
  1060     "Created: / 29.7.1998 / 19:19:48 / cg"
  1060     "Created: / 29.7.1998 / 19:19:48 / cg"
  1061 !
  1061 !
  1066      The size of the argArray must match the number of arguments the receiver expects."
  1066      The size of the argArray must match the number of arguments the receiver expects."
  1067 
  1067 
  1068     |a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12|
  1068     |a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12|
  1069 
  1069 
  1070     (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
  1070     (argArray notNil and:[(argArray class ~~ Array) and:[argArray isArray not]]) ifTrue:[
  1071         ^ self badArgumentArry
  1071 	^ self badArgumentArry
  1072     ].
  1072     ].
  1073     (argArray size == nargs) ifFalse:[
  1073     (argArray size == nargs) ifFalse:[
  1074         ^ self wrongNumberOfArguments:(argArray size)
  1074 	^ self wrongNumberOfArguments:(argArray size)
  1075     ].
  1075     ].
  1076 %{
  1076 %{
  1077 
  1077 
  1078     REGISTER OBJFUNC thecode;
  1078     REGISTER OBJFUNC thecode;
  1079     OBJ home;
  1079     OBJ home;
  1081     int __nargs;
  1081     int __nargs;
  1082     OBJ nA;
  1082     OBJ nA;
  1083 
  1083 
  1084 #if defined(THIS_CONTEXT)
  1084 #if defined(THIS_CONTEXT)
  1085     if (__ISVALID_ILC_LNO(__pilc))
  1085     if (__ISVALID_ILC_LNO(__pilc))
  1086             __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
  1086 	    __ContextInstPtr(__thisContext)->c_lineno = __ILC_LNO_AS_OBJ(__pilc);
  1087 #endif
  1087 #endif
  1088     thecode = __BlockInstPtr(self)->b_code;
  1088     thecode = __BlockInstPtr(self)->b_code;
       
  1089 
       
  1090     nA = __INST(nargs);
  1089 
  1091 
  1090 #ifndef NEW_BLOCK_CALL
  1092 #ifndef NEW_BLOCK_CALL
  1091     home = __BlockInstPtr(self)->b_home;
  1093     home = __BlockInstPtr(self)->b_home;
  1092     if (thecode != (OBJFUNC)nil) {
  1094     if (thecode != (OBJFUNC)nil) {
  1093         if ((nA = __INST(nargs)) == __MKSMALLINT(0)) {
  1095 	/* the most common case (0 args) here (without a switch) */
  1094             RETURN ( (*thecode)(home) );
  1096 
  1095         }
  1097 	if (nA == __MKSMALLINT(0)) {
  1096 
  1098 	    RETURN ( (*thecode)(home) );
  1097         switch (__intVal(__INST(nargs))) {
  1099 	}
  1098             default:
  1100 
  1099                 goto error;
  1101 	ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
  1100             case 12:
  1102 	switch ((INT)(nA)) {
  1101                 ap = __ArrayInstPtr(argArray)->a_element;
  1103 	    default:
  1102                 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]) );
  1104 		goto error;
  1103             case 11:
  1105 	    case __MKSMALLINT(12):
  1104                 ap = __ArrayInstPtr(argArray)->a_element;
  1106 		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]) );
  1105                 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]) );
  1107 	    case __MKSMALLINT(11):
  1106             case 10:
  1108 		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]) );
  1107                 ap = __ArrayInstPtr(argArray)->a_element;
  1109 	    case __MKSMALLINT(10):
  1108                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9]) );
  1110 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8], ap[9]) );
  1109             case 9:
  1111 	    case __MKSMALLINT(9):
  1110                 ap = __ArrayInstPtr(argArray)->a_element;
  1112 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) );
  1111                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7], ap[8]) );
  1113 	    case __MKSMALLINT(8):
  1112             case 8:
  1114 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) );
  1113                 ap = __ArrayInstPtr(argArray)->a_element;
  1115 	    case __MKSMALLINT(7):
  1114                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6], ap[7]) );
  1116 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) );
  1115             case 7:
  1117 	    case __MKSMALLINT(6):
  1116                 ap = __ArrayInstPtr(argArray)->a_element;
  1118 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) );
  1117                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5], ap[6]) );
  1119 	    case __MKSMALLINT(5):
  1118             case 6:
  1120 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4]) );
  1119                 ap = __ArrayInstPtr(argArray)->a_element;
  1121 	    case __MKSMALLINT(4):
  1120                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4], ap[5]) );
  1122 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3]) );
  1121             case 5:
  1123 	    case __MKSMALLINT(3):
  1122                 ap = __ArrayInstPtr(argArray)->a_element;
  1124 		RETURN ( (*thecode)(home, ap[0], ap[1], ap[2]) );
  1123                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3], ap[4]) );
  1125 	    case __MKSMALLINT(2):
  1124             case 4:
  1126 		RETURN ( (*thecode)(home, ap[0], ap[1]) );
  1125                 ap = __ArrayInstPtr(argArray)->a_element;
  1127 	    case __MKSMALLINT(1):
  1126                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2], ap[3]) );
  1128 		RETURN ( (*thecode)(home, ap[0]) );
  1127             case 3:
  1129 	    case __MKSMALLINT(0):
  1128                 ap = __ArrayInstPtr(argArray)->a_element;
  1130 		RETURN ( (*thecode)(home) );
  1129                 RETURN ( (*thecode)(home, ap[0], ap[1], ap[2]) );
  1131 		break;
  1130             case 2:
  1132 	}
  1131                 ap = __ArrayInstPtr(argArray)->a_element;
       
  1132                 RETURN ( (*thecode)(home, ap[0], ap[1]) );
       
  1133             case 1:
       
  1134                 RETURN ( (*thecode)(home, __ArrayInstPtr(argArray)->a_element[0]) );
       
  1135             case 0:
       
  1136                 RETURN ( (*thecode)(home) );
       
  1137                 break;
       
  1138         }
       
  1139     }
  1133     }
  1140 #endif
  1134 #endif
  1141 
  1135 
  1142     __nargs = __intVal(__INST(nargs));
  1136     if (nA != __MKSMALLINT(0)) {
  1143     if (__nargs) {
  1137 	ap = __arrayVal(argArray);   /* nonNil after above test (size is known to be ok) */
  1144         switch (__nargs) {
  1138 	switch ((INT)nA) {
  1145             default:
  1139 	    default:
  1146                 goto error;
  1140 		goto error;
  1147             case 12:
  1141 	    case __MKSMALLINT(12):
  1148                 a12 = __ArrayInstPtr(argArray)->a_element[11];
  1142 		a12 = ap[11];
  1149             case 11:
  1143 	    case __MKSMALLINT(11):
  1150                 a11 = __ArrayInstPtr(argArray)->a_element[10];
  1144 		a11 = ap[10];
  1151             case 10:
  1145 	    case __MKSMALLINT(10):
  1152                 a10 = __ArrayInstPtr(argArray)->a_element[9];
  1146 		a10 = ap[9];
  1153             case 9:
  1147 	    case __MKSMALLINT(9):
  1154                 a9 = __ArrayInstPtr(argArray)->a_element[8];
  1148 		a9 = ap[8];
  1155             case 8:
  1149 	    case __MKSMALLINT(8):
  1156                 a8 = __ArrayInstPtr(argArray)->a_element[7];
  1150 		a8 = ap[7];
  1157             case 7:
  1151 	    case __MKSMALLINT(7):
  1158                 a7 = __ArrayInstPtr(argArray)->a_element[6];
  1152 		a7 = ap[6];
  1159             case 6:
  1153 	    case __MKSMALLINT(6):
  1160                 a6 = __ArrayInstPtr(argArray)->a_element[5];
  1154 		a6 = ap[5];
  1161             case 5:
  1155 	    case __MKSMALLINT(5):
  1162                 a5 = __ArrayInstPtr(argArray)->a_element[4];
  1156 		a5 = ap[4];
  1163             case 4:
  1157 	    case __MKSMALLINT(4):
  1164                 a4 = __ArrayInstPtr(argArray)->a_element[3];
  1158 		a4 = ap[3];
  1165             case 3:
  1159 	    case __MKSMALLINT(3):
  1166                 a3 = __ArrayInstPtr(argArray)->a_element[2];
  1160 		a3 = ap[2];
  1167             case 2:
  1161 	    case __MKSMALLINT(2):
  1168                 a2 = __ArrayInstPtr(argArray)->a_element[1];
  1162 		a2 = ap[1];
  1169             case 1:
  1163 	    case __MKSMALLINT(1):
  1170                 a1 = __ArrayInstPtr(argArray)->a_element[0];
  1164 		a1 = ap[0];
  1171             case 0:
  1165 	    case __MKSMALLINT(0):
  1172                 break;
  1166 		break;
  1173         }
  1167 	}
  1174     }
  1168     }
  1175 
  1169 
  1176 #ifdef NEW_BLOCK_CALL
  1170 #ifdef NEW_BLOCK_CALL
  1177     if (thecode != (OBJFUNC)nil) {
  1171     if (thecode != (OBJFUNC)nil) {
  1178         RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
  1172 	RETURN ( (*thecode)(self, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
  1179     }
  1173     }
  1180 # ifdef PASS_ARG_POINTER
  1174 # ifdef PASS_ARG_POINTER
  1181     RETURN ( __interpret(self, __nargs, nil, nil, nil, nil, &a1) );
  1175     RETURN ( __interpret(self, __nargs, nil, nil, nil, nil, &a1) );
  1182 # else
  1176 # else
  1183     RETURN ( __interpret(self, __nargs, nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
  1177     RETURN ( __interpret(self, __nargs, nil, nil, nil, nil, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12) );
  1197 %}.
  1191 %}.
  1198     "
  1192     "
  1199      the above code only supports up-to 12 arguments
  1193      the above code only supports up-to 12 arguments
  1200     "
  1194     "
  1201     ^ ArgumentSignal
  1195     ^ ArgumentSignal
  1202         raiseRequestWith:self
  1196 	raiseRequestWith:self
  1203         errorString:'only blocks with up-to 12 arguments supported'
  1197 	errorString:'only blocks with up-to 12 arguments supported'
  1204 !
  1198 !
  1205 
  1199 
  1206 valueWithOptionalArgument:arg
  1200 valueWithOptionalArgument:arg
  1207     "evaluate the receiver.
  1201     "evaluate the receiver.
  1208      Optionally pass an argument (if the receiver is a one arg block)."
  1202      Optionally pass an argument (if the receiver is a one arg block)."
  1209 
  1203 
  1210     self numArgs == 1 ifTrue:[
  1204     self numArgs == 1 ifTrue:[
  1211         ^ self value:arg
  1205 	^ self value:arg
  1212     ].
  1206     ].
  1213     ^ self value
  1207     ^ self value
  1214 
  1208 
  1215     "
  1209     "
  1216      |block|
  1210      |block|
  1231      Answer nil if the signal is not handled."
  1225      Answer nil if the signal is not handled."
  1232 
  1226 
  1233     |sig handler|
  1227     |sig handler|
  1234 
  1228 
  1235     theContext selector == #on:do: ifTrue:[
  1229     theContext selector == #on:do: ifTrue:[
  1236         sig := theContext argAt:1.
  1230 	sig := theContext argAt:1.
  1237         sig isNil ifTrue:[
  1231 	sig isNil ifTrue:[
  1238             'Block [warning]: nil arg in on:do:-context (undefined Exception)' errorPrintCR.
  1232 	    'Block [warning]: nil arg in on:do:-context (undefined Exception)' errorPrintCR.
  1239             theContext fullPrint.
  1233 	    theContext fullPrint.
  1240             ^ nil.
  1234 	    ^ nil.
  1241         ].
  1235 	].
  1242         sig isSignal ifFalse:[
  1236 	sig isSignal ifFalse:[
  1243             'Block [warning]: non-Exception arg in on:do:-context' errorPrintCR.
  1237 	    'Block [warning]: non-Exception arg in on:do:-context' errorPrintCR.
  1244             theContext fullPrint.
  1238 	    theContext fullPrint.
  1245             ^ nil.
  1239 	    ^ nil.
  1246         ].
  1240 	].
  1247         (sig == signal or:[sig accepts:signal]) ifTrue:[
  1241 	(sig == signal or:[sig accepts:signal]) ifTrue:[
  1248             handler := theContext argAt:2.
  1242 	    handler := theContext argAt:2.
  1249             "/ this is for backward compatibility when no ex-arg
  1243 	    "/ this is for backward compatibility when no ex-arg
  1250             "/ is expected in the block. Is it worth the effort ?
  1244 	    "/ is expected in the block. Is it worth the effort ?
  1251             handler numArgs == 0 ifTrue:[
  1245 	    handler numArgs == 0 ifTrue:[
  1252                 ^ [:ex | handler value]
  1246 		^ [:ex | handler value]
  1253             ].
  1247 	    ].
  1254             ^ handler
  1248 	    ^ handler
  1255         ].
  1249 	].
  1256     ] ifFalse:[
  1250     ] ifFalse:[
  1257         "must be #valueWithExceptionHandler:"
  1251 	"must be #valueWithExceptionHandler:"
  1258         handler := theContext argAt:1.
  1252 	handler := theContext argAt:1.
  1259         ^ handler handlerForSignal:signal.
  1253 	^ handler handlerForSignal:signal.
  1260     ].
  1254     ].
  1261 
  1255 
  1262     ^ nil
  1256     ^ nil
  1263 
  1257 
  1264     "Created: / 25.7.1999 / 19:52:58 / stefan"
  1258     "Created: / 25.7.1999 / 19:52:58 / stefan"
  1301     "/ thisContext markForHandle. -- same as above pragma
  1295     "/ thisContext markForHandle. -- same as above pragma
  1302     ^ self value. "the real logic is in Exception>>doRaise"
  1296     ^ self value. "the real logic is in Exception>>doRaise"
  1303 
  1297 
  1304     "
  1298     "
  1305      [
  1299      [
  1306         1 foo
  1300 	1 foo
  1307      ] on:MessageNotUnderstoodSignal do:[:ex | self halt]
  1301      ] on:MessageNotUnderstoodSignal do:[:ex | self halt]
  1308 
  1302 
  1309      [
  1303      [
  1310         1 foo
  1304 	1 foo
  1311      ] on:SignalSet anySignal do:[:ex| 2 bar. self halt]
  1305      ] on:SignalSet anySignal do:[:ex| 2 bar. self halt]
  1312     "
  1306     "
  1313 
  1307 
  1314     "Modified: / 26.7.1999 / 15:30:48 / stefan"
  1308     "Modified: / 26.7.1999 / 15:30:48 / stefan"
  1315 !
  1309 !
  1449     restartAction := [ myContext restart ].
  1443     restartAction := [ myContext restart ].
  1450     ^ self value:restartAction.
  1444     ^ self value:restartAction.
  1451 
  1445 
  1452     "
  1446     "
  1453      [:restart |
  1447      [:restart |
  1454         (self confirm:'try again ?') ifTrue:[
  1448 	(self confirm:'try again ?') ifTrue:[
  1455             restart value.
  1449 	    restart value.
  1456         ]
  1450 	]
  1457      ] valueWithRestart
  1451      ] valueWithRestart
  1458     "
  1452     "
  1459 
  1453 
  1460     "Modified: / 25.1.2000 / 21:47:50 / cg"
  1454     "Modified: / 25.1.2000 / 21:47:50 / cg"
  1461 !
  1455 !
  1575 
  1569 
  1576 "/
  1570 "/
  1577 "/    aStream nextPutAll:'[] in '.
  1571 "/    aStream nextPutAll:'[] in '.
  1578 "/    homeClass := home containingClass.
  1572 "/    homeClass := home containingClass.
  1579 "/    homeClass notNil ifTrue:[
  1573 "/    homeClass notNil ifTrue:[
  1580 "/	homeClass name printOn:aStream.
  1574 "/      homeClass name printOn:aStream.
  1581 "/	aStream space.
  1575 "/      aStream space.
  1582 "/	(homeClass selectorForMethod:home) printOn:aStream
  1576 "/      (homeClass selectorForMethod:home) printOn:aStream
  1583 "/    ] ifFalse:[
  1577 "/    ] ifFalse:[
  1584 "/	aStream nextPutAll:' ???' 
  1578 "/      aStream nextPutAll:' ???' 
  1585 "/    ]
  1579 "/    ]
  1586 "/
  1580 "/
  1587 
  1581 
  1588 ! !
  1582 ! !
  1589 
  1583 
  1653      if any becomes runnable due to the evaluation of the receiver
  1647      if any becomes runnable due to the evaluation of the receiver
  1654      (i.e. if a semaphore is signalled)."
  1648      (i.e. if a semaphore is signalled)."
  1655 
  1649 
  1656     "we must keep track of blocking-state if this is called nested"
  1650     "we must keep track of blocking-state if this is called nested"
  1657     (OperatingSystem blockInterrupts) ifTrue:[
  1651     (OperatingSystem blockInterrupts) ifTrue:[
  1658         "/ already blocked.
  1652 	"/ already blocked.
  1659         ^ self value
  1653 	^ self value
  1660     ].
  1654     ].
  1661 
  1655 
  1662     ^ self ensure:[OperatingSystem unblockInterrupts].
  1656     ^ self ensure:[OperatingSystem unblockInterrupts].
  1663 !
  1657 !
  1664 
  1658 
  1669     |oldPrio activeProcess|
  1663     |oldPrio activeProcess|
  1670 
  1664 
  1671     activeProcess := Processor activeProcess.
  1665     activeProcess := Processor activeProcess.
  1672     oldPrio := activeProcess changePriority:(Processor highestPriority).
  1666     oldPrio := activeProcess changePriority:(Processor highestPriority).
  1673     ^ self ensure:[
  1667     ^ self ensure:[
  1674         activeProcess priority:oldPrio
  1668 	activeProcess priority:oldPrio
  1675     ]
  1669     ]
  1676 ! !
  1670 ! !
  1677 
  1671 
  1678 !Block methodsFor:'process creation'!
  1672 !Block methodsFor:'process creation'!
  1679 
  1673 
  1763      This avoids hardwiring access to the first argument in
  1757      This avoids hardwiring access to the first argument in
  1764      #unwind methods (and theoretically allows for other unwinding
  1758      #unwind methods (and theoretically allows for other unwinding
  1765      methods to be added)"
  1759      methods to be added)"
  1766 
  1760 
  1767     aContext selector == #'value:onUnwindDo:' ifTrue:[
  1761     aContext selector == #'value:onUnwindDo:' ifTrue:[
  1768         ^ aContext argAt:2
  1762 	^ aContext argAt:2
  1769     ].
  1763     ].
  1770 
  1764 
  1771     "/ for now, only #valueNowOrOnUnwindDo:
  1765     "/ for now, only #valueNowOrOnUnwindDo:
  1772     "/          or   #valueOnUnwindDo:
  1766     "/          or   #valueOnUnwindDo:
  1773     "/          or   #ensure:
  1767     "/          or   #ensure:
  1796     "
  1790     "
  1797      |s|
  1791      |s|
  1798 
  1792 
  1799      s := 'Makefile' asFilename readStream.
  1793      s := 'Makefile' asFilename readStream.
  1800      [:arg |
  1794      [:arg |
  1801         ^ self
  1795 	^ self
  1802      ] value:12345 onUnwindDo:[
  1796      ] value:12345 onUnwindDo:[
  1803         Transcript showCR:'closing the stream - even though a return occurred'.
  1797 	Transcript showCR:'closing the stream - even though a return occurred'.
  1804         s close
  1798 	s close
  1805      ]
  1799      ]
  1806     "
  1800     "
  1807     "
  1801     "
  1808      [
  1802      [
  1809          |s|
  1803 	 |s|
  1810 
  1804 
  1811          s := 'Makefile' asFilename readStream.
  1805 	 s := 'Makefile' asFilename readStream.
  1812          [:arg |
  1806 	 [:arg |
  1813             Processor activeProcess terminate
  1807 	    Processor activeProcess terminate
  1814          ] value:12345 onUnwindDo:[
  1808 	 ] value:12345 onUnwindDo:[
  1815             Transcript showCR:'closing the stream - even though process was terminated'.
  1809 	    Transcript showCR:'closing the stream - even though process was terminated'.
  1816             s close
  1810 	    s close
  1817          ]
  1811 	 ]
  1818      ] fork
  1812      ] fork
  1819     "
  1813     "
  1820 
  1814 
  1821 !
  1815 !
  1822 
  1816 
  1845     "
  1839     "
  1846      |f|
  1840      |f|
  1847 
  1841 
  1848      f := 'Makefile' asFilename readStream.
  1842      f := 'Makefile' asFilename readStream.
  1849      [
  1843      [
  1850         l := f nextLine.
  1844 	l := f nextLine.
  1851         l isNil ifTrue:[^ 'oops']
  1845 	l isNil ifTrue:[^ 'oops']
  1852      ] valueNowOrOnUnwindDo:[
  1846      ] valueNowOrOnUnwindDo:[
  1853         f close
  1847 	f close
  1854      ]
  1848      ]
  1855     "
  1849     "
  1856 
  1850 
  1857     "Modified: 16.4.1996 / 11:05:26 / stefan"
  1851     "Modified: 16.4.1996 / 11:05:26 / stefan"
  1858 !
  1852 !
  1876     "
  1870     "
  1877      |s|
  1871      |s|
  1878 
  1872 
  1879      s := 'Makefile' asFilename readStream.
  1873      s := 'Makefile' asFilename readStream.
  1880      [
  1874      [
  1881         ^ self
  1875 	^ self
  1882      ] valueOnUnwindDo:[
  1876      ] valueOnUnwindDo:[
  1883         Transcript showCR:'closing the stream - even though a return occurred'.
  1877 	Transcript showCR:'closing the stream - even though a return occurred'.
  1884         s close
  1878 	s close
  1885      ]
  1879      ]
  1886     "
  1880     "
  1887     "
  1881     "
  1888      [
  1882      [
  1889          |s|
  1883 	 |s|
  1890 
  1884 
  1891          s := 'Makefile' asFilename readStream.
  1885 	 s := 'Makefile' asFilename readStream.
  1892          [
  1886 	 [
  1893             Processor activeProcess terminate
  1887 	    Processor activeProcess terminate
  1894          ] valueOnUnwindDo:[
  1888 	 ] valueOnUnwindDo:[
  1895             Transcript showCR:'closing the stream - even though process was terminated'.
  1889 	    Transcript showCR:'closing the stream - even though process was terminated'.
  1896             s close
  1890 	    s close
  1897          ]
  1891 	 ]
  1898      ] fork
  1892      ] fork
  1899     "
  1893     "
  1900 ! !
  1894 ! !
  1901 
  1895 
  1902 !Block class methodsFor:'documentation'!
  1896 !Block class methodsFor:'documentation'!
  1903 
  1897 
  1904 version
  1898 version
  1905     ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.111 2001-12-14 10:00:45 cg Exp $'
  1899     ^ '$Header: /cvs/stx/stx/libbasic/Block.st,v 1.112 2002-04-11 09:45:18 cg Exp $'
  1906 ! !
  1900 ! !
  1907 Block initialize!
  1901 Block initialize!