wrote some incomplete code to support native method definition - method(#native) ...

This commit is contained in:
hyunghwan.chung 2017-02-18 15:00:45 +00:00
parent 607e6c8502
commit 93e776a9d8
6 changed files with 92 additions and 27 deletions

View File

@ -4,7 +4,7 @@
## ##
class(#pointer) Class(Apex) class(#pointer) Class(Apex)
{ {
dcl spec selfspec superclass subclasses name instvars classvars classinstvars pooldics instmthdic classmthdic nsdic trsize. dcl spec selfspec superclass subclasses name modname instvars classvars classinstvars pooldics instmthdic classmthdic nsdic trsize.
method(#class) basicNew method(#class) basicNew
{ {

View File

@ -42,6 +42,12 @@
#define INVALID_IP MOO_TYPE_MAX(moo_oow_t) #define INVALID_IP MOO_TYPE_MAX(moo_oow_t)
#define PFTYPE_NONE 0
#define PFTYPE_NUMBERED 1
#define PFTYPE_NAMED 2
#define PFTYPE_EXCEPTION 3
#define PFTYPE_ENSURE 4
enum class_mod_t enum class_mod_t
{ {
CLASS_INDEXED = (1 << 0) CLASS_INDEXED = (1 << 0)
@ -2470,6 +2476,12 @@ static MOO_INLINE int set_superclass_fqn (moo_t* moo, const moo_oocs_t* name)
return 0; return 0;
} }
static MOO_INLINE int set_class_modname (moo_t* moo, const moo_oocs_t* name)
{
if (copy_string_to (moo, name, &moo->c->cls.modname, &moo->c->cls.modname_capa, 0, '\0') <= -1) return -1;
return 0;
}
static MOO_INLINE int add_class_level_variable (moo_t* moo, var_type_t index, const moo_oocs_t* name) static MOO_INLINE int add_class_level_variable (moo_t* moo, var_type_t index, const moo_oocs_t* name)
{ {
int n; int n;
@ -3368,7 +3380,7 @@ static int compile_method_primitive (moo_t* moo)
MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx)) MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx))
{ {
/* external named primitive containing a period. */ /* external named primitive containing a period. */
moo->c->mth.pftype = 2; moo->c->mth.pftype = PFTYPE_NAMED;
moo->c->mth.pfnum = lit_idx; moo->c->mth.pfnum = lit_idx;
break; break;
} }
@ -3383,7 +3395,7 @@ static int compile_method_primitive (moo_t* moo)
return -1; return -1;
} }
moo->c->mth.pftype = 1; moo->c->mth.pftype = PFTYPE_NUMBERED;
moo->c->mth.pfnum = pfnum; moo->c->mth.pfnum = pfnum;
break; break;
} }
@ -3398,11 +3410,11 @@ static int compile_method_primitive (moo_t* moo)
{ {
/* TODO: exception handler is supposed to be used by BlockContext on:do:. /* TODO: exception handler is supposed to be used by BlockContext on:do:.
* it needs to check the number of arguments at least */ * it needs to check the number of arguments at least */
moo->c->mth.pftype = 3; moo->c->mth.pftype = PFTYPE_EXCEPTION;
} }
else if (is_token_word(moo, VOCA_ENSURE)) else if (is_token_word(moo, VOCA_ENSURE))
{ {
moo->c->mth.pftype = 4; moo->c->mth.pftype = PFTYPE_ENSURE;
} }
else else
{ {
@ -5570,7 +5582,8 @@ static int add_compiled_method (moo_t* moo)
if (!name) return -1; if (!name) return -1;
moo_pushtmp (moo, (moo_oop_t*)&name); tmp_count++; moo_pushtmp (moo, (moo_oop_t*)&name); tmp_count++;
/* The variadic data part passed to moo_instantiate() is not GC-safe */ /* The variadic data part passed to moo_instantiate() is not GC-safe.
* let's delay initialization of variadic data a bit. */
#if defined(MOO_USE_METHOD_TRAILER) #if defined(MOO_USE_METHOD_TRAILER)
mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literal_count, moo->c->mth.code.ptr, moo->c->mth.code.len); mth = (moo_oop_method_t)moo_instantiatewithtrailer (moo, moo->_method, moo->c->mth.literal_count, moo->c->mth.code.ptr, moo->c->mth.code.len);
#else #else
@ -5706,24 +5719,24 @@ static int add_compiled_method (moo_t* moo)
} }
} }
} }
else if (moo->c->mth.pftype == 1) else if (moo->c->mth.pftype == PFTYPE_NUMBERED)
{ {
preamble_code = MOO_METHOD_PREAMBLE_PRIMITIVE; preamble_code = MOO_METHOD_PREAMBLE_PRIMITIVE;
preamble_index = moo->c->mth.pfnum; preamble_index = moo->c->mth.pfnum;
} }
else if (moo->c->mth.pftype == 2) else if (moo->c->mth.pftype == PFTYPE_NAMED)
{ {
preamble_code = MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE; preamble_code = MOO_METHOD_PREAMBLE_NAMED_PRIMITIVE;
preamble_index = moo->c->mth.pfnum; /* index to literal frame */ preamble_index = moo->c->mth.pfnum; /* index to literal frame */
} }
else if (moo->c->mth.pftype == 3) else if (moo->c->mth.pftype == PFTYPE_EXCEPTION)
{ {
preamble_code = MOO_METHOD_PREAMBLE_EXCEPTION; preamble_code = MOO_METHOD_PREAMBLE_EXCEPTION;
preamble_index = 0; preamble_index = 0;
} }
else else
{ {
MOO_ASSERT (moo, moo->c->mth.pftype == 4); MOO_ASSERT (moo, moo->c->mth.pftype == PFTYPE_ENSURE);
preamble_code = MOO_METHOD_PREAMBLE_ENSURE; preamble_code = MOO_METHOD_PREAMBLE_ENSURE;
preamble_index = 0; preamble_index = 0;
} }
@ -5789,7 +5802,7 @@ static int compile_method_definition (moo_t* moo)
moo->c->mth.literal_count = 0; moo->c->mth.literal_count = 0;
moo->c->mth.balit_count = 0; moo->c->mth.balit_count = 0;
moo->c->mth.arlit_count = 0; moo->c->mth.arlit_count = 0;
moo->c->mth.pftype = 0; moo->c->mth.pftype = PFTYPE_NONE;
moo->c->mth.pfnum = 0; moo->c->mth.pfnum = 0;
moo->c->mth.blk_depth = 0; moo->c->mth.blk_depth = 0;
moo->c->mth.code.len = 0; moo->c->mth.code.len = 0;
@ -5832,12 +5845,33 @@ static int compile_method_definition (moo_t* moo)
if (moo->c->mth.native) if (moo->c->mth.native)
{ {
moo_oow_t lit_idx;
if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD) if (TOKEN_TYPE(moo) != MOO_IOTOK_PERIOD)
{ {
/* . expected */ /* . expected */
set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo)); set_syntax_error (moo, MOO_SYNERR_PERIOD, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; return -1;
} }
/* TODO: i can check if the native method is available at compile time by querying the module.
* do the check depending on the compiler option */
//moo->c->cls.self_oop->modname + "." + moo->c->mth.name and make symbol.
#if 0
if (add_symbol_literal(moo, xxx, 0, &lit_idx) <= -1 ||
!MOO_OOI_IN_METHOD_PREAMBLE_INDEX_RANGE(lit_idx))
{
/* TODO: change error code */
set_syntax_error (moo, MOO_SYNERR_PFID, TOKEN_LOC(moo), MOO_NULL);
return -1;
}
/* external named primitive containing a period. */
moo->c->mth.pftype = PFTYPE_NAMED;
moo->c->mth.pfnum = lit_idx;
#endif
} }
else else
{ {
@ -5929,6 +5963,13 @@ static int make_defined_class (moo_t* moo)
if (!tmp) return -1; if (!tmp) return -1;
moo->c->cls.self_oop->name = (moo_oop_char_t)tmp; moo->c->cls.self_oop->name = (moo_oop_char_t)tmp;
if (moo->c->cls.modname.len > 0)
{
tmp = moo_makesymbol (moo, moo->c->cls.modname.ptr, moo->c->cls.modname.len);
if (!tmp) return -1;
moo->c->cls.self_oop->modname = tmp;
}
tmp = moo_makestring (moo, moo->c->cls.vars[VAR_INSTANCE].ptr, moo->c->cls.vars[VAR_INSTANCE].len); tmp = moo_makestring (moo, moo->c->cls.vars[VAR_INSTANCE].ptr, moo->c->cls.vars[VAR_INSTANCE].len);
if (!tmp) return -1; if (!tmp) return -1;
moo->c->cls.self_oop->instvars = (moo_oop_char_t)tmp; moo->c->cls.self_oop->instvars = (moo_oop_char_t)tmp;
@ -6000,8 +6041,6 @@ static int __compile_class_definition (moo_t* moo, int extend)
* NOTE: when extending a class, class-module-import and variable-definition are not allowed. * NOTE: when extending a class, class-module-import and variable-definition are not allowed.
*/ */
moo_oop_association_t ass; moo_oop_association_t ass;
moo_ooch_t modname[MOO_MOD_NAME_LEN_MAX + 1];
moo_oow_t modnamelen = 0;
if (!extend && TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN) if (!extend && TOKEN_TYPE(moo) == MOO_IOTOK_LPAREN)
{ {
@ -6096,6 +6135,8 @@ static int __compile_class_definition (moo_t* moo, int extend)
/* extending class */ /* extending class */
MOO_ASSERT (moo, moo->c->cls.flags == 0); MOO_ASSERT (moo, moo->c->cls.flags == 0);
MOO_INFO2 (moo, "Extending a class %.*js\n", moo->c->cls.fqn.len, moo->c->cls.fqn.ptr);
/*ass = moo_lookupsysdic(moo, &moo->c->cls.name);*/ /*ass = moo_lookupsysdic(moo, &moo->c->cls.name);*/
ass = moo_lookupdic(moo, moo->c->cls.ns_oop, &moo->c->cls.name); ass = moo_lookupdic(moo, moo->c->cls.ns_oop, &moo->c->cls.name);
if (ass && if (ass &&
@ -6118,8 +6159,8 @@ static int __compile_class_definition (moo_t* moo, int extend)
moo->c->cls.super_oop = moo->c->cls.self_oop->superclass; moo->c->cls.super_oop = moo->c->cls.self_oop->superclass;
MOO_ASSERT (moo, (moo_oop_t)moo->c->cls.super_oop == moo->_nil || MOO_ASSERT (moo, moo->c->cls.super_oop == moo->_nil ||
MOO_CLASSOF(moo, moo->c->cls.super_oop) == moo->_class); MOO_CLASSOF(moo, moo->c->cls.super_oop) == moo->_class);
} }
else else
{ {
@ -6243,6 +6284,8 @@ static int __compile_class_definition (moo_t* moo, int extend)
if (is_token_word (moo, VOCA_FROM)) if (is_token_word (moo, VOCA_FROM))
{ {
/* handle the module importing(from) part.
* class XXX from 'mod.name' */
GET_TOKEN (moo); GET_TOKEN (moo);
if (TOKEN_TYPE(moo) != MOO_IOTOK_STRLIT) if (TOKEN_TYPE(moo) != MOO_IOTOK_STRLIT)
{ {
@ -6250,16 +6293,20 @@ static int __compile_class_definition (moo_t* moo, int extend)
return -1; return -1;
} }
if (TOKEN_NAME_LEN(moo) < 1 || if (TOKEN_NAME_LEN(moo) <= 0 ||
TOKEN_NAME_LEN(moo) > MOO_MOD_NAME_LEN_MAX || TOKEN_NAME_LEN(moo) > MOO_MOD_NAME_LEN_MAX ||
moo_findoochar(TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo), '_')) moo_findoochar(TOKEN_NAME_PTR(moo), TOKEN_NAME_LEN(moo), '-') )
{ {
/* check for a bad module name.
* also disallow a dash in the name - i like converting
* a period to a dash when mapping the module name to an
* actual module file. disallowing a dash lowers confusion
* when loading a module. */
set_syntax_error (moo, MOO_SYNERR_MODNAME, TOKEN_LOC(moo), TOKEN_NAME(moo)); set_syntax_error (moo, MOO_SYNERR_MODNAME, TOKEN_LOC(moo), TOKEN_NAME(moo));
return -1; return -1;
} }
modnamelen = TOKEN_NAME_LEN(moo); if (set_class_modname (moo, TOKEN_NAME(moo)) <= -1) return -1;
moo_copyoochars (modname, TOKEN_NAME_PTR(moo), modnamelen);
GET_TOKEN (moo); GET_TOKEN (moo);
} }
@ -6367,17 +6414,25 @@ static int __compile_class_definition (moo_t* moo, int extend)
if (make_defined_class(moo) <= -1) return -1; if (make_defined_class(moo) <= -1) return -1;
if (modnamelen > 0) if (moo->c->cls.modname.len > 0)
{ {
if (moo_importmod (moo, moo->c->cls.self_oop, modname, modnamelen) <= -1) return -1; MOO_ASSERT (moo, MOO_CLASSOF(moo, moo->c->cls.self_oop->modname) == moo->_symbol);
/* [NOTE]
* even if the modname field is set in the class object itself
* by make_define_class(), i pass the module name in the compiler
* memory(not part of the object memory) to moo_importmod().
* no big overhead as it's already available. but Accessing
* this extra module name, i'm free from GC headache */
if (moo_importmod (moo, moo->c->cls.self_oop, moo->c->cls.modname.ptr, moo->c->cls.modname.len) <= -1) return -1;
} }
if (moo->c->cls.self_oop->trsize == moo->_nil && if (moo->c->cls.self_oop->trsize == moo->_nil &&
moo->c->cls.self_oop->superclass != moo->_nil) moo->c->cls.self_oop->superclass != moo->_nil)
{ {
/* [NOTE] /* the trailer size has not been set by the module importer.
* update the trailer size field after module importing * if the superclass has the trailer size set, this class must
* as the importer can set the trailer size legitimately */ * inherit so that the inherited methods work well when they
* access the trailer space */
moo->c->cls.self_oop->trsize = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trsize; moo->c->cls.self_oop->trsize = ((moo_oop_class_t)moo->c->cls.self_oop->superclass)->trsize;
} }
} }
@ -6419,10 +6474,14 @@ static int compile_class_definition (moo_t* moo, int extend)
moo->c->cls.indexed_type = MOO_OBJ_TYPE_OOP; moo->c->cls.indexed_type = MOO_OBJ_TYPE_OOP;
moo->c->cls.name.len = 0; moo->c->cls.name.len = 0;
moo->c->cls.fqn.len = 0;
moo->c->cls.supername.len = 0; moo->c->cls.supername.len = 0;
moo->c->cls.superfqn.len = 0;
MOO_MEMSET (&moo->c->cls.fqn_loc, 0, MOO_SIZEOF(moo->c->cls.fqn_loc)); MOO_MEMSET (&moo->c->cls.fqn_loc, 0, MOO_SIZEOF(moo->c->cls.fqn_loc));
MOO_MEMSET (&moo->c->cls.superfqn_loc, 0, MOO_SIZEOF(moo->c->cls.superfqn_loc)); MOO_MEMSET (&moo->c->cls.superfqn_loc, 0, MOO_SIZEOF(moo->c->cls.superfqn_loc));
moo->c->cls.modname.len = 0;
MOO_ASSERT (moo, MOO_COUNTOF(moo->c->cls.var_count) == MOO_COUNTOF(moo->c->cls.vars)); MOO_ASSERT (moo, MOO_COUNTOF(moo->c->cls.var_count) == MOO_COUNTOF(moo->c->cls.vars));
for (i = 0; i < MOO_COUNTOF(moo->c->cls.var_count); i++) for (i = 0; i < MOO_COUNTOF(moo->c->cls.var_count); i++)
{ {
@ -6769,6 +6828,7 @@ static void fini_compiler (moo_t* moo)
if (moo->c->tok.name.ptr) moo_freemem (moo, moo->c->tok.name.ptr); if (moo->c->tok.name.ptr) moo_freemem (moo, moo->c->tok.name.ptr);
if (moo->c->cls.fqn.ptr) moo_freemem (moo, moo->c->cls.fqn.ptr); if (moo->c->cls.fqn.ptr) moo_freemem (moo, moo->c->cls.fqn.ptr);
if (moo->c->cls.superfqn.ptr) moo_freemem (moo, moo->c->cls.superfqn.ptr); if (moo->c->cls.superfqn.ptr) moo_freemem (moo, moo->c->cls.superfqn.ptr);
if (moo->c->cls.modname.ptr) moo_freemem (moo, moo->c->cls.modname.ptr);
for (i = 0; i < MOO_COUNTOF(moo->c->cls.vars); i++) for (i = 0; i < MOO_COUNTOF(moo->c->cls.vars); i++)
{ {

View File

@ -364,9 +364,9 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags)
/* length including the prefix and the name. but excluding the postfix */ /* length including the prefix and the name. but excluding the postfix */
xlen = len + bcslen; xlen = len + bcslen;
/* convert a period(.) to a dash(-) */
for (i = len; i < xlen; i++) for (i = len; i < xlen; i++)
{ {
/* convert a period(.) to a dash(-) */
if (bufptr[i] == '.') bufptr[i] = '-'; if (bufptr[i] == '.') bufptr[i] = '-';
} }

View File

@ -451,6 +451,9 @@ struct moo_compiler_t
moo_oow_t superfqn_capa; moo_oow_t superfqn_capa;
moo_ioloc_t superfqn_loc; moo_ioloc_t superfqn_loc;
moo_oocs_t modname; /* module name after 'from' */
moo_oow_t modname_capa;
/* instance variable, class variable, class instance variable */ /* instance variable, class variable, class instance variable */
moo_oocs_t vars[3]; moo_oocs_t vars[3];
moo_oow_t vars_capa[3]; moo_oow_t vars_capa[3];

View File

@ -541,7 +541,8 @@ int moo_importmod (moo_t* moo, moo_oop_class_t _class, const moo_ooch_t* name, m
/* moo_openmod(), moo_closemod(), etc call a user-defined callback. /* moo_openmod(), moo_closemod(), etc call a user-defined callback.
* i need to protect _class in case the user-defined callback allocates * i need to protect _class in case the user-defined callback allocates
* a OOP memory chunk and GC occurs */ * a OOP memory chunk and GC occurs. */
moo_pushtmp (moo, (moo_oop_t*)&_class); moo_pushtmp (moo, (moo_oop_t*)&_class);
pair = moo_rbt_search (&moo->modtab, name, len); pair = moo_rbt_search (&moo->modtab, name, len);

View File

@ -446,7 +446,7 @@ struct moo_set_t
moo_oop_oop_t bucket; /* Array */ moo_oop_oop_t bucket; /* Array */
}; };
#define MOO_CLASS_NAMED_INSTVARS 13 #define MOO_CLASS_NAMED_INSTVARS 14
typedef struct moo_class_t moo_class_t; typedef struct moo_class_t moo_class_t;
typedef struct moo_class_t* moo_oop_class_t; typedef struct moo_class_t* moo_oop_class_t;
struct moo_class_t struct moo_class_t
@ -460,6 +460,7 @@ struct moo_class_t
moo_oop_t subclasses; /* Array of subclasses */ moo_oop_t subclasses; /* Array of subclasses */
moo_oop_char_t name; /* Symbol */ moo_oop_char_t name; /* Symbol */
moo_oop_t modname; /* Symbol if importing a module. nil if not. */
/* == NEVER CHANGE THIS ORDER OF 3 ITEMS BELOW == */ /* == NEVER CHANGE THIS ORDER OF 3 ITEMS BELOW == */
moo_oop_char_t instvars; /* String */ moo_oop_char_t instvars; /* String */