diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index d1638ab..4305d6b 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -76,6 +76,29 @@ class(#pointer) Array(Collection) { 0 priorTo: (anArray basicSize) do: [:i | self at: i put: (anArray at: i) ]. } + + method = anArray + { + | size i | + if (self class ~~ anArray class) { ^false }. + + size := self size. + if (size ~~ anArray size) { ^false }. + + i := 0. + while (i < size) + { + if ((self at: i) ~= (anArray at: i)) { ^false }. + i := i + 1. + }. + + ^true. + } + + method ~= anArray + { + ^(self = anArray) not + } } ## ------------------------------------------------------------------------------- diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 9c80d6f..deaaae7 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -62,46 +62,11 @@ class Semaphore(Object) var(#get,#set) _group := nil. - method(#class) forMutualExclusion - { - | sem | - sem := self new. - sem signal. - ^sem - } - ## ================================================================== method(#primitive) signal. method(#primitive) wait. -(* -TODO: timed wait... - method waitWithTimeout: seconds - { - | s | - s := Semaphore new. - Processor signal: s after: seconds. - self waitWithTimedSemaphore: s. - - if (self. - } - - method waitWithTimeout: seconds and: nanoSeconds - { - - self primitiveFailed - } -*) - - (* TODO: MIGRATE TO MUTEX... - method critical: aBlock - { - self wait. - ^aBlock ensure: [ self signal ] - }*) - - ## ================================================================== method heapIndex @@ -145,8 +110,14 @@ class Mutex(Semaphore) ^s. } - method lock { ^self wait } - method unlock { ^self signal } +(* +TODO: how to prohibit wait and signal??? + method(#prohibited) wait. + method(#prohibited) signal. +*) + + method lock { ^super wait } + method unlock { ^super signal } method critical: block { diff --git a/moo/kernel/test-002.moo b/moo/kernel/test-002.moo index a33fe24..2e3349d 100644 --- a/moo/kernel/test-002.moo +++ b/moo/kernel/test-002.moo @@ -49,6 +49,42 @@ class MyObject(Object) ^true } + method(#class) test_mutex + { + | mtx sem v p q | + + mtx := Mutex new. + sem := Semaphore new. + + p := 0. + + [ mtx lock. + v := 0. + 2000 timesRepeat: [v := v + 1. p := p + 1. ]. + q := v. + mtx unlock. + sem signal. + ] fork. + + [ mtx critical: [ + v := 0. + 2000 timesRepeat: [v := v + 1. p := p + 1. ]. + q := v. + ]. + sem signal. + ] fork. + + mtx lock. + v := 0. + 2000 timesRepeat: [v := v + 1. p := p + 1. ]. + mtx unlock. + + sem wait. + sem wait. + + ^%( v, p ) ## v must be 2000, p must be 6000 + } + method(#class) main { | tc limit | @@ -57,7 +93,8 @@ class MyObject(Object) ## 0 - 4 [ self proc1 == 100 ], [ Processor sleepFor: 2. self proc1 == 200 ], - [ self test_semaphore_heap == true ] + [ self test_semaphore_heap == true ], + [ self test_mutex = #(2000 6000) ] ). limit := tc size. diff --git a/moo/kernel/test-003.moo b/moo/kernel/test-003.moo index 2fe42fa..db713a4 100644 --- a/moo/kernel/test-003.moo +++ b/moo/kernel/test-003.moo @@ -67,16 +67,19 @@ class MyObject(TestObject) [(Apex isKindOf: Class) == true], [(Apex isKindOf: Apex) == true], [(SmallInteger isKindOf: Integer) == false], - [(10 isKindOf: Integer) == true], - [(10 isKindOf: 20) == false], + [(SmallInteger isKindOf: SmallInteger) == false], + [(Object isKindOf: SmallInteger) == false], ## 10-14 + [(10 isKindOf: Integer) == true], + [(10 isKindOf: 20) == false], [([] isKindOf: BlockContext) == true], [([] isKindOf: MethodContext) == false], [([] isKindOf: Context) == true], + + ## 15-20 [('string' isKindOf: String) == true], [(#symbol isKindOf: String) == true], - [('string' isKindOf: Symbol) == false], [(#symbol isKindOf: Symbol) == true] ). diff --git a/moo/lib/exec.c b/moo/lib/exec.c index f1ab703..adf4dde 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -494,8 +494,8 @@ static MOO_INLINE void chain_into_semaphore (moo_t* moo, moo_oop_process_t proc, MOO_ASSERT (moo, (moo_oop_t)proc->sem_wait.next == moo->_nil); /* a semaphore or a semaphore group must be given for process chaining */ - MOO_ASSERT (moo, MOO_CLASSOF(moo,sem) == moo->_semaphore || - MOO_CLASSOF(moo,sem) == moo->_semaphore_group); + MOO_ASSERT (moo, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore) || + moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore_group)); /* i assume the head part of the semaphore has the same layout as * the semaphore group */ @@ -513,8 +513,8 @@ static MOO_INLINE void unchain_from_semaphore (moo_t* moo, moo_oop_process_t pro MOO_ASSERT (moo, (moo_oop_t)proc->sem != moo->_nil); - MOO_ASSERT (moo, MOO_CLASSOF(moo, proc->sem) == moo->_semaphore || - MOO_CLASSOF(moo, proc->sem) == moo->_semaphore_group); + MOO_ASSERT (moo, moo_iskindof(moo, proc->sem, moo->_semaphore) || + moo_iskindof(moo, proc->sem, moo->_semaphore_group)); MOO_ASSERT (moo, MOO_OFFSETOF(moo_semaphore_t,waiting) == MOO_OFFSETOF(moo_semaphore_group_t,waiting)); @@ -859,7 +859,7 @@ static MOO_INLINE moo_oop_t await_semaphore_group (moo_t* moo, moo_oop_semaphore moo_oop_semaphore_t sem; moo_ooi_t numsems, sempos, i, count; - MOO_ASSERT (moo, MOO_CLASSOF(moo,semgrp) == moo->_semaphore_group); + MOO_ASSERT (moo, moo_iskindof(moo, (moo_oop_t)semgrp, moo->_semaphore_group)); /* check if there is a signaled semaphore in the group */ numsems = MOO_OOP_TO_SMOOI(semgrp->size); @@ -1673,15 +1673,10 @@ static moo_pfrc_t pf_not_identical (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs) +static int _equal_objects (moo_t* moo, moo_oop_t rcv, moo_oop_t arg) { - moo_oop_t rcv, arg; int rtag; - MOO_ASSERT (moo, nargs == 1); - - rcv = MOO_STACK_GETRCV(moo, nargs); - arg = MOO_STACK_GETARG(moo, nargs, 0); if (rcv == arg) return 1; /* identical. so equal */ rtag = MOO_OOP_GET_TAG(rcv); @@ -1721,18 +1716,33 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs) case MOO_OBJ_TYPE_CHAR: case MOO_OBJ_TYPE_HALFWORD: case MOO_OBJ_TYPE_WORD: - return (MOO_MEMCMP (((moo_oop_byte_t)rcv)->slot, ((moo_oop_byte_t)arg)->slot, MOO_BYTESOF(moo,rcv)) == 0)? 1: 0; + return (MOO_MEMCMP (MOO_OBJ_GET_BYTE_SLOT(rcv), MOO_OBJ_GET_BYTE_SLOT(arg), MOO_BYTESOF(moo,rcv)) == 0)? 1: 0; default: + { if (rcv == moo->_nil) return arg == moo->_nil? 1: 0; if (rcv == moo->_true) return arg == moo->_true? 1: 0; if (rcv == moo->_false) return arg == moo->_false? 1: 0; - - /* MOO_OBJ_TYPE_OOP, ... */ - MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv)); + /* MOO_OBJ_TYPE_OOP, ... */ + MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_TYPE(rcv) == MOO_OBJ_TYPE_OOP); + + #if 1 + MOO_DEBUG1 (moo, "<_equal_objects> Cannot compare objects of type %d\n", (int)MOO_OBJ_GET_FLAGS_TYPE(rcv)); moo_seterrnum (moo, MOO_ENOIMPL); /* TODO: better error code */ return -1; + #else + for (i = 0; i < MOO_OBJ_GET_SIZE(rcv); i++) + { + /* TODO: remove recursion */ + + /* NOTE: even if the object implements the equality method, + * this primitive method doesn't honor it. */ + if (!_equal_objects(moo, ((moo_oop_oop_t)rcv)->slot[i], ((moo_oop_oop_t)arg)->slot[i])) return 0; + } + return 1; + #endif + } } } } @@ -1740,9 +1750,13 @@ static moo_pfrc_t _equal_objects (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs) { + moo_oop_t rcv, arg; int n; - n = _equal_objects (moo, nargs); + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + n = _equal_objects (moo, rcv, arg); if (n <= -1) return MOO_PF_FAILURE; MOO_STACK_SETRET (moo, nargs, (n? moo->_true: moo->_false)); @@ -1751,9 +1765,13 @@ static moo_pfrc_t pf_equal (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs) { + moo_oop_t rcv, arg; int n; - n = _equal_objects (moo, nargs); + rcv = MOO_STACK_GETRCV(moo, nargs); + arg = MOO_STACK_GETARG(moo, nargs, 0); + + n = _equal_objects (moo, rcv, arg); if (n <= -1) return MOO_PF_FAILURE; MOO_STACK_SETRET (moo, nargs, (n? moo->_false: moo->_true)); @@ -2588,7 +2606,7 @@ static moo_pfrc_t pf_processor_add_gcfin_semaphore (moo_t* moo, moo_ooi_t nargs) MOO_ASSERT (moo, nargs == 1); sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0); - MOO_PF_CHECK_ARGS (moo, nargs, MOO_CLASSOF(moo,sem) == moo->_semaphore); + MOO_PF_CHECK_ARGS (moo, nargs, moo_iskindof(moo, (moo_oop_t)sem, moo->_semaphore)); /* TODO: no overwriting.. */ moo->sem_gcfin = sem; diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index f72dd59..776aec0 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -359,7 +359,7 @@ struct moo_iotok_t MOO_IOTOK_RPAREN, MOO_IOTOK_HASHPAREN, /* #( - array literal */ MOO_IOTOK_HASHBRACK, /* #[ - byte array literal */ - MOO_IOTOK_PERCPAREN, /* %{ - array expression */ + MOO_IOTOK_PERCPAREN, /* %( - array expression */ MOO_IOTOK_PERCBRACE, /* %{ - dictionary expression */ MOO_IOTOK_PERIOD, MOO_IOTOK_COMMA,