From c7e87698d0f9a6b4c8b939f67ea892e7aaf77d79 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Mon, 28 Sep 2020 15:44:04 +0000 Subject: [PATCH] still experimenting to find a good way to represent byte codes and literal frames in the interactive mode --- bin/main.c | 14 +++++-- lib/comp.c | 113 +++++++++++--------------------------------------- lib/exec.c | 7 +++- lib/hcl-prv.h | 11 ++++- lib/hcl-s.c | 6 +-- lib/hcl.h | 47 +++------------------ lib/obj.c | 4 +- lib/read.c | 8 ++-- 8 files changed, 66 insertions(+), 144 deletions(-) diff --git a/bin/main.c b/bin/main.c index b6308b2..b678be2 100644 --- a/bin/main.c +++ b/bin/main.c @@ -822,7 +822,7 @@ static int handle_dbgopt (hcl_t* hcl, const hcl_bch_t* str) cm = hcl_find_bchar_in_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 { @@ -1082,8 +1082,8 @@ int main (int argc, char* argv[]) { hcl_bitmask_t trait = 0; - /*trait |= HCL_NOGC;*/ - trait |= HCL_AWAIT_PROCS; + /*trait |= HCL_TRAIT_NOGC;*/ + trait |= HCL_TRAIT_AWAIT_PROCS; hcl_setoption (hcl, HCL_TRAIT, &trait); /* disable GC logs */ @@ -1160,6 +1160,14 @@ hcl_logufmt (hcl, HCL_LOG_WARN, fmt, ustr, 0x6789); } #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) { hcl_oop_t obj; diff --git a/lib/comp.c b/lib/comp.c index dc1212d..6b742fd 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -33,7 +33,7 @@ enum }; #define TV_BUFFER_ALIGN 256 -#define BLK_TMPRCNT_BUFFER_ALIGN 128 +#define BLK_INFO_BUFFER_ALIGN 128 #define EMIT_BYTE_INSTRUCTION(hcl,code) \ 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 -// back one new literal frame => current literal frame index - 1 - - <--- code/literal frame #0 -(defun plus(x y) <--- code/literal frame #1 + +(defun plus(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) (- 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) ) - <--- code/literal frame #0 (plus 10 20) <---- minus is now available (minus 10 1) - + +literals --> // // characeter 'A' // "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) { 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; + 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; return 0; } @@ -225,24 +161,25 @@ static int find_temporary_variable_backward (hcl_t* hcl, hcl_oop_t name, hcl_oow 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); - 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; - newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_TMPRCNT_BUFFER_ALIGN); - tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.tmprcnt, newcapa * HCL_SIZEOF(*tmp)); + newcapa = HCL_ALIGN (hcl->c->blk.depth + 1, BLK_INFO_BUFFER_ALIGN); + tmp = (hcl_oow_t*)hcl_reallocmem (hcl, hcl->c->blk.info, newcapa * HCL_SIZEOF(*tmp)); if (!tmp) return -1; - hcl->c->blk.tmprcnt_capa = newcapa; - hcl->c->blk.tmprcnt = tmp; + hcl->c->blk.info_capa = newcapa; + 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; } @@ -1123,7 +1060,7 @@ static int compile_lambda (hcl_t* hcl, hcl_oop_t src, int defun) return -1; } 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 * 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, * 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 */ { - 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; 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. * 1 means current->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); 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 */ 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? */ 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); diff --git a/lib/exec.c b/lib/exec.c index 46ce5eb..046081e 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -2216,7 +2216,7 @@ static int execute (hcl_t* hcl) /* the stack contains the final return value so the stack pointer must be 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); else goto done; @@ -2280,6 +2280,9 @@ static int execute (hcl_t* hcl) #if 0 + if (hcl->option.trait & HCL_TRAIT_INTERACTIVE) + { + /* the MAKE_BLOCK instruction is followed by the long JUMP_FORWARD_X instruction. * i can decode the instruction and get the size of instructions * of the block context */ @@ -2294,6 +2297,8 @@ static int execute (hcl_t* hcl) HCL_DEBUG1(hcl, "**** MAKE BLOCK joff = %zu\n", joff); } + + } #endif diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 8dcf1e2..960d788 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -228,6 +228,13 @@ struct 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 { /* output handler */ @@ -305,8 +312,8 @@ struct hcl_compiler_t struct { hcl_ooi_t depth; - hcl_oow_t* tmprcnt; - hcl_oow_t tmprcnt_capa; + hcl_blk_info_t* info; + hcl_oow_t info_capa; } blk; /* lambda block */ }; #endif diff --git a/lib/hcl-s.c b/lib/hcl-s.c index 04e6809..1f91bd7 100644 --- a/lib/hcl-s.c +++ b/lib/hcl-s.c @@ -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); #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; #endif 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_getoption (server->dummy_hcl, HCL_TRAIT, &trait); #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; #endif 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); #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; #endif hcl_setoption (server->dummy_hcl, HCL_TRAIT, &trait); diff --git a/lib/hcl.h b/lib/hcl.h index 81f27f8..98174ae 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -183,16 +183,18 @@ typedef enum hcl_option_dflval_t hcl_option_dflval_t; enum hcl_trait_t { #if defined(HCL_BUILD_DEBUG) - HCL_DEBUG_GC = (1u << 0), + HCL_TRAIT_DEBUG_GC = (1u << 0), HCL_DEBUG_BIGINT = (1u << 1), #endif + HCL_TRAIT_INTERACTIVE = (1u << 7), + /* perform no garbage collection when the heap is full. * 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 */ - HCL_AWAIT_PROCS = (1u << 9) + HCL_TRAIT_AWAIT_PROCS = (1u << 9) }; 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) -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 { hcl_oow_t _instsize; @@ -1270,14 +1243,6 @@ struct hcl_t } xbuf; /* buffer to support sprintf */ } sprintf; - struct - { - hcl_ccl_t* ptr; - hcl_oow_t capa; - hcl_oow_t len; - hcl_oow_t index; - } ccl; - struct { struct @@ -1598,7 +1563,7 @@ HCL_EXPORT void hcl_deregcb ( /** * 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_t* hcl diff --git a/lib/obj.c b/lib/obj.c index e83a5b9..806e12f 100644 --- a/lib/obj.c +++ b/lib/obj.c @@ -31,11 +31,11 @@ void* hcl_allocbytes (hcl_t* hcl, hcl_oow_t size) hcl_uint8_t* ptr; #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 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_LOG4 (hcl, HCL_LOG_GC | HCL_LOG_INFO, diff --git a/lib/read.c b/lib/read.c index 8e399c9..01256d9 100644 --- a/lib/read.c +++ b/lib/read.c @@ -2262,11 +2262,11 @@ static void fini_compiler (hcl_t* hcl) hcl->c->tv.capa = 0; } - if (hcl->c->blk.tmprcnt) + if (hcl->c->blk.info) { - hcl_freemem (hcl, hcl->c->blk.tmprcnt); - hcl->c->blk.tmprcnt = HCL_NULL; - hcl->c->blk.tmprcnt_capa = 0; + hcl_freemem (hcl, hcl->c->blk.info); + hcl->c->blk.info = HCL_NULL; + hcl->c->blk.info_capa = 0; hcl->c->blk.depth = -1; }