still experimenting to find a good way to represent byte codes and literal frames in the interactive mode

This commit is contained in:
hyung-hwan 2020-09-28 15:44:04 +00:00
parent b9ae46afff
commit c7e87698d0
8 changed files with 66 additions and 144 deletions

View File

@ -822,7 +822,7 @@ static int handle_dbgopt (hcl_t* hcl, const hcl_bch_t* str)
cm = hcl_find_bchar_in_bcstr(flt, ','); cm = hcl_find_bchar_in_bcstr(flt, ',');
len = cm? (cm - flt): hcl_count_bcstr(flt); len = cm? (cm - flt): hcl_count_bcstr(flt);
if (hcl_comp_bchars_bcstr (flt, len, "gc") == 0) dbgopt |= HCL_DEBUG_GC; if (hcl_comp_bchars_bcstr (flt, len, "gc") == 0) dbgopt |= HCL_TRAIT_DEBUG_GC;
else if (hcl_comp_bchars_bcstr (flt, len, "bigint") == 0) dbgopt |= HCL_DEBUG_BIGINT; else if (hcl_comp_bchars_bcstr (flt, len, "bigint") == 0) dbgopt |= HCL_DEBUG_BIGINT;
else else
{ {
@ -1082,8 +1082,8 @@ int main (int argc, char* argv[])
{ {
hcl_bitmask_t trait = 0; hcl_bitmask_t trait = 0;
/*trait |= HCL_NOGC;*/ /*trait |= HCL_TRAIT_NOGC;*/
trait |= HCL_AWAIT_PROCS; trait |= HCL_TRAIT_AWAIT_PROCS;
hcl_setoption (hcl, HCL_TRAIT, &trait); hcl_setoption (hcl, HCL_TRAIT, &trait);
/* disable GC logs */ /* disable GC logs */
@ -1160,6 +1160,14 @@ hcl_logufmt (hcl, HCL_LOG_WARN, fmt, ustr, 0x6789);
} }
#endif #endif
if (xtn->reader_istty)
{
hcl_bitmask_t trait;
hcl_getoption (hcl, HCL_TRAIT, &trait);
trait |= HCL_TRAIT_INTERACTIVE;
hcl_setoption (hcl, HCL_TRAIT, &trait);
}
while (1) while (1)
{ {
hcl_oop_t obj; hcl_oop_t obj;

View File

@ -33,7 +33,7 @@ enum
}; };
#define TV_BUFFER_ALIGN 256 #define TV_BUFFER_ALIGN 256
#define BLK_TMPRCNT_BUFFER_ALIGN 128 #define BLK_INFO_BUFFER_ALIGN 128
#define EMIT_BYTE_INSTRUCTION(hcl,code) \ #define EMIT_BYTE_INSTRUCTION(hcl,code) \
do { if (emit_byte_instruction(hcl,code) <= -1) return -1; } while(0) do { if (emit_byte_instruction(hcl,code) <= -1) return -1; } while(0)
@ -43,31 +43,26 @@ enum
/* -------------------------------------------- /* --------------------------------------------
// literal frame is not fully a stack
// new literal frame => current litera count + 1 (defun plus(x y)
// back one new literal frame => current literal frame index - 1
<--- code/literal frame #0
(defun plus(x y) <--- code/literal frame #1
(printf "plus %d %d\n" x y) (printf "plus %d %d\n" x y)
(defun minus(x y) <--- code/literal frame #2 (defun minus(x y)
(printf "minus %d %d\n" x y) (printf "minus %d %d\n" x y)
(- x y) (- x y)
) )
(+ x y) <--- code/literal frame #1 (+ x y)
) )
<--- code/literal frame #0
(defun dummy(q) <--- code/literal frame #3 (defun dummy(q)
(printf "%s\n" q) (printf "%s\n" q)
) )
<--- code/literal frame #0
(plus 10 20) (plus 10 20)
<---- minus is now available <---- minus is now available
(minus 10 1) (minus 10 1)
literals -->
// //
// characeter 'A' // characeter 'A'
// "string" // "string"
@ -78,67 +73,6 @@ enum
------------------------------ */ ------------------------------ */
static int acquire_ccl (hcl_t* hcl)
{
hcl_ccl_t* ccl;
if (hcl->ccl.len >= hcl->ccl.capa)
{
hcl_ccl_t* tmp;
tmp = hcl_reallocmem(hcl, hcl->ccl.ptr, hcl->ccl.capa + 32);
if (HCL_UNLIKELY(!tmp)) return -1;
hcl->ccl.capa += 32;
}
ccl = &hcl->ccl.ptr[hcl->ccl.len];
HCL_MEMSET (ccl, 0, SIZEOF(*ccl));
ccl->pindex = hcl->ccl.index;
hcl->ccl.index = hcl->ccl.len++;
return 0;
}
static int release_ccl (hcl_t* hcl)
{
hcl->ccl.index = hcl->ccl.ptr[hcl->ccl.index].pindex;
}
static void destroy_ccls (hcl_t* hcl)
{
while (hcl->ccl.len > 0)
{
hcl_ccl_t* ccl = &hcl->ccl.ptr[--hcl->ccl.len];
if (ccl->bc.ptr)
{
hcl_freemem (hcl, ccl->bc.ptr);
ccl->bc.ptr = HCL_NULL;
ccl->bc.capa = 0;
ccl->bc.len = 0;
}
if (ccl->lit.ptr)
{
while (ccl->lit.len > 0)
{
hcl_clv_t* clv = &ccl->lit.ptr[--ccl->lit.len];
hcl_freemem (hcl, clv);
}
hcl_freemem (hcl, ccl->lit.ptr);
ccl->lit.ptr = HCL_NULL;
ccl->lit.capa = 0;
ccl->lit.len = 0;
}
}
hcl_freemem (hcl, hcl->ccl.ptr);
hcl->ccl.ptr = HCL_NULL;
hcl->ccl.capa = 0;
hcl->ccl.len = 0;
hcl->ccl.index = 0;
}
static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index) static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index)
{ {
hcl_oow_t capa, i; hcl_oow_t capa, i;
@ -168,6 +102,8 @@ static int add_literal (hcl_t* hcl, hcl_oop_t obj, hcl_oow_t* index)
} }
*index = hcl->code.lit.len; *index = hcl->code.lit.len;
if (hcl->option.trait & HCL_TRAIT_INTERACTIVE) *index -= hcl->c->blk.info[hcl->c->blk.depth].litbase;
((hcl_oop_oop_t)hcl->code.lit.arr)->slot[hcl->code.lit.len++] = obj; ((hcl_oop_oop_t)hcl->code.lit.arr)->slot[hcl->code.lit.len++] = obj;
return 0; return 0;
} }
@ -225,24 +161,25 @@ static int find_temporary_variable_backward (hcl_t* hcl, hcl_oop_t name, hcl_oow
return -1; return -1;
} }
static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_count) static int store_temporary_variable_count_for_block (hcl_t* hcl, hcl_oow_t tmpr_count, hcl_oow_t lit_base)
{ {
HCL_ASSERT (hcl, hcl->c->blk.depth >= 0); HCL_ASSERT (hcl, hcl->c->blk.depth >= 0);
if (hcl->c->blk.depth >= hcl->c->blk.tmprcnt_capa) if (hcl->c->blk.depth >= hcl->c->blk.info_capa)
{ {
hcl_oow_t* tmp; hcl_blk_info_t* tmp;
hcl_oow_t newcapa; hcl_oow_t newcapa;
newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_TMPRCNT_BUFFER_ALIGN); newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_INFO_BUFFER_ALIGN);
tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.tmprcnt, newcapa * HCL_SIZEOF(*tmp)); tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.info, newcapa * HCL_SIZEOF(*tmp));
if (!tmp) return -1; if (!tmp) return -1;
hcl->c->blk.tmprcnt_capa = newcapa; hcl->c->blk.info_capa = newcapa;
hcl->c->blk.tmprcnt = tmp; hcl->c->blk.info = tmp;
} }
hcl->c->blk.tmprcnt[hcl->c->blk.depth] = tmpr_count; hcl->c->blk.info[hcl->c->blk.depth].tmprcnt = tmpr_count;
hcl->c->blk.info[hcl->c->blk.depth].litbase = lit_base;
return 0; return 0;
} }
@ -1123,7 +1060,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src, int defun)
return -1; return -1;
} }
hcl->c->blk.depth++; hcl->c->blk.depth++;
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size) <= -1) return -1; if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, hcl->code.lit.len) <= -1) return -1;
/* use the accumulated number of temporaries so far when generating /* use the accumulated number of temporaries so far when generating
* the make_block instruction. at context activation time, the actual * the make_block instruction. at context activation time, the actual
@ -1627,14 +1564,14 @@ static int emit_indexed_variable_access (hcl_t* hcl, hcl_oow_t index, hcl_oob_t
/* if a temporary variable is accessed inside a block, /* if a temporary variable is accessed inside a block,
* use a special instruction to indicate it */ * use a special instruction to indicate it */
HCL_ASSERT (hcl, index < hcl->c->blk.tmprcnt[hcl->c->blk.depth]); HCL_ASSERT (hcl, index < hcl->c->blk.info[hcl->c->blk.depth].tmprcnt);
for (i = hcl->c->blk.depth; i > 0; i--) /* excluded the top level -- TODO: change this code depending on global variable handling */ for (i = hcl->c->blk.depth; i > 0; i--) /* excluded the top level -- TODO: change this code depending on global variable handling */
{ {
if (index >= hcl->c->blk.tmprcnt[i - 1]) if (index >= hcl->c->blk.info[i - 1].tmprcnt)
{ {
hcl_oow_t ctx_offset, index_in_ctx; hcl_oow_t ctx_offset, index_in_ctx;
ctx_offset = hcl->c->blk.depth - i; ctx_offset = hcl->c->blk.depth - i;
index_in_ctx = index - hcl->c->blk.tmprcnt[i - 1]; index_in_ctx = index - hcl->c->blk.info[i - 1].tmprcnt;
/* ctx_offset 0 means the current context. /* ctx_offset 0 means the current context.
* 1 means current->home. * 1 means current->home.
* 2 means current->home->home. * 2 means current->home->home.
@ -2564,7 +2501,7 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl)
jip = HCL_OOP_TO_SMOOI(cf->operand); jip = HCL_OOP_TO_SMOOI(cf->operand);
hcl->c->blk.depth--; hcl->c->blk.depth--;
hcl->c->tv.size = hcl->c->blk.tmprcnt[hcl->c->blk.depth]; hcl->c->tv.size = hcl->c->blk.info[hcl->c->blk.depth].tmprcnt;
/* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */
block_code_size = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); block_code_size = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1);
@ -2682,7 +2619,7 @@ int hcl_compile (hcl_t* hcl, hcl_oop_t obj)
/* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */ /* TODO: in case i implement all global variables as block arguments at the top level...what should i do? */
hcl->c->blk.depth++; hcl->c->blk.depth++;
if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size) <= -1) return -1; if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.size, 0) <= -1) return -1;
PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj); PUSH_CFRAME (hcl, COP_COMPILE_OBJECT, obj);

View File

@ -2216,7 +2216,7 @@ static int execute (hcl_t* hcl)
/* the stack contains the final return value so the stack pointer must be 0. */ /* the stack contains the final return value so the stack pointer must be 0. */
HCL_ASSERT (hcl, hcl->sp == 0); HCL_ASSERT (hcl, hcl->sp == 0);
if (hcl->option.trait & HCL_AWAIT_PROCS) if (hcl->option.trait & HCL_TRAIT_AWAIT_PROCS)
terminate_process (hcl, hcl->processor->active); terminate_process (hcl, hcl->processor->active);
else else
goto done; goto done;
@ -2280,6 +2280,9 @@ static int execute (hcl_t* hcl)
#if 0 #if 0
if (hcl->option.trait & HCL_TRAIT_INTERACTIVE)
{
/* the MAKE_BLOCK instruction is followed by the long JUMP_FORWARD_X instruction. /* the MAKE_BLOCK instruction is followed by the long JUMP_FORWARD_X instruction.
* i can decode the instruction and get the size of instructions * i can decode the instruction and get the size of instructions
* of the block context */ * of the block context */
@ -2294,6 +2297,8 @@ static int execute (hcl_t* hcl)
HCL_DEBUG1(hcl, "**** MAKE BLOCK joff = %zu\n", joff); HCL_DEBUG1(hcl, "**** MAKE BLOCK joff = %zu\n", joff);
} }
}
#endif #endif

View File

@ -228,6 +228,13 @@ struct hcl_cframe_t
typedef struct hcl_cframe_t hcl_cframe_t; typedef struct hcl_cframe_t hcl_cframe_t;
struct hcl_blk_info_t
{
hcl_oow_t tmprcnt;
hcl_oow_t litbase;
};
typedef struct hcl_blk_info_t hcl_blk_info_t;
struct hcl_compiler_t struct hcl_compiler_t
{ {
/* output handler */ /* output handler */
@ -305,8 +312,8 @@ struct hcl_compiler_t
struct struct
{ {
hcl_ooi_t depth; hcl_ooi_t depth;
hcl_oow_t* tmprcnt; hcl_blk_info_t* info;
hcl_oow_t tmprcnt_capa; hcl_oow_t info_capa;
} blk; /* lambda block */ } blk; /* lambda block */
}; };
#endif #endif

View File

@ -748,7 +748,7 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
hcl_getoption (proto->hcl, HCL_TRAIT, &trait); hcl_getoption (proto->hcl, HCL_TRAIT, &trait);
#if defined(HCL_BUILD_DEBUG) #if defined(HCL_BUILD_DEBUG)
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC; if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT; if (proto->worker->server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
#endif #endif
hcl_setoption (proto->hcl, HCL_TRAIT, &trait); hcl_setoption (proto->hcl, HCL_TRAIT, &trait);
@ -1677,7 +1677,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
hcl_setcmgr (server->dummy_hcl, hcl_server_getcmgr(server)); hcl_setcmgr (server->dummy_hcl, hcl_server_getcmgr(server));
hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait); hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait);
#if defined(HCL_BUILD_DEBUG) #if defined(HCL_BUILD_DEBUG)
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC; if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT; if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
#endif #endif
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait); hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);
@ -2357,7 +2357,7 @@ int hcl_server_setoption (hcl_server_t* server, hcl_server_option_t id, const vo
hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait); hcl_getoption (server->dummy_hcl, HCL_TRAIT, &trait);
#if defined(HCL_BUILD_DEBUG) #if defined(HCL_BUILD_DEBUG)
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_DEBUG_GC; if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_GC) trait |= HCL_TRAIT_DEBUG_GC;
if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT; if (server->cfg.trait & HCL_SERVER_TRAIT_DEBUG_BIGINT) trait |= HCL_DEBUG_BIGINT;
#endif #endif
hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait); hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait);

View File

@ -183,16 +183,18 @@ typedef enum hcl_option_dflval_t hcl_option_dflval_t;
enum hcl_trait_t enum hcl_trait_t
{ {
#if defined(HCL_BUILD_DEBUG) #if defined(HCL_BUILD_DEBUG)
HCL_DEBUG_GC = (1u << 0), HCL_TRAIT_DEBUG_GC = (1u << 0),
HCL_DEBUG_BIGINT = (1u << 1), HCL_DEBUG_BIGINT = (1u << 1),
#endif #endif
HCL_TRAIT_INTERACTIVE = (1u << 7),
/* perform no garbage collection when the heap is full. /* perform no garbage collection when the heap is full.
* you still can use hcl_gc() explicitly. */ * you still can use hcl_gc() explicitly. */
HCL_NOGC = (1u << 8), HCL_TRAIT_NOGC = (1u << 8),
/* wait for running process when exiting from the main method */ /* wait for running process when exiting from the main method */
HCL_AWAIT_PROCS = (1u << 9) HCL_TRAIT_AWAIT_PROCS = (1u << 9)
}; };
typedef enum hcl_trait_t hcl_trait_t; typedef enum hcl_trait_t hcl_trait_t;
@ -1091,35 +1093,6 @@ typedef struct hcl_compiler_t hcl_compiler_t;
#define HCL_ERRMSG_CAPA (2048) #define HCL_ERRMSG_CAPA (2048)
typedef struct hcl_clv_t hcl_clv_t;
struct hcl_clv_t /* literal value in compiler */
{
int type; /* int, string, byte string, character, etc */
hcl_oow_t size;
/* data is placed here */
};
typedef struct hcl_ccl_t hcl_ccl_t;
struct hcl_ccl_t /* code and literal in compiler */
{
struct
{
hcl_uint8_t* ptr;
hcl_oow_t capa;
hcl_oow_t len;
} bc;
struct
{
hcl_clv_t* ptr;
hcl_oow_t capa;
hcl_oow_t len;
} lit;
hcl_oow_t pindex;
};
struct hcl_t struct hcl_t
{ {
hcl_oow_t _instsize; hcl_oow_t _instsize;
@ -1270,14 +1243,6 @@ struct hcl_t
} xbuf; /* buffer to support sprintf */ } xbuf; /* buffer to support sprintf */
} sprintf; } sprintf;
struct
{
hcl_ccl_t* ptr;
hcl_oow_t capa;
hcl_oow_t len;
hcl_oow_t index;
} ccl;
struct struct
{ {
struct struct
@ -1598,7 +1563,7 @@ HCL_EXPORT void hcl_deregcb (
/** /**
* The hcl_gc() function performs garbage collection. * The hcl_gc() function performs garbage collection.
* It is not affected by #HCL_NOGC. * It is not affected by #HCL_TRAIT_NOGC.
*/ */
HCL_EXPORT void hcl_gc ( HCL_EXPORT void hcl_gc (
hcl_t* hcl hcl_t* hcl

View File

@ -31,11 +31,11 @@ void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size)
hcl_uint8_t* ptr; hcl_uint8_t* ptr;
#if defined(HCL_BUILD_DEBUG) #if defined(HCL_BUILD_DEBUG)
if ((hcl->option.trait & HCL_DEBUG_GC) && !(hcl->option.trait & HCL_NOGC)) hcl_gc (hcl); if ((hcl->option.trait & HCL_TRAIT_DEBUG_GC) && !(hcl->option.trait & HCL_TRAIT_NOGC)) hcl_gc (hcl);
#endif #endif
ptr = (hcl_uint8_t*)hcl_allocheapmem(hcl, hcl->curheap, size); ptr = (hcl_uint8_t*)hcl_allocheapmem(hcl, hcl->curheap, size);
if (!ptr && hcl->errnum == HCL_EOOMEM && !(hcl->option.trait & HCL_NOGC)) if (!ptr && hcl->errnum == HCL_EOOMEM && !(hcl->option.trait & HCL_TRAIT_NOGC))
{ {
hcl_gc (hcl); hcl_gc (hcl);
HCL_LOG4 (hcl, HCL_LOG_GC | HCL_LOG_INFO, HCL_LOG4 (hcl, HCL_LOG_GC | HCL_LOG_INFO,

View File

@ -2262,11 +2262,11 @@ static void fini_compiler (hcl_t* hcl)
hcl->c->tv.capa = 0; hcl->c->tv.capa = 0;
} }
if (hcl->c->blk.tmprcnt) if (hcl->c->blk.info)
{ {
hcl_freemem (hcl, hcl->c->blk.tmprcnt); hcl_freemem (hcl, hcl->c->blk.info);
hcl->c->blk.tmprcnt = HCL_NULL; hcl->c->blk.info = HCL_NULL;
hcl->c->blk.tmprcnt_capa = 0; hcl->c->blk.info_capa = 0;
hcl->c->blk.depth = -1; hcl->c->blk.depth = -1;
} }