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, ',');
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;

View File

@ -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);

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. */
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 */
@ -2293,6 +2296,8 @@ static int execute (hcl_t* hcl)
#endif
HCL_DEBUG1(hcl, "**** MAKE BLOCK joff = %zu\n", joff);
}
}
#endif

View File

@ -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

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);
#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);

View File

@ -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

View File

@ -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,

View File

@ -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;
}