changeset 6498 | 3db82d6e6146 |
parent 6320 | 0db3f79930a9 |
child 6512 | f015412236b3 |
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! |