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:
parent
0e75970f13
commit
910a83096e
@ -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).
|
||||
|
@ -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.
|
||||
|
@ -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'
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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'};
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user