added moo_genpfmethods() and moo_findpfimpl() for convenience of writing primitive modules

This commit is contained in:
hyunghwan.chung
2017-02-14 10:25:26 +00:00
parent 71aa1110ed
commit f89d809cdc
10 changed files with 121 additions and 208 deletions

View File

@@ -26,6 +26,8 @@
#include "moo-prv.h"
#define DECODE_LOG_MASK (MOO_LOG_MNEMONIC)
#if defined(NDEBUG)
/* get rid of instruction logging regardless of the log mask
* in the release build */
@@ -34,7 +36,6 @@
# define LOG_INST_2(moo,fmt,a1,a2)
# define LOG_INST_3(moo,fmt,a1,a2,a3)
#else
# define DECODE_LOG_MASK (MOO_LOG_MNEMONIC)
# define LOG_INST_0(moo,fmt) MOO_LOG1(moo, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer)
# define LOG_INST_1(moo,fmt,a1) MOO_LOG2(moo, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1)
# define LOG_INST_2(moo,fmt,a1,a2) MOO_LOG3(moo, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2)

View File

@@ -1353,7 +1353,7 @@ static moo_pfrc_t pf_class (moo_t* moo, moo_ooi_t nargs)
static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
{
moo_oop_t _class, szoop, obj;
moo_oow_t size = 0, trsz = 0;
moo_oow_t size = 0; /* size of the variable/indexed part */
_class = MOO_STACK_GETRCV(moo, nargs);
if (MOO_CLASSOF(moo, _class) != moo->_class)
@@ -1375,15 +1375,17 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs)
}
if (MOO_OOP_IS_SMOOI(((moo_oop_class_t)_class)->trsize))
trsz = MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize);
/* moo_instantiate() ignores size if the instance specification
* disallows indexed(variable) parts. */
/* TODO: should i check the specification before calling
* moo_instantiate()? */
MOO_DEBUG2 (moo, "<basic new> SIZE ... %d TRSZ %d\n", (int)size, (int)trsz);
obj = trsz <= 0? moo_instantiate (moo, _class, MOO_NULL, size):
moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, trsz);
{
obj = moo_instantiatewithtrailer (moo, _class, size, MOO_NULL, MOO_OOP_TO_SMOOI(((moo_oop_class_t)_class)->trsize));
}
else
{
/* moo_instantiate() will ignore size if the instance specification
* disallows indexed(variable) parts. */
/* TODO: should i check the specification before calling
* moo_instantiate()? */
obj = moo_instantiate (moo, _class, MOO_NULL, size);
}
if (!obj) return MOO_PF_HARD_FAILURE;
MOO_STACK_SETRET (moo, nargs, obj);
@@ -1402,7 +1404,6 @@ static moo_pfrc_t pf_ngc_new (moo_t* moo, moo_ooi_t nargs)
* also allow NGC code in non-safe mode. in safe mode, ngc_new is same as normal new.
* ngc_dispose should not do anything in safe mode. */
return pf_basic_new (moo, nargs);
}
static moo_pfrc_t pf_ngc_dispose (moo_t* moo, moo_ooi_t nargs)
@@ -2629,7 +2630,7 @@ struct pf_t
moo_ooi_t min_nargs; /* expected number of arguments */
moo_ooi_t max_nargs; /* expected number of arguments */
moo_pfimpl_t handler;
const char* name; /* the name is supposed to be 7-bit ascii only */
const char* name; /* the name is supposed to be 7-bit ascii only */
};
typedef struct pf_t pf_t;

View File

@@ -982,16 +982,6 @@ moo_oop_t moo_allocwordobj (
moo_oow_t len
);
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_instantiatewithtrailer (
moo_t* moo,
moo_oop_t _class,
moo_oow_t vlen,
const moo_oob_t* tptr,
moo_oow_t tlen
);
#endif
/* ========================================================================= */
/* sym.c */
/* ========================================================================= */

View File

@@ -756,6 +756,52 @@ oops:
return -1;
}
int moo_genpfmethods (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount)
{
int ret = 0;
moo_oow_t i;
moo_pushtmp (moo, &_class);
for (i = 0; i < pfcount; i++)
{
if (moo_genpfmethod (moo, mod, _class, pfinfo[i].type, pfinfo[i].mthname, pfinfo[i].variadic, MOO_NULL) <= -1)
{
/* TODO: delete pfmethod generated??? */
ret = -1;
break;
}
}
moo_poptmp (moo);
return ret;
}
moo_pfimpl_t moo_findpfimpl (moo_t* moo, const moo_pfinfo_t* pfinfo, moo_oow_t pfcount, const moo_ooch_t* name)
{
int left, right, mid, n;
left = 0; right = pfcount - 1;
while (left <= right)
{
mid = (left + right) / 2;
n = moo_compoocstr (name, pfinfo[mid].mthname);
if (n < 0) right = mid - 1;
else if (n > 0) left = mid + 1;
else
{
return pfinfo[mid].handler;
}
}
moo->errnum = MOO_ENOENT;
return MOO_NULL;
}
/* -------------------------------------------------------------------------- */
int moo_setclasstrsize (moo_t* moo, moo_oop_t _class, moo_oow_t size)
{
register moo_oop_class_t c;
@@ -823,6 +869,7 @@ eperm:
return -1;
}
void* moo_getobjtrailer (moo_t* moo, moo_oop_t obj, moo_oow_t* size)
{
if (!MOO_OBJ_IS_OOP_POINTER(obj) || !MOO_OBJ_GET_FLAGS_TRAILER(obj)) return MOO_NULL;

View File

@@ -824,6 +824,16 @@ typedef moo_pfrc_t (*moo_pfimpl_t) (
moo_ooi_t nargs
);
typedef struct moo_pfinfo_t moo_pfinfo_t;
struct moo_pfinfo_t
{
moo_method_type_t type;
moo_ooch_t mthname[32];
int variadic;
moo_pfimpl_t handler;
};
typedef struct moo_mod_t moo_mod_t;
typedef int (*moo_mod_load_t) (
@@ -1347,6 +1357,14 @@ MOO_EXPORT moo_oop_t moo_instantiate (
moo_oow_t vlen
);
MOO_EXPORT moo_oop_t moo_instantiatewithtrailer (
moo_t* moo,
moo_oop_t _class,
moo_oow_t vlen,
const moo_oob_t* trptr,
moo_oow_t trlen
);
MOO_EXPORT moo_oop_t moo_shallowcopy (
moo_t* moo,
moo_oop_t oop
@@ -1497,6 +1515,21 @@ MOO_EXPORT int moo_genpfmethod (
const moo_ooch_t* name
);
MOO_EXPORT int moo_genpfmethods (
moo_t* moo,
moo_mod_t* mod,
moo_oop_t _class,
const moo_pfinfo_t* pfinfo,
moo_oow_t pfcount
);
MOO_EXPORT moo_pfimpl_t moo_findpfimpl (
moo_t* moo,
const moo_pfinfo_t* pfinfo,
moo_oow_t pfcount,
const moo_ooch_t* name
);
/* =========================================================================
* STRING ENCODING CONVERSION
* ========================================================================= */

View File

@@ -364,10 +364,7 @@ moo_oop_t moo_instantiate2 (moo_t* moo, moo_oop_t _class, const void* vptr, moo_
return oop;
}
#if defined(MOO_USE_METHOD_TRAILER)
moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, const moo_oob_t* tptr, moo_oow_t tlen)
moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vlen, const moo_oob_t* trptr, moo_oow_t trlen)
{
moo_oop_t oop;
moo_obj_type_t type;
@@ -387,14 +384,14 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl
switch (type)
{
case MOO_OBJ_TYPE_OOP:
oop = moo_allocoopobjwithtrailer(moo, alloclen, tptr, tlen);
oop = moo_allocoopobjwithtrailer(moo, alloclen, trptr, trlen);
break;
default:
MOO_DEBUG3 (moo, "Not allowed to instantiate a non-pointer object of the %.*js class with trailer %zu\n",
MOO_OBJ_GET_SIZE(((moo_oop_class_t)_class)->name),
MOO_OBJ_GET_CHAR_SLOT(((moo_oop_class_t)_class)->name),
tlen);
trlen);
moo->errnum = MOO_EPERM;
oop = MOO_NULL;
@@ -405,5 +402,4 @@ moo_oop_t moo_instantiatewithtrailer (moo_t* moo, moo_oop_t _class, moo_oow_t vl
moo_poptmps (moo, tmp_count);
return oop;
}
#endif