diff --git a/moo/kernel/Except.moo b/moo/kernel/Except.moo index cbf52dd..1a869bb 100644 --- a/moo/kernel/Except.moo +++ b/moo/kernel/Except.moo @@ -81,13 +81,15 @@ TODO: can i convert 'thisProcess primError' to a relevant exception? ##thisContext unwindTo: (Processor activeProcess initialContext) return: nil. ## TOOD: IMPROVE THIS EXPERIMENTAL BACKTRACE... +System logNl: '== BACKTRACE =='. ctx := thisContext. while (ctx notNil) { - if (ctx class == MethodContext) { (ctx method owner name & '>>' & ctx method name) dump }. + if (ctx class == MethodContext) { System logNl: (' ' & ctx method owner name & '>>' & ctx method name) }. ## TODO: include blockcontext??? ctx := ctx sender. }. +System logNl: '== END OF BACKTRACE =='. thisContext unwindTo: (thisProcess initialContext) return: nil. ('### EXCEPTION NOT HANDLED #### ' & self class name & ' - ' & self messageText) dump. diff --git a/moo/lib/logfmt.c b/moo/lib/logfmt.c index f58212a..d54630d 100644 --- a/moo/lib/logfmt.c +++ b/moo/lib/logfmt.c @@ -189,6 +189,7 @@ static int put_ooch (moo_t* moo, moo_oow_t mask, moo_ooch_t ch, moo_oow_t len) { /* this is not equivalent to put_oocs(moo,mask,&ch, 1); * this function is to emit a single character multiple times */ + moo_oow_t rem; if (len <= 0) return 1; @@ -207,50 +208,73 @@ static int put_ooch (moo_t* moo, moo_oow_t mask, moo_ooch_t ch, moo_oow_t len) } redo: + rem = 0; if (len > moo->log.capa - moo->log.len) { - moo_oow_t newcapa; + moo_oow_t newcapa, max; moo_ooch_t* tmp; - if (len > MOO_TYPE_MAX(moo_oow_t) - moo->log.len) + max = MOO_TYPE_MAX(moo_oow_t) - moo->log.len; + if (len > max) { - /* data too big */ - moo_seterrnum (moo, MOO_ETOOBIG); - return -1; + /* data too big. */ + rem += len - max; + len = max; } - newcapa = MOO_ALIGN(moo->log.len + len, 512); /* TODO: adjust this capacity */ + newcapa = MOO_ALIGN_POW2(moo->log.len + len, 512); /* TODO: adjust this capacity */ /* +1 to handle line ending injection more easily */ - tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); + //tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); +tmp = 0; if (!tmp) { if (moo->log.len > 0) { /* can't expand the buffer. just flush the existing contents */ + /* TODO: HANDLE LINE ENDING CONVENTION BETTER... */ + if (moo->log.ptr[moo->log.len - 1] != '\n') + { + /* no line ending - append a line terminator */ + moo->log.ptr[moo->log.len++] = '\n'; + } moo->vmprim.log_write (moo, moo->log.last_mask, moo->log.ptr, moo->log.len); moo->log.len = 0; - goto redo; } - return -1; + + if (len > moo->log.capa) + { + rem += len - moo->log.capa; + len = moo->log.capa; + } + goto out; } moo->log.ptr = tmp; moo->log.capa = newcapa; } - +out: while (len > 0) { moo->log.ptr[moo->log.len++] = ch; len--; } - moo->log.last_mask = mask; + + if (rem > 0) + { + len = rem; + goto redo; + } + + return 1; /* success */ } static int put_oocs (moo_t* moo, moo_oow_t mask, const moo_ooch_t* ptr, moo_oow_t len) { + moo_oow_t rem; + if (len <= 0) return 1; if (moo->log.len > 0 && moo->log.last_mask != mask) @@ -268,42 +292,64 @@ static int put_oocs (moo_t* moo, moo_oow_t mask, const moo_ooch_t* ptr, moo_oow_ } redo: + rem = 0; if (len > moo->log.capa - moo->log.len) { - moo_oow_t newcapa; + moo_oow_t newcapa, max; moo_ooch_t* tmp; - if (len > MOO_TYPE_MAX(moo_oow_t) - moo->log.len) + + max = MOO_TYPE_MAX(moo_oow_t) - moo->log.len; + if (len > max) { - /* data too big */ - moo_seterrnum (moo, MOO_ETOOBIG); - return -1; + /* data too big. */ + rem += len - max; + len = max; } - newcapa = MOO_ALIGN(moo->log.len + len, 512); /* TODO: adjust this capacity */ + newcapa = MOO_ALIGN_POW2(moo->log.len + len, 512); /* TODO: adjust this capacity */ /* +1 to handle line ending injection more easily */ - tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); + //tmp = moo_reallocmem (moo, moo->log.ptr, (newcapa + 1) * MOO_SIZEOF(*tmp)); +tmp = 0; if (!tmp) { if (moo->log.len > 0) { /* can't expand the buffer. just flush the existing contents */ + /* TODO: HANDLE LINE ENDING CONVENTION BETTER... */ + if (moo->log.ptr[moo->log.len - 1] != '\n') + { + /* no line ending - append a line terminator */ + moo->log.ptr[moo->log.len++] = '\n'; + } moo->vmprim.log_write (moo, moo->log.last_mask, moo->log.ptr, moo->log.len); moo->log.len = 0; - goto redo; } - return -1; + if (len > moo->log.capa) + { + rem += len - moo->log.capa; + len = moo->log.capa; + } + goto out; } 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; + + if (rem > 0) + { + ptr += len; + len = rem; + goto redo; + } + return 1; /* success */ } diff --git a/moo/lib/main.c b/moo/lib/main.c index b6703d4..ed8f09e 100644 --- a/moo/lib/main.c +++ b/moo/lib/main.c @@ -637,7 +637,11 @@ static int write_all (int fd, const char* ptr, moo_oow_t len) #if defined(EWOULDBLOCK) if (errno == EWOULDBLOCK) continue; #endif + #endif + #if defined(EINTR) + /* TODO: would this interfere with non-blocking nature of this VM? */ + if (errno == EINTR) continue; #endif return -1; } diff --git a/moo/lib/moo.c b/moo/lib/moo.c index 2c2035a..15ac306 100644 --- a/moo/lib/moo.c +++ b/moo/lib/moo.c @@ -96,6 +96,15 @@ int moo_init (moo_t* moo, moo_mmgr_t* mmgr, moo_oow_t heapsz, const moo_vmprim_t 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? */ + /* 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 + * reallocation fails */ + /* +1 required for consistency with put_oocs and put_ooch in logfmt.c */ + moo->log.ptr = moo_allocmem (moo, (moo->log.capa + 1) * MOO_SIZEOF(*moo->log.ptr)); + if (!moo->log.ptr) goto oops; + /* TODO: introduce a permanent heap */ /*moo->permheap = moo_makeheap (moo, what is the best size???); if (!moo->permheap) goto oops; */ @@ -122,6 +131,8 @@ oops: if (moo->newheap) moo_killheap (moo, moo->newheap); if (moo->curheap) moo_killheap (moo, moo->curheap); if (moo->permheap) moo_killheap (moo, moo->permheap); + if (moo->log.ptr) moo_freemem (moo, moo->log.ptr); + moo->log.capa = 0; return -1; }