diff --git a/moo/lib/exec.c b/moo/lib/exec.c index 0b5aaea..05f25db 100644 --- a/moo/lib/exec.c +++ b/moo/lib/exec.c @@ -1464,7 +1464,7 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) { /* the receiver is not a class object */ MOO_DEBUG1 (moo, " Receiver is not a class - %O\n", _class); - moo_seterrnum (moo, MOO_EMSGRCV); + moo_seterrbfmt (moo, MOO_EMSGRCV, "non-class receiver - %O", _class); return MOO_PF_FAILURE; } @@ -1472,7 +1472,7 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) if (MOO_CLASS_SELFSPEC_FLAGS(MOO_OOP_TO_SMOOI(_class->selfspec)) & MOO_CLASS_SELFSPEC_FLAG_LIMITED) { MOO_DEBUG1 (moo, " Receiver is #limited - %O\n", _class); - moo_seterrnum (moo, MOO_EPERM); + moo_seterrbfmt (moo, MOO_EPERM, "#limited receiver - %O", _class); return MOO_PF_FAILURE; } @@ -1482,8 +1482,8 @@ static MOO_INLINE moo_pfrc_t pf_basic_new (moo_t* moo, moo_ooi_t nargs) if (moo_inttooow (moo, szoop, &size) <= 0) { /* integer out of range or not integer */ - MOO_DEBUG0 (moo, " Size out of range or not integer\n"); - moo_seterrnum (moo, MOO_EINVAL); + MOO_DEBUG1 (moo, " Size out of range or not integer - %O\n", szoop); + moo_seterrbfmt (moo, MOO_EINVAL, "size out of range or not integer - %O", szoop); return MOO_PF_FAILURE; } } @@ -4076,12 +4076,12 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) if (stack_base != moo->sp - nargs - 1) { /* a primitive function handler must not touch the stack when it returns soft failure */ - MOO_DEBUG3 (moo, "Stack seems to get corrupted by a primitive handler function - %O<<%.*js\n", method->owner, MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name)); + MOO_DEBUG3 (moo, "Stack seems to get corrupted by a primitive handler function - %O>>%.*js\n", method->owner, MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name)); moo_seterrnum (moo, MOO_EINTERN); return -1; } - MOO_DEBUG3 (moo, "Sending primitiveFailed for empty primitive body - %O<<%.*js\n", method->owner, MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name)); + MOO_DEBUG3 (moo, "Sending primitiveFailed for empty primitive body - %O>>%.*js\n", method->owner, MOO_OBJ_GET_SIZE(method->name), MOO_OBJ_GET_CHAR_SLOT(method->name)); /* * | arg1 | <---- stack_base + 3 * | arg0 | <---- stack_base + 2 @@ -4097,10 +4097,12 @@ static int start_method (moo_t* moo, moo_oop_method_t method, moo_oow_t nargs) /* send primitiveFailed to self */ if (send_message_with_str (moo, prim_fail_msg, 15, 0, nargs + 1) <= -1) return -1; - break; } - - if (activate_new_method (moo, method, nargs) <= -1) return -1; + else + { + /* arrange to execute the method body */ + if (activate_new_method (moo, method, nargs) <= -1) return -1; + } break; } diff --git a/moo/lib/logfmt.c b/moo/lib/logfmt.c index d54630d..014d671 100644 --- a/moo/lib/logfmt.c +++ b/moo/lib/logfmt.c @@ -222,12 +222,22 @@ redo: len = max; } - newcapa = MOO_ALIGN_POW2(moo->log.len + len, 512); /* TODO: adjust this capacity */ + newcapa = MOO_ALIGN_POW2(moo->log.len + len, MOO_LOG_CAPA_ALIGN); /* TODO: adjust this capacity */ + if (newcapa > moo->option.log_maxcapa) + { + /* [NOTE] + * it doesn't adjust newcapa to moo->option.log_maxcapa. + * nor does it cut the input to fit it into the adjusted capacity. + * if maxcapa set is not aligned to MOO_LOG_CAPA_ALIGN, + * the largest buffer capacity may be suboptimal */ + goto make_do; + } + /* +1 to handle line ending injection more easily */ - //tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); -tmp = 0; + tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); if (!tmp) { + make_do: if (moo->log.len > 0) { /* can't expand the buffer. just flush the existing contents */ @@ -246,14 +256,15 @@ tmp = 0; rem += len - moo->log.capa; len = moo->log.capa; } - goto out; - } - moo->log.ptr = tmp; - moo->log.capa = newcapa; + } + else + { + moo->log.ptr = tmp; + moo->log.capa = newcapa; + } } -out: while (len > 0) { moo->log.ptr[moo->log.len++] = ch; @@ -298,7 +309,6 @@ redo: moo_oow_t newcapa, max; moo_ooch_t* tmp; - max = MOO_TYPE_MAX(moo_oow_t) - moo->log.len; if (len > max) { @@ -308,11 +318,21 @@ redo: } newcapa = MOO_ALIGN_POW2(moo->log.len + len, 512); /* TODO: adjust this capacity */ + if (newcapa > moo->option.log_maxcapa) + { + /* [NOTE] + * it doesn't adjust newcapa to moo->option.log_maxcapa. + * nor does it cut the input to fit it into the adjusted capacity. + * if maxcapa set is not aligned to MOO_LOG_CAPA_ALIGN, + * the largest buffer capacity may be suboptimal */ + goto make_do; + } + /* +1 to handle line ending injection more easily */ - //tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); -tmp = 0; + tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); if (!tmp) { + make_do: if (moo->log.len > 0) { /* can't expand the buffer. just flush the existing contents */ @@ -331,14 +351,14 @@ tmp = 0; rem += len - moo->log.capa; len = moo->log.capa; } - goto out; } - - moo->log.ptr = tmp; - moo->log.capa = newcapa; + else + { + moo->log.ptr = tmp; + moo->log.capa = newcapa; + } } -out: MOO_MEMCPY (&moo->log.ptr[moo->log.len], ptr, len * MOO_SIZEOF(*ptr)); moo->log.len += len; moo->log.last_mask = mask; diff --git a/moo/lib/moo-prv.h b/moo/lib/moo-prv.h index 3ba2965..0f2294b 100644 --- a/moo/lib/moo-prv.h +++ b/moo/lib/moo-prv.h @@ -65,6 +65,7 @@ */ #define MOO_LIMIT_OBJ_SIZE + /* TODO: delete these header inclusion lines */ #include diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 15ac306..12c6908 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -92,11 +92,12 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t moo->vmprim = *vmprim; moo->option.log_mask = ~0u; + moo->option.log_maxcapa = MOO_DFL_LOG_MAXCAPA; moo->option.dfl_symtab_size = MOO_DFL_SYMTAB_SIZE; moo->option.dfl_sysdic_size = MOO_DFL_SYSDIC_SIZE; moo->option.dfl_procstk_size = MOO_DFL_PROCSTK_SIZE; - moo->log.capa = 512; /* TODO: is this a good initial size? */ + moo->log.capa = MOO_ALIGN_POW2(1, MOO_LOG_CAPA_ALIGN); /* TODO: is this a good initial size? */ /* alloate the log buffer in advance though it may get reallocated * in put_oocs and put_ooch in logfmt.c. this is to let the logging * routine still function despite some side-effects when @@ -239,6 +240,10 @@ int moo_setoption (moo_t* moo, moo_option_t id, const void* value) moo->option.log_mask = *(const unsigned int*)value; return 0; + case MOO_LOG_MAXCAPA: + moo->option.log_maxcapa = *(moo_oow_t*)value; + return 0; + case MOO_SYMTAB_SIZE: { moo_oow_t w; @@ -290,6 +295,10 @@ int moo_getoption (moo_t* moo, moo_option_t id, void* value) *(unsigned int*)value = moo->option.log_mask; return 0; + case MOO_LOG_MAXCAPA: + *(moo_oow_t*)value = moo->option.log_mask; + return 0; + case MOO_SYMTAB_SIZE: *(moo_oow_t*)value = moo->option.dfl_symtab_size; return 0; diff --git a/moo/lib/moo.h b/moo/lib/moo.h index 0718d0b..2243c3a 100644 --- a/moo/lib/moo.h +++ b/moo/lib/moo.h @@ -89,14 +89,19 @@ enum moo_option_t { MOO_TRAIT, MOO_LOG_MASK, + MOO_LOG_MAXCAPA, MOO_SYMTAB_SIZE, /* default system table size */ MOO_SYSDIC_SIZE, /* default system dictionary size */ MOO_PROCSTK_SIZE /* default process stack size */ }; typedef enum moo_option_t moo_option_t; +/* [NOTE] ensure that it is a power of 2 */ +#define MOO_LOG_CAPA_ALIGN 512 + enum moo_option_dflval_t { + MOO_DFL_LOG_MAXCAPA = MOO_LOG_CAPA_ALIGN * 16, MOO_DFL_SYMTAB_SIZE = 5000, MOO_DFL_SYSDIC_SIZE = 5000, MOO_DFL_PROCSTK_SIZE = 5000 @@ -986,6 +991,7 @@ struct moo_t { unsigned int trait; unsigned int log_mask; + moo_oow_t log_maxcapa; moo_oow_t dfl_symtab_size; moo_oow_t dfl_sysdic_size; moo_oow_t dfl_procstk_size; @@ -1393,7 +1399,7 @@ MOO_EXPORT void moo_fini ( # define moo_setcmgr(moo,mgr) ((moo)->cmgr = (mgr)) # define moo_geterrnum(moo) ((moo)->errnum) -# define moo_seterrnum(moo,num) ((moo)->errmsg.len = 0, (moo)->errnum = (num),) +# define moo_seterrnum(moo,num) ((moo)->errmsg.len = 0, (moo)->errnum = (num)) #endif