enhanced the primitive module loader such that it can load multiple primitmive groups from a single module file.

fixed a bug of setting errnum wrongly in character conversion functions
This commit is contained in:
hyunghwan.chung
2017-02-13 13:25:42 +00:00
parent ff122bdcc8
commit 73231a29d7
12 changed files with 218 additions and 101 deletions

View File

@ -68,11 +68,12 @@ libmoo_la_LDFLAGS = $(LDFLAGS_LIB_COMMON)
libmoo_la_LIBADD = $(LIBADD_LIB_COMMON)
if ENABLE_STATIC_MODULE
libmoo_la_LIBADD += -lmoo-ffi -lmoo-console -lmoo-stdio
libmoo_la_LIBADD += -lmoo-ffi -lmoo-console -lmoo-stdio -lmoo-x11
libmoo_la_DEPENDENCIES = \
$(abs_builddir)/../mod/libmoo-ffi.la \
$(abs_builddir)/../mod/libmoo-console.la \
$(abs_builddir)/../mod/libmoo-stdio.la
$(abs_builddir)/../mod/libmoo-stdio.la \
$(abs_builddir)/../mod/libmoo-x11.la
endif
bin_PROGRAMS = moo

View File

@ -95,7 +95,7 @@ host_triplet = @host@
# to the first number in -version-info above
@WIN32_TRUE@am__append_3 = -DMOO_DEFAULT_MODPREFIX=\"libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"-1\"
@WIN32_FALSE@am__append_4 = -DMOO_DEFAULT_MODPREFIX=\"$(libdir)/libmoo-\" -DMOO_DEFAULT_MODPOSTFIX=\"\"
@ENABLE_STATIC_MODULE_TRUE@am__append_5 = -lmoo-ffi -lmoo-console -lmoo-stdio
@ENABLE_STATIC_MODULE_TRUE@am__append_5 = -lmoo-ffi -lmoo-console -lmoo-stdio -lmoo-x11
@ENABLE_STATIC_MODULE_FALSE@libmoo_la_DEPENDENCIES = \
@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_3) \
@ENABLE_STATIC_MODULE_FALSE@ $(am__DEPENDENCIES_1)
@ -448,7 +448,8 @@ libmoo_la_LIBADD = $(LIBADD_LIB_COMMON) $(am__append_5)
@ENABLE_STATIC_MODULE_TRUE@libmoo_la_DEPENDENCIES = \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libmoo-ffi.la \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libmoo-console.la \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libmoo-stdio.la
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libmoo-stdio.la \
@ENABLE_STATIC_MODULE_TRUE@ $(abs_builddir)/../mod/libmoo-x11.la
moo_SOURCES = main.c
moo_CPPFLAGS = $(CPPFLAGS_LIB_COMMON)

View File

@ -26,13 +26,20 @@
#include "moo-prv.h"
#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)
#define LOG_INST_3(moo,fmt,a1,a2,a3) MOO_LOG4(moo, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3)
#if defined(NDEBUG)
/* get rid of instruction logging regardless of the log mask
* in the release build */
# define LOG_INST_0(moo,fmt)
# define LOG_INST_1(moo,fmt,a1)
# 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)
# define LOG_INST_3(moo,fmt,a1,a2,a3) MOO_LOG4(moo, DECODE_LOG_MASK, " %06zd " fmt "\n", fetched_instruction_pointer, a1, a2, a3)
#endif
#define FETCH_BYTE_CODE(moo) (cdptr[ip++])
#define FETCH_BYTE_CODE_TO(moo,v_oow) (v_oow = FETCH_BYTE_CODE(moo))

View File

@ -2871,31 +2871,34 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
/*sp = moo->sp;*/
sb = moo->sp - nargs - 1; /* stack base before receiver and arguments */
#if !defined(NDEBUG)
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
LOG_INST_1 (moo, "preamble_named_primitive %zd", pf_name_index);
MOO_ASSERT (moo, pf_name_index >= 0);
/* merge two SmallIntegers to get a full pointer */
name = method->slot[pf_name_index];
MOO_ASSERT (moo, MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR));
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(name));
MOO_ASSERT (moo, MOO_CLASSOF(moo,name) == moo->_symbol);
#endif
/* merge two SmallIntegers to get a full pointer from the cached data */
w = (moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[0]) << (MOO_OOW_BITS / 2) |
(moo_oow_t)MOO_OOP_TO_SMOOI(method->preamble_data[1]);
handler = (moo_pfimpl_t)w;
if (handler) goto exec_handler;
else
{
MOO_ASSERT (moo, pf_name_index >= 0);
name = method->slot[pf_name_index];
MOO_ASSERT (moo, MOO_ISTYPEOF(moo,name,MOO_OBJ_TYPE_CHAR));
MOO_ASSERT (moo, MOO_OBJ_GET_FLAGS_EXTRA(name));
MOO_ASSERT (moo, MOO_CLASSOF(moo,name) == moo->_symbol);
handler = moo_querymod (moo, ((moo_oop_char_t)name)->slot, MOO_OBJ_GET_SIZE(name));
}
#if defined(NDEBUG)
pf_name_index = MOO_METHOD_GET_PREAMBLE_INDEX(preamble);
name = method->slot[pf_name_index];
#endif
handler = moo_querymod (moo, ((moo_oop_char_t)name)->slot, MOO_OBJ_GET_SIZE(name));
if (handler)
{
int n;
/* split a pointer to two OOP fields as SmallIntegers for storing. */
/* split a pointer to two OOP fields as SmallIntegers for storing/caching. */
method->preamble_data[0] = MOO_SMOOI_TO_OOP((moo_oow_t)handler >> (MOO_OOW_BITS / 2));
method->preamble_data[1] = MOO_SMOOI_TO_OOP((moo_oow_t)handler & MOO_LBMASK(moo_oow_t, MOO_OOW_BITS / 2));
@ -2913,18 +2916,18 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs)
moo_poptmp (moo);
if (n <= MOO_PF_HARD_FAILURE)
{
MOO_DEBUG2 (moo, "Hard failure indicated by primitive function %p - return code %d\n", handler, n);
MOO_DEBUG4 (moo, "Hard failure indicated by primitive function %p - %.*js - return code %d\n", handler, MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot, n);
return -1; /* hard primitive failure */
}
if (n >= MOO_PF_SUCCESS) break; /* primitive ok*/
/* soft primitive failure */
MOO_DEBUG1 (moo, "Soft failure indicated by primitive function %p\n", handler);
MOO_DEBUG3 (moo, "Soft failure indicated by primitive function %p - %.*js\n", handler, MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot);
}
else
{
/* no handler found */
MOO_DEBUG0 (moo, "Soft failure for non-existent primitive function\n");
MOO_DEBUG2 (moo, "Soft failure for non-existent primitive function - %.*js\n", MOO_OBJ_GET_SIZE(name), ((moo_oop_char_t)name)->slot);
}
#if defined(MOO_USE_OBJECT_TRAILER)

View File

@ -349,7 +349,7 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags)
if (flags & MOO_VMPRIM_OPENDL_PFMOD)
{
moo_oow_t len;
moo_oow_t len, i, xlen;
/* opening a primitive function module - mostly libmoo-xxxx */
len = moo_copybcstr (bufptr, bufcapa, MOO_DEFAULT_PFMODPREFIX);
@ -360,16 +360,43 @@ static void* dl_open (moo_t* moo, const moo_ooch_t* name, int flags)
#else
bcslen = moo_copybcstr (&bufptr[len], bcslen, name);
#endif
moo_copybcstr (&bufptr[bcslen + len], bufcapa - bcslen - len, MOO_DEFAULT_PFMODPOSTFIX);
/* length including the prefix and the name. but excluding the postfix */
xlen = len + bcslen;
/* convert a period(.) to a dash(-) */
for (i = len; i < xlen; i++)
{
if (bufptr[i] == '.') bufptr[i] = '-';
}
retry:
moo_copybcstr (&bufptr[xlen], bufcapa - xlen, MOO_DEFAULT_PFMODPOSTFIX);
/* both prefix and postfix attached. for instance, libmoo-xxx */
handle = lt_dlopenext (bufptr);
if (!handle)
{
MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %hs\n", bufptr, name, lt_dlerror());
bufptr[bcslen + len] = '\0';
/* try without prefix and postfix */
bufptr[xlen] = '\0';
handle = lt_dlopenext (&bufptr[len]);
if (!handle) MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %s\n", &bufptr[len], name, lt_dlerror());
if (!handle)
{
moo_bch_t* dash;
MOO_DEBUG3 (moo, "Failed to open(ext) DL %hs[%js] - %s\n", &bufptr[len], name, lt_dlerror());
dash = moo_rfindbchar (bufptr, moo_countbcstr(bufptr), '-');
if (dash)
{
/* remove a segment at the back.
* [NOTE] a dash contained in the original name before
* period-to-dash transformation may cause extraneous/wrong
* loading reattempts. */
xlen = dash - bufptr;
goto retry;
}
}
else MOO_DEBUG3 (moo, "Opened(ext) DL %hs[%js] handle %p\n", &bufptr[len], name, handle);
}
else
@ -429,7 +456,7 @@ static void* dl_getsym (moo_t* moo, void* handle, const moo_ooch_t* name)
{
#if defined(USE_LTDL)
moo_bch_t stabuf[64], * bufptr;
moo_oow_t bufcapa, ucslen, bcslen;
moo_oow_t bufcapa, ucslen, bcslen, i;
const moo_bch_t* symname;
void* sym;
@ -458,6 +485,9 @@ static void* dl_getsym (moo_t* moo, void* handle, const moo_ooch_t* name)
bcslen = moo_copybcstr (&bufptr[1], bcslen, name);
#endif
/* convert a period(.) to an underscore(_) */
for (i = 1; i <= bcslen; i++) if (bufptr[i] == '.') bufptr[i] = '_';
symname = &bufptr[1]; /* try the name as it is */
sym = lt_dlsym (handle, symname);
if (!sym)

View File

@ -359,6 +359,7 @@ void moo_freemem (moo_t* moo, void* ptr)
#include "../mod/console.h"
#include "../mod/_ffi.h"
#include "../mod/_stdio.h"
#include "../mod/_x11.h"
static struct
{
@ -367,9 +368,11 @@ static struct
}
static_modtab[] =
{
{ "console", moo_mod_console },
{ "ffi", moo_mod_ffi },
{ "stdio", moo_mod_stdio },
{ "console", moo_mod_console },
{ "ffi", moo_mod_ffi },
{ "stdio", moo_mod_stdio },
{ "x11", moo_mod_x11 },
{ "x11.win", moo_mod_x11_win }
};
#endif
@ -420,8 +423,10 @@ moo_mod_data_t* moo_openmod (moo_t* moo, const moo_ooch_t* name, moo_oow_t namel
if (n >= MOO_COUNTOF(static_modtab))
{
MOO_DEBUG2 (moo, "Cannot find a static module [%.*js]\n", namelen, name);
moo->errnum = MOO_ENOENT;
return MOO_NULL;
/* TODO: fall back to find dynamic module further on supported platforms instead of returning error here... */
}
if (load)
@ -593,11 +598,11 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen
moo_oow_t mod_name_len;
moo_pfimpl_t handler;
sep = moo_findoochar (pfid, pfidlen, '.');
sep = moo_rfindoochar (pfid, pfidlen, '.');
if (!sep)
{
/* i'm writing a conservative code here. the compiler should
* guarantee that an underscore is included in an primitive identifer.
* guarantee that a period is included in an primitive identifer.
* what if the compiler is broken? imagine a buggy compiler rewritten
* in moo itself? */
MOO_DEBUG2 (moo, "Internal error - no period in a primitive function identifier [%.*js] - buggy compiler?\n", pfidlen, pfid);
@ -607,6 +612,10 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen
mod_name_len = sep - pfid;
/* the first through the segment before the last compose a module id.
* the last segment is the primitive function name.
* for instance, in con.window.open, con.window is a module id and
* open is the primitive function name. */
pair = moo_rbt_search (&moo->modtab, pfid, mod_name_len);
if (pair)
{
@ -615,13 +624,14 @@ moo_pfimpl_t moo_querymod (moo_t* moo, const moo_ooch_t* pfid, moo_oow_t pfidlen
}
else
{
/* open a module using the part before the last period */
mdp = moo_openmod (moo, pfid, mod_name_len);
if (!mdp) return MOO_NULL;
}
if ((handler = mdp->mod.query (moo, &mdp->mod, sep + 1)) == MOO_NULL)
{
/* the primitive function is not found. keep the module open */
/* the primitive function is not found. but keep the module open even if it's opened above */
MOO_DEBUG2 (moo, "Cannot find a primitive function [%js] in a module [%js]\n", sep + 1, mdp->mod.name);
moo->errnum = MOO_ENOENT; /* TODO: proper error code and handling */
return MOO_NULL;
@ -696,6 +706,8 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty
return -1;
}
MOO_DEBUG3 (moo, ">>>> PFGEN X11 [%.*js] %js\n", moo->sbuf[0].len, moo->sbuf[0].ptr, mod->name);
pfidsym = (moo_oop_char_t)moo_makesymbol (moo, moo->sbuf[0].ptr, moo->sbuf[0].len);
if (!pfidsym)
{
@ -728,7 +740,7 @@ int moo_genpfmethod (moo_t* moo, moo_mod_t* mod, moo_oop_t _class, moo_method_ty
mth->tmpr_count = MOO_SMOOI_TO_OOP(arg_count);
mth->tmpr_nargs = MOO_SMOOI_TO_OOP(arg_count);
/* TODO: emit BCODE_RETURN_NIL ? */
/* TODO: emit BCODE_RETURN_NIL as a fallback or self primitiveFailed? or anything else?? */
if (!moo_putatdic (moo, cls->mthdic[type], (moo_oop_t)mnsym, (moo_oop_t)mth))
{

View File

@ -1081,13 +1081,27 @@ typedef enum moo_log_mask_t moo_log_mask_t;
#define MOO_LOG5(moo,mask,fmt,a1,a2,a3,a4,a5) do { if (MOO_LOG_ENABLED(moo,mask)) moo_logbfmt(moo, mask, fmt, a1, a2, a3, a4, a5); } while(0)
#define MOO_LOG6(moo,mask,fmt,a1,a2,a3,a4,a5,a6) do { if (MOO_LOG_ENABLED(moo,mask)) moo_logbfmt(moo, mask, fmt, a1, a2, a3, a4, a5, a6); } while(0)
#define MOO_DEBUG0(moo,fmt) MOO_LOG0(moo, MOO_LOG_DEBUG, fmt)
#define MOO_DEBUG1(moo,fmt,a1) MOO_LOG1(moo, MOO_LOG_DEBUG, fmt, a1)
#define MOO_DEBUG2(moo,fmt,a1,a2) MOO_LOG2(moo, MOO_LOG_DEBUG, fmt, a1, a2)
#define MOO_DEBUG3(moo,fmt,a1,a2,a3) MOO_LOG3(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3)
#define MOO_DEBUG4(moo,fmt,a1,a2,a3,a4) MOO_LOG4(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4)
#define MOO_DEBUG5(moo,fmt,a1,a2,a3,a4,a5) MOO_LOG5(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4, a5)
#define MOO_DEBUG6(moo,fmt,a1,a2,a3,a4,a5,a6) MOO_LOG6(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4, a5, a6)
#if defined(NDEBUG)
/* [NOTE]
* get rid of debugging message totally regardless of
* the log mask in the release build.
*/
# define MOO_DEBUG0(moo,fmt)
# define MOO_DEBUG1(moo,fmt,a1)
# define MOO_DEBUG2(moo,fmt,a1,a2)
# define MOO_DEBUG3(moo,fmt,a1,a2,a3)
# define MOO_DEBUG4(moo,fmt,a1,a2,a3,a4)
# define MOO_DEBUG5(moo,fmt,a1,a2,a3,a4,a5)
# define MOO_DEBUG6(moo,fmt,a1,a2,a3,a4,a5,a6)
#else
# define MOO_DEBUG0(moo,fmt) MOO_LOG0(moo, MOO_LOG_DEBUG, fmt)
# define MOO_DEBUG1(moo,fmt,a1) MOO_LOG1(moo, MOO_LOG_DEBUG, fmt, a1)
# define MOO_DEBUG2(moo,fmt,a1,a2) MOO_LOG2(moo, MOO_LOG_DEBUG, fmt, a1, a2)
# define MOO_DEBUG3(moo,fmt,a1,a2,a3) MOO_LOG3(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3)
# define MOO_DEBUG4(moo,fmt,a1,a2,a3,a4) MOO_LOG4(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4)
# define MOO_DEBUG5(moo,fmt,a1,a2,a3,a4,a5) MOO_LOG5(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4, a5)
# define MOO_DEBUG6(moo,fmt,a1,a2,a3,a4,a5,a6) MOO_LOG6(moo, MOO_LOG_DEBUG, fmt, a1, a2, a3, a4, a5, a6)
#endif
#define MOO_INFO0(moo,fmt) MOO_LOG0(moo, MOO_LOG_INFO, fmt)
#define MOO_INFO1(moo,fmt,a1) MOO_LOG1(moo, MOO_LOG_INFO, fmt, a1)

View File

@ -631,8 +631,11 @@ int moo_convbtouchars (moo_t* moo, const moo_bch_t* bcs, moo_oow_t* bcslen, moo_
n = bcsn_to_ucsn_with_cmgr (bcs, bcslen, ucs, ucslen, moo->cmgr, 0);
/* -1: illegal character, -2, buffer too small, -3: incomplete sequence */
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
if (n <= -1)
{
/* -1: illegal character, -2: buffer too small, -3: incomplete sequence */
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
}
return n;
}
@ -643,7 +646,11 @@ int moo_convutobchars (moo_t* moo, const moo_uch_t* ucs, moo_oow_t* ucslen, moo_
int n;
n = ucsn_to_bcsn_with_cmgr (ucs, ucslen, bcs, bcslen, moo->cmgr);
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
if (n <= -1)
{
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
}
return n;
}
@ -654,7 +661,11 @@ int moo_convbtoucstr (moo_t* moo, const moo_bch_t* bcs, moo_oow_t* bcslen, moo_u
int n;
n = bcs_to_ucs_with_cmgr (bcs, bcslen, ucs, ucslen, moo->cmgr, 0);
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
if (n <= -1)
{
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
}
return n;
}
@ -665,7 +676,11 @@ int moo_convutobcstr (moo_t* moo, const moo_uch_t* ucs, moo_oow_t* ucslen, moo_b
int n;
n = ucs_to_bcs_with_cmgr (ucs, ucslen, bcs, bcslen, moo->cmgr);
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
if (n <= -1)
{
moo->errnum = (n == -2)? MOO_EBUFFULL: MOO_EECERR;
}
return n;
}