renamed MOO_SYNERR_SELFINACC to MOO_SYNERR_SUPERINACC

fixed interface signature checker to handle a method signature without body and a full interface method with body differently
This commit is contained in:
hyunghwan.chung 2019-10-09 16:58:10 +00:00
parent 0e75970f13
commit 910a83096e
7 changed files with 79 additions and 33 deletions

View File

@ -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).

View File

@ -88,6 +88,8 @@ class System(Apex)
ret := class perform: method_name.
]
ensure: [
// signal end of the main process.
// __os_sig_handler will terminate all running subprocesses.
self _setSig: 16rFF.
].
@ -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.

View File

@ -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'

View File

@ -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,9 +9106,16 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati
* the method. it's an error */
}
if (MOO_CLASSOF(moo, ass->value) == moo->_methsig)
{
/* 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),
@ -9110,6 +9128,7 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati
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),
@ -9119,6 +9138,26 @@ static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_associati
);
return -1;
}
}
else
{
/* 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;
}

View File

@ -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'};

View File

@ -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.

View File

@ -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 */