added moo_findmethodinclasschain()
added MOO_SYNERR_CLASSNCIFCE finished implementing interface conformance check primitively
This commit is contained in:
parent
a6a2cb2d16
commit
18b270529c
@ -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.
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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'
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
|
141
moo/lib/exec.c
141
moo/lib/exec.c
@ -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,
|
||||
|
@ -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));
|
||||
|
@ -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 */
|
||||
/* ========================================================================= */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user