diff --git a/stix/kernel/Context.st b/stix/kernel/Context.st index 9e87b16..0e42531 100644 --- a/stix/kernel/Context.st +++ b/stix/kernel/Context.st @@ -7,7 +7,7 @@ #class(#pointer) Context(Apex) { - #dcl sender ip sp ntmprs. + #dcl sender ip sp ntmprs ensure_block. #method sender { @@ -75,6 +75,8 @@ #method findExceptionHandlerBlock: anExceptionClass { + ## find an exception handler block for a given exception class. + ## ## for this to work, self must be an exception handler context. ## For a single on:do: call, ## self class specNumInstVars must return 8. @@ -85,7 +87,9 @@ | bound exc | ## NOTE: if on:do: has a temporary varible, bound must be adjusted to reflect it. bound := self basicSize - 1. - 8 to: bound by: 2 do: [ :i | +## TODO: change 9 to a constant when stix is enhanced to support constant definition +## or calcuate the minimum size using the class information. + 9 to: bound by: 2 do: [ :i | exc := self basicAt: i. ((anExceptionClass == exc) or: [anExceptionClass inheritsFrom: exc]) ifTrue: [^self basicAt: (i + 1)]. ] @@ -330,6 +334,7 @@ thisContext isExceptionHandlerContext dump. { ## TODO: ensure that the ensured block is executed after exception handler... | v | + self.ensure_block := aBlock. v := self on: Exception do: [:ex | aBlock value. ex pass diff --git a/stix/kernel/test-010.st b/stix/kernel/test-010.st index 86744dd..9d06d09 100644 --- a/stix/kernel/test-010.st +++ b/stix/kernel/test-010.st @@ -111,7 +111,25 @@ " } - + + #method(#class) aaa_123 + { + | v1 | + v1 := [ + | k | + k := 99. + [ + [ + ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ]. + [ ^20 ] ensure: [('ensure 1 ', (k asString)) dump ]. + ] ensure: ['ensure 2' dump ]. + ] ensure: ['ensure 3' dump ]. + ] on: Exception do: [:ex | + ('EXCETION - ' , ex messageText) dump. + ## Exception signal: 'qqq'. + ]. + ^v1 + } #method(#class) main { | v1 | @@ -131,17 +149,21 @@ "[1 xxx] ifCurtailed: ['XXXXXXXX CURTAILED XXXXXXXXX' dump. Exception signal: 'jjjj']." - v1 := [ +" v1 := [ | k | k := 99. [ - [ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ]. - ] ensure: ['ensure 2' dump ]. + [ + ##[ Exception signal: 'simulated error' ] ensure: [('ensure 1 ', (k asString)) dump ]. + [ ^20 ] ensure: [('ensure 1 ', (k asString)) dump ]. + ] ensure: ['ensure 2' dump ]. + ] ensure: ['ensure 3' dump ]. ] on: Exception do: [:ex | ('EXCETION - ' , ex messageText) dump. ## Exception signal: 'qqq'. ]. - +" + v1 := self aaa_123. '--------------------------------' dump. v1 dump. 'END OF MAIN' dump. diff --git a/stix/lib/exec.c b/stix/lib/exec.c index 723bccd..2dda872 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -1672,6 +1672,7 @@ printf ("PRIM BlockContext value FAIL - NARGS MISMATCH\n"); #else blkctx->ip = rcv_blkctx->ip; blkctx->ntmprs = rcv_blkctx->ntmprs; + blkctx->ensure_block = rcv_blkctx->ensure_block; blkctx->method_or_nargs = rcv_blkctx->method_or_nargs; blkctx->receiver_or_source = (stix_oop_t)rcv_blkctx; blkctx->home = rcv_blkctx->home; @@ -3838,7 +3839,23 @@ return -1; */ stix->ip--; #else - if (stix->active_context->origin == stix->processor->active->initial_context->origin) + if ((stix_oop_t)stix->active_context->ensure_block != stix->_nil) + { +STIX_LOG0 (stix, STIX_LOG_ERROR, "ABOUT TO EVALUATE ENSURE BLOCK ....\n"); + STIX_STACK_PUSH (stix, (stix_oop_t)stix->active_context->ensure_block); + +stix->active_context->ensure_block = (stix_oop_context_t)stix->_nil; +stix->ip--; + if (prim_block_value (stix, 0) <= 0) + { + /* TODO: problems in evaluating an ensure-block */ + /* TODO: ..... */ + STIX_STACK_POP (stix); +STIX_LOG0 (stix, STIX_LOG_ERROR, "ERROR ENSURE BLOCK FAILURE....\n"); + } + + } + else if (stix->active_context->origin == stix->processor->active->initial_context->origin) { /* method return from a processified block * @@ -3924,7 +3941,7 @@ return -1; /* NOTE: this condition is true for the processified block context also. * stix->active_context->origin == stix->processor->active->initial_context->origin * however, the check here is done after context switching and the - * processified block check is done against the context before switching */ + * processified block check has been done against the context before switching */ /* the stack contains the final return value so the stack pointer must be 0. */ STIX_ASSERT (stix->sp == 0); diff --git a/stix/lib/stix.h b/stix/lib/stix.h index 2816b4b..17e71bc 100644 --- a/stix/lib/stix.h +++ b/stix/lib/stix.h @@ -513,7 +513,7 @@ struct stix_method_t #define STIX_METHOD_PREAMBLE_INDEX_MAX 0xFFFF #define STIX_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(num) ((num) >= STIX_METHOD_PREAMBLE_INDEX_MIN && (num) <= STIX_METHOD_PREAMBLE_INDEX_MAX) -#define STIX_CONTEXT_NAMED_INSTVARS 8 +#define STIX_CONTEXT_NAMED_INSTVARS 9 typedef struct stix_context_t stix_context_t; typedef struct stix_context_t* stix_oop_context_t; struct stix_context_t @@ -540,6 +540,9 @@ struct stix_context_t * defined its 'home'. */ stix_oop_t ntmprs; + /* **** */ + stix_oop_context_t ensure_block; + /* CompiledMethod for a method context, * SmallInteger for a block context */ stix_oop_t method_or_nargs;