enhanced the vm logging interface

attempted to execute ensure blocks on process termination. (wip)
This commit is contained in:
hyunghwan.chung
2016-07-01 16:31:47 +00:00
parent 1445d0deb0
commit 436babff3c
14 changed files with 418 additions and 123 deletions

View File

@ -1916,39 +1916,25 @@ static STIX_INLINE int add_class_level_variable (stix_t* stix, var_type_t index,
static STIX_INLINE int add_pool_dictionary (stix_t* stix, const stix_oocs_t* name, stix_oop_set_t pooldic_oop)
{
int n;
stix_oow_t saved_len;
saved_len = stix->c->cls.pooldic.len;
n = copy_string_to (stix, name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ');
if (n >= 0)
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
{
if (stix->c->cls.pooldic_count >= stix->c->cls.pooldic_oop_capa)
{
stix_oow_t new_capa;
stix_oop_set_t* tmp;
stix_oow_t new_capa;
stix_oop_set_t* tmp;
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
if (!tmp)
{
stix->c->cls.pooldic.len = saved_len;
return -1;
}
new_capa = STIX_ALIGN(stix->c->cls.pooldic_oop_capa + 1, POOLDIC_OOP_BUFFER_ALIGN);
tmp = stix_reallocmem (stix, stix->c->cls.pooldic_oops, new_capa * STIX_SIZEOF(stix_oop_set_t));
if (!tmp) return -1;
stix->c->cls.pooldic_oop_capa = new_capa;
stix->c->cls.pooldic_oops = tmp;
}
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
stix->c->cls.pooldic_count++;
/* TODO: check if pooldic_count overflows */
stix->c->cls.pooldic_oop_capa = new_capa;
stix->c->cls.pooldic_oops = tmp;
}
return n;
}
stix->c->cls.pooldic_oops[stix->c->cls.pooldic_count] = pooldic_oop;
stix->c->cls.pooldic_count++;
/* TODO: check if pooldic_count overflows */
return 0;
}
static stix_ooi_t find_class_level_variable (stix_t* stix, stix_oop_class_t self, const stix_oocs_t* name, var_info_t* var)
{
@ -2281,6 +2267,46 @@ wrong_name:
return -1;
}
static int resolve_pooldic (stix_t* stix, int dotted, const stix_oocs_t* name)
{
stix_oocs_t last; /* the last segment */
stix_oop_set_t ns_oop; /* name space */
stix_oop_association_t ass;
stix_oow_t i;
if (dotted)
{
if (preprocess_dotted_name(stix, 0, 0, name, &stix->c->tok.loc, &last, &ns_oop) <= -1) return -1;
}
else
{
last = *name;
/* it falls back to the name space of the class */
ns_oop = stix->c->cls.ns_oop;
}
/* check if the name refers to a pool dictionary */
ass = stix_lookupdic (stix, ns_oop, &last);
if (!ass || STIX_CLASSOF(stix, ass->value) != stix->_pool_dictionary)
{
set_syntax_error (stix, STIX_SYNERR_POOLDIC, &stix->c->tok.loc, name);
return -1;
}
/* check if the same dictionary pool has been declared for import */
for (i = 0; i < stix->c->cls.pooldic_count; i++)
{
if ((stix_oop_set_t)ass->value == stix->c->cls.pooldic_oops[i])
{
set_syntax_error (stix, STIX_SYNERR_POOLDICDUP, &stix->c->tok.loc, name);
return -1;
}
}
return 0;
}
static int compile_class_level_variables (stix_t* stix)
{
var_type_t dcl_type = VAR_INSTANCE;
@ -2304,7 +2330,7 @@ static int compile_class_level_variables (stix_t* stix)
}
else if (is_token_symbol(stix, VOCA_POOLDIC))
{
/* #dcl(#pooldic) */
/* #dcl(#pooldic) - import a pool dictionary */
dcl_type = VAR_GLOBAL; /* this is not a real type. use for branching below */
GET_TOKEN (stix);
}
@ -2360,6 +2386,12 @@ static int compile_class_level_variables (stix_t* stix)
}
if (add_pool_dictionary(stix, &stix->c->tok.name, (stix_oop_set_t)ass->value) <= -1) return -1;
if (copy_string_to (stix, &stix->c->tok.name, &stix->c->cls.pooldic, &stix->c->cls.pooldic_capa, 1, ' ') <= -1)
{
stix->c->cls.pooldic_count--;
return -1;
}
GET_TOKEN (stix);
}
while (1);
@ -2401,9 +2433,6 @@ static int compile_class_level_variables (stix_t* stix)
GET_TOKEN (stix);
return 0;
}
static int compile_unary_method_name (stix_t* stix)
@ -2761,7 +2790,6 @@ static int get_variable_info (stix_t* stix, const stix_oocs_t* name, const stix_
}
else
{
if (find_class_level_variable(stix, stix->c->cls.self_oop, name, var) >= 0)
{
class_level_variable:
@ -4881,11 +4909,9 @@ static int __compile_pooldic_definition (stix_t* stix)
case STIX_IOTOK_NUMLIT:
case STIX_IOTOK_RADNUMLIT:
{
lit = string_to_num (stix, &stix->c->tok.name, stix->c->tok.type == STIX_IOTOK_RADNUMLIT);
if (!lit) return -1;
goto add_literal;
}
case STIX_IOTOK_BPAREN: /* #[ */
if (read_byte_array_literal(stix, &lit) <= -1) return -1;
@ -5005,8 +5031,7 @@ static int compile_stream (stix_t* stix)
}
else if (is_token_symbol(stix, VOCA_POOLDIC))
{
/* TODO: allow #pooldic within #class */
/* #pooldic SharedPoolDic { #abc := 20. #defg := 'ayz' } */
/* #pooldic SharedPoolDic { #ABC := 20. #DEFG := 'ayz' } */
GET_TOKEN (stix);
if (compile_pooldic_definition(stix) <= -1) return -1;
}

View File

@ -557,7 +557,6 @@ static void resume_process (stix_t* stix, stix_oop_process_t proc)
/* don't switch to this process. just set the state to RUNNING */
}
#if 0
else if (proc->state == STIX_SMOOI_TO_OOP(PROC_STATE_RUNNABLE))
{
@ -1167,56 +1166,100 @@ static int prim_dump (stix_t* stix, stix_ooi_t nargs)
return 1; /* success */
}
static void log_char_object (stix_t* stix, stix_oow_t mask, stix_oop_char_t msg)
{
stix_ooi_t n;
stix_oow_t rem;
const stix_ooch_t* ptr;
STIX_ASSERT (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR);
rem = STIX_OBJ_GET_SIZE(msg);
ptr = msg->slot;
start_over:
while (rem > 0)
{
if (*ptr == '\0')
{
n = stix_logbfmt (stix, mask, "%C", *ptr);
STIX_ASSERT (n == 1);
rem -= n;
ptr += n;
goto start_over;
}
n = stix_logbfmt (stix, mask, "%.*S", rem, ptr);
if (n <= -1) break;
if (n == 0)
{
/* to skip the unprinted character.
* actually, this check is not needed because of '\0' skipping
* at the beginning of the loop */
n = stix_logbfmt (stix, mask, "%C", *ptr);
STIX_ASSERT (n == 1);
}
rem -= n;
ptr += n;
}
}
static int prim_log (stix_t* stix, stix_ooi_t nargs)
{
stix_oop_t msg, level;
stix_oow_t mask;
stix_ooi_t k;
STIX_ASSERT (nargs >= 2);
level = STIX_STACK_GET(stix, stix->sp);
msg = STIX_STACK_GET(stix, stix->sp - 1);
level = STIX_STACK_GET(stix, stix->sp - nargs + 1);
if (!STIX_OOP_IS_SMOOI(level)) mask = STIX_LOG_APP | STIX_LOG_INFO;
else mask = STIX_LOG_APP | STIX_OOP_TO_SMOOI(level);
/* TODO: SUPPORT ARBITRARY NUMBERS OF MESSAGES */
if (!STIX_OOP_IS_SMOOI(level)) level = STIX_SMOOI_TO_OOP(STIX_LOG_INFO);
if (STIX_OOP_IS_POINTER(msg) && STIX_OBJ_GET_FLAGS_TYPE(msg))
for (k = nargs - 1; k > 0; )
{
stix_ooi_t n;
stix_oow_t rem;
const stix_ooch_t* ptr;
--k;
msg = STIX_STACK_GET(stix, stix->sp - k);
rem = STIX_OBJ_GET_SIZE(msg);
ptr = ((stix_oop_char_t)msg)->slot;
start_over:
while (rem > 0)
if (msg == stix->_nil || msg == stix->_true || msg == stix->_false)
{
if (*ptr == '\0')
{
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr);
STIX_ASSERT (n == 1);
rem -= n;
ptr += n;
goto start_over;
}
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%.*S", rem, ptr);
if (n <= -1) break;
if (n == 0)
{
/* to skip the unprinted character.
* actually, this check is not needed because of '\0' skipping
* at the beginning of the loop */
n = stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%C", *ptr);
STIX_ASSERT (n == 1);
}
rem -= n;
ptr += n;
goto dump_object;
}
else if (STIX_OOP_IS_POINTER(msg))
{
if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_CHAR)
{
log_char_object (stix, mask, (stix_oop_char_t)msg);
}
else if (STIX_OBJ_GET_FLAGS_TYPE(msg) == STIX_OBJ_TYPE_OOP)
{
/* visit only 1-level down into an array-like object */
stix_oop_t inner;
stix_oow_t i;
if (STIX_CLASSOF(stix,msg) == stix->_association) goto dump_object;
for (i = 0; i < STIX_OBJ_GET_SIZE(msg); i++)
{
inner = ((stix_oop_oop_t)msg)->slot[i];
if (STIX_OOP_IS_POINTER(inner) &&
STIX_OBJ_GET_FLAGS_TYPE(inner) == STIX_OBJ_TYPE_CHAR)
{
log_char_object (stix, mask, (stix_oop_char_t)inner);
}
else
{
stix_logbfmt (stix, mask, "%O", inner);
}
}
}
else goto dump_object;
}
else
{
dump_object:
stix_logbfmt (stix, mask, "%O", msg);
}
}
else
{
stix_logbfmt (stix, STIX_LOG_APP | STIX_OOP_TO_SMOOI(level), "%O", msg);
}
STIX_STACK_POPS (stix, nargs); /* delete arguments, keep self */
@ -2656,7 +2699,7 @@ typedef struct prim_t prim_t;
static prim_t primitives[] =
{
{ 0, MAX_NARGS, prim_dump, "_dump" },
{ 2, 2, prim_log, "_log" },
{ 2, MAX_NARGS, prim_log, "_log" },
{ 1, 1, prim_identical, "_identical" },
{ 1, 1, prim_not_identical, "_not_identical" },

View File

@ -131,14 +131,14 @@ static stix_bch_t bch_nullstr[] = { '(','n','u','l','l', ')','\0' };
typedef int (*stix_fmtout_putch_t) (
stix_t* stix,
unsigned int mask,
stix_oow_t mask,
stix_ooch_t c,
stix_oow_t len
);
typedef int (*stix_fmtout_putcs_t) (
stix_t* stix,
unsigned int mask,
stix_oow_t mask,
const stix_ooch_t* ptr,
stix_oow_t len
);
@ -147,7 +147,7 @@ typedef struct stix_fmtout_t stix_fmtout_t;
struct stix_fmtout_t
{
stix_oow_t count; /* out */
int mask; /* in */
stix_oow_t mask; /* in */
stix_fmtout_putch_t putch; /* in */
stix_fmtout_putcs_t putcs; /* in */
};
@ -185,7 +185,7 @@ static stix_bch_t* sprintn_upper (stix_bch_t* nbuf, stix_uintmax_t num, int base
}
/* ------------------------------------------------------------------------- */
static int put_ooch (stix_t* stix, unsigned int mask, stix_ooch_t ch, stix_oow_t len)
static int put_ooch (stix_t* stix, stix_oow_t mask, stix_ooch_t ch, stix_oow_t len)
{
if (len <= 0) return 1;
@ -237,7 +237,7 @@ redo:
return 1; /* success */
}
static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, stix_oow_t len)
static int put_oocs (stix_t* stix, stix_oow_t mask, const stix_ooch_t* ptr, stix_oow_t len)
{
if (len <= 0) return 1;
@ -277,7 +277,7 @@ static int put_oocs (stix_t* stix, unsigned int mask, const stix_ooch_t* ptr, st
/* ------------------------------------------------------------------------- */
static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
static void print_object (stix_t* stix, stix_oow_t mask, stix_oop_t oop)
{
if (oop == stix->_nil)
{
@ -365,6 +365,9 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
case '\0':
escaped = '0';
break;
case '\n':
escaped = 'n';
break;
case '\r':
escaped = 'r';
break;
@ -450,6 +453,10 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
/* print the class name */
stix_logbfmt (stix, mask, "%.*S", STIX_OBJ_GET_SIZE(((stix_oop_class_t)oop)->name), ((stix_oop_class_t)oop)->name->slot);
}
else if ((stix_oop_t)c == stix->_association)
{
stix_logbfmt (stix, mask, "%O -> %O", ((stix_oop_association_t)oop)->key, ((stix_oop_association_t)oop)->value);
}
else
{
stix_logbfmt (stix, mask, "instance of %.*S(%p)", STIX_OBJ_GET_SIZE(c->name), ((stix_oop_char_t)c->name)->slot, oop);
@ -473,7 +480,7 @@ static void print_object (stix_t* stix, unsigned int mask, stix_oop_t oop)
#define FMTCHAR_IS_OOCH
#include "logfmtv.h"
stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt, ...)
stix_ooi_t stix_logbfmt (stix_t* stix, stix_oow_t mask, const stix_bch_t* fmt, ...)
{
int x;
va_list ap;
@ -495,7 +502,7 @@ stix_ooi_t stix_logbfmt (stix_t* stix, unsigned int mask, const stix_bch_t* fmt,
return (x <= -1)? -1: fo.count;
}
stix_ooi_t stix_logoofmt (stix_t* stix, unsigned int mask, const stix_ooch_t* fmt, ...)
stix_ooi_t stix_logoofmt (stix_t* stix, stix_oow_t mask, const stix_ooch_t* fmt, ...)
{
int x;
va_list ap;

View File

@ -30,6 +30,7 @@
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
#if defined(_WIN32)
@ -330,7 +331,7 @@ printf ("MOD_GETSYM [%s]\n", &buf[0]);
/* ========================================================================= */
static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len)
static void log_write (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len)
{
#if defined(_WIN32)
# error NOT IMPLEMENTED
@ -340,30 +341,71 @@ static void log_write (stix_t* stix, unsigned int mask, const stix_ooch_t* msg,
stix_oow_t ucslen, bcslen, msgidx;
int n;
msgidx = 0;
/*if (mask & STIX_LOG_GC) return;*/ /* don't show gc logs */
/* TODO: beautify the log message.
* do classification based on mask. */
/*
{
char ts[32];
struct tm tm;
time_t now;
now = time(NULL);
localtime_r (&now, &tm);
strftime (ts, sizeof(ts), "%Y-%m-%d %H:%M:%S %z ", &tm);
write (1, ts, strlen(ts));
}
*/
msgidx = 0;
while (len > 0)
{
ucslen = len;
bcslen = STIX_COUNTOF(buf);
n = stix_ucstoutf8 (&msg[msgidx], &ucslen, buf, &bcslen);
if (n == 0)
{
write (1, buf, bcslen); /* TODO: write all */
break;
}
else if (n == -2)
if (n == 0 || n == -2)
{
stix_oow_t rem;
const stix_bch_t* ptr;
/* n = 0:
* converted all successfully
* n == -2:
* buffer not sufficient. not all got converted yet.
* write what have been converted this round. */
STIX_ASSERT (ucslen > 0); /* if this fails, the buffer size must be increased */
write (1, buf, bcslen); /* TODO: write all */
msgidx += ucslen;
len -= ucslen;
/* attempt to write all converted characters */
rem = bcslen;
ptr = buf;
while (rem > 0)
{
stix_ooi_t wr;
wr = write (1, ptr, rem); /* TODO: write all */
if (wr <= -1)
{
/*if (errno == EAGAIN || errno == EWOULDBLOCK)
{
push it to internal buffers? before writing data just converted, need to write buffered data first.
}*/
break;
}
ptr += wr;
rem -= wr;
}
if (n == 0) break;
else
{
msgidx += ucslen;
len -= ucslen;
}
}
else if (n <= -1)
{

View File

@ -407,7 +407,7 @@ struct stix_class_t
stix_oop_char_t classinstvars; /* String */
/* == NEVER CHANGE THE ORDER OF 3 ITEMS ABOVE == */
stix_oop_char_t pooldics; /* String */
stix_oop_char_t pooldics; /* String - pool dictionaries imported */
/* [0] - instance methods, MethodDictionary
* [1] - class methods, MethodDictionary */
@ -678,7 +678,7 @@ typedef void* (*stix_mod_open_t) (stix_t* stix, const stix_ooch_t* name);
typedef void (*stix_mod_close_t) (stix_t* stix, void* handle);
typedef void* (*stix_mod_getsym_t) (stix_t* stix, void* handle, const stix_ooch_t* name);
typedef void (*stix_log_write_t) (stix_t* stix, unsigned int mask, const stix_ooch_t* msg, stix_oow_t len);
typedef void (*stix_log_write_t) (stix_t* stix, stix_oow_t mask, const stix_ooch_t* msg, stix_oow_t len);
struct stix_vmprim_t
{
@ -1134,14 +1134,14 @@ STIX_EXPORT void stix_freemem (
STIX_EXPORT stix_ooi_t stix_logbfmt (
stix_t* stix,
unsigned int mask,
stix_oow_t mask,
const stix_bch_t* fmt,
...
);
STIX_EXPORT stix_ooi_t stix_logoofmt (
stix_t* stix,
unsigned int mask,
stix_oow_t mask,
const stix_ooch_t* fmt,
...
);