diff --git a/moo/kernel/Collect.moo b/moo/kernel/Collect.moo index b4bb117..865384c 100644 --- a/moo/kernel/Collect.moo +++ b/moo/kernel/Collect.moo @@ -1382,13 +1382,12 @@ class SymbolTable(AssociativeCollection) class Dictionary(AssociativeCollection) { /* [NOTE] - * VM require Dictionary to implement new: and __put_assoc + * VM requires Dictionary to implement new: and __put_assoc * for the dictionary expression notation - ##{ } */ // TODO: implement Dictionary as a Hashed List/Table or Red-Black Tree - // Do not inherit Set upon reimplementation - // + method(#class) new: capacity { ^super new: (capacity + 10). diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index b33a36b..d611436 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -88,7 +88,9 @@ class System(Apex) ret := class perform: method_name. ] ensure: [ - self _setSig: 16rFF. + // signal end of the main process. + // __os_sig_handler will terminate all running subprocesses. + self _setSig: 16rFF. ]. ^ret. @@ -198,7 +200,7 @@ class System(Apex) /* 0 -> startup <--- this should also be stored in the 'caller' variable. 1 -> __gc_finalizer - 2 -> __os_signal_handler + 2 -> __os_sig_handler 3 .. -> other processes started by application. */ proc := System _findProcessByIdGreaterThan: 2. diff --git a/moo/kernel/generr.moo b/moo/kernel/generr.moo index 86e00d9..9efe469 100644 --- a/moo/kernel/generr.moo +++ b/moo/kernel/generr.moo @@ -103,7 +103,7 @@ class MyObject(Object) 'inaccessible variable' 'ambiguous variable' 'too many instance/class variables' - 'inaccessible self' + 'inaccessible super' 'wrong expression primary' 'too many temporaries' 'too many arguments' diff --git a/moo/lib/comp.c b/moo/lib/comp.c index d6ec7b0..e7e7d80 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -5685,6 +5685,18 @@ static int compile_expression_primary (moo_t* moo, const moo_oocs_t* ident, cons break; case MOO_IOTOK_SUPER: + if (moo->c->cunit->cunit_type == MOO_CUNIT_INTERFACE) + { + /* i don't allow super in an interface method + * message sending to super requires the owning class + * of an active method. a method taken by a class from + * an interface points to the interface in the owner field. + * for now, it's best not to allow it. + * see moo_findmethod() in exec.c */ + moo_setsynerrbfmt (moo, MOO_SYNERR_SUPERINACC, TOKEN_LOC(moo), TOKEN_NAME(moo), "super inaccessible in interface method"); + return -1; + } + if (emit_byte_instruction(moo, BCODE_PUSH_RECEIVER, TOKEN_LOC(moo)) <= -1) return -1; GET_TOKEN (moo); *to_super = 1; @@ -9058,7 +9070,6 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati ciim_t* ciim = (ciim_t*)ctx; moo_oocs_t name; moo_oop_method_t mth; - moo_oop_methsig_t sig; name.ptr = MOO_OBJ_GET_CHAR_SLOT(ass->key); name.len = MOO_OBJ_GET_SIZE(ass->key); @@ -9095,31 +9106,59 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati * the method. it's an error */ } - sig = (moo_oop_methsig_t)ass->value; - if (MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) != MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(sig->preamble))) + if (MOO_CLASSOF(moo, ass->value) == moo->_methsig) { - moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL, - "%.*js>>%.*js modifiers conficting with %.*js>>%.*js", - MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), - name.len, name.ptr, - MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name), - name.len, name.ptr - ); - return -1; + /* it's a method signature without body */ + + moo_oop_methsig_t sig; + + sig = (moo_oop_methsig_t)ass->value; + if (MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) != MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(sig->preamble))) + { + modifier_conflict: + moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL, + "%.*js>>%.*js modifiers conficting with %.*js>>%.*js", + MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), + name.len, name.ptr, + MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name), + name.len, name.ptr + ); + return -1; + } + + if (mth->tmpr_nargs != sig->tmpr_nargs) /* don't need MOO_OOP_TO_SMOOI */ + { + param_conflict: + moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL, + "%.*js>>%.*js parameters conflicting with %.*js>>%.*js", + MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), + name.len, name.ptr, + MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name), + name.len, name.ptr + ); + return -1; + } } - - if (mth->tmpr_nargs != sig->tmpr_nargs) /* don't need MOO_OOP_TO_SMOOI */ + else { - moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL, - "%.*js>>%.*js parameters conflicting with %.*js>>%.*js", - MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name), - name.len, name.ptr, - MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name), - name.len, name.ptr - ); - return -1; + /* it is a full interface method */ + + moo_oop_method_t sig; + + MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method); + + sig = (moo_oop_method_t)ass->value; + if (MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(mth->preamble)) != MOO_METHOD_GET_PREAMBLE_FLAGS(MOO_OOP_TO_SMOOI(sig->preamble))) + { + goto modifier_conflict; + } + + if (mth->tmpr_nargs != sig->tmpr_nargs) /* don't need MOO_OOP_TO_SMOOI */ + { + goto param_conflict; + } } - + return 0; } diff --git a/moo/lib/err.c b/moo/lib/err.c index e66c6ee..0099215 100644 --- a/moo/lib/err.c +++ b/moo/lib/err.c @@ -128,7 +128,7 @@ static moo_ooch_t synerrstr_52[] = {'u','n','u','s','a','b','l','e',' ','v','a', static moo_ooch_t synerrstr_53[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','v','a','r','i','a','b','l','e','\0'}; static moo_ooch_t synerrstr_54[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'}; static moo_ooch_t synerrstr_55[] = {'t','o','o',' ','m','a','n','y',' ','i','n','s','t','a','n','c','e','/','c','l','a','s','s',' ','v','a','r','i','a','b','l','e','s','\0'}; -static moo_ooch_t synerrstr_56[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'}; +static moo_ooch_t synerrstr_56[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','u','p','e','r','\0'}; static moo_ooch_t synerrstr_57[] = {'w','r','o','n','g',' ','e','x','p','r','e','s','s','i','o','n',' ','p','r','i','m','a','r','y','\0'}; static moo_ooch_t synerrstr_58[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'}; static moo_ooch_t synerrstr_59[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'}; diff --git a/moo/lib/exec.c b/moo/lib/exec.c index f62f301..b30db19 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1829,7 +1829,7 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t message.ptr = MOO_OBJ_GET_CHAR_SLOT(selector); message.len = MOO_OBJ_GET_SIZE(selector); - + _class = MOO_CLASSOF(moo, receiver); if (_class == moo->_class) { @@ -1849,6 +1849,12 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t { MOO_ASSERT (moo, moo->active_method); MOO_ASSERT (moo, moo->active_method->owner); + + /* if 'super' is allowed in the interface method, the owner field + * can be an interface. super must not be allowed in the interface + * method body. */ + MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_method->owner) == moo->_class); + c = (moo_oop_class_t)((moo_oop_class_t)moo->active_method->owner)->superclass; if ((moo_oop_t)c == moo->_nil) goto not_found; /* c is nil if it reached the top of the hierarchy. @@ -1863,7 +1869,7 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t mcidx = ((moo_oow_t)_class ^ (moo_oow_t)selector) & (MOO_METHOD_CACHE_SIZE - 1); mcitm = &moo->method_cache[mth_type][mcidx]; - if (mcitm->receiver_class == c && mcitm->selector == selector /*&& mcitm->method_type == mth_type*/) + if (mcitm->receiver_class == c && mcitm->selector == selector /*&& mcitm->method_type == mth_type*/) { /* cache hit */ #if defined(MOO_PROFILE_VM) @@ -1871,7 +1877,7 @@ moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, moo_oop_char_t #endif return mcitm->method; } - + /* [IMPORT] the method lookup logic should be the same as ciim_on_each_method() in comp.c */ mth = find_method_in_class_chain(moo, c, mth_type, &message); if (mth) diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 24d86ba..cd9d1d1 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -1892,7 +1892,7 @@ enum moo_synerrnum_t MOO_SYNERR_VARINACC, /* inaccessible variable - e.g. accessing an instance variable from a class method is not allowed. */ MOO_SYNERR_VARAMBIG, /* ambiguious variable - e.g. the variable is found in multiple pool dictionaries imported */ MOO_SYNERR_VARFLOOD, /* too many instance/class variables */ - MOO_SYNERR_SELFINACC, /* inaccessible self */ + MOO_SYNERR_SUPERINACC, /* inaccessible super */ MOO_SYNERR_PRIMARYINVAL, /* wrong expression primary */ MOO_SYNERR_TMPRFLOOD, /* too many temporaries */ MOO_SYNERR_ARGFLOOD, /* too many arguments */