From be677dd53a7beda418595c595cc2e0d7a8825ebe Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Wed, 15 Feb 2017 11:57:24 +0000 Subject: [PATCH] added partial experimental code for io event handling --- moo/kernel/Process.moo | 17 +++-- moo/lib/bigint.c | 14 ++-- moo/lib/comp.c | 2 +- moo/lib/dic.c | 8 +-- moo/lib/exec.c | 141 ++++++++++++++++++++++++++++++----------- moo/lib/gc.c | 22 +++---- moo/lib/logfmt.c | 12 ++-- moo/lib/main.c | 60 ++++++++++++++---- moo/lib/moo-prv.h | 9 ++- moo/lib/moo.c | 70 ++++++++++---------- moo/lib/moo.h | 93 +++++++++++++-------------- moo/lib/obj.c | 25 ++++---- moo/lib/sym.c | 2 +- moo/mod/ffi.c | 2 +- moo/mod/stdio.c | 2 +- moo/mod/x11.c | 100 ++++++++++++++++++++++------- 16 files changed, 368 insertions(+), 211 deletions(-) diff --git a/moo/kernel/Process.moo b/moo/kernel/Process.moo index 6776009..638d761 100644 --- a/moo/kernel/Process.moo +++ b/moo/kernel/Process.moo @@ -426,12 +426,21 @@ class ProcessScheduler(Object) self primitiveFailed. } - "method signal: semaphore onInput: file + method signal: semaphore onInput: file { - }" - "method signal: semaphore onOutput: file + + self primitiveFailed. + } + method signal: semaphore onOutput: file { - }" + + self primitiveFailed. + } + method signal: semaphore onInOutput: file + { + + self primitiveFailed. + } method return: object to: context { diff --git a/moo/lib/bigint.c b/moo/lib/bigint.c index a8e7daa..9b0ca8a 100644 --- a/moo/lib/bigint.c +++ b/moo/lib/bigint.c @@ -209,7 +209,7 @@ static int is_normalized_integer (moo_t* moo, moo_oop_t oop) if (MOO_OOP_IS_SMOOI(oop)) return 1; if (MOO_OOP_IS_POINTER(oop)) { - moo_oop_t c; + moo_oop_class_t c; /* TODO: is it better to introduce a special integer mark into the class itself */ /* TODO: or should it check if it's a subclass, subsubclass, subsubsubclass, etc of a large_integer as well? */ c = MOO_OBJ_GET_CLASS(oop); @@ -231,7 +231,7 @@ static int is_normalized_integer (moo_t* moo, moo_oop_t oop) MOO_INLINE static int is_bigint (moo_t* moo, moo_oop_t x) { - moo_oop_t c; + moo_oop_class_t c; MOO_ASSERT (moo, MOO_OOP_IS_POINTER(x)); @@ -540,7 +540,7 @@ static MOO_INLINE moo_oop_t expand_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t } -static MOO_INLINE moo_oop_t _clone_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t count, moo_oop_t _class) +static MOO_INLINE moo_oop_t _clone_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t count, moo_oop_class_t _class) { moo_oop_t z; moo_oow_t i; @@ -567,20 +567,20 @@ static MOO_INLINE moo_oop_t clone_bigint (moo_t* moo, moo_oop_t oop, moo_oow_t c static MOO_INLINE moo_oop_t clone_bigint_negated (moo_t* moo, moo_oop_t oop, moo_oow_t count) { - moo_oop_t c; + moo_oop_class_t _class; MOO_ASSERT (moo, MOO_OOP_IS_POINTER(oop)); if (MOO_OBJ_GET_CLASS(oop) == moo->_large_positive_integer) { - c = moo->_large_negative_integer; + _class = moo->_large_negative_integer; } else { MOO_ASSERT (moo, MOO_OBJ_GET_CLASS(oop) == moo->_large_negative_integer); - c = moo->_large_positive_integer; + _class = moo->_large_positive_integer; } - return _clone_bigint (moo, oop, count, c); + return _clone_bigint (moo, oop, count, _class); } static MOO_INLINE moo_oop_t clone_bigint_to_positive (moo_t* moo, moo_oop_t oop, moo_oow_t count) diff --git a/moo/lib/comp.c b/moo/lib/comp.c index 6a1d074..749d739 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -6341,7 +6341,7 @@ static int __compile_class_definition (moo_t* moo, int extend) if (modnamelen > 0) { - if (moo_importmod (moo, (moo_oop_t)moo->c->cls.self_oop, modname, modnamelen) <= -1) return -1; + if (moo_importmod (moo, moo->c->cls.self_oop, modname, modnamelen) <= -1) return -1; } if (moo->c->cls.self_oop->trsize == moo->_nil && diff --git a/moo/lib/dic.c b/moo/lib/dic.c index 0b78fa5..e024e13 100644 --- a/moo/lib/dic.c +++ b/moo/lib/dic.c @@ -74,7 +74,7 @@ static moo_oop_oop_t expand_bucket (moo_t* moo, moo_oop_oop_t oldbuc) MOO_ASSERT (moo, MOO_CLASSOF(moo,ass) == moo->_association); key = (moo_oop_char_t)ass->key; - MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == (moo_oop_t)moo->_symbol); + MOO_ASSERT (moo, MOO_CLASSOF(moo,key) == moo->_symbol); index = moo_hashoochars(key->slot, MOO_OBJ_GET_SIZE(key)) % newsz; while (newbuc->slot[index] != moo->_nil) index = (index + 1) % newsz; @@ -334,14 +334,14 @@ found: return 0; } -moo_oop_set_t moo_makedic (moo_t* moo, moo_oop_t cls, moo_oow_t size) +moo_oop_set_t moo_makedic (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) { moo_oop_set_t dic; moo_oop_t tmp; - MOO_ASSERT (moo, MOO_CLASSOF(moo,cls) == moo->_class); + MOO_ASSERT (moo, MOO_CLASSOF(moo,_class) == moo->_class); - dic = (moo_oop_set_t)moo_instantiate (moo, cls, MOO_NULL, 0); + dic = (moo_oop_set_t)moo_instantiate (moo, _class, MOO_NULL, 0); if (!dic) return MOO_NULL; MOO_ASSERT (moo, MOO_OBJ_GET_SIZE(dic) == MOO_SET_NAMED_INSTVARS); diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 79b99db..ecce7ea 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -107,6 +107,8 @@ # define __PRIMITIVE_NAME__ (&__FUNCTION__[4]) #endif +static void signal_io_semaphore (moo_t* moo, int mask, void* ctx); + /* ------------------------------------------------------------------------- */ static MOO_INLINE int vm_startup (moo_t* moo) { @@ -139,7 +141,7 @@ static MOO_INLINE void vm_sleep (moo_t* moo, const moo_ntime_t* dur) static MOO_INLINE void vm_mux_wait (moo_t* moo, const moo_ntime_t* dur) { - moo->vmprim.mux_wait (moo, dur); + moo->vmprim.mux_wait (moo, dur, signal_io_semaphore); } /* ------------------------------------------------------------------------- */ @@ -741,6 +743,7 @@ static void update_sem_heap (moo_t* moo, moo_ooi_t index, moo_oop_semaphore_t ne static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem) { moo_ooi_t index; + int n; if (moo->sem_io_count >= SEM_IO_MAX) { @@ -764,18 +767,24 @@ static int add_to_sem_io (moo_t* moo, moo_oop_semaphore_t sem) } MOO_ASSERT (moo, moo->sem_io_count <= MOO_SMOOI_MAX); - - if (moo->vmprim.mux_add (moo) <= -1) /*TODO: pass data */ - { - return -1; - } + MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1)); index = moo->sem_io_count; moo->sem_io[index] = sem; - sem->heap_index = MOO_SMOOI_TO_OOP(index); + sem->io_index = MOO_SMOOI_TO_OOP(index); moo->sem_io_count++; - return 0; + moo_pushtmp (moo, (moo_oop_t*)&sem); + n = moo->vmprim.mux_add (moo, sem); + moo_poptmp (moo); + if (n <= -1) + { + /* roll back */ + sem->io_index = MOO_SMOOI_TO_OOP(-1); + moo->sem_io_count--; + } +MOO_DEBUG1 (moo, "ADDED TO SEM IO => sem_io_count => %d\n", (int)moo->sem_io_count); + return n; } static void delete_from_sem_io (moo_t* moo, moo_ooi_t index) @@ -784,10 +793,11 @@ static void delete_from_sem_io (moo_t* moo, moo_ooi_t index) moo_oop_semaphore_t sem, lastsem; sem = moo->sem_io[index]; + moo_pushtmp (moo, (moo_oop_t*)&sem); + moo->vmprim.mux_del (moo, sem); + moo_poptmp (moo); sem->io_index = MOO_SMOOI_TO_OOP(-1); - moo->vmprim.mux_del (moo); /* TODO: pass data... */ - moo->sem_io_count--; if (moo->sem_io_count > 0 && index != moo->sem_io_count) { @@ -798,6 +808,41 @@ static void delete_from_sem_io (moo_t* moo, moo_ooi_t index) } } + +static void signal_io_semaphore (moo_t* moo, int mask, void* ctx) +{ + moo_oow_t sem_io_index = (moo_oow_t)ctx; + +/* TODO: sanity check on the index. conditional handling on mask */ + if (sem_io_index < moo->sem_io_count) + { + moo_oop_semaphore_t sem; + moo_oop_process_t proc; + + sem = moo->sem_io[sem_io_index]; + proc = signal_semaphore (moo, sem); + + if (moo->processor->active == moo->nil_process && (moo_oop_t)proc != moo->_nil) + { + /* this is the only runnable process. + * switch the process to the running state. + * it uses wake_new_process() instead of + * switch_to_process() as there is no running + * process at this moment */ + MOO_ASSERT (moo, proc->state == MOO_SMOOI_TO_OOP(PROC_STATE_RUNNABLE)); + MOO_ASSERT (moo, proc == moo->processor->runnable_head); + + wake_new_process (moo, proc); /* switch to running */ + moo->proc_switched = 1; + } + } + else + { + MOO_LOG1 (moo, MOO_LOG_WARN, "Warning - Invalid semaphore index %zu\n", sem_io_index); + } +} +/* ------------------------------------------------------------------------- */ + static moo_oop_process_t start_initial_process (moo_t* moo, moo_oop_context_t c) { moo_oop_process_t proc; @@ -949,8 +994,8 @@ static moo_oop_method_t find_method (moo_t* moo, moo_oop_t receiver, const moo_o int dic_no; /* TODO: implement method lookup cache */ - cls = (moo_oop_class_t)MOO_CLASSOF(moo, receiver); - if ((moo_oop_t)cls == moo->_class) + cls = MOO_CLASSOF(moo, receiver); + if (cls == moo->_class) { /* receiver is a class object (an instance of Class) */ c = receiver; @@ -997,7 +1042,7 @@ static moo_oop_method_t find_method (moo_t* moo, moo_oop_t receiver, const moo_o while (c != moo->_nil); not_found: - if ((moo_oop_t)cls == moo->_class) + if (cls == moo->_class) { /* the object is an instance of Class. find the method * in an instance method dictionary of Class also */ @@ -1189,7 +1234,8 @@ static moo_pfrc_t pf_log (moo_t* moo, moo_ooi_t nargs) else if (MOO_OBJ_GET_FLAGS_TYPE(msg) == MOO_OBJ_TYPE_OOP) { /* visit only 1-level down into an array-like object */ - moo_oop_t inner, _class; + moo_oop_t inner; + moo_oop_class_t _class; moo_oow_t i, spec; _class = MOO_CLASSOF(moo, msg); @@ -1339,23 +1385,25 @@ static moo_pfrc_t pf_not_equal (moo_t* moo, moo_ooi_t nargs) static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs) { - moo_oop_t rcv, c; + moo_oop_t rcv; + moo_oop_class_t _class; MOO_ASSERT (moo, nargs == 0); rcv = MOO_STACK_GETRCV(moo, nargs); - c = MOO_CLASSOF(moo, rcv); + _class = MOO_CLASSOF(moo, rcv); - MOO_STACK_SETRET (moo, nargs, c); + MOO_STACK_SETRET (moo, nargs, (moo_oop_t)_class); return MOO_PF_SUCCESS; } static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) { - moo_oop_t _class, szoop, obj; + moo_oop_class_t _class; + moo_oop_t szoop, obj; moo_oow_t size = 0; /* size of the variable/indexed part */ - _class = MOO_STACK_GETRCV(moo, nargs); + _class = (moo_oop_class_t)MOO_STACK_GETRCV(moo, nargs); if (MOO_CLASSOF(moo, _class) != moo->_class) { /* the receiver is not a class object */ @@ -2091,24 +2139,20 @@ static moo_pfrc_t pf_processor_add_timed_semaphore (moo_t* moo, moo_ooi_t nargs) return MOO_PF_SUCCESS; } -static moo_pfrc_t pf_processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t __processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs, int mask) { - moo_oop_t rcv, sec, nsec; + moo_oop_t rcv, fd; moo_oop_semaphore_t sem; - MOO_ASSERT (moo, nargs == 3); + MOO_ASSERT (moo, nargs == 2); - nsec = MOO_STACK_GETARG (moo, nargs, 2); - if (!MOO_OOP_IS_SMOOI(nsec)) return MOO_PF_FAILURE; - - sec = MOO_STACK_GETARG(moo, nargs, 1); + fd = MOO_STACK_GETARG(moo, nargs, 1); sem = (moo_oop_semaphore_t)MOO_STACK_GETARG(moo, nargs, 0); rcv = MOO_STACK_GETRCV(moo, nargs); - /* ProcessScheduler>>signal:after: calls this primitive function. */ if (rcv != (moo_oop_t)moo->processor || MOO_CLASSOF(moo,sem) != moo->_semaphore || - !MOO_OOP_IS_SMOOI(sec)) return MOO_PF_FAILURE; + !MOO_OOP_IS_SMOOI(fd)) return MOO_PF_FAILURE; if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1)) @@ -2118,15 +2162,29 @@ static moo_pfrc_t pf_processor_add_io_semaphore (moo_t* moo, moo_ooi_t nargs) MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1)); } -/* TOOD: sanity check on argument 2 and 3 */ - sem->io_data = MOO_STACK_GETARG(moo, nargs, 1); - sem->io_mask = MOO_STACK_GETARG(moo, nargs, 2); - if (add_to_sem_io (moo, sem) <= -1) return MOO_PF_HARD_FAILURE; + sem->io_handle = fd; + sem->io_mask = MOO_SMOOI_TO_OOP(mask); + if (add_to_sem_io (moo, sem) <= -1) return MOO_PF_HARD_FAILURE; /*TODO: let it return SUCESS but SETRET(error()); */ MOO_STACK_SETRETTORCV (moo, nargs); /* ^self */ return MOO_PF_SUCCESS; } +static moo_pfrc_t pf_processor_add_input_semaphore (moo_t* moo, moo_ooi_t nargs) +{ + return __processor_add_io_semaphore (moo, nargs, 1); +} + +static moo_pfrc_t pf_processor_add_output_semaphore (moo_t* moo, moo_ooi_t nargs) +{ + return __processor_add_io_semaphore (moo, nargs, 2); +} + +static moo_pfrc_t pf_processor_add_inoutput_semaphore (moo_t* moo, moo_ooi_t nargs) +{ + return __processor_add_io_semaphore (moo, nargs, 3); +} + static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs) { /* remove a semaphore from processor's signal scheduling */ @@ -2156,7 +2214,7 @@ static moo_pfrc_t pf_processor_remove_semaphore (moo_t* moo, moo_ooi_t nargs) if (MOO_OOP_IS_SMOOI(sem->io_index) && sem->io_index != MOO_SMOOI_TO_OOP(-1)) { - delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->heap_index)); + delete_from_sem_io (moo, MOO_OOP_TO_SMOOI(sem->io_index)); MOO_ASSERT (moo, sem->io_index == MOO_SMOOI_TO_OOP(-1)); } @@ -2672,7 +2730,9 @@ static pf_t pftab[] = { 1, 1, pf_processor_schedule, "_processor_schedule" }, { 2, 3, pf_processor_add_timed_semaphore, "_processor_add_timed_semaphore" }, - { 3, 3, pf_processor_add_io_semaphore, "_processor_add_io_semaphore" }, + { 2, 2, pf_processor_add_input_semaphore, "_processor_add_input_semaphore" }, + { 2, 2, pf_processor_add_output_semaphore, "_processor_add_output_semaphore" }, + { 2, 2, pf_processor_add_inoutput_semaphore, "_processor_add_inoutput_semaphore" }, { 1, 1, pf_processor_remove_semaphore, "_processor_remove_semaphore" }, { 2, 2, pf_processor_return_to, "_processor_return_to" }, @@ -2710,6 +2770,7 @@ int moo_getpfnum (moo_t* moo, const moo_ooch_t* ptr, moo_oow_t len) { int i; +/* TODO: have the pftable sorted alphabetically and do binary search */ for (i = 0; i < MOO_COUNTOF(pftab); i++) { if (moo_compoocharsbcstr(ptr, len, pftab[i].name) == 0) @@ -3096,9 +3157,15 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) MOO_SUBNTIME (&ft, &ft, (moo_ntime_t*)&now); if (moo->sem_io_count > 0) + { +MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_WAIT()\n"); vm_mux_wait (moo, &ft); + } else - vm_sleep (moo, &ft); /* TODO: change this to i/o multiplexer??? */ + { +MOO_DEBUG0 (moo, "ABOUT TO CALL VM_MUX_SLEEP()\n"); + vm_sleep (moo, &ft); + } vm_gettime (moo, &now); } else @@ -3106,7 +3173,7 @@ static MOO_INLINE int switch_process_if_needed (moo_t* moo) /* there is a running process. go on */ break; } - } + } while (moo->sem_heap_count > 0 && !moo->abort_req); } @@ -3795,7 +3862,7 @@ int moo_execute (moo_t* moo) t = (moo_oop_t)moo_makedic (moo, moo->_dictionary, b1 + 10); MOO_STACK_PUSH (moo, t); */ - MOO_STACK_PUSH (moo, moo->_dictionary); + MOO_STACK_PUSH (moo, (moo_oop_t)moo->_dictionary); MOO_STACK_PUSH (moo, MOO_SMOOI_TO_OOP(b1)); if (send_message (moo, moo->dicnewsym, 0, 1) <= -1) goto oops; break; diff --git a/moo/lib/gc.c b/moo/lib/gc.c index d0107e7..8ff5cab 100644 --- a/moo/lib/gc.c +++ b/moo/lib/gc.c @@ -120,7 +120,7 @@ static kernel_class_info_t kernel_classes[] = * BOOTSTRAPPER * ----------------------------------------------------------------------- */ -static moo_oop_t alloc_kernel_class (moo_t* moo, moo_oow_t indexed_classvars, moo_oow_t spec) +static moo_oop_class_t alloc_kernel_class (moo_t* moo, moo_oow_t indexed_classvars, moo_oow_t spec) { moo_oop_class_t c; @@ -128,11 +128,11 @@ static moo_oop_t alloc_kernel_class (moo_t* moo, moo_oow_t indexed_classvars, mo if (!c) return MOO_NULL; MOO_OBJ_SET_FLAGS_KERNEL (c, 1); - MOO_OBJ_SET_CLASS (c, moo->_class); + MOO_OBJ_SET_CLASS (c, (moo_oop_t)moo->_class); c->spec = MOO_SMOOI_TO_OOP(spec); c->selfspec = MOO_SMOOI_TO_OOP(MOO_CLASS_SELFSPEC_MAKE(indexed_classvars, 0)); - return (moo_oop_t)c; + return c; } static int ignite_1 (moo_t* moo) @@ -154,7 +154,7 @@ static int ignite_1 (moo_t* moo) if (!moo->_class) return -1; MOO_ASSERT (moo, MOO_OBJ_GET_CLASS(moo->_class) == MOO_NULL); - MOO_OBJ_SET_CLASS (moo->_class, moo->_class); + MOO_OBJ_SET_CLASS (moo->_class, (moo_oop_t)moo->_class); /* -------------------------------------------------------------- * Apex - proto-object with 1 class variable. @@ -220,7 +220,7 @@ static int ignite_1 (moo_t* moo) !moo->_character || !moo->_small_integer || !moo->_large_positive_integer || !moo->_large_negative_integer) return -1; - MOO_OBJ_SET_CLASS (moo->_nil, moo->_undefined_object); + MOO_OBJ_SET_CLASS (moo->_nil, (moo_oop_t)moo->_undefined_object); return 0; } @@ -268,7 +268,7 @@ static int ignite_2 (moo_t* moo) moo->processor->active = moo->nil_process; /* Export the system dictionary via the first class variable of the Stix class */ - ((moo_oop_class_t)moo->_apex)->slot[0] = (moo_oop_t)moo->sysdic; + moo->_apex->slot[0] = (moo_oop_t)moo->sysdic; return 0; } @@ -309,11 +309,11 @@ static int ignite_3 (moo_t* moo) sym = moo_makesymbol (moo, str_dicnew, MOO_COUNTOF(str_dicnew)); if (!sym) return -1; - moo->dicnewsym = sym; + moo->dicnewsym = (moo_oop_char_t)sym; sym = moo_makesymbol (moo, str_dicputassoc, MOO_COUNTOF(str_dicputassoc)); if (!sym) return -1; - moo->dicputassocsym = sym; + moo->dicputassocsym = (moo_oop_char_t)sym; return 0; } @@ -459,7 +459,7 @@ moo_oop_t moo_moveoop (moo_t* moo, moo_oop_t oop) * the class field has been updated to the new object * in the 'else' block below. i can simply return it * without further migration. */ - return MOO_OBJ_GET_CLASS(oop); + return (moo_oop_t)MOO_OBJ_GET_CLASS(oop); } else { @@ -527,7 +527,7 @@ static moo_uint8_t* scan_new_heap (moo_t* moo, moo_uint8_t* ptr) } #endif - MOO_OBJ_SET_CLASS (oop, moo_moveoop(moo, MOO_OBJ_GET_CLASS(oop))); + MOO_OBJ_SET_CLASS (oop, moo_moveoop(moo, (moo_oop_t)MOO_OBJ_GET_CLASS(oop))); if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_OOP) { moo_oop_oop_t xtmp; @@ -732,7 +732,7 @@ moo_oop_t moo_shallowcopy (moo_t* moo, moo_oop_t oop) moo_oop_t z; moo_oop_class_t c; - c = (moo_oop_class_t)MOO_OBJ_GET_CLASS(oop); + c = MOO_OBJ_GET_CLASS(oop); moo_pushtmp (moo, &oop); z = moo_instantiate (moo, (moo_oop_t)c, MOO_NULL, MOO_OBJ_GET_SIZE(oop) - MOO_CLASS_SPEC_NAMED_INSTVAR(MOO_OOP_TO_SMOOI(c->spec))); moo_poptmp(moo); diff --git a/moo/lib/logfmt.c b/moo/lib/logfmt.c index cfbb08f..4cf96f8 100644 --- a/moo/lib/logfmt.c +++ b/moo/lib/logfmt.c @@ -328,7 +328,7 @@ static void print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop) MOO_ASSERT (moo, MOO_OOP_IS_POINTER(oop)); c = (moo_oop_class_t)MOO_OBJ_GET_CLASS(oop); /*MOO_CLASSOF(moo, oop);*/ - if ((moo_oop_t)c == moo->_large_negative_integer) + if (c == moo->_large_negative_integer) { moo_oow_t i; moo_logbfmt (moo, mask, "-16r"); @@ -337,7 +337,7 @@ static void print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop) moo_logbfmt (moo, mask, "%0*lX", (int)(MOO_SIZEOF(moo_liw_t) * 2), (unsigned long)((moo_oop_liword_t)oop)->slot[--i]); } } - else if ((moo_oop_t)c == moo->_large_positive_integer) + else if (c == moo->_large_positive_integer) { moo_oow_t i; moo_logbfmt (moo, mask, "16r"); @@ -348,7 +348,7 @@ static void print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop) } else if (MOO_OBJ_GET_FLAGS_TYPE(oop) == MOO_OBJ_TYPE_CHAR) { - if ((moo_oop_t)c == moo->_symbol) + if (c == moo->_symbol) { moo_logbfmt (moo, mask, "#%.*js", MOO_OBJ_GET_SIZE(oop), ((moo_oop_char_t)oop)->slot); } @@ -455,7 +455,7 @@ static void print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop) } moo_logbfmt (moo, mask, "]]]"); } - else if ((moo_oop_t)c == moo->_array) + else if (c == moo->_array) { moo_logbfmt (moo, mask, "#("); for (i = 0; i < MOO_OBJ_GET_SIZE(oop); i++) @@ -465,12 +465,12 @@ static void print_object (moo_t* moo, moo_oow_t mask, moo_oop_t oop) } moo_logbfmt (moo, mask, ")"); } - else if ((moo_oop_t)c == moo->_class) + else if (c == moo->_class) { /* print the class name */ moo_logbfmt (moo, mask, "%.*js", MOO_OBJ_GET_SIZE(((moo_oop_class_t)oop)->name), ((moo_oop_class_t)oop)->name->slot); } - else if ((moo_oop_t)c == moo->_association) + else if (c == moo->_association) { moo_logbfmt (moo, mask, "%O -> %O", ((moo_oop_association_t)oop)->key, ((moo_oop_association_t)oop)->value); } diff --git a/moo/lib/main.c b/moo/lib/main.c index abf7906..a2e96cc 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -821,42 +821,74 @@ static void vm_sleep (moo_t* moo, const moo_ntime_t* dur) #endif } -static int mux_add (moo_t* moo) +static int mux_add (moo_t* moo, moo_oop_semaphore_t sem) { xtn_t* xtn = (xtn_t*)moo_getxtn(moo); struct epoll_event ev; + moo_ooi_t mask; - ev.events = EPOLLIN | EPOLLOUT; - ev.data.u64 = 10; + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask)); -/* - if (epoll_ctl (xtn->ep, EPOLL_CTL_DEL, 000, &ev) == -1) + mask = MOO_OOP_TO_SMOOI(sem->io_mask); + ev.events = 0; + if (mask & 1) ev.events |= EPOLLIN; /*TODO: define io mask constants... */ + if (mask & 2) ev.events |= EPOLLOUT; + ev.data.ptr = (void*)MOO_OOP_TO_SMOOI(sem->io_index); + + if (ev.events == 0) { - moo_syserrtoerrnum (errno); + MOO_DEBUG2 (moo, " Invalid semaphore mask %zd on handle %zd\n", mask, MOO_OOP_TO_SMOOI(sem->io_handle)); + moo_seterrnum (moo, MOO_EINVAL); return -1; } -*/ + + if (epoll_ctl (xtn->ep, EPOLL_CTL_ADD, MOO_OOP_TO_SMOOI(sem->io_handle), &ev) == -1) + { + moo_seterrnum (moo, moo_syserrtoerrnum (errno)); + MOO_DEBUG2 (moo, " epoll_ctl failure on handle %zd - %hs\n", MOO_OOP_TO_SMOOI(sem->io_handle), strerror(errno)); + return -1; + } + return 0; } -static void mux_del (moo_t* moo) +static void mux_del (moo_t* moo, moo_oop_semaphore_t sem) { xtn_t* xtn = (xtn_t*)moo_getxtn(moo); struct epoll_event ev; -/* epoll_ctl (xtn->ep, EPOLL_CTL_DEL, 00, &ev);*/ + + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_index)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_handle)); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(sem->io_mask)); + + epoll_ctl (xtn->ep, EPOLL_CTL_DEL, MOO_OOP_TO_SMOOI(sem->io_handle), &ev); } -static void mux_wait (moo_t* moo, const moo_ntime_t* dur) +static void mux_wait (moo_t* moo, const moo_ntime_t* dur, moo_vmprim_muxwait_cb_t muxwcb) { xtn_t* xtn = (xtn_t*)moo_getxtn(moo); - int tmout = 0; + int tmout = 0, n; + struct epoll_event ev[32]; /*TODO: make it into xtn->evt_ptr or somewhere else as a dynamically allocated memory block */ if (dur) tmout = MOO_SECNSEC_TO_MSEC(dur->sec, dur->nsec); -/* - if (epoll_wait (xtn->ep, xtn->evt_ptr, xtn->evt_capa, tmout) > 0) + + n = epoll_wait (xtn->ep, ev, MOO_COUNTOF(ev), tmout); + while (n > 0) { + int mask; + + --n; + + mask = 0; + if (ev[n].events & EPOLLIN) mask |= 1; /* TODO define constants for IO Mask */ + if (ev[n].events & EPOLLOUT) mask |= 2; + if (ev[n].events & EPOLLERR) mask |= 4; + if (ev[n].events & EPOLLHUP) mask |= 8; + + muxwcb (moo, mask, ev[n].data.ptr); } -*/ } /* ========================================================================= */ diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 5bdbba7..5ccb166 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -1036,9 +1036,9 @@ int moo_deletedic ( ); moo_oop_set_t moo_makedic ( - moo_t* moo, - moo_oop_t cls, - moo_oow_t size + moo_t* moo, + moo_oop_class_t _class, + moo_oow_t size ); /* ========================================================================= */ @@ -1048,7 +1048,6 @@ moo_oop_process_t moo_makeproc ( moo_t* moo ); - /* ========================================================================= */ /* bigint.c */ /* ========================================================================= */ @@ -1200,7 +1199,7 @@ void moo_closemod ( int moo_importmod ( moo_t* moo, - moo_oop_t _class, + moo_oop_class_t _class, const moo_ooch_t* name, moo_oow_t len ); diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 4e4366e..2778ba4 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -531,7 +531,7 @@ void moo_closemod (moo_t* moo, moo_mod_data_t* mdp) } } -int moo_importmod (moo_t* moo, moo_oop_t _class, const moo_ooch_t* name, moo_oow_t len) +int moo_importmod (moo_t* moo, moo_oop_class_t _class, const moo_ooch_t* name, moo_oow_t len) { moo_rbt_pair_t* pair; moo_mod_data_t* mdp; @@ -540,7 +540,7 @@ int moo_importmod (moo_t* moo, moo_oop_t _class, const moo_ooch_t* name, moo_oow /* moo_openmod(), moo_closemod(), etc call a user-defined callback. * i need to protect _class in case the user-defined callback allocates * a OOP memory chunk and GC occurs */ - moo_pushtmp (moo, &_class); + moo_pushtmp (moo, (moo_oop_t*)&_class); pair = moo_rbt_search (&moo->modtab, name, len); if (pair) @@ -644,13 +644,12 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen /* -------------------------------------------------------------------------- */ /* add a new primitive method */ -int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_type_t type, const moo_ooch_t* mthname, int variadic, const moo_ooch_t* pfname) +int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, moo_method_type_t type, const moo_ooch_t* mthname, int variadic, const moo_ooch_t* pfname) { /* NOTE: this function is a subset of add_compiled_method() in comp.c */ moo_oop_char_t mnsym, pfidsym; moo_oop_method_t mth; - moo_oop_class_t cls; moo_oow_t tmp_count = 0, i; moo_ooi_t arg_count = 0; moo_oocs_t cs; @@ -661,9 +660,8 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty if (!pfname) pfname = mthname; - cls = (moo_oop_class_t)_class; - moo_pushtmp (moo, (moo_oop_t*)&cls); tmp_count++; - MOO_ASSERT (moo, MOO_CLASSOF(moo, (moo_oop_t)cls->mthdic[type]) == moo->_method_dictionary); + moo_pushtmp (moo, (moo_oop_t*)&_class); tmp_count++; + MOO_ASSERT (moo, MOO_CLASSOF(moo, (moo_oop_t)_class->mthdic[type]) == moo->_method_dictionary); for (i = 0; mthname[i]; i++) { @@ -678,16 +676,16 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty if (arg_count > 0 && mthname[i - 1] != ':') { oops_inval: - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - invalid name\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - invalid name\n", mthname, _class->name); moo->errnum = MOO_EINVAL; goto oops; } cs.ptr = (moo_ooch_t*)mthname; cs.len = i; - if (moo_lookupdic (moo, cls->mthdic[type], &cs) != MOO_NULL) + if (moo_lookupdic (moo, _class->mthdic[type], &cs) != MOO_NULL) { - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - duplicate\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - duplicate\n", mthname, _class->name); moo->errnum = MOO_EEXIST; goto oops; } @@ -702,14 +700,14 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty moo_concatoocstrtosbuf(moo, dot, 0) <= -1 || moo_concatoocstrtosbuf(moo, pfname, 0) <= -1) { - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - VM memory shortage\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - VM memory shortage\n", mthname, _class->name); return -1; } pfidsym = (moo_oop_char_t)moo_makesymbol (moo, moo->sbuf[0].ptr, moo->sbuf[0].len); if (!pfidsym) { - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - symbol instantiation failure\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - symbol instantiation failure\n", mthname, _class->name); goto oops; } moo_pushtmp (moo, (moo_oop_t*)&pfidsym); tmp_count++; @@ -721,7 +719,7 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty #endif if (!mth) { - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - method instantiation failure\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - method instantiation failure\n", mthname, _class->name); goto oops; } @@ -729,7 +727,7 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty mth->slot[0] = (moo_oop_t)pfidsym; /* premable should contain the index to the literal frame which is always 0 */ - mth->owner = cls; + mth->owner = _class; mth->name = mnsym; if (variadic) preamble_flags |= MOO_METHOD_PREAMBLE_FLAG_VARIADIC; mth->preamble = MOO_SMOOI_TO_OOP(MOO_METHOD_MAKE_PREAMBLE(MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE, 0, preamble_flags)); @@ -740,13 +738,13 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty /* TODO: emit BCODE_RETURN_NIL as a fallback or self primitiveFailed? or anything else?? */ - if (!moo_putatdic (moo, cls->mthdic[type], (moo_oop_t)mnsym, (moo_oop_t)mth)) + if (!moo_putatdic (moo, _class->mthdic[type], (moo_oop_t)mnsym, (moo_oop_t)mth)) { - MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - failed to add to method dictionary\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Cannot generate primitive function method [%js] in [%O] - failed to add to method dictionary\n", mthname, _class->name); goto oops; } - MOO_DEBUG2 (moo, "Generated primitive function method [%js] in [%O]\n", mthname, cls->name); + MOO_DEBUG2 (moo, "Generated primitive function method [%js] in [%O]\n", mthname, _class->name); moo_poptmps (moo, tmp_count); tmp_count = 0; return 0; @@ -756,12 +754,12 @@ oops: return -1; } -int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount) +int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount) { int ret = 0; moo_oow_t i; - moo_pushtmp (moo, &_class); + moo_pushtmp (moo, (moo_oop_t*)&_class); for (i = 0; i < pfcount; i++) { if (moo_genpfmethod (moo, mod, _class, pfinfo[i].type, pfinfo[i].mthname, pfinfo[i].variadic, MOO_NULL) <= -1) @@ -801,53 +799,51 @@ moo_pfimpl_t moo_findpfimpl (moo_t* moo, const moo_pfinfo_t* pfinfo, moo_oow_t p /* -------------------------------------------------------------------------- */ -int moo_setclasstrsize (moo_t* moo, moo_oop_t _class, moo_oow_t size) +int moo_setclasstrsize (moo_t* moo, moo_oop_class_t _class, moo_oow_t size) { - register moo_oop_class_t c; moo_oop_class_t sc; moo_oow_t spec; MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class); MOO_ASSERT (moo, size <= MOO_SMOOI_MAX); - c = (moo_oop_class_t)_class; - if ((moo_oop_t)c == moo->_method) + if (_class == moo->_method) { /* the bytes code emitted by the compiler go to the trailer part * regardless of the trailer size. you're not allowed to change it */ MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class\n", size, - MOO_OBJ_GET_SIZE(c->name), - MOO_OBJ_GET_CHAR_SLOT(c->name)); + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name)); goto eperm; } - spec = MOO_OOP_TO_SMOOI(c->spec); + spec = MOO_OOP_TO_SMOOI(_class->spec); if (MOO_CLASS_SPEC_IS_INDEXED(spec) && MOO_CLASS_SPEC_INDEXED_TYPE(spec) != MOO_OBJ_TYPE_OOP) { MOO_DEBUG3 (moo, "Not allowed to set trailer size to %zu on the %.*js class representing a non-pointer object\n", size, - MOO_OBJ_GET_SIZE(c->name), - MOO_OBJ_GET_CHAR_SLOT(c->name)); + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name)); goto eperm; } - if (c->trsize != moo->_nil) + if (_class->trsize != moo->_nil) { MOO_DEBUG3 (moo, "Not allowed to re-set trailer size to %zu on the %.*js class\n", size, - MOO_OBJ_GET_SIZE(c->name), - MOO_OBJ_GET_CHAR_SLOT(c->name)); + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name)); goto eperm; } - sc = (moo_oop_class_t)c->superclass; + sc = (moo_oop_class_t)_class->superclass; if (MOO_OOP_IS_SMOOI(sc->trsize) && size < MOO_OOP_TO_SMOOI(sc->trsize)) { MOO_DEBUG6 (moo, "Not allowed to set the trailer size of %.*js to be smaller(%zu) than that(%zu) of the superclass %.*js\n", size, - MOO_OBJ_GET_SIZE(c->name), - MOO_OBJ_GET_CHAR_SLOT(c->name), + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name), MOO_OOP_TO_SMOOI(sc->trsize), MOO_OBJ_GET_SIZE(sc->name), MOO_OBJ_GET_CHAR_SLOT(sc->name)); @@ -855,11 +851,11 @@ int moo_setclasstrsize (moo_t* moo, moo_oop_t _class, moo_oow_t size) } /* you can only set the trailer size once when it's not set yet */ - c->trsize = MOO_SMOOI_TO_OOP(size); + _class->trsize = MOO_SMOOI_TO_OOP(size); MOO_DEBUG3 (moo, "Set trailer size to %zu on the %.*js class\n", size, - MOO_OBJ_GET_SIZE(c->name), - MOO_OBJ_GET_CHAR_SLOT(c->name)); + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name)); return 0; eperm: diff --git a/moo/lib/moo.h b/moo/lib/moo.h index b3d76bd..458cd51 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -353,10 +353,10 @@ typedef enum moo_obj_type_t moo_obj_type_t; #define MOO_OBJ_SET_FLAGS_TRAILER(oop,v) MOO_SETBITS(moo_oow_t, (oop)->_flags, MOO_OBJ_FLAGS_TRAILER_SHIFT, MOO_OBJ_FLAGS_TRAILER_BITS, v) #define MOO_OBJ_GET_SIZE(oop) ((oop)->_size) -#define MOO_OBJ_GET_CLASS(oop) ((oop)->_class) +#define MOO_OBJ_GET_CLASS(oop) ((moo_oop_class_t)((oop)->_class)) #define MOO_OBJ_SET_SIZE(oop,v) ((oop)->_size = (v)) -#define MOO_OBJ_SET_CLASS(oop,c) ((oop)->_class = (c)) +#define MOO_OBJ_SET_CLASS(oop,c) ((oop)->_class = (moo_oop_t)(c)) /* [NOTE] this macro doesn't include the size of the trailer */ #define MOO_OBJ_BYTESOF(oop) ((MOO_OBJ_GET_SIZE(oop) + MOO_OBJ_GET_FLAGS_EXTRA(oop)) * MOO_OBJ_GET_FLAGS_UNIT(oop)) @@ -697,7 +697,7 @@ struct moo_semaphore_t moo_oop_t heap_ftime_nsec; /* firing time */ moo_oop_t io_index; - moo_oop_t io_data; + moo_oop_t io_handle; moo_oop_t io_mask; /* SmallInteger */ }; @@ -759,9 +759,11 @@ typedef void (*moo_vmprim_cleanup_t) (moo_t* moo); typedef void (*moo_vmprim_gettime_t) (moo_t* moo, moo_ntime_t* now); typedef void (*moo_vmprim_sleep_t) (moo_t* moo, const moo_ntime_t* duration); -typedef int (*moo_vmprim_muxadd_t) (moo_t* moo); -typedef void (*moo_vmprim_muxdel_t) (moo_t* moo); -typedef void (*moo_vmprim_muxwait_t) (moo_t* moo, const moo_ntime_t* duration); +typedef int (*moo_vmprim_muxadd_t) (moo_t* moo, moo_oop_semaphore_t sem); +typedef void (*moo_vmprim_muxdel_t) (moo_t* moo, moo_oop_semaphore_t sem); + +typedef void (*moo_vmprim_muxwait_cb_t) (moo_t* moo, int mask, void* ctx); +typedef void (*moo_vmprim_muxwait_t) (moo_t* moo, const moo_ntime_t* duration, moo_vmprim_muxwait_cb_t muxwcb); struct moo_vmprim_t { @@ -844,7 +846,7 @@ typedef int (*moo_mod_load_t) ( typedef int (*moo_mod_import_t) ( moo_t* moo, moo_mod_t* mod, - moo_oop_t _class + moo_oop_class_t _class ); typedef moo_pfimpl_t (*moo_mod_query_t) ( @@ -938,39 +940,39 @@ struct moo_t * Be sure to Keep these kernel class pointers registered in the * kernel_classes table in gc.c * ============================================================= */ - moo_oop_t _apex; /* Apex */ - moo_oop_t _undefined_object; /* UndefinedObject */ - moo_oop_t _class; /* Class */ - moo_oop_t _object; /* Object */ - moo_oop_t _string; /* String */ + moo_oop_class_t _apex; /* Apex */ + moo_oop_class_t _undefined_object; /* UndefinedObject */ + moo_oop_class_t _class; /* Class */ + moo_oop_class_t _object; /* Object */ + moo_oop_class_t _string; /* String */ - moo_oop_t _symbol; /* Symbol */ - moo_oop_t _array; /* Array */ - moo_oop_t _byte_array; /* ByteArray */ - moo_oop_t _symbol_set; /* SymbolSet */ - moo_oop_t _dictionary; - moo_oop_t _system_dictionary; /* SystemDictionary */ + moo_oop_class_t _symbol; /* Symbol */ + moo_oop_class_t _array; /* Array */ + moo_oop_class_t _byte_array; /* ByteArray */ + moo_oop_class_t _symbol_set; /* SymbolSet */ + moo_oop_class_t _dictionary; + moo_oop_class_t _system_dictionary; /* SystemDictionary */ - moo_oop_t _namespace; /* Namespace */ - moo_oop_t _pool_dictionary; /* PoolDictionary */ - moo_oop_t _method_dictionary; /* MethodDictionary */ - moo_oop_t _method; /* CompiledMethod */ - moo_oop_t _association; /* Association */ + moo_oop_class_t _namespace; /* Namespace */ + moo_oop_class_t _pool_dictionary; /* PoolDictionary */ + moo_oop_class_t _method_dictionary; /* MethodDictionary */ + moo_oop_class_t _method; /* CompiledMethod */ + moo_oop_class_t _association; /* Association */ - moo_oop_t _method_context; /* MethodContext */ - moo_oop_t _block_context; /* BlockContext */ - moo_oop_t _process; /* Process */ - moo_oop_t _semaphore; /* Semaphore */ - moo_oop_t _process_scheduler; /* ProcessScheduler */ + moo_oop_class_t _method_context; /* MethodContext */ + moo_oop_class_t _block_context; /* BlockContext */ + moo_oop_class_t _process; /* Process */ + moo_oop_class_t _semaphore; /* Semaphore */ + moo_oop_class_t _process_scheduler; /* ProcessScheduler */ - moo_oop_t _error_class; /* Error */ - moo_oop_t _true_class; /* True */ - moo_oop_t _false_class; /* False */ - moo_oop_t _character; /* Character */ - moo_oop_t _small_integer; /* SmallInteger */ + moo_oop_class_t _error_class; /* Error */ + moo_oop_class_t _true_class; /* True */ + moo_oop_class_t _false_class; /* False */ + moo_oop_class_t _character; /* Character */ + moo_oop_class_t _small_integer; /* SmallInteger */ - moo_oop_t _large_positive_integer; /* LargePositiveInteger */ - moo_oop_t _large_negative_integer; /* LargeNegativeInteger */ + moo_oop_class_t _large_positive_integer; /* LargePositiveInteger */ + moo_oop_class_t _large_negative_integer; /* LargeNegativeInteger */ /* ============================================================= * END KERNEL CLASSES * ============================================================= */ @@ -978,7 +980,7 @@ struct moo_t /* ============================================================= * KEY SYSTEM DICTIONARIES * ============================================================= */ - moo_oop_t* tagged_classes[4]; + moo_oop_class_t* tagged_classes[4]; moo_oop_set_t symtab; /* system-wide symbol table. instance of SymbolSet */ moo_oop_set_t sysdic; /* system dictionary. instance of SystemDictionary */ moo_oop_process_scheduler_t processor; /* instance of ProcessScheduler */ @@ -1351,15 +1353,15 @@ MOO_EXPORT void moo_gc ( * */ MOO_EXPORT moo_oop_t moo_instantiate ( - moo_t* moo, - moo_oop_t _class, + moo_t* moo, + moo_oop_class_t _class, const void* vptr, - moo_oow_t vlen + moo_oow_t vlen ); MOO_EXPORT moo_oop_t moo_instantiatewithtrailer ( moo_t* moo, - moo_oop_t _class, + moo_oop_class_t _class, moo_oow_t vlen, const moo_oob_t* trptr, moo_oow_t trlen @@ -1453,9 +1455,9 @@ MOO_EXPORT int moo_inttoooi ( * TRAILER MANAGEMENT * ========================================================================= */ MOO_EXPORT int moo_setclasstrsize ( - moo_t* moo, - moo_oop_t _class, - moo_oow_t size + moo_t* moo, + moo_oop_class_t _class, + moo_oow_t size ); MOO_EXPORT void* moo_getobjtrailer ( @@ -1505,14 +1507,13 @@ MOO_EXPORT void moo_freemem ( void* ptr ); - /* ========================================================================= * PRIMITIVE METHOD MANIPULATION * ========================================================================= */ MOO_EXPORT int moo_genpfmethod ( moo_t* moo, moo_mod_t* mod, - moo_oop_t _class, + moo_oop_class_t _class, moo_method_type_t type, const moo_ooch_t* mthname, int variadic, @@ -1522,7 +1523,7 @@ MOO_EXPORT int moo_genpfmethod ( MOO_EXPORT int moo_genpfmethods ( moo_t* moo, moo_mod_t* mod, - moo_oop_t _class, + moo_oop_class_t _class, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount ); diff --git a/moo/lib/obj.c b/moo/lib/obj.c index 418d2b4..cabad2c 100644 --- a/moo/lib/obj.c +++ b/moo/lib/obj.c @@ -169,7 +169,7 @@ moo_oop_t moo_allocwordobj (moo_t* moo, const moo_oow_t* ptr, moo_oow_t len) return alloc_numeric_array (moo, ptr, len, MOO_OBJ_TYPE_WORD, MOO_SIZEOF(moo_oow_t), 0); } -static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, moo_obj_type_t* type, moo_oow_t* outlen) +static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_class_t _class, moo_oow_t vlen, moo_obj_type_t* type, moo_oow_t* outlen) { moo_oow_t spec; moo_oow_t named_instvar; @@ -178,8 +178,8 @@ static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, MOO_ASSERT (moo, MOO_OOP_IS_POINTER(_class)); MOO_ASSERT (moo, MOO_CLASSOF(moo, _class) == moo->_class); - MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->spec)); - spec = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->spec); + MOO_ASSERT (moo, MOO_OOP_IS_SMOOI(_class->spec)); + spec = MOO_OOP_TO_SMOOI(_class->spec); named_instvar = MOO_CLASS_SPEC_NAMED_INSTVAR(spec); /* size of the named_instvar part */ @@ -243,7 +243,7 @@ static MOO_INLINE int decode_spec (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, return 0; } -moo_oop_t moo_instantiate (moo_t* moo, moo_oop_t _class, const void* vptr, moo_oow_t vlen) +moo_oop_t moo_instantiate (moo_t* moo, moo_oop_class_t _class, const void* vptr, moo_oow_t vlen) { moo_oop_t oop; moo_obj_type_t type; @@ -258,7 +258,7 @@ moo_oop_t moo_instantiate (moo_t* moo, moo_oop_t _class, const void* vptr, moo_o return MOO_NULL; } - moo_pushtmp (moo, &_class); tmp_count++; + moo_pushtmp (moo, (moo_oop_t*)&_class); tmp_count++; switch (type) { @@ -307,12 +307,13 @@ moo_oop_t moo_instantiate (moo_t* moo, moo_oop_t _class, const void* vptr, moo_o break; } - if (oop) MOO_OBJ_SET_CLASS (oop, _class); + if (oop) MOO_OBJ_SET_CLASS (oop, (moo_oop_t)_class); moo_poptmps (moo, tmp_count); return oop; } -moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_oow_t vlen, int ngc) +/* TODO: ... */ +moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_class_t _class, const void* vptr, moo_oow_t vlen, int ngc) { moo_oop_t oop; moo_obj_type_t type; @@ -327,7 +328,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_ return MOO_NULL; } - moo_pushtmp (moo, &_class); tmp_count++; + moo_pushtmp (moo, (moo_oop_t*)&_class); tmp_count++; /* TODO: support NGC */ switch (type) @@ -364,7 +365,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_ return oop; } -moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, const moo_oob_t* trptr, moo_oow_t trlen) +moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_class_t _class, moo_oow_t vlen, const moo_oob_t* trptr, moo_oow_t trlen) { moo_oop_t oop; moo_obj_type_t type; @@ -379,7 +380,7 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl return MOO_NULL; } - moo_pushtmp (moo, &_class); tmp_count++; + moo_pushtmp (moo, (moo_oop_t*)&_class); tmp_count++; switch (type) { @@ -389,8 +390,8 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl default: MOO_DEBUG3 (moo, "Not allowed to instantiate a non-pointer object of the %.*js class with trailer %zu\n", - MOO_OBJ_GET_SIZE(((moo_oop_class_t)_class)->name), - MOO_OBJ_GET_CHAR_SLOT(((moo_oop_class_t)_class)->name), + MOO_OBJ_GET_SIZE(_class->name), + MOO_OBJ_GET_CHAR_SLOT(_class->name), trlen); moo->errnum = MOO_EPERM; diff --git a/moo/lib/sym.c b/moo/lib/sym.c index 6e1d78e..b9316f1 100644 --- a/moo/lib/sym.c +++ b/moo/lib/sym.c @@ -103,7 +103,7 @@ static moo_oop_t find_or_make_symbol (moo_t* moo, const moo_ooch_t* ptr, moo_oow while (moo->symtab->bucket->slot[index] != moo->_nil) { symbol = (moo_oop_char_t)moo->symtab->bucket->slot[index]; - MOO_ASSERT (moo, MOO_CLASSOF(moo,symbol) == (moo_oop_t)moo->_symbol); + MOO_ASSERT (moo, MOO_CLASSOF(moo,symbol) == moo->_symbol); if (len == MOO_OBJ_GET_SIZE(symbol) && moo_equaloochars (ptr, symbol->slot, len)) diff --git a/moo/mod/ffi.c b/moo/mod/ffi.c index d0a1a78..052805b 100644 --- a/moo/mod/ffi.c +++ b/moo/mod/ffi.c @@ -550,7 +550,7 @@ static moo_pfinfo_t pfinfos[] = /* ------------------------------------------------------------------------ */ -static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) +static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(ffi_t)) <= -1) return -1; return moo_genpfmethods (moo, mod, _class, pfinfos, MOO_COUNTOF(pfinfos)); diff --git a/moo/mod/stdio.c b/moo/mod/stdio.c index 6a29770..54d105c 100644 --- a/moo/mod/stdio.c +++ b/moo/mod/stdio.c @@ -221,7 +221,7 @@ static moo_pfinfo_t pfinfos[] = }; /* ------------------------------------------------------------------------ */ -static int import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) +static int import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { if (moo_setclasstrsize (moo, _class, MOO_SIZEOF(stdio_t)) <= -1) return -1; return moo_genpfmethods (moo, mod, _class, pfinfos, MOO_COUNTOF(pfinfos)); diff --git a/moo/mod/x11.c b/moo/mod/x11.c index 82a30d4..a37c8ea 100644 --- a/moo/mod/x11.c +++ b/moo/mod/x11.c @@ -94,12 +94,6 @@ static moo_pfrc_t pf_disconnect (moo_t* moo, moo_ooi_t nargs) { x11_t* x11; - if (nargs != 0) - { - moo_seterrnum (moo, MOO_EINVAL); - goto softfail; - } - x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); MOO_DEBUG1 (moo, " %p\n", x11->c); @@ -115,33 +109,86 @@ softfail: return MOO_PF_SUCCESS; } -/* ------------------------------------------------------------------------ */ - -static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs) +static moo_pfrc_t pf_getfd (moo_t* moo, moo_ooi_t nargs) { - MOO_STACK_SETRET (moo, nargs, moo->_nil); -#if 0 + x11_t* x11; + + x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + MOO_DEBUG1 (moo, " %p\n", x11->c); + + if (x11->c) + { + int c; + + c = xcb_get_file_descriptor(x11->c); + if (!MOO_IN_SMOOI_RANGE(c)) goto error; + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(c)); + } + else + { + error: + MOO_STACK_SETRETTOERROR (moo, nargs); /* TODO: be more specific about error code */ + } + + return MOO_PF_SUCCESS; +} + + +static moo_pfrc_t pf_getevent (moo_t* moo, moo_ooi_t nargs) +{ + x11_t* x11; + xcb_generic_event_t* evt; + + x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + MOO_DEBUG1 (moo, " %p\n", x11->c); + + evt = xcb_poll_for_event(x11->c); + if (evt) + { + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(evt->response_type)); /* TODO: translate evt to the event object */ + } + else + { + MOO_STACK_SETRET (moo, nargs, moo->_nil); + } + return MOO_PF_SUCCESS; +} + +static moo_pfrc_t pf_makewin (moo_t* moo, moo_ooi_t nargs) +{ + x11_t* x11; + xcb_screen_t* screen; + xcb_window_t win; + + x11 = (x11_t*)moo_getobjtrailer(moo, MOO_STACK_GETRCV(moo, nargs), MOO_NULL); + MOO_DEBUG1 (moo, " %p\n", x11->c); + screen = xcb_setup_roots_iterator(xcb_get_setup(x11->c)).data; - x11->mw = xcb_generate_id (xtn->c); + win = xcb_generate_id (x11->c); xcb_create_window (x11->c, XCB_COPY_FROM_PARENT, - xtn->mw, + win, screen->root, 0, 0, 300, 300, 10, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, 0, MOO_NULL); - xcb_map_window (xtn->xcb, xtn->mw); - xcb_flush (xtn->xcb); +/*TODO: use xcb_request_check() for error handling */ + xcb_map_window (x11->c, win); + xcb_flush (x11->c); - xcb_generic_event_t* evt; - while ((evt = xcb_poll_for_event(xtn->xcb, 0)) - { - /* TODO: dispatch event read */ - } -#endif + MOO_STACK_SETRET (moo, nargs, MOO_SMOOI_TO_OOP(win)); /* TODO: write this function to return a window handle... */ + return MOO_PF_SUCCESS; +} + + +/* ------------------------------------------------------------------------ */ + +static moo_pfrc_t pf_win_create (moo_t* moo, moo_ooi_t nargs) +{ + MOO_STACK_SETRET (moo, nargs, moo->_nil); MOO_DEBUG0 (moo, "x11.window.create....\n"); return MOO_PF_SUCCESS; } @@ -153,15 +200,20 @@ MOO_DEBUG0 (moo, "x11.window.destroy....\n"); return MOO_PF_SUCCESS; } + /* ------------------------------------------------------------------------ */ static moo_pfinfo_t x11_pfinfo[] = { + { I, { '_','_','g','e','t','e','v','e','n','t','\0'}, 0, pf_getevent }, + { I, { '_','_','m','a','k','e','w','i','n','\0'}, 0, pf_makewin }, { I, { 'c','o','n','n','e','c','t','\0' }, 0, pf_connect }, - { I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect } + { I, { 'd','i','s','c','o','n','n','e','c','t','\0' }, 0, pf_disconnect }, + { I, { 'g','e','t','f','d','\0' }, 0, pf_getfd } + }; -static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) +static int x11_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_t)) <= -1) return -1; return moo_genpfmethods(moo, mod, _class, x11_pfinfo, MOO_COUNTOF(x11_pfinfo)); @@ -194,7 +246,7 @@ static moo_pfinfo_t x11_win_pfinfo[] = { I, { 'd','i','s','t','r','o','y','\0' }, 0, pf_win_destroy } }; -static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_t _class) +static int x11_win_import (moo_t* moo, moo_mod_t* mod, moo_oop_class_t _class) { if (moo_setclasstrsize(moo, _class, MOO_SIZEOF(x11_win_t)) <= -1) return -1; return moo_genpfmethods(moo, mod, _class, x11_win_pfinfo, MOO_COUNTOF(x11_win_pfinfo));