enhanced the vm logging interface
attempted to execute ensure blocks on process termination. (wip)
This commit is contained in:
parent
1445d0deb0
commit
436babff3c
@ -239,7 +239,6 @@
|
|||||||
^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass].
|
^(self isMemberOf: aClass) or: [self class inheritsFrom: aClass].
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
## -------------------------------------------------------
|
## -------------------------------------------------------
|
||||||
"
|
"
|
||||||
|
@ -108,8 +108,10 @@
|
|||||||
#pooldic Log
|
#pooldic Log
|
||||||
{
|
{
|
||||||
## -----------------------------------------------------------
|
## -----------------------------------------------------------
|
||||||
|
## defines log levels
|
||||||
## these items must follow defintions in stix.h
|
## these items must follow defintions in stix.h
|
||||||
## -----------------------------------------------------------
|
## -----------------------------------------------------------
|
||||||
|
|
||||||
#DEBUG := 1.
|
#DEBUG := 1.
|
||||||
#INFO := 2.
|
#INFO := 2.
|
||||||
#WARN := 4.
|
#WARN := 4.
|
||||||
@ -127,27 +129,50 @@
|
|||||||
|
|
||||||
#dcl(#pooldic) Log.
|
#dcl(#pooldic) Log.
|
||||||
|
|
||||||
#method log: message level: level
|
#method atLevel: level log: message
|
||||||
{
|
{
|
||||||
<primitive: #_log>
|
<primitive: #_log>
|
||||||
## do nothing upon logging failure
|
## do nothing upon logging failure
|
||||||
}
|
}
|
||||||
|
|
||||||
#method logNl: message level: level
|
#method atLevel: level log: message and: message2
|
||||||
{
|
{
|
||||||
self log: message level: level.
|
<primitive: #_log>
|
||||||
self log: S'\n' level: level.
|
## do nothing upon logging failure
|
||||||
^self.
|
}
|
||||||
|
|
||||||
|
#method atLevel: level log: message and: message2 and: message3
|
||||||
|
{
|
||||||
|
<primitive: #_log>
|
||||||
|
## do nothing upon logging failure
|
||||||
|
}
|
||||||
|
|
||||||
|
#method atLevel: level logNl: message
|
||||||
|
{
|
||||||
|
## the #_log primitive accepts an array.
|
||||||
|
## so the following lines should work also.
|
||||||
|
## | x |
|
||||||
|
## x := Array new: 2.
|
||||||
|
## x at: 0 put: message.
|
||||||
|
## x at: 1 put: S'\n'.
|
||||||
|
## ^self atLevel: level log: x.
|
||||||
|
|
||||||
|
^self atLevel: level log: message and: S'\n'.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method atLevel: level logNl: message and: message2
|
||||||
|
{
|
||||||
|
^self atLevel: level log: message and: message2 and: S'\n'.
|
||||||
}
|
}
|
||||||
|
|
||||||
#method log: message
|
#method log: message
|
||||||
{
|
{
|
||||||
^self log: message level: Log.INFO.
|
^self atLevel: Log.INFO log: message.
|
||||||
}
|
}
|
||||||
|
|
||||||
#method logNl: message
|
#method logNl: message
|
||||||
{
|
{
|
||||||
^self logNl: message level: Log.INFO.
|
^self atLevel: Log.INFO logNl: message.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,3 +189,20 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#extend Apex
|
||||||
|
{
|
||||||
|
## -------------------------------------------------------
|
||||||
|
## Association has been defined now. let's add association
|
||||||
|
## creating methods
|
||||||
|
## -------------------------------------------------------
|
||||||
|
|
||||||
|
#method(#class) -> object
|
||||||
|
{
|
||||||
|
^Association new key: self value: object
|
||||||
|
}
|
||||||
|
|
||||||
|
#method -> object
|
||||||
|
{
|
||||||
|
^Association new key: self value: object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -246,6 +246,4 @@
|
|||||||
{
|
{
|
||||||
ip := self.source pc.
|
ip := self.source pc.
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,6 +165,8 @@
|
|||||||
].
|
].
|
||||||
stop := (ctx == context).
|
stop := (ctx == context).
|
||||||
ctx := ctx sender.
|
ctx := ctx sender.
|
||||||
|
|
||||||
|
## stop ifFalse: [ stop := ctx isNil ].
|
||||||
].
|
].
|
||||||
|
|
||||||
^retval
|
^retval
|
||||||
|
@ -37,12 +37,19 @@
|
|||||||
##^Processor resume: self.
|
##^Processor resume: self.
|
||||||
}
|
}
|
||||||
|
|
||||||
#method terminate
|
#method _terminate
|
||||||
{
|
{
|
||||||
<primitive: #_process_terminate>
|
<primitive: #_process_terminate>
|
||||||
self primitiveFailed
|
self primitiveFailed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method terminate
|
||||||
|
{
|
||||||
|
##search from the top contextof the process down to intial_contextand find ensure blocks and execute them.
|
||||||
|
self.current_context unwindTo: self.initial_context return: nil.
|
||||||
|
^self _terminate
|
||||||
|
}
|
||||||
|
|
||||||
#method yield
|
#method yield
|
||||||
{
|
{
|
||||||
<primitive: #_process_yield>
|
<primitive: #_process_yield>
|
||||||
@ -58,15 +65,6 @@
|
|||||||
{
|
{
|
||||||
^self.initial_context
|
^self.initial_context
|
||||||
}
|
}
|
||||||
|
|
||||||
#method sleep: seconds
|
|
||||||
{
|
|
||||||
| s |
|
|
||||||
s := Semaphore new.
|
|
||||||
Processor signal: s after: seconds.
|
|
||||||
## Processor activeProcess dump.
|
|
||||||
s wait.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#class Semaphore(Object)
|
#class Semaphore(Object)
|
||||||
@ -405,4 +403,26 @@
|
|||||||
<primitive: #_processor_return_to>
|
<primitive: #_processor_return_to>
|
||||||
self primitiveFailed.
|
self primitiveFailed.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#method sleepFor: secs
|
||||||
|
{
|
||||||
|
## -----------------------------------------------------
|
||||||
|
## put the calling process to sleep for given seconds.
|
||||||
|
## -----------------------------------------------------
|
||||||
|
| s |
|
||||||
|
s := Semaphore new.
|
||||||
|
self signal: s after: secs.
|
||||||
|
s wait.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method sleepFor: secs and: nanosecs
|
||||||
|
{
|
||||||
|
## -----------------------------------------------------
|
||||||
|
## put the calling process to sleep for given seconds.
|
||||||
|
## -----------------------------------------------------
|
||||||
|
| s |
|
||||||
|
s := Semaphore new.
|
||||||
|
self signal: s after: secs and: nanosecs
|
||||||
|
s wait.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,22 @@
|
|||||||
#class Association(Magnitude)
|
#class Association(Magnitude)
|
||||||
{
|
{
|
||||||
#dcl key value.
|
#dcl key value.
|
||||||
|
|
||||||
|
#method key: key value: value
|
||||||
|
{
|
||||||
|
self.key := key.
|
||||||
|
self.value := value.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method key
|
||||||
|
{
|
||||||
|
^self.key
|
||||||
|
}
|
||||||
|
|
||||||
|
#method value
|
||||||
|
{
|
||||||
|
^self.value
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#class Character(Magnitude)
|
#class Character(Magnitude)
|
||||||
|
@ -182,11 +182,11 @@
|
|||||||
s3 := Semaphore new.
|
s3 := Semaphore new.
|
||||||
|
|
||||||
t1 := [
|
t1 := [
|
||||||
10 timesRepeat: ['BLOCK #1' dump. Processor activeProcess sleep: 1.].
|
10 timesRepeat: ['BLOCK #1' dump. Processor sleepFor: 1.].
|
||||||
s1 signal
|
s1 signal
|
||||||
] newProcess.
|
] newProcess.
|
||||||
t2 := [
|
t2 := [
|
||||||
5 timesRepeat: ['BLOCK #2' dump. "Processor activeProcess sleep: 1." ].
|
5 timesRepeat: ['BLOCK #2' dump. "Processor sleepFor: 1." ].
|
||||||
'SIGNALLING S2...' dump. s2 signal.
|
'SIGNALLING S2...' dump. s2 signal.
|
||||||
] newProcess.
|
] newProcess.
|
||||||
|
|
||||||
|
@ -221,7 +221,7 @@
|
|||||||
## on: Exception do: [:ex | ex messageText dump].
|
## on: Exception do: [:ex | ex messageText dump].
|
||||||
|
|
||||||
'SLEEPING FOR 10 seconds ....' dump.
|
'SLEEPING FOR 10 seconds ....' dump.
|
||||||
Processor activeProcess sleep: 10.
|
Processor sleepFor: 10.
|
||||||
|
|
||||||
'>>>>> END OF MAIN' dump.
|
'>>>>> END OF MAIN' dump.
|
||||||
}
|
}
|
||||||
|
101
stix/kernel/test-013.st
Normal file
101
stix/kernel/test-013.st
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
|
||||||
|
#include 'Stix.st'.
|
||||||
|
|
||||||
|
#################################################################
|
||||||
|
## MAIN
|
||||||
|
#################################################################
|
||||||
|
|
||||||
|
## TODO: use #define to define a class or use #class to define a class.
|
||||||
|
## use #extend to extend a class
|
||||||
|
## using #class for both feels confusing.
|
||||||
|
|
||||||
|
#extend Apex
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#extend SmallInteger
|
||||||
|
{
|
||||||
|
#method getTrue: anInteger
|
||||||
|
{
|
||||||
|
^anInteger + 9999.
|
||||||
|
}
|
||||||
|
|
||||||
|
#method inc
|
||||||
|
{
|
||||||
|
^self + 1.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#class TestObject(Object)
|
||||||
|
{
|
||||||
|
#dcl(#class) Q R.
|
||||||
|
#dcl(#classinst) a1 a2.
|
||||||
|
|
||||||
|
#method test999
|
||||||
|
{
|
||||||
|
^self.Q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#class B.TestObject(Object)
|
||||||
|
{
|
||||||
|
#dcl(#class) Q R.
|
||||||
|
#dcl(#classinst) a1 a2.
|
||||||
|
|
||||||
|
#method test000
|
||||||
|
{
|
||||||
|
^self.Q
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#pooldic ABC
|
||||||
|
{
|
||||||
|
#KKK := 20.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#class MyObject(TestObject)
|
||||||
|
{
|
||||||
|
#method(#class) main
|
||||||
|
{
|
||||||
|
| v1 v2 |
|
||||||
|
System logNl: 'START OF MAIN'.
|
||||||
|
v2 := [
|
||||||
|
[ v1 := [ System logNl: 'xxxxxxxxxxxxxxxxc'. Exception signal: 'qqqqq' ] value.
|
||||||
|
'OK OK OK' dump. ] ensure: [ System logNl: 'ENSURE ENSURE ENSURE'].
|
||||||
|
]
|
||||||
|
on: Exception
|
||||||
|
do: [:ex |
|
||||||
|
System logNl: ('Exception: ', ex messageText).
|
||||||
|
ex return: 10.
|
||||||
|
##ex retry.
|
||||||
|
System logNl: '--- THIS MUST NOT BE PRINTED ---'.
|
||||||
|
].
|
||||||
|
|
||||||
|
|
||||||
|
System logNl: '---------------------'.
|
||||||
|
System log: 'v1=>'; log: v1; log: ' v2=>'; logNl: v2.
|
||||||
|
|
||||||
|
v1 := [
|
||||||
|
[
|
||||||
|
[
|
||||||
|
1 to: 10000 by: 1 do: [:i | System logNl: i asString. Processor sleepFor: 5. ]
|
||||||
|
] ensure: [ System logNl: '<<<PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP>>>' ].
|
||||||
|
|
||||||
|
] ensure: [ System logNl: '<<--------------------->>' ].
|
||||||
|
] newProcess.
|
||||||
|
|
||||||
|
System logNl: 'RESUMING v1'.
|
||||||
|
v1 resume.
|
||||||
|
v1 terminate.
|
||||||
|
|
||||||
|
##[
|
||||||
|
## [ Processor activeProcess terminate. ] ensure: [System logNl: '<<<PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP>>>' ].
|
||||||
|
##] ensure: [ System logNl: '<<--------------------->>' ].
|
||||||
|
|
||||||
|
System logNl: S'\0\0\0END OF MAIN\0AB\0\0\0C\0\0\0'.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1916,14 +1916,6 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index,
|
|||||||
|
|
||||||
static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop)
|
static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop)
|
||||||
{
|
{
|
||||||
int n;
|
|
||||||
stix_oow_t saved_len;
|
|
||||||
|
|
||||||
saved_len = stix->c->cls.pooldic.len;
|
|
||||||
|
|
||||||
n = copy_string_to (stix, name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ');
|
|
||||||
if (n >= 0)
|
|
||||||
{
|
|
||||||
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
|
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
|
||||||
{
|
{
|
||||||
stix_oow_t new_capa;
|
stix_oow_t new_capa;
|
||||||
@ -1931,11 +1923,7 @@ static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* nam
|
|||||||
|
|
||||||
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
|
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
|
||||||
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
|
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
|
||||||
if (!tmp)
|
if (!tmp) return -1;
|
||||||
{
|
|
||||||
stix->c->cls.pooldic.len = saved_len;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stix->c->cls.pooldic_oop_capa = new_capa;
|
stix->c->cls.pooldic_oop_capa = new_capa;
|
||||||
stix->c->cls.pooldic_oops = tmp;
|
stix->c->cls.pooldic_oops = tmp;
|
||||||
@ -1944,12 +1932,10 @@ static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* nam
|
|||||||
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
|
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
|
||||||
stix->c->cls.pooldic_count++;
|
stix->c->cls.pooldic_count++;
|
||||||
/* TODO: check if pooldic_count overflows */
|
/* TODO: check if pooldic_count overflows */
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static stix_ooi_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_oocs_t* name, var_info_t* var)
|
static stix_ooi_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_oocs_t* name, var_info_t* var)
|
||||||
{
|
{
|
||||||
stix_oow_t pos;
|
stix_oow_t pos;
|
||||||
@ -2281,6 +2267,46 @@ wrong_name:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int resolve_pooldic (stix_t* stix, int dotted, const stix_oocs_t* name)
|
||||||
|
{
|
||||||
|
stix_oocs_t last; /* the last segment */
|
||||||
|
stix_oop_set_t ns_oop; /* name space */
|
||||||
|
stix_oop_association_t ass;
|
||||||
|
stix_oow_t i;
|
||||||
|
|
||||||
|
if (dotted)
|
||||||
|
{
|
||||||
|
if (preprocess_dotted_name(stix, 0, 0, name, &stix->c->tok.loc, &last, &ns_oop) <= -1) return -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
last = *name;
|
||||||
|
/* it falls back to the name space of the class */
|
||||||
|
ns_oop = stix->c->cls.ns_oop;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the name refers to a pool dictionary */
|
||||||
|
ass = stix_lookupdic (stix, ns_oop, &last);
|
||||||
|
if (!ass || STIX_CLASSOF(stix, ass->value) != stix->_pool_dictionary)
|
||||||
|
{
|
||||||
|
set_syntax_error (stix, STIX_SYNERR_POOLDIC, &stix->c->tok.loc, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if the same dictionary pool has been declared for import */
|
||||||
|
for (i = 0; i < stix->c->cls.pooldic_count; i++)
|
||||||
|
{
|
||||||
|
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i])
|
||||||
|
{
|
||||||
|
set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, &stix->c->tok.loc, name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int compile_class_level_variables (stix_t* stix)
|
static int compile_class_level_variables (stix_t* stix)
|
||||||
{
|
{
|
||||||
var_type_t dcl_type = VAR_INSTANCE;
|
var_type_t dcl_type = VAR_INSTANCE;
|
||||||
@ -2304,7 +2330,7 @@ static int compile_class_level_variables (stix_t* stix)
|
|||||||
}
|
}
|
||||||
else if (is_token_symbol(stix, VOCA_POOLDIC))
|
else if (is_token_symbol(stix, VOCA_POOLDIC))
|
||||||
{
|
{
|
||||||
/* #dcl(#pooldic) */
|
/* #dcl(#pooldic) - import a pool dictionary */
|
||||||
dcl_type = VAR_GLOBAL; /* this is not a real type. use for branching below */
|
dcl_type = VAR_GLOBAL; /* this is not a real type. use for branching below */
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
}
|
}
|
||||||
@ -2360,6 +2386,12 @@ static int compile_class_level_variables (stix_t* stix)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (add_pool_dictionary(stix, &stix->c->tok.name, (stix_oop_set_t)ass->value) <= -1) return -1;
|
if (add_pool_dictionary(stix, &stix->c->tok.name, (stix_oop_set_t)ass->value) <= -1) return -1;
|
||||||
|
if (copy_string_to (stix, &stix->c->tok.name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ') <= -1)
|
||||||
|
{
|
||||||
|
stix->c->cls.pooldic_count--;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
}
|
}
|
||||||
while (1);
|
while (1);
|
||||||
@ -2401,9 +2433,6 @@ static int compile_class_level_variables (stix_t* stix)
|
|||||||
|
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile_unary_method_name (stix_t* stix)
|
static int compile_unary_method_name (stix_t* stix)
|
||||||
@ -2761,7 +2790,6 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0)
|
if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0)
|
||||||
{
|
{
|
||||||
class_level_variable:
|
class_level_variable:
|
||||||
@ -4881,11 +4909,9 @@ static int __compile_pooldic_definition (stix_t* stix)
|
|||||||
|
|
||||||
case STIX_IOTOK_NUMLIT:
|
case STIX_IOTOK_NUMLIT:
|
||||||
case STIX_IOTOK_RADNUMLIT:
|
case STIX_IOTOK_RADNUMLIT:
|
||||||
{
|
|
||||||
lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
|
lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
|
||||||
if (!lit) return -1;
|
if (!lit) return -1;
|
||||||
goto add_literal;
|
goto add_literal;
|
||||||
}
|
|
||||||
|
|
||||||
case STIX_IOTOK_BPAREN: /* #[ */
|
case STIX_IOTOK_BPAREN: /* #[ */
|
||||||
if (read_byte_array_literal(stix, &lit) <= -1) return -1;
|
if (read_byte_array_literal(stix, &lit) <= -1) return -1;
|
||||||
@ -5005,8 +5031,7 @@ static int compile_stream (stix_t* stix)
|
|||||||
}
|
}
|
||||||
else if (is_token_symbol(stix, VOCA_POOLDIC))
|
else if (is_token_symbol(stix, VOCA_POOLDIC))
|
||||||
{
|
{
|
||||||
/* TODO: allow #pooldic within #class */
|
/* #pooldic SharedPoolDic { #ABC := 20. #DEFG := 'ayz' } */
|
||||||
/* #pooldic SharedPoolDic { #abc := 20. #defg := 'ayz' } */
|
|
||||||
GET_TOKEN (stix);
|
GET_TOKEN (stix);
|
||||||
if (compile_pooldic_definition(stix) <= -1) return -1;
|
if (compile_pooldic_definition(stix) <= -1) return -1;
|
||||||
}
|
}
|
||||||
|
@ -557,7 +557,6 @@ static void resume_process (stix_t* stix, stix_oop_process_t proc)
|
|||||||
|
|
||||||
/* don't switch to this process. just set the state to RUNNING */
|
/* don't switch to this process. just set the state to RUNNING */
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
else if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
|
else if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
|
||||||
{
|
{
|
||||||
@ -1167,56 +1166,100 @@ static int prim_dump (stix_t* stix, stix_ooi_t nargs)
|
|||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int prim_log (stix_t* stix, stix_ooi_t nargs)
|
static void log_char_object (stix_t* stix, stix_oow_t mask, stix_oop_char_t msg)
|
||||||
{
|
{
|
||||||
stix_oop_t msg, level;
|
|
||||||
|
|
||||||
STIX_ASSERT (nargs >= 2);
|
|
||||||
|
|
||||||
level = STIX_STACK_GET(stix, stix->sp);
|
|
||||||
msg = STIX_STACK_GET(stix, stix->sp - 1);
|
|
||||||
|
|
||||||
/* TODO: SUPPORT ARBITRARY NUMBERS OF MESSAGES */
|
|
||||||
if (!STIX_OOP_IS_SMOOI(level)) level = STIX_SMOOI_TO_OOP(STIX_LOG_INFO);
|
|
||||||
|
|
||||||
if (STIX_OOP_IS_POINTER(msg) && STIX_OBJ_GET_FLAGS_TYPE(msg))
|
|
||||||
{
|
|
||||||
stix_ooi_t n;
|
stix_ooi_t n;
|
||||||
stix_oow_t rem;
|
stix_oow_t rem;
|
||||||
const stix_ooch_t* ptr;
|
const stix_ooch_t* ptr;
|
||||||
|
|
||||||
rem = STIX_OBJ_GET_SIZE(msg);
|
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR);
|
||||||
ptr = ((stix_oop_char_t)msg)->slot;
|
|
||||||
|
|
||||||
start_over:
|
rem = STIX_OBJ_GET_SIZE(msg);
|
||||||
|
ptr = msg->slot;
|
||||||
|
|
||||||
|
start_over:
|
||||||
while (rem > 0)
|
while (rem > 0)
|
||||||
{
|
{
|
||||||
if (*ptr == '\0')
|
if (*ptr == '\0')
|
||||||
{
|
{
|
||||||
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr);
|
n = stix_logbfmt (stix, mask, "%C", *ptr);
|
||||||
STIX_ASSERT (n == 1);
|
STIX_ASSERT (n == 1);
|
||||||
rem -= n;
|
rem -= n;
|
||||||
ptr += n;
|
ptr += n;
|
||||||
goto start_over;
|
goto start_over;
|
||||||
}
|
}
|
||||||
|
|
||||||
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%.*S", rem, ptr);
|
n = stix_logbfmt (stix, mask, "%.*S", rem, ptr);
|
||||||
if (n <= -1) break;
|
if (n <= -1) break;
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
/* to skip the unprinted character.
|
/* to skip the unprinted character.
|
||||||
* actually, this check is not needed because of '\0' skipping
|
* actually, this check is not needed because of '\0' skipping
|
||||||
* at the beginning of the loop */
|
* at the beginning of the loop */
|
||||||
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr);
|
n = stix_logbfmt (stix, mask, "%C", *ptr);
|
||||||
STIX_ASSERT (n == 1);
|
STIX_ASSERT (n == 1);
|
||||||
}
|
}
|
||||||
rem -= n;
|
rem -= n;
|
||||||
ptr += n;
|
ptr += n;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int prim_log (stix_t* stix, stix_ooi_t nargs)
|
||||||
|
{
|
||||||
|
stix_oop_t msg, level;
|
||||||
|
stix_oow_t mask;
|
||||||
|
stix_ooi_t k;
|
||||||
|
|
||||||
|
STIX_ASSERT (nargs >= 2);
|
||||||
|
|
||||||
|
level = STIX_STACK_GET(stix, stix->sp - nargs + 1);
|
||||||
|
if (!STIX_OOP_IS_SMOOI(level)) mask = STIX_LOG_APP | STIX_LOG_INFO;
|
||||||
|
else mask = STIX_LOG_APP | STIX_OOP_TO_SMOOI(level);
|
||||||
|
|
||||||
|
for (k = nargs - 1; k > 0; )
|
||||||
|
{
|
||||||
|
--k;
|
||||||
|
msg = STIX_STACK_GET(stix, stix->sp - k);
|
||||||
|
|
||||||
|
if (msg == stix->_nil || msg == stix->_true || msg == stix->_false)
|
||||||
|
{
|
||||||
|
goto dump_object;
|
||||||
|
}
|
||||||
|
else if (STIX_OOP_IS_POINTER(msg))
|
||||||
|
{
|
||||||
|
if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR)
|
||||||
|
{
|
||||||
|
log_char_object (stix, mask, (stix_oop_char_t)msg);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
|
||||||
|
if (STIX_CLASSOF(stix,msg) == stix->_association) goto dump_object;
|
||||||
|
|
||||||
|
for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++)
|
||||||
|
{
|
||||||
|
inner = ((stix_oop_oop_t)msg)->slot[i];
|
||||||
|
if (STIX_OOP_IS_POINTER(inner) &&
|
||||||
|
STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR)
|
||||||
|
{
|
||||||
|
log_char_object (stix, mask, (stix_oop_char_t)inner);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%O", msg);
|
stix_logbfmt (stix, mask, "%O", inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else goto dump_object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dump_object:
|
||||||
|
stix_logbfmt (stix, mask, "%O", msg);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
STIX_STACK_POPS (stix, nargs); /* delete arguments, keep self */
|
STIX_STACK_POPS (stix, nargs); /* delete arguments, keep self */
|
||||||
@ -2656,7 +2699,7 @@ typedef struct prim_t prim_t;
|
|||||||
static prim_t primitives[] =
|
static prim_t primitives[] =
|
||||||
{
|
{
|
||||||
{ 0, MAX_NARGS, prim_dump, "_dump" },
|
{ 0, MAX_NARGS, prim_dump, "_dump" },
|
||||||
{ 2, 2, prim_log, "_log" },
|
{ 2, MAX_NARGS, prim_log, "_log" },
|
||||||
|
|
||||||
{ 1, 1, prim_identical, "_identical" },
|
{ 1, 1, prim_identical, "_identical" },
|
||||||
{ 1, 1, prim_not_identical, "_not_identical" },
|
{ 1, 1, prim_not_identical, "_not_identical" },
|
||||||
|
@ -131,14 +131,14 @@ static stix_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' };
|
|||||||
|
|
||||||
typedef int (*stix_fmtout_putch_t) (
|
typedef int (*stix_fmtout_putch_t) (
|
||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
unsigned int mask,
|
stix_oow_t mask,
|
||||||
stix_ooch_t c,
|
stix_ooch_t c,
|
||||||
stix_oow_t len
|
stix_oow_t len
|
||||||
);
|
);
|
||||||
|
|
||||||
typedef int (*stix_fmtout_putcs_t) (
|
typedef int (*stix_fmtout_putcs_t) (
|
||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
unsigned int mask,
|
stix_oow_t mask,
|
||||||
const stix_ooch_t* ptr,
|
const stix_ooch_t* ptr,
|
||||||
stix_oow_t len
|
stix_oow_t len
|
||||||
);
|
);
|
||||||
@ -147,7 +147,7 @@ typedef struct stix_fmtout_t stix_fmtout_t;
|
|||||||
struct stix_fmtout_t
|
struct stix_fmtout_t
|
||||||
{
|
{
|
||||||
stix_oow_t count; /* out */
|
stix_oow_t count; /* out */
|
||||||
int mask; /* in */
|
stix_oow_t mask; /* in */
|
||||||
stix_fmtout_putch_t putch; /* in */
|
stix_fmtout_putch_t putch; /* in */
|
||||||
stix_fmtout_putcs_t putcs; /* in */
|
stix_fmtout_putcs_t putcs; /* in */
|
||||||
};
|
};
|
||||||
@ -185,7 +185,7 @@ static stix_bch_t* sprintn_upper (stix_bch_t* nbuf, stix_uintmax_t num, int base
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
static int put_ooch (stix_t* stix, unsigned int mask, stix_ooch_t ch, stix_oow_t len)
|
static int put_ooch (stix_t* stix, stix_oow_t mask, stix_ooch_t ch, stix_oow_t len)
|
||||||
{
|
{
|
||||||
if (len <= 0) return 1;
|
if (len <= 0) return 1;
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ redo:
|
|||||||
return 1; /* success */
|
return 1; /* success */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, stix_oow_t len)
|
static int put_oocs (stix_t* stix, stix_oow_t mask, const stix_ooch_t* ptr, stix_oow_t len)
|
||||||
{
|
{
|
||||||
if (len <= 0) return 1;
|
if (len <= 0) return 1;
|
||||||
|
|
||||||
@ -277,7 +277,7 @@ static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, st
|
|||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
/* ------------------------------------------------------------------------- */
|
||||||
|
|
||||||
static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
|
static void print_object (stix_t* stix, stix_oow_t mask, stix_oop_t oop)
|
||||||
{
|
{
|
||||||
if (oop == stix->_nil)
|
if (oop == stix->_nil)
|
||||||
{
|
{
|
||||||
@ -365,6 +365,9 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
|
|||||||
case '\0':
|
case '\0':
|
||||||
escaped = '0';
|
escaped = '0';
|
||||||
break;
|
break;
|
||||||
|
case '\n':
|
||||||
|
escaped = 'n';
|
||||||
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
escaped = 'r';
|
escaped = 'r';
|
||||||
break;
|
break;
|
||||||
@ -450,6 +453,10 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
|
|||||||
/* print the class name */
|
/* print the class name */
|
||||||
stix_logbfmt (stix, mask, "%.*S", STIX_OBJ_GET_SIZE(((stix_oop_class_t)oop)->name), ((stix_oop_class_t)oop)->name->slot);
|
stix_logbfmt (stix, mask, "%.*S", STIX_OBJ_GET_SIZE(((stix_oop_class_t)oop)->name), ((stix_oop_class_t)oop)->name->slot);
|
||||||
}
|
}
|
||||||
|
else if ((stix_oop_t)c == stix->_association)
|
||||||
|
{
|
||||||
|
stix_logbfmt (stix, mask, "%O -> %O", ((stix_oop_association_t)oop)->key, ((stix_oop_association_t)oop)->value);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
stix_logbfmt (stix, mask, "instance of %.*S(%p)", STIX_OBJ_GET_SIZE(c->name), ((stix_oop_char_t)c->name)->slot, oop);
|
stix_logbfmt (stix, mask, "instance of %.*S(%p)", STIX_OBJ_GET_SIZE(c->name), ((stix_oop_char_t)c->name)->slot, oop);
|
||||||
@ -473,7 +480,7 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
|
|||||||
#define FMTCHAR_IS_OOCH
|
#define FMTCHAR_IS_OOCH
|
||||||
#include "logfmtv.h"
|
#include "logfmtv.h"
|
||||||
|
|
||||||
stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt, ...)
|
stix_ooi_t stix_logbfmt (stix_t* stix, stix_oow_t mask, const stix_bch_t* fmt, ...)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@ -495,7 +502,7 @@ stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt,
|
|||||||
return (x <= -1)? -1: fo.count;
|
return (x <= -1)? -1: fo.count;
|
||||||
}
|
}
|
||||||
|
|
||||||
stix_ooi_t stix_logoofmt (stix_t* stix, unsigned int mask, const stix_ooch_t* fmt, ...)
|
stix_ooi_t stix_logoofmt (stix_t* stix, stix_oow_t mask, const stix_ooch_t* fmt, ...)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
@ -330,7 +331,7 @@ printf ("MOD_GETSYM [%s]\n", &buf[0]);
|
|||||||
|
|
||||||
/* ========================================================================= */
|
/* ========================================================================= */
|
||||||
|
|
||||||
static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len)
|
static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
# error NOT IMPLEMENTED
|
# error NOT IMPLEMENTED
|
||||||
@ -340,31 +341,72 @@ static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg,
|
|||||||
stix_oow_t ucslen, bcslen, msgidx;
|
stix_oow_t ucslen, bcslen, msgidx;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
msgidx = 0;
|
|
||||||
|
|
||||||
|
|
||||||
/*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */
|
/*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */
|
||||||
|
|
||||||
/* TODO: beautify the log message.
|
/* TODO: beautify the log message.
|
||||||
* do classification based on mask. */
|
* do classification based on mask. */
|
||||||
|
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
char ts[32];
|
||||||
|
struct tm tm;
|
||||||
|
time_t now;
|
||||||
|
now = time(NULL);
|
||||||
|
localtime_r (&now, &tm);
|
||||||
|
strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", &tm);
|
||||||
|
write (1, ts, strlen(ts));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
msgidx = 0;
|
||||||
while (len > 0)
|
while (len > 0)
|
||||||
{
|
{
|
||||||
ucslen = len;
|
ucslen = len;
|
||||||
bcslen = STIX_COUNTOF(buf);
|
bcslen = STIX_COUNTOF(buf);
|
||||||
|
|
||||||
n = stix_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen);
|
n = stix_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen);
|
||||||
if (n == 0)
|
if (n == 0 || n == -2)
|
||||||
{
|
{
|
||||||
write (1, buf, bcslen); /* TODO: write all */
|
stix_oow_t rem;
|
||||||
|
const stix_bch_t* ptr;
|
||||||
|
/* n = 0:
|
||||||
|
* converted all successfully
|
||||||
|
* n == -2:
|
||||||
|
* buffer not sufficient. not all got converted yet.
|
||||||
|
* write what have been converted this round. */
|
||||||
|
|
||||||
|
STIX_ASSERT (ucslen > 0); /* if this fails, the buffer size must be increased */
|
||||||
|
|
||||||
|
/* attempt to write all converted characters */
|
||||||
|
rem = bcslen;
|
||||||
|
ptr = buf;
|
||||||
|
while (rem > 0)
|
||||||
|
{
|
||||||
|
stix_ooi_t wr;
|
||||||
|
|
||||||
|
wr = write (1, ptr, rem); /* TODO: write all */
|
||||||
|
if (wr <= -1)
|
||||||
|
{
|
||||||
|
/*if (errno == EAGAIN || errno == EWOULDBLOCK)
|
||||||
|
{
|
||||||
|
push it to internal buffers? before writing data just converted, need to write buffered data first.
|
||||||
|
}*/
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (n == -2)
|
|
||||||
|
ptr += wr;
|
||||||
|
rem -= wr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n == 0) break;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
STIX_ASSERT (ucslen > 0); /* if this fails, the buffer size must be increased */
|
|
||||||
write (1, buf, bcslen); /* TODO: write all */
|
|
||||||
msgidx += ucslen;
|
msgidx += ucslen;
|
||||||
len -= ucslen;
|
len -= ucslen;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (n <= -1)
|
else if (n <= -1)
|
||||||
{
|
{
|
||||||
/* conversion error */
|
/* conversion error */
|
||||||
|
@ -407,7 +407,7 @@ struct stix_class_t
|
|||||||
stix_oop_char_t classinstvars; /* String */
|
stix_oop_char_t classinstvars; /* String */
|
||||||
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
|
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
|
||||||
|
|
||||||
stix_oop_char_t pooldics; /* String */
|
stix_oop_char_t pooldics; /* String - pool dictionaries imported */
|
||||||
|
|
||||||
/* [0] - instance methods, MethodDictionary
|
/* [0] - instance methods, MethodDictionary
|
||||||
* [1] - class methods, MethodDictionary */
|
* [1] - class methods, MethodDictionary */
|
||||||
@ -678,7 +678,7 @@ typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_ooch_t* name);
|
|||||||
typedef void (*stix_mod_close_t) (stix_t* stix, void* handle);
|
typedef void (*stix_mod_close_t) (stix_t* stix, void* handle);
|
||||||
typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name);
|
typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name);
|
||||||
|
|
||||||
typedef void (*stix_log_write_t) (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len);
|
typedef void (*stix_log_write_t) (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len);
|
||||||
|
|
||||||
struct stix_vmprim_t
|
struct stix_vmprim_t
|
||||||
{
|
{
|
||||||
@ -1134,14 +1134,14 @@ STIX_EXPORT void stix_freemem (
|
|||||||
|
|
||||||
STIX_EXPORT stix_ooi_t stix_logbfmt (
|
STIX_EXPORT stix_ooi_t stix_logbfmt (
|
||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
unsigned int mask,
|
stix_oow_t mask,
|
||||||
const stix_bch_t* fmt,
|
const stix_bch_t* fmt,
|
||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
|
||||||
STIX_EXPORT stix_ooi_t stix_logoofmt (
|
STIX_EXPORT stix_ooi_t stix_logoofmt (
|
||||||
stix_t* stix,
|
stix_t* stix,
|
||||||
unsigned int mask,
|
stix_oow_t mask,
|
||||||
const stix_ooch_t* fmt,
|
const stix_ooch_t* fmt,
|
||||||
...
|
...
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user