From 7fc4262d015e974d2358c2f95067fd27ab72460b Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Fri, 29 Jan 2021 12:39:31 +0000 Subject: [PATCH] made enhancement to show location information for the ECALL runtime error --- lib/comp.c | 30 ++++++++++++++-------------- lib/decode.c | 4 ++-- lib/exec.c | 55 +++++++++++++++++++++++++++++++++++++++------------ lib/hcl-prv.h | 8 ++++---- lib/utl.c | 20 +++++++++---------- 5 files changed, 73 insertions(+), 44 deletions(-) diff --git a/lib/comp.c b/lib/comp.c index 4f02cb1..6da0e97 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -413,7 +413,7 @@ write_long: hcl_seterrnum (hcl, HCL_ERANGE); return -1; } -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || emit_byte_instruction(hcl, (param_1 >> 8) & 0xFF, HCL_NULL) <= -1 || emit_byte_instruction(hcl, param_1 & 0xFF, HCL_NULL) <= -1) return -1; @@ -429,7 +429,7 @@ write_long2: hcl_seterrnum (hcl, HCL_ERANGE); return -1; } -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || emit_byte_instruction(hcl, (param_1 >> 24) & 0xFF, HCL_NULL) <= -1 || emit_byte_instruction(hcl, (param_1 >> 16) & 0xFF, HCL_NULL) <= -1 || @@ -495,7 +495,7 @@ write_long: hcl_seterrnum (hcl, HCL_ERANGE); return -1; } -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) if (emit_byte_instruction(hcl, bc, srcloc) <= -1 || emit_byte_instruction(hcl, param_1 >> 8, HCL_NULL) <= -1 || emit_byte_instruction(hcl, param_1 & 0xFF, HCL_NULL) <= -1 || @@ -517,7 +517,7 @@ static HCL_INLINE int emit_long_param (hcl_t* hcl, hcl_oow_t param) return -1; } -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) return (emit_byte_instruction(hcl, param >> 8, HCL_NULL) <= -1 || emit_byte_instruction(hcl, param & 0xFF, HCL_NULL) <= -1)? -1: 0; #else @@ -595,7 +595,7 @@ static HCL_INLINE void patch_long_jump (hcl_t* hcl, hcl_ooi_t jip, hcl_ooi_t jum jump_offset -= MAX_CODE_JUMP; } -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) patch_instruction (hcl, jip + 1, jump_offset >> 8); patch_instruction (hcl, jip + 2, jump_offset & 0xFF); #else @@ -605,7 +605,7 @@ static HCL_INLINE void patch_long_jump (hcl_t* hcl, hcl_ooi_t jip, hcl_ooi_t jum static HCL_INLINE void patch_long_param (hcl_t* hcl, hcl_ooi_t ip, hcl_oow_t param) { -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) patch_instruction (hcl, ip, param >> 8); patch_instruction (hcl, ip + 1, param & 0xFF); #else @@ -991,7 +991,7 @@ static int compile_continue (hcl_t* hcl, hcl_cnode_t* src) HCL_ASSERT (hcl, hcl->code.bc.len < HCL_SMOOI_MAX); jump_offset = hcl->code.bc.len - tcf->u.post_while.cond_pos + 1; - if (jump_offset > 3) jump_offset += HCL_HCL_CODE_LONG_PARAM_SIZE; + if (jump_offset > 3) jump_offset += HCL_CODE_LONG_PARAM_SIZE; if (emit_single_param_instruction(hcl, HCL_CODE_JUMP_BACKWARD_0, jump_offset, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; POP_CFRAME (hcl); @@ -2482,7 +2482,7 @@ static HCL_INLINE int patch_nearest_post_if_body (hcl_t* hcl, hcl_cnode_t* cmd) if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); if (jump_offset > MAX_CODE_JUMP * 2) { @@ -2633,7 +2633,7 @@ static HCL_INLINE int post_and_expr (hcl_t* hcl) jip = cf->u.post_and.jump_inst_pos; /* patch the jump insruction emitted after each expression inside the 'and' expression */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); patch_long_jump (hcl, jip, jump_offset); POP_CFRAME(hcl); @@ -2695,7 +2695,7 @@ static HCL_INLINE int post_or_expr (hcl_t* hcl) jip = cf->u.post_or.jump_inst_pos; /* patch the jump insruction emitted after each expression inside the 'and' expression */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); patch_long_jump (hcl, jip, jump_offset); POP_CFRAME(hcl); @@ -2752,7 +2752,7 @@ static HCL_INLINE int post_if_body (hcl_t* hcl) } /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD_IF_FALSE instruction */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); if (jump_offset > MAX_CODE_JUMP * 2) { @@ -2854,12 +2854,12 @@ static HCL_INLINE int post_while_body (hcl_t* hcl) HCL_ASSERT (hcl, hcl->code.bc.len < HCL_SMOOI_MAX); jump_offset = hcl->code.bc.len - cf->u.post_while.cond_pos + 1; - if (jump_offset > 3) jump_offset += HCL_HCL_CODE_LONG_PARAM_SIZE; + if (jump_offset > 3) jump_offset += HCL_CODE_LONG_PARAM_SIZE; if (emit_single_param_instruction (hcl, HCL_CODE_JUMP_BACKWARD_0, jump_offset, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; jip = cf->u.post_while.jump_inst_pos; /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD_IF_FALSE/JUMP_FORWARD_IF_TRUE instruction */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); if (jump_offset > MAX_CODE_JUMP * 2) { hcl_setsynerrbfmt (hcl, HCL_SYNERR_BLKFLOOD, &cf->u.post_while.start_loc, HCL_NULL, "code too big - size %zu", jump_offset); @@ -2885,7 +2885,7 @@ static int update_break (hcl_t* hcl) jip = cf->u._break.jump_inst_pos;; /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ - jump_offset = hcl->code.bc.len - jip - (HCL_HCL_CODE_LONG_PARAM_SIZE + 1); + jump_offset = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); /* no explicit about jump_offset. because break can only place inside * a loop, the same check in post_while_body() must assert @@ -3056,7 +3056,7 @@ static HCL_INLINE int emit_lambda (hcl_t* hcl) hcl->c->tv2.wcount = 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); + block_code_size = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); if (block_code_size == 0) { diff --git a/lib/decode.c b/lib/decode.c index 8ed806e..e019b72 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -46,7 +46,7 @@ #define FETCH_BYTE_CODE(hcl) (cdptr[ip++]) #define FETCH_BYTE_CODE_TO(hcl,v_ooi) (v_ooi = FETCH_BYTE_CODE(hcl)) -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) # define FETCH_PARAM_CODE_TO(hcl,v_ooi) \ do { \ v_ooi = FETCH_BYTE_CODE(hcl); \ @@ -195,7 +195,7 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) case HCL_CODE_PUSH_LITERAL_X2: FETCH_PARAM_CODE_TO (hcl, b1); FETCH_PARAM_CODE_TO (hcl, b2); - #if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) + #if (HCL_CODE_LONG_PARAM_SIZE == 2) b1 = (b1 << 16) | b2; #else b1 = (b1 << 8) | b2; diff --git a/lib/exec.c b/lib/exec.c index ba5f975..ea35e74 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -100,7 +100,7 @@ static HCL_INLINE const char* proc_state_to_string (int state) /*#define FETCH_BYTE_CODE(hcl) ((hcl)->code.bc.arr->slot[(hcl)->ip++])*/ #define FETCH_BYTE_CODE(hcl) ((hcl)->active_code[(hcl)->ip++]) #define FETCH_BYTE_CODE_TO(hcl, v_oow) (v_oow = FETCH_BYTE_CODE(hcl)) -#if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#if (HCL_CODE_LONG_PARAM_SIZE == 2) # define FETCH_PARAM_CODE_TO(hcl, v_oow) \ do { \ v_oow = FETCH_BYTE_CODE(hcl); \ @@ -261,11 +261,25 @@ static HCL_INLINE hcl_oop_context_t make_context (hcl_t* hcl, hcl_ooi_t ntmprs) return (hcl_oop_context_t)hcl_allocoopobj(hcl, HCL_BRAND_CONTEXT, HCL_CONTEXT_NAMED_INSTVARS + (hcl_oow_t)ntmprs); } -static HCL_INLINE hcl_oop_function_t make_function (hcl_t* hcl, hcl_oow_t lfsize, const hcl_oob_t* bptr, hcl_oow_t blen) +static HCL_INLINE hcl_oop_function_t make_function (hcl_t* hcl, hcl_oow_t lfsize, const hcl_oob_t* bptr, hcl_oow_t blen, hcl_dbgl_t* locptr) { + hcl_oop_function_t func; + /* the literal frame is placed in the variable part. * the byte code is placed in the trailer space */ - return (hcl_oop_function_t)hcl_allocoopobjwithtrailer(hcl, HCL_BRAND_FUNCTION, HCL_FUNCTION_NAMED_INSTVARS + lfsize, bptr, blen); + func = (hcl_oop_function_t)hcl_allocoopobjwithtrailer(hcl, HCL_BRAND_FUNCTION, HCL_FUNCTION_NAMED_INSTVARS + lfsize, bptr, blen); + if (HCL_UNLIKELY(!func)) return HCL_NULL; + + if (locptr) + { + hcl_oop_t tmp; + hcl_pushvolat (hcl, (hcl_oop_t*)&func); + tmp = hcl_makebytearray(hcl, (hcl_oob_t*)locptr, HCL_SIZEOF(*locptr) * blen); + hcl_popvolat (hcl); + if (tmp) func->dbgi = tmp; + } + + return func; } static HCL_INLINE void fill_function_data (hcl_t* hcl, hcl_oop_function_t func, hcl_ooi_t nargs, hcl_ooi_t ntmprs, hcl_oop_context_t homectx, const hcl_oop_t* lfptr, hcl_oow_t lfsize) @@ -2760,7 +2774,7 @@ static int execute (hcl_t* hcl) case HCL_CODE_PUSH_LITERAL_X2: FETCH_PARAM_CODE_TO (hcl, b1); FETCH_PARAM_CODE_TO (hcl, b2); - #if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) + #if (HCL_CODE_LONG_PARAM_SIZE == 2) b1 = (b1 << 16) | b2; #else b1 = (b1 << 8) | b2; @@ -2972,7 +2986,24 @@ static int execute (hcl_t* hcl) { cannot_call: /* run time error */ +if (hcl->active_function->dbgi != hcl->_nil) +{ + hcl_dbgl_t* dbgl; + hcl_ooi_t ip; + static hcl_ooch_t dash[] = { '*', '\0' }; + + HCL_ASSERT (hcl, HCL_IS_BYTEARRAY(hcl, hcl->active_function->dbgi)); + dbgl = (hcl_dbgl_t*)HCL_OBJ_GET_BYTE_SLOT(hcl->active_function->dbgi); + ip = hcl->ip - 1; + if (bcode == HCL_CODE_CALL_X) ip -= HCL_CODE_LONG_PARAM_SIZE; + +hcl_seterrbfmt (hcl, HCL_ECALL, "cannot call %O [%js:%zu]", + rcv, (dbgl[ip].fname? dbgl[ip].fname: dash), dbgl[ip].sline); +} +else +{ hcl_seterrbfmt (hcl, HCL_ECALL, "cannot call %O", rcv); +} goto oops; } break; @@ -3531,15 +3562,15 @@ static int execute (hcl_t* hcl) * of the block context */ HCL_ASSERT (hcl, hcl->active_code[hcl->ip] == HCL_CODE_JUMP_FORWARD_X); joff = hcl->active_code[hcl->ip + 1]; - #if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) + #if (HCL_CODE_LONG_PARAM_SIZE == 2) joff = (joff << 8) | hcl->active_code[hcl->ip + 2]; #endif /* copy the byte codes from the active context to the new context */ - #if (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) - func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff); + #if (HCL_CODE_LONG_PARAM_SIZE == 2) + func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 3], joff, HCL_NULL); #else - func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 2], joff); + func = make_function(hcl, b4, &hcl->active_code[hcl->ip + 2], joff, HCL_NULL); #endif if (HCL_UNLIKELY(!func)) goto oops; @@ -3569,9 +3600,9 @@ static int execute (hcl_t* hcl) /* the long forward jump instruction has the format of * 11000100 KKKKKKKK or 11000100 KKKKKKKK KKKKKKKK - * depending on HCL_HCL_CODE_LONG_PARAM_SIZE. change 'ip' to point to + * depending on HCL_CODE_LONG_PARAM_SIZE. change 'ip' to point to * the instruction after the jump. */ - fill_block_data (hcl, blkobj, b1, b2, hcl->ip + HCL_HCL_CODE_LONG_PARAM_SIZE + 1, hcl->active_context); + fill_block_data (hcl, blkobj, b1, b2, hcl->ip + HCL_CODE_LONG_PARAM_SIZE + 1, hcl->active_context); /* push the new block context to the stack of the active context */ HCL_STACK_PUSH (hcl, (hcl_oop_t)blkobj); @@ -3645,11 +3676,9 @@ hcl_oop_t hcl_execute (hcl_t* hcl) } /* create a virtual function object that hold the bytes codes generated */ - func = make_function(hcl, hcl->code.lit.len, hcl->code.bc.ptr, hcl->code.bc.len); + func = make_function(hcl, hcl->code.lit.len, hcl->code.bc.ptr, hcl->code.bc.len, hcl->code.locptr); if (HCL_UNLIKELY(!func)) return HCL_NULL; -/* TODO: copy the debug information as well into the dbgi field of the function object. */ - /* pass nil for the home context of the initial function */ fill_function_data (hcl, func, 0, 0, (hcl_oop_context_t)hcl->_nil, hcl->code.lit.arr->slot, hcl->code.lit.len); diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 8b32a2a..c39c024 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -32,7 +32,7 @@ #include /* you can define this to either 1 or 2 */ -#define HCL_HCL_CODE_LONG_PARAM_SIZE 2 +#define HCL_CODE_LONG_PARAM_SIZE 2 /* this is useful for debugging. hcl_gc() can be called * while hcl has not been fully initialized when this is defined*/ @@ -467,7 +467,7 @@ struct hcl_compiler_t #endif -#if defined(HCL_HCL_CODE_LONG_PARAM_SIZE) && (HCL_HCL_CODE_LONG_PARAM_SIZE == 1) +#if defined(HCL_CODE_LONG_PARAM_SIZE) && (HCL_CODE_LONG_PARAM_SIZE == 1) # define MAX_CODE_INDEX (0xFFu) # define MAX_CODE_NTMPRS (0xFFu) # define MAX_CODE_NARGS (0xFFu) @@ -476,7 +476,7 @@ struct hcl_compiler_t # define MAX_CODE_JUMP (0xFFu) # define MAX_CODE_PARAM (0xFFu) # define MAX_CODE_PARAM2 (0xFFFFu) -#elif defined(HCL_HCL_CODE_LONG_PARAM_SIZE) && (HCL_HCL_CODE_LONG_PARAM_SIZE == 2) +#elif defined(HCL_CODE_LONG_PARAM_SIZE) && (HCL_CODE_LONG_PARAM_SIZE == 2) # define MAX_CODE_INDEX (0xFFFFu) # define MAX_CODE_NTMPRS (0xFFFFu) # define MAX_CODE_NARGS (0xFFFFu) @@ -486,7 +486,7 @@ struct hcl_compiler_t # define MAX_CODE_PARAM (0xFFFFu) # define MAX_CODE_PARAM2 (0xFFFFFFFFu) #else -# error Unsupported HCL_HCL_CODE_LONG_PARAM_SIZE +# error Unsupported HCL_CODE_LONG_PARAM_SIZE #endif diff --git a/lib/utl.c b/lib/utl.c index f72e5d8..a4dea60 100644 --- a/lib/utl.c +++ b/lib/utl.c @@ -855,7 +855,7 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucharswithheadroom (hcl_t* hcl, hcl_oow_t headro } ptr = (hcl_uch_t*)hcl_allocmem(hcl, headroom_bytes + ((outlen + 1) * HCL_SIZEOF(hcl_uch_t))); - if (!ptr) return HCL_NULL; + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; inlen = bcslen; @@ -888,7 +888,7 @@ HCL_INLINE hcl_bch_t* hcl_duputobcharswithheadroom (hcl_t* hcl, hcl_oow_t headro } ptr = (hcl_bch_t*)hcl_allocmem(hcl, headroom_bytes + ((outlen + 1) * HCL_SIZEOF(hcl_bch_t))); - if (!ptr) return HCL_NULL; + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; inlen = ucslen; ptr = (hcl_bch_t*)((hcl_oob_t*)ptr + headroom_bytes); @@ -919,8 +919,8 @@ HCL_INLINE hcl_uch_t* hcl_dupbtoucstrwithheadroom (hcl_t* hcl, hcl_oow_t headroo } outlen++; - ptr = (hcl_uch_t*)hcl_allocmem (hcl, headroom_bytes + (outlen * HCL_SIZEOF(hcl_uch_t))); - if (!ptr) return HCL_NULL; + ptr = (hcl_uch_t*)hcl_allocmem(hcl, headroom_bytes + (outlen * HCL_SIZEOF(hcl_uch_t))); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; hcl_convbtoucstr (hcl, bcs, &inlen, ptr, &outlen); if (ucslen) *ucslen = outlen; @@ -944,8 +944,8 @@ HCL_INLINE hcl_bch_t* hcl_duputobcstrwithheadroom (hcl_t* hcl, hcl_oow_t headroo } outlen++; - ptr = (hcl_bch_t*)hcl_allocmem (hcl, headroom_bytes + (outlen * HCL_SIZEOF(hcl_bch_t))); - if (!ptr) return HCL_NULL; + ptr = (hcl_bch_t*)hcl_allocmem(hcl, headroom_bytes + (outlen * HCL_SIZEOF(hcl_bch_t))); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; ptr = (hcl_bch_t*)((hcl_oob_t*)ptr + headroom_bytes); @@ -964,8 +964,8 @@ hcl_uch_t* hcl_dupuchars (hcl_t* hcl, const hcl_uch_t* ucs, hcl_oow_t ucslen) { hcl_uch_t* ptr; - ptr = (hcl_uch_t*)hcl_allocmem (hcl, (ucslen + 1) * HCL_SIZEOF(hcl_uch_t)); - if (!ptr) return HCL_NULL; + ptr = (hcl_uch_t*)hcl_allocmem(hcl, (ucslen + 1) * HCL_SIZEOF(hcl_uch_t)); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; hcl_copy_uchars (ptr, ucs, ucslen); ptr[ucslen] = '\0'; @@ -976,8 +976,8 @@ hcl_bch_t* hcl_dupbchars (hcl_t* hcl, const hcl_bch_t* bcs, hcl_oow_t bcslen) { hcl_bch_t* ptr; - ptr = (hcl_bch_t*)hcl_allocmem (hcl, (bcslen + 1) * HCL_SIZEOF(hcl_bch_t)); - if (!ptr) return HCL_NULL; + ptr = (hcl_bch_t*)hcl_allocmem(hcl, (bcslen + 1) * HCL_SIZEOF(hcl_bch_t)); + if (HCL_UNLIKELY(!ptr)) return HCL_NULL; hcl_copy_bchars (ptr, bcs, bcslen); ptr[bcslen] = '\0';