diff --git a/stix/kernel/Context.st b/stix/kernel/Context.st index b227165..4606dfa 100644 --- a/stix/kernel/Context.st +++ b/stix/kernel/Context.st @@ -558,12 +558,12 @@ { #method(#class) signal { - self new signal + ^self new signal } #method(#class) signal: text { - self new signal: text + ^self new signal: text } #method handlerContext: context @@ -587,7 +587,6 @@ | excctx excblk retval actpos | self.signalContext := thisContext. - excctx := (thisContext sender) findExceptionContext. [excctx notNil] whileTrue: [ excblk := excctx findExceptionHandlerFor: (self class). @@ -608,7 +607,8 @@ ## ----------------------------------------------------------------- ## FATAL ERROR - no exception handler. ## ----------------------------------------------------------------- - thisContext unwindTo: nil return: nil. + ##thisContext unwindTo: nil return: nil. + thisContext unwindTo: (Processor activeProcess initialContext) return: nil. ('### EXCEPTION NOT HANDLED #### ', self class name, ' - ', self messageText) dump. ## TODO: debug the current process???? " Processor activeProcess terminate. @@ -617,7 +617,7 @@ #method signal: text { self.messageText := text. - self signal. + ^self signal. } #method pass @@ -626,38 +626,39 @@ ((self.handlerContext sender) findExceptionContext) handleException: self. } -" -TODO: implement these methods.... #method return: value { - self.handlerContext notNil ifTrue: [ - Processor return: value to: (self.handlerContext sender) - ] + (self.handlerContext notNil) ifTrue: [ + Processor return: value to: self.handlerContext. + ]. } #method retry { - ## TODO: verify if return:to: causes unnecessary stack growth. - self.handlerContext notNil - ifTrue: [ - ## TODO: should i reset self.handlerContext and self.signalContext to nil? - self.handlerContext pc: 0. - Processor return: self to: self.handlerContext. - ##Processor forceContext: self.handlerContext. - ] +## TODO: verify if return:to: causes unnecessary stack growth. + (self.handlerContext notNil) ifTrue: [ + self.handlerContext pc: 0. + Processor return: self to: self.handlerContext. + ]. + } + + #method resume: value + { +## TODO: verify if return:to: causes unnecessary stack growth. +## is this correct??? + (self.signalContext notNil and: [self.handlerContext notNil]) ifTrue: [ + | ctx | + ctx := self.signalContext sender. + self.signalContext := nil. + self.handlerContext := nil. + Processor return: value to: ctx. + ]. } #method resume { - ## TODO: verify if return:to: causes unnecessary stack growth. - ## is this correct??? - self.signalContext notNil - ifTrue: [ - ## TODO: should i reset self.handlerContext and self.signalContext to nil? - Processor return: self to: (self.signalContext sender). - ] + ^self resume: nil. } -" } #class NoSuchMessageException(Exception) diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index e704f69..19df57f 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -19,14 +19,14 @@ ^self.next. } - #method next: aProcess + #method next: process { - self.next := aProcess. + self.next := process. } - #method prev: aProcess + #method prev: process { - self.prev := aProcess. + self.prev := process. } #method resume @@ -51,7 +51,12 @@ #method sp { - ^sp. + ^self.sp. + } + + #method initialContext + { + ^self.initial_context } #method sleep: seconds @@ -341,7 +346,7 @@ ^self.active. } - #method resume: aProcess + #method resume: process { self primitiveFailed. @@ -349,14 +354,14 @@ "The primitive does something like the following in principle: (self.tally = 0) ifTrue: [ - self.head := aProcess. - self.tail := aProcess. + self.head := process. + self.tail := process. self.tally := 1. ] ifFalse: [ - aProcess next: self.head. - self.head prev: aProcess. - self.head := aProcess. + process next: self.head. + self.head prev: process. + self.head := process. self.tally := self.tally + 1. ]. " @@ -370,47 +375,34 @@ } " - #method signal: aSemaphore after: anInteger + #method signal: semaphore after: secs { self primitiveFailed. } - #method signal: aSemaphore after: aSecond and: aNanoSecond + #method signal: semaphore after: secs and: nanosecs { self primitiveFailed. } - #method unsignal: aSemaphore + #method unsignal: semaphore { self primitiveFailed. } - "#method signal: aSemaphore onInput: file + "#method signal: semaphore onInput: file { }" - "#method signal: aSemaphore onOutput: file + "#method signal: semaphore onOutput: file { }" - #method return: anObject to: aContext + #method return: object to: context { self primitiveFailed. } - - #method returnTo: aContext andEval: aBlock with: arg - { - - self primitiveFailed. - } - - #method forceContext: aContext - { - - self primitiveFailed. - } - } diff --git a/stix/kernel/test-011.st b/stix/kernel/test-011.st index 67cbaa1..b7c160c 100644 --- a/stix/kernel/test-011.st +++ b/stix/kernel/test-011.st @@ -39,9 +39,9 @@ #method(#class) main2 { - | k | + | k q | 'BEGINNING OF main2' dump. - k := ['this is test-011' dump. Exception signal: 'main2 screwed...'. 8888 dump. ] + k := [ 'this is test-011' dump. q := Exception signal: 'main2 screwed...'. q dump. 8888 dump. ] on: Exception do: [ :ex | 'Exception occurred' dump. ex messageText dump. @@ -51,6 +51,7 @@ 'AFTER RETURN' dump. ]. + 'k=>>> ' dump. k dump. 'END OF main2' dump. } @@ -149,10 +150,10 @@ 'BEGINNING OF test11' dump. [ |p | - p := [ Exception signal: 'Exception in a new process of test11'. ] newProcess. + p := [ 'TEST11 IN NEW PROCESS' dump. Exception signal: 'Exception raised in a new process of test11'. ] newProcess. 'JJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJJ' dump. - p resume. - ] on: Exception do: [:ex | 'EXCEPTION ----------' dump. ex messageText dump ]. + p resume. ## resume the new process + ] on: Exception do: [:ex | '---- EXCEPTION IN TEST11. THIS MUST NOT BE PRINTED----------' dump. ex messageText dump ]. 'END OF test11' dump. } @@ -181,9 +182,10 @@ [ self main2 ] on: Exception do: [ :ex | 'EXCEPTION CAUGHT IN MAIN....' dump. ex messageText dump. - "ex pass." + ##ex pass. 'Returning back to where the exception has signalled in main2...' dump. - ex resume. + ##ex resume. + ex resume: 'RESUMED WITH THIS STRING'. ]. '##############################' dump. @@ -218,6 +220,9 @@ ## on: PrimitiveFailureException do: [:ex | 'PRIMITIVE FAILURE CAUGHT HERE HERE HERE' dump] ## on: Exception do: [:ex | ex messageText dump]. + 'SLEEPING FOR 10 seconds ....' dump. + Processor activeProcess sleep: 10. + '>>>>> END OF MAIN' dump. } } diff --git a/stix/lib/exec.c b/stix/lib/exec.c index e1dd09d..a564244 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -1026,7 +1026,10 @@ static STIX_INLINE int activate_new_method (stix_t* stix, stix_oop_method_t mth) #if defined(STIX_USE_PROCSTK) /* when process stack is used, the stack pointer in a context - * is a stack pointer of a process before it is activated */ + * is a stack pointer of a process before it is activated. + * this stack pointer is stored to the context so that it is + * used to restore the process stack pointer upon returning from + * a method context. */ ctx->sp = STIX_SMOOI_TO_OOP(stix->sp); #else /* do nothing */ @@ -1709,7 +1712,11 @@ STIX_DEBUG0 (stix, "PRIM BlockContext value FAIL - NARGS MISMATCH\n"); STIX_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */ STIX_ASSERT (blkctx->home != stix->_nil); - blkctx->sp = STIX_SMOOI_TO_OOP(local_ntmprs - 1); +#if defined(STIX_USE_PROCSTK) + blkctx->sp = STIX_SMOOI_TO_OOP(-1); /* not important at all */ +#else + blkctx->sp = STIX_SMOOI_TO_OOP(local_ntmprs - 1); +#endif blkctx->sender = stix->active_context; *pblkctx = blkctx; @@ -1720,6 +1727,7 @@ static int prim_block_value (stix_t* stix, stix_ooi_t nargs) { int x; stix_oop_context_t blkctx; + stix_oow_t sp; x = __block_value (stix, nargs, nargs, 0, &blkctx); if (x <= 0) return x; /* hard failure and soft failure */ @@ -1967,6 +1975,7 @@ static int prim_processor_remove_semaphore (stix_t* stix, stix_ooi_t nargs) } STIX_STACK_POPS (stix, nargs); + /* leave the receiver in the stack. ^self */ return 1; } @@ -1987,58 +1996,17 @@ static int prim_processor_return_to (stix_t* stix, stix_ooi_t nargs) STIX_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */ +/* TODO: verify if this is correct? does't it correct restore the stack pointer? + * test complex chains of method contexts and block contexts */ + if (STIX_CLASSOF(stix, ctx) == stix->_method_context) + { + /* when returning to a method context, load the sp register with + * the value stored in the context */ + stix->sp = STIX_OOP_TO_SMOOI(((stix_oop_context_t)ctx)->sp); + } STIX_STACK_PUSH (stix, ret); - SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)ctx); - - return 1; -} - -static int prim_processor_return_to_and_eval (stix_t* stix, stix_ooi_t nargs) -{ - stix_oop_t rcv, ctx, blk, blkarg; - - STIX_ASSERT (nargs == 3); - - rcv = STIX_STACK_GET(stix, stix->sp - 3); - ctx = STIX_STACK_GET(stix, stix->sp - 2); - blk = STIX_STACK_GET(stix, stix->sp - 1); - blkarg = STIX_STACK_GET(stix, stix->sp); - - if (rcv != (stix_oop_t)stix->processor) return 0; - - if (STIX_CLASSOF(stix, ctx) != stix->_block_context && - STIX_CLASSOF(stix, ctx) != stix->_method_context) return 0; - - if (STIX_CLASSOF(stix, blk) != stix->_block_context) return 0; - - STIX_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */ - STIX_STACK_PUSH (stix, stix->_nil); /* TODO: change the return value.. */ - SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)ctx); - - STIX_STACK_PUSH (stix, blk); - STIX_STACK_PUSH (stix, blkarg); - return prim_block_value (stix, 1); -} - -static int prim_processor_force_context (stix_t* stix, stix_ooi_t nargs) -{ - stix_oop_t rcv, ctx; - - STIX_ASSERT (nargs == 1); - - rcv = STIX_STACK_GET(stix, stix->sp - 1); - ctx = STIX_STACK_GET(stix, stix->sp); - - if (rcv != (stix_oop_t)stix->processor) return 0; - - if (STIX_CLASSOF(stix, ctx) != stix->_block_context && - STIX_CLASSOF(stix, ctx) != stix->_method_context) return 0; - - STIX_STACK_POPS (stix, nargs + 1); /* pop arguments and receiver */ - /* TODO: push nothing??? */ SWITCH_ACTIVE_CONTEXT (stix, (stix_oop_context_t)ctx); - return 1; } @@ -2733,8 +2701,6 @@ static prim_t primitives[] = { 2, 3, prim_processor_add_timed_semaphore, "_processor_add_timed_semaphore" }, { 1, 1, prim_processor_remove_semaphore, "_processor_remove_semaphore" }, { 2, 2, prim_processor_return_to, "_processor_return_to" }, - { 3, 3, prim_processor_return_to_and_eval, "_processor_return_to_and_eval" }, - { 1, 1, prim_processor_force_context, "_processor_force_context" }, { 1, 1, prim_integer_add, "_integer_add" }, { 1, 1, prim_integer_sub, "_integer_sub" },