added moo_findmethodinclasschain()

added MOO_SYNERR_CLASSNCIFCE
finished implementing interface conformance check primitively
This commit is contained in:
hyunghwan.chung 2018-10-12 09:09:45 +00:00
parent a6a2cb2d16
commit 18b270529c
10 changed files with 210 additions and 125 deletions

View File

@ -1,8 +1,14 @@
interface ClassInterface
{
method name.
method superclass.
}
##
## the Class object should be a variable-pointer object because
## it needs to accomodate class instance variables.
##
class(#pointer,#limited) Class(Apex)
class(#pointer,#limited) Class(Apex) [ClassInterface]
{
var spec, selfspec, superclass, subclasses, name, modname.
var instvars, classinstvars, classvars, pooldics.

View File

@ -3,7 +3,7 @@
interface X11able
{
method(#dual) abc.
method(#dual) def.
method(#dual,#liberal) def(x, y).
}
interface X11able2
{
@ -13,7 +13,7 @@ interface X11able2
interface X11able3
{
method(#dual) abc3.
method(#dual) class.
}
@ -33,8 +33,8 @@ class X11(Object) [X11able,selfns.X11able3] from 'x11'
var llevent_blocks.
method(#dual) abc { ^nil }
method(#dual) def { ^nil }
method(#dual) abc3 { ^nil }
method(#dual,#liberal) def(x, z) { ^nil }
###method(#dual) abc3 { ^nil }
interface X11able3
{

View File

@ -80,6 +80,7 @@ class MyObject(Object)
'duplicate name'
'undefined name'
'contradictory class definition'
'class not conforming to interface'
'invalid non-pointer instance size'
'prohibited inheritance'
'variable declaration not allowed'

View File

@ -4253,7 +4253,7 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
MOO_ASSERT (moo, moo->c->cunit->cunit_type == MOO_CUNIT_CLASS);
/* called inside a class definition */
if (cc->super_oop)
if (cc->in_class_body)
{
/* [NOTE]
* cls.ns_oop is set when the class name is enountered.
@ -4262,6 +4262,7 @@ static MOO_INLINE int find_dotted_ident (moo_t* moo, const moo_oocs_t* name, con
* on the other hand, cls.ns_oop is not MOO_NULL as long as
* cls.super_oop is not MOO_NULL.
*/
MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
/* cc->self_oop may still be MOO_NULL if the class has not been instantiated */
@ -4371,11 +4372,11 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
}
}
if (cc->super_oop)
if (cc->in_class_body)
{
/* called inside a class definition */
/* read a comment in find_dotted_ident() for the reason behind
* the if condition above. */
* the 'if' condition above. */
MOO_ASSERT (moo, cc->super_oop != MOO_NULL);
MOO_ASSERT (moo, cc->ns_oop != MOO_NULL);
@ -4384,7 +4385,7 @@ static MOO_INLINE int find_undotted_ident (moo_t* moo, const moo_oocs_t* name, c
{
/* if the current class being compiled has not been instantiated,
* no validation nor adjustment of the var->pos field is performed */
return cc->self_oop? validate_class_level_variable (moo, var, name, name_loc): 0;
return cc->self_oop? validate_class_level_variable(moo, var, name, name_loc): 0;
}
}
@ -7310,7 +7311,7 @@ static int make_defined_class (moo_t* moo)
/* this is an internally created class object being defined. */
MOO_ASSERT (moo, MOO_CLASSOF(moo, cc->self_oop) == moo->_class);
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_KERNEL(cc->self_oop) == 1);
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_KERNEL(cc->self_oop) == MOO_OBJ_FLAGS_KERNEL_IMMATURE);
if (spec != MOO_OOP_TO_SMOOI(cc->self_oop->spec) ||
self_spec != MOO_OOP_TO_SMOOI(cc->self_oop->selfspec))
@ -7341,7 +7342,7 @@ static int make_defined_class (moo_t* moo)
* if superclass is byte variable, the current class cannot be word variable or something else.
* TODO: TODO: TODO:
*/
MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, 2);
MOO_OBJ_SET_FLAGS_KERNEL (cc->self_oop, MOO_OBJ_FLAGS_KERNEL_MATURE);
cc->self_oop->superclass = cc->super_oop;
@ -7680,7 +7681,8 @@ static int process_class_superclass (moo_t* moo)
if (get_variable_info(moo, &cc->superfqn, &cc->superfqn_loc, superfqn_is_dotted, &var) <= -1) return -1;
if (var.type != VAR_GLOBAL) goto unknown_superclass;
if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class && MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != 1)
if (MOO_CLASSOF(moo, var.u.gbl->value) == moo->_class &&
MOO_OBJ_GET_FLAGS_KERNEL(var.u.gbl->value) != MOO_OBJ_FLAGS_KERNEL_IMMATURE)
{
/* the value found must be a class and it must not be an incomplete internal class object.
* 0(non-kernel object)
@ -7830,17 +7832,21 @@ struct ciim_t
};
typedef struct ciim_t ciim_t;
static int on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t ass, void* ctx)
static int ciim_on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t ass, void* ctx)
{
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);
ass = moo_lookupdic(moo, ciim->_class->mthdic[ciim->mth_type], &name);
if (!ass)
{/* TODO: change error code */
moo_setsynerrbfmt (moo, MOO_SYNERR_ARGFLOOD, MOO_NULL, MOO_NULL,
/* [IMPORT] the method lookup logic should be the same as moo_findmethod() in exec.c */
mth = moo_findmethodinclasschain(moo, ciim->_class, ciim->mth_type, &name);
if (!mth)
{
moo_setsynerrbfmt (moo, MOO_SYNERR_CLASSNCIFCE, MOO_NULL, MOO_NULL,
"%.*js not implementing %.*js>>%.*js",
MOO_OBJ_GET_SIZE(ciim->_class->name), MOO_OBJ_GET_CHAR_SLOT(ciim->_class->name),
MOO_OBJ_GET_SIZE(ciim->ifce->name), MOO_OBJ_GET_CHAR_SLOT(ciim->ifce->name),
@ -7849,7 +7855,31 @@ static int on_each_method (moo_t* moo, moo_oop_dic_t dic, moo_oop_association_t
return -1;
}
/* TODO: check preamble flags in signature */
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)))
{
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 */
{
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;
}
return 0;
}
@ -7860,12 +7890,12 @@ static int class_implements_interface (moo_t* moo, moo_oop_class_t _class, moo_o
ciim.ifce = ifce;
ciim._class = _class;
ciim.mth_type = MOO_METHOD_INSTANCE;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_INSTANCE], on_each_method, &ciim) <= -1) return 0;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_INSTANCE], ciim_on_each_method, &ciim) <= -1) return 0;
ciim.ifce = ifce;
ciim._class = _class;
ciim.mth_type = MOO_METHOD_CLASS;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_CLASS], on_each_method, &ciim) <= -1) return 0;
if (moo_walkdic(moo, ifce->mthdic[MOO_METHOD_CLASS], ciim_on_each_method, &ciim) <= -1) return 0;
return 1;
}
@ -7975,7 +8005,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name);
if (ass && MOO_CLASSOF(moo, ass->value) == moo->_class &&
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != 1)
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) != MOO_OBJ_FLAGS_KERNEL_IMMATURE)
{
/* the value must be a class object.
* and it must be either a user-defined(0) or completed kernel built-in(2).
@ -7999,7 +8029,8 @@ static int __compile_class_definition (moo_t* moo, int class_type)
ass = moo_lookupdic(moo, (moo_oop_dic_t)cc->ns_oop, &cc->name);
if (ass)
{
if (MOO_CLASSOF(moo, ass->value) != moo->_class || MOO_OBJ_GET_FLAGS_KERNEL(ass->value) > 1)
if (MOO_CLASSOF(moo, ass->value) != moo->_class ||
MOO_OBJ_GET_FLAGS_KERNEL(ass->value) == MOO_OBJ_FLAGS_KERNEL_MATURE)
{
/* the object found with the name is not a class object
* or the the class object found is a fully defined kernel
@ -8030,6 +8061,7 @@ static int __compile_class_definition (moo_t* moo, int class_type)
}
}
cc->in_class_body = 1;
if (TOKEN_TYPE(moo) != MOO_IOTOK_LBRACE)
{
moo_setsynerr (moo, MOO_SYNERR_LBRACE, TOKEN_LOC(moo), TOKEN_NAME(moo));

View File

@ -107,49 +107,50 @@ static moo_ooch_t synerrstr_27[] = {'p','r','i','m','i','t','i','v','e',':',' ',
static moo_ooch_t synerrstr_28[] = {'w','r','o','n','g',' ','d','i','r','e','c','t','i','v','e','\0'};
static moo_ooch_t synerrstr_29[] = {'w','r','o','n','g',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_30[] = {'d','u','p','l','i','c','a','t','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_31[] = {'u','n','d','e','f','i','n','e','d',' ','n','a','a','e','\0'};
static moo_ooch_t synerrstr_31[] = {'u','n','d','e','f','i','n','e','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_32[] = {'c','o','n','t','r','a','d','i','c','t','o','r','y',' ','c','l','a','s','s',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_33[] = {'i','n','v','a','l','i','d',' ','n','o','n','-','p','o','i','n','t','e','r',' ','i','n','s','t','a','n','c','e',' ','s','i','z','e','\0'};
static moo_ooch_t synerrstr_34[] = {'p','r','o','h','i','b','i','t','e','d',' ','i','n','h','e','r','i','t','a','n','c','e','\0'};
static moo_ooch_t synerrstr_35[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static moo_ooch_t synerrstr_36[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_37[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_38[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_39[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_40[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_41[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_42[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_43[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_44[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_45[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_46[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_47[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_48[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_49[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'};
static moo_ooch_t synerrstr_50[] = {'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_51[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_52[] = {'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_53[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'};
static moo_ooch_t synerrstr_54[] = {'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_55[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_56[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_57[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_58[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_59[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_60[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
static moo_ooch_t synerrstr_61[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_63[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_64[] = {'f','a','i','l','e','d',' ','t','o',' ','i','m','p','o','r','t',' ','m','o','d','u','l','e','\0'};
static moo_ooch_t synerrstr_65[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_66[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_67[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_68[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_69[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_70[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_71[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'};
static moo_ooch_t synerrstr_72[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_73[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_33[] = {'c','l','a','s','s',' ','n','o','t',' ','c','o','n','f','o','r','m','i','n','g',' ','t','o',' ','i','n','t','e','r','f','a','c','e','\0'};
static moo_ooch_t synerrstr_34[] = {'i','n','v','a','l','i','d',' ','n','o','n','-','p','o','i','n','t','e','r',' ','i','n','s','t','a','n','c','e',' ','s','i','z','e','\0'};
static moo_ooch_t synerrstr_35[] = {'p','r','o','h','i','b','i','t','e','d',' ','i','n','h','e','r','i','t','a','n','c','e','\0'};
static moo_ooch_t synerrstr_36[] = {'v','a','r','i','a','b','l','e',' ','d','e','c','l','a','r','a','t','i','o','n',' ','n','o','t',' ','a','l','l','o','w','e','d','\0'};
static moo_ooch_t synerrstr_37[] = {'m','o','d','i','f','i','e','r',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_38[] = {'w','r','o','n','g',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_39[] = {'d','i','s','a','l','l','o','w','e','d',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_40[] = {'d','u','p','l','i','c','a','t','e',' ','m','o','d','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_41[] = {'m','e','t','h','o','d',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_42[] = {'d','u','p','l','i','c','a','t','e',' ','m','e','t','h','o','d',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_43[] = {'i','n','v','a','l','i','d',' ','v','a','r','i','a','d','i','c',' ','m','e','t','h','o','d',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_44[] = {'v','a','r','i','a','b','l','e',' ','n','a','m','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_45[] = {'d','u','p','l','i','c','a','t','e',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_46[] = {'d','u','p','l','i','c','a','t','e',' ','t','e','m','p','o','r','a','r','y',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_47[] = {'d','u','p','l','i','c','a','t','e',' ','v','a','r','i','a','b','l','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_48[] = {'d','u','p','l','i','c','a','t','e',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_49[] = {'u','n','d','e','c','l','a','r','e','d',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_50[] = {'u','n','u','s','a','b','l','e',' ','v','a','r','i','a','b','l','e',' ','i','n',' ','c','o','m','p','i','l','e','d',' ','c','o','d','e','\0'};
static moo_ooch_t synerrstr_51[] = {'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_52[] = {'a','m','b','i','g','u','o','u','s',' ','v','a','r','i','a','b','l','e','\0'};
static moo_ooch_t synerrstr_53[] = {'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_54[] = {'i','n','a','c','c','e','s','s','i','b','l','e',' ','s','e','l','f','\0'};
static moo_ooch_t synerrstr_55[] = {'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_56[] = {'t','o','o',' ','m','a','n','y',' ','t','e','m','p','o','r','a','r','i','e','s','\0'};
static moo_ooch_t synerrstr_57[] = {'t','o','o',' ','m','a','n','y',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_58[] = {'t','o','o',' ','m','a','n','y',' ','b','l','o','c','k',' ','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',' ','b','l','o','c','k',' ','a','r','g','u','m','e','n','t','s','\0'};
static moo_ooch_t synerrstr_60[] = {'t','o','o',' ','l','a','r','g','e',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_61[] = {'t','o','o',' ','l','a','r','g','e',' ','a','r','r','a','y',' ','e','x','p','r','e','s','s','i','o','n','\0'};
static moo_ooch_t synerrstr_62[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','n','u','m','b','e','r','\0'};
static moo_ooch_t synerrstr_63[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','i','d','e','n','t','i','f','i','e','r','\0'};
static moo_ooch_t synerrstr_64[] = {'w','r','o','n','g',' ','p','r','i','m','i','t','i','v','e',' ','f','u','n','c','t','i','o','n',' ','a','r','g','u','m','e','n','t',' ','d','e','f','i','n','i','t','i','o','n','\0'};
static moo_ooch_t synerrstr_65[] = {'f','a','i','l','e','d',' ','t','o',' ','i','m','p','o','r','t',' ','m','o','d','u','l','e','\0'};
static moo_ooch_t synerrstr_66[] = {'#','i','n','c','l','u','d','e',' ','e','r','r','o','r','\0'};
static moo_ooch_t synerrstr_67[] = {'w','r','o','n','g',' ','p','r','a','g','m','a',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_68[] = {'w','r','o','n','g',' ','n','a','m','e','s','p','a','c','e',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_69[] = {'w','r','o','n','g',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_70[] = {'d','u','p','l','i','c','a','t','e',' ','p','o','o','l','d','i','c','i','m','p','o','r','t',' ','n','a','m','e','\0'};
static moo_ooch_t synerrstr_71[] = {'l','i','t','e','r','a','l',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t synerrstr_72[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','n','o','t',' ','w','i','t','h','i','n',' ','a',' ','l','o','o','p','\0'};
static moo_ooch_t synerrstr_73[] = {'b','r','e','a','k',' ','o','r',' ','c','o','n','t','i','n','u','e',' ','w','i','t','h','i','n',' ','a',' ','b','l','o','c','k','\0'};
static moo_ooch_t synerrstr_74[] = {'w','h','i','l','e',' ','e','x','p','e','c','t','e','d','\0'};
static moo_ooch_t* synerrstr[] =
{
synerrstr_0, synerrstr_1, synerrstr_2, synerrstr_3, synerrstr_4, synerrstr_5, synerrstr_6, synerrstr_7,
@ -161,7 +162,7 @@ static moo_ooch_t* synerrstr[] =
synerrstr_48, synerrstr_49, synerrstr_50, synerrstr_51, synerrstr_52, synerrstr_53, synerrstr_54, synerrstr_55,
synerrstr_56, synerrstr_57, synerrstr_58, synerrstr_59, synerrstr_60, synerrstr_61, synerrstr_62, synerrstr_63,
synerrstr_64, synerrstr_65, synerrstr_66, synerrstr_67, synerrstr_68, synerrstr_69, synerrstr_70, synerrstr_71,
synerrstr_72, synerrstr_73
synerrstr_72, synerrstr_73, synerrstr_74
};
#endif
/* END: GENERATED WITH generr.moo */

View File

@ -1620,82 +1620,107 @@ static MOO_INLINE int activate_new_method (moo_t* moo, moo_oop_method_t mth, moo
return 0;
}
MOO_INLINE moo_oop_method_t find_method_in_class (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_association_t ass;
moo_oop_dic_t mthdic;
mthdic = _class->mthdic[mth_type];
/* if a kernel class is not defined in the bootstrapping code,
* the method dictionary is still nil. you must define all the initial
* kernel classes properly before you can use this function */
MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil);
MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary);
ass = (moo_oop_association_t)moo_lookupdic(moo, mthdic, name);
if (ass)
{
/* found the method */
MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method);
return (moo_oop_method_t)ass->value;
}
/* NOTE: moo_seterrXXX() is not called here */
return MOO_NULL;
}
MOO_INLINE moo_oop_method_t find_method_in_class_chain (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
do
{
mth = find_method_in_class(moo, _class, mth_type, name);
if (mth) return mth;
_class = (moo_oop_class_t)_class->superclass;
}
while ((moo_oop_t)_class != moo->_nil);
/* NOTE: moo_seterrXXX() is not called here */
return MOO_NULL;
}
moo_oop_method_t moo_findmethodinclass (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
mth = find_method_in_class(moo, _class, mth_type, name);
if (!mth) moo_seterrnum (moo, MOO_ENOENT);
return mth;
}
moo_oop_method_t moo_findmethodinclasschain (moo_t* moo, moo_oop_class_t _class, int mth_type, const moo_oocs_t* name)
{
moo_oop_method_t mth;
mth = find_method_in_class_chain(moo, _class, mth_type, name);
if (!mth) moo_seterrnum (moo, MOO_ENOENT);
return mth;
}
moo_oop_method_t moo_findmethod (moo_t* moo, moo_oop_t receiver, const moo_oocs_t* message, int super)
{
moo_oop_class_t cls;
moo_oop_association_t ass;
moo_oop_t c;
moo_oop_dic_t mthdic;
int dic_no;
/* TODO: implement method lookup cache */
moo_oop_class_t _class;
moo_oop_class_t c;
int mth_type;
moo_oop_method_t mth;
cls = MOO_CLASSOF(moo, receiver);
if (cls == moo->_class)
_class = MOO_CLASSOF(moo, receiver);
if (_class == moo->_class)
{
/* receiver is a class object (an instance of Class) */
c = receiver;
dic_no = MOO_METHOD_CLASS;
c = (moo_oop_class_t)receiver;
mth_type = MOO_METHOD_CLASS;
}
else
{
/* receiver is not a class object. so take its class */
c = (moo_oop_t)cls;
dic_no = MOO_METHOD_INSTANCE;
c = _class;
mth_type = MOO_METHOD_INSTANCE;
}
MOO_ASSERT (moo, c != moo->_nil);
MOO_ASSERT (moo, (moo_oop_t)c != moo->_nil);
if (super)
{
/*
moo_oop_method_t m;
MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->active_context->origin) == moo->_method_context);
m = (moo_oop_method_t)moo->active_context->origin->method_or_nargs;
c = ((moo_oop_class_t)m->owner)->superclass;
*/
MOO_ASSERT (moo, moo->active_method);
MOO_ASSERT (moo, moo->active_method->owner);
c = ((moo_oop_class_t)moo->active_method->owner)->superclass;
if (c == moo->_nil) goto not_found; /* reached the top of the hierarchy */
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 hierarch.
// otherwise c points to a class object
}
do
{
mthdic = ((moo_oop_class_t)c)->mthdic[dic_no];
/* if a kernel class is not defined in the bootstrapping code,
* the method dictionary is still nil. the initial kernel classes
* must all be defined properly */
MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil);
MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary);
ass = (moo_oop_association_t)moo_lookupdic (moo, mthdic, message);
if (ass)
{
/* found the method */
MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method);
return (moo_oop_method_t)ass->value;
}
c = ((moo_oop_class_t)c)->superclass;
}
while (c != moo->_nil);
/* [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) return mth;
not_found:
if (cls == moo->_class)
if (_class == moo->_class)
{
/* the object is an instance of Class. find the method
* in an instance method dictionary of Class also */
mthdic = ((moo_oop_class_t)cls)->mthdic[MOO_METHOD_INSTANCE];
MOO_ASSERT (moo, (moo_oop_t)mthdic != moo->_nil);
MOO_ASSERT (moo, MOO_CLASSOF(moo, mthdic) == moo->_method_dictionary);
ass = (moo_oop_association_t)moo_lookupdic (moo, mthdic, message);
if (ass)
{
MOO_ASSERT (moo, MOO_CLASSOF(moo, ass->value) == moo->_method);
return (moo_oop_method_t)ass->value;
}
mth = find_method_in_class(moo, _class, MOO_METHOD_INSTANCE, message);
if (mth) return mth;
}
MOO_LOG3 (moo, MOO_LOG_DEBUG, "Method '%.*js' not found in %O\n", message->len, message->ptr, receiver);
@ -1727,14 +1752,14 @@ static int start_initial_process_and_context (moo_t* moo, const moo_oocs_t* objn
#if defined(INVOKE_DIRECTLY)
ass = moo_lookupsysdic (moo, objname);
ass = moo_lookupsysdic(moo, objname);
if (!ass || MOO_CLASSOF(moo, ass->value) != moo->_class)
{
MOO_LOG2 (moo, MOO_LOG_DEBUG, "Cannot find a class '%.*js'", objname->len, objname->ptr);
return -1;
}
mth = moo_findmethod (moo, ass->value, mthname, 0);
mth = moo_findmethod(moo, ass->value, mthname, 0);
if (!mth)
{
MOO_LOG4 (moo, MOO_LOG_DEBUG, "Cannot find a method %.*js>>%.*js", objname->len, objname->ptr, mthname->len, mthname->ptr);
@ -1758,7 +1783,7 @@ TODO: overcome this problem - accept parameters....
startup.ptr = str_startup;
startup.len = 7;
mth = moo_findmethod (moo, (moo_oop_t)moo->_system, &startup, 0);
mth = moo_findmethod(moo, (moo_oop_t)moo->_system, &startup, 0);
if (!mth)
{
MOO_LOG0 (moo, MOO_LOG_DEBUG, "Cannot find the startup method in the system class");
@ -4016,7 +4041,7 @@ static int send_message (moo_t* moo, moo_oop_char_t selector, int to_super, moo_
mthname.ptr = fbm;
mthname.len = 18;
method = moo_findmethod (moo, receiver, &mthname, 0);
method = moo_findmethod(moo, receiver, &mthname, 0);
if (!method)
{
/* this must not happen as long as doesNotUnderstand: is implemented under Apex.
@ -4053,7 +4078,7 @@ static int send_message_with_str (moo_t* moo, const moo_ooch_t* nameptr, moo_oow
mthname.ptr = (moo_ooch_t*)nameptr;
mthname.len = namelen;
method = moo_findmethod (moo, receiver, &mthname, to_super);
method = moo_findmethod(moo, receiver, &mthname, to_super);
if (!method)
{
MOO_LOG4 (moo, MOO_LOG_IC | MOO_LOG_FATAL,

View File

@ -409,7 +409,7 @@ static moo_oop_class_t alloc_kernel_class (moo_t* moo, int class_flags, moo_oow_
c = (moo_oop_class_t)moo_allocoopobj (moo, MOO_CLASS_NAMED_INSTVARS + num_classvars);
if (!c) return MOO_NULL;
MOO_OBJ_SET_FLAGS_KERNEL (c, 1);
MOO_OBJ_SET_FLAGS_KERNEL (c, MOO_OBJ_FLAGS_KERNEL_IMMATURE);
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(num_classvars, 0, class_flags));

View File

@ -607,6 +607,7 @@ struct moo_cunit_class_t
moo_ioloc_t modname_loc;
moo_oopbuf_t ifces;
int in_class_body; /* set to non-zero after '{' has been encountered */
/* instance variable, class variable, class instance variable, constant
* var[0] - named instance variables
@ -1426,6 +1427,20 @@ moo_oop_method_t moo_findmethod (
int super
);
moo_oop_method_t moo_findmethodinclass (
moo_t* moo,
moo_oop_class_t _class,
int mth_type,
const moo_oocs_t* name
);
moo_oop_method_t moo_findmethodinclasschain (
moo_t* moo,
moo_oop_class_t _class,
int mth_type,
const moo_oocs_t* name
);
/* ========================================================================= */
/* moo.c */
/* ========================================================================= */

View File

@ -446,6 +446,10 @@ typedef enum moo_gcfin_t moo_gcfin_t;
(((moo_oow_t)(r)) << MOO_OBJ_FLAGS_TRAILER_SHIFT) \
)
#define MOO_OBJ_FLAGS_KERNEL_USER 0
#define MOO_OBJ_FLAGS_KERNEL_IMMATURE 1
#define MOO_OBJ_FLAGS_KERNEL_MATURE 2
#define MOO_OBJ_HEADER \
moo_oow_t _flags; \
moo_oow_t _size; \
@ -1684,6 +1688,7 @@ enum moo_synerrnum_t
MOO_SYNERR_NAMEDUPL, /* duplicate name */
MOO_SYNERR_NAMEUNDEF, /* undefined name */
MOO_SYNERR_CLASSCONTRA, /* contradictory class */
MOO_SYNERR_CLASSNCIFCE, /* class not conforming to interface */
MOO_SYNERR_NPINSTSIZEINVAL, /* invalid non-pointer instance size */
MOO_SYNERR_INHERITBANNED, /* prohibited inheritance */
MOO_SYNERR_VARDCLBANNED, /* variable declaration not allowed */

View File

@ -795,7 +795,7 @@ moo_pfrc_t moo_pf_responds_to (moo_t* moo, moo_mod_t* mod, moo_ooi_t nargs)
mthname.ptr = MOO_OBJ_GET_CHAR_SLOT(selector);
mthname.len = MOO_OBJ_GET_SIZE(selector);
if (moo_findmethod (moo, rcv, &mthname, 0))
if (moo_findmethod(moo, rcv, &mthname, 0))
{
MOO_STACK_SETRET (moo, nargs, moo->_true);
}