diff --git a/stix/kernel/Collect.st b/stix/kernel/Collect.st index 52105cb..225374b 100644 --- a/stix/kernel/Collect.st +++ b/stix/kernel/Collect.st @@ -170,10 +170,20 @@ ^self atLevel: Log.INFO log: message. } + #method log: message and: message2 + { + ^self atLevel: Log.INFO log: message and: message2. + } + #method logNl: message { ^self atLevel: Log.INFO logNl: message. } + + #method logNl: message and: message2 + { + ^self atLevel: Log.INFO logNl: message and: message2. + } } #class Namespace(Set) diff --git a/stix/kernel/Except.st b/stix/kernel/Except.st index 9595b19..20f42a1 100644 --- a/stix/kernel/Except.st +++ b/stix/kernel/Except.st @@ -150,6 +150,7 @@ ## ------------------------------------------------------------------- | ctx stop | + ctx := self. stop := false. [stop] whileFalse: [ diff --git a/stix/kernel/Process.st b/stix/kernel/Process.st index 1798732..3a95aa2 100644 --- a/stix/kernel/Process.st +++ b/stix/kernel/Process.st @@ -43,9 +43,38 @@ self primitiveFailed } + #method _suspend + { + + self primitiveFailed + } + #method terminate { ##search from the top contextof the process down to intial_contextand find ensure blocks and execute them. + ## if a different process calls 'terminate' on a process, + ## the ensureblock is not executed in the context of the + ## process being terminated, but in the context of terminatig process. + ## + ## 1) process termianted by another process + ## p := [ + ## [ 1 to: 10000 by: 1 do: [:ex | System logNl: i asString] ] ensure: [System logNl: 'ensured....'] + ## ] newProcess. + ## p resume. + ## p terminate. + ## + ## 2) process terminated by itself + ## p := [ + ## [ Processor activeProcess terminate. ] ensure: [System logNl: 'ensured....'] + ## ] newProcess. + ## p resume. + ## p terminate. + ## ---------------------------------------------------------------------------------------------------------- + ## the process must be frozen first. while unwinding is performed, + ## the process must not be scheduled. + ## ---------------------------------------------------------------------------------------------------------- + + (Processor activeProcess ~~ self) ifTrue: [ self _suspend ]. self.current_context unwindTo: self.initial_context return: nil. ^self _terminate } diff --git a/stix/kernel/test-013.st b/stix/kernel/test-013.st index 87a8b2c..b010a2f 100644 --- a/stix/kernel/test-013.st +++ b/stix/kernel/test-013.st @@ -80,7 +80,8 @@ v1 := [ [ [ - 1 to: 10000 by: 1 do: [:i | System logNl: i asString. Processor sleepFor: 5. ] + ##1 to: 20000 by: 1 do: [:i | System logNl: i asString. "Processor sleepFor: 1." ] + Processor activeProcess terminate. ] ensure: [ System logNl: '<<>>' ]. ] ensure: [ System logNl: '<<--------------------->>' ]. @@ -88,9 +89,10 @@ System logNl: 'RESUMING v1'. v1 resume. + Processor sleepFor: 1. v1 terminate. - ##[ + ##[ ## [ Processor activeProcess terminate. ] ensure: [System logNl: '<<>>' ]. ##] ensure: [ System logNl: '<<--------------------->>' ]. diff --git a/stix/lib/exec.c b/stix/lib/exec.c index aad5418..6da6a97 100644 --- a/stix/lib/exec.c +++ b/stix/lib/exec.c @@ -97,6 +97,7 @@ (stix)->active_method = (stix_oop_method_t)(stix)->active_context->origin->method_or_nargs; \ SET_ACTIVE_METHOD_CODE(stix); \ LOAD_ACTIVE_IP (stix); \ + (stix)->processor->active->current_context = (stix)->active_context; \ } while (0) #define FETCH_BYTE_CODE(stix) ((stix)->active_code[(stix)->ip++]) @@ -1234,14 +1235,19 @@ static int prim_log (stix_t* stix, stix_ooi_t nargs) else if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_OOP) { /* visit only 1-level down into an array-like object */ - stix_oop_t inner; - stix_oow_t i; + stix_oop_t inner, _class; + stix_oow_t i, spec; - if (STIX_CLASSOF(stix,msg) == stix->_association) goto dump_object; + _class = STIX_CLASSOF(stix, msg); + + spec = STIX_OOP_TO_SMOOI(((stix_oop_class_t)_class)->spec); + if (STIX_CLASS_SPEC_NAMED_INSTVAR(spec) > 0 || !STIX_CLASS_SPEC_IS_INDEXED(spec)) goto dump_object; for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++) { inner = ((stix_oop_oop_t)msg)->slot[i]; + + if (i > 0) stix_logbfmt (stix, mask, " "); if (STIX_OOP_IS_POINTER(inner) && STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR) { @@ -1869,6 +1875,20 @@ static int prim_process_yield (stix_t* stix, stix_ooi_t nargs) return 1; } +static int prim_process_suspend (stix_t* stix, stix_ooi_t nargs) +{ + stix_oop_t rcv; + STIX_ASSERT (nargs == 0); + + rcv = STIX_STACK_GET(stix, stix->sp); + if (STIX_CLASSOF(stix,rcv) != stix->_process) return 0; + + suspend_process (stix, (stix_oop_process_t)rcv); + + /* keep the receiver in the stack top */ + return 1; +} + static int prim_semaphore_signal (stix_t* stix, stix_ooi_t nargs) { stix_oop_t rcv; @@ -2724,6 +2744,7 @@ static prim_t primitives[] = { 0, 0, prim_process_resume, "_process_resume" }, { 0, 0, prim_process_terminate, "_process_terminate" }, { 0, 0, prim_process_yield, "_process_yield" }, + { 0, 0, prim_process_suspend, "_process_suspend" }, { 0, 0, prim_semaphore_signal, "_semaphore_signal" }, { 0, 0, prim_semaphore_wait, "_semaphore_wait" },