From 5537e1850ae02a00e710663dcb77579975378687 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 11 Apr 2021 15:08:27 +0000 Subject: [PATCH] reimplementing try-catch --- lib/comp.c | 52 +++++++++++++++++++++------------------------------ lib/decode.c | 8 +++++++- lib/exec.c | 7 ++++++- lib/hcl-prv.h | 9 +++++---- 4 files changed, 39 insertions(+), 37 deletions(-) diff --git a/lib/comp.c b/lib/comp.c index 9031ad8..64ded38 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -463,6 +463,8 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 case HCL_CODE_JUMP2_BACKWARD_IF_TRUE: case HCL_CODE_JUMP2_BACKWARD_IF_FALSE: case HCL_CODE_JUMP2_BACKWARD: + case HCL_CODE_TRY_ENTER: + case HCL_CODE_TRY_ENTER2: case HCL_CODE_PUSH_INTLIT: case HCL_CODE_PUSH_NEGINTLIT: case HCL_CODE_PUSH_CHARLIT: @@ -664,7 +666,8 @@ static HCL_INLINE void patch_long_jump (hcl_t* hcl, hcl_ooi_t jip, hcl_ooi_t jum hcl->code.bc.ptr[jip] == HCL_CODE_JUMP_FORWARD_IF_FALSE || hcl->code.bc.ptr[jip] == HCL_CODE_JUMP_BACKWARD_X || hcl->code.bc.ptr[jip] == HCL_CODE_JUMP_BACKWARD_IF_TRUE || - hcl->code.bc.ptr[jip] == HCL_CODE_JUMP_BACKWARD_IF_FALSE); + hcl->code.bc.ptr[jip] == HCL_CODE_JUMP_BACKWARD_IF_FALSE || + hcl->code.bc.ptr[jip] == HCL_CODE_TRY_ENTER); /* JUMP2 instructions are chosen to be greater than its JUMP counterpart by 1 */ patch_instruction (hcl, jip, hcl->code.bc.ptr[jip] + 1); @@ -1040,8 +1043,6 @@ static int compile_or (hcl_t* hcl, hcl_cnode_t* src) } - - static HCL_INLINE int compile_or_expr (hcl_t* hcl) { hcl_cnode_t* obj, * expr; @@ -1137,9 +1138,8 @@ static int compile_break (hcl_t* hcl, hcl_cnode_t* src) } else if (hcl->c->cblk.info[i]._type == HCL_CBLK_TYPE_TRY) { - //must emit an instruction to exit from the try loop. - /* TODO: do something for finally - if (emit_byte_instruction(hcl, HCL_CODE_EXIT_TRY, HCL_CNODE_GET_LOC(src)) <= -1) return -1;*/ + /*must emit an instruction to exit from the try loop.*/ + if (emit_byte_instruction(hcl, HCL_CODE_TRY_EXIT, HCL_CNODE_GET_LOC(src)) <= -1) return -1; } } @@ -1243,9 +1243,8 @@ static int compile_continue (hcl_t* hcl, hcl_cnode_t* src) } else if (hcl->c->cblk.info[i]._type == HCL_CBLK_TYPE_TRY) { - //must emit an instruction to exit from the try loop. - /* TODO: do something for finally - if (emit_byte_instruction(hcl, HCL_CODE_EXIT_TRY, HCL_CNODE_GET_LOC(src)) <= -1) return -1;*/ + /*must emit an instruction to exit from the try loop.*/ + if (emit_byte_instruction(hcl, HCL_CODE_TRY_EXIT, HCL_CNODE_GET_LOC(src)) <= -1) return -1; } } @@ -1885,27 +1884,16 @@ static int compile_try (hcl_t* hcl, hcl_cnode_t* src) hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "redundant cdr in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); return -1; } - - -/* TODO: allow local temporary variables?? */ - -#if 0 - if (hcl->c->fnblk.depth == HCL_TYPE_MAX(hcl_ooi_t)) - { - hcl_setsynerrbfmt (hcl, HCL_SYNERR_BLKDEPTH, HCL_CNODE_GET_LOC(src), HCL_NULL, "block depth too deep in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); - return -1; - } - hcl->c->fnblk.depth++; - if (store_temporary_variable_count_for_block(hcl, hcl->c->tv.wcount, hcl->c->tv.s.len, hcl->code.lit.len) <= -1) return -1; -#else - /*push_cblk ....*/ -#endif + + if (push_cblk(hcl, HCL_CNODE_GET_LOC(src), HCL_CBLK_TYPE_TRY) <= -1) return -1; /* TODO: HCL_TRAIT_INTERACTIVE??? */ +#if 0 if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_BLOCK, 0, 0, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; + #endif jump_inst_pos = hcl->code.bc.len; - if (emit_single_param_instruction(hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; + if (emit_single_param_instruction(hcl, HCL_CODE_TRY_ENTER, MAX_CODE_JUMP, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; SWITCH_TOP_CFRAME (hcl, COP_COMPILE_TRY_OBJECT_LIST, obj); /* 1*/ PUSH_SUBCFRAME (hcl, COP_POST_TRY, cmd); /* 2 */ @@ -1927,7 +1915,6 @@ static HCL_INLINE int patch_nearest_post_try (hcl_t* hcl) jip = cf->u.post_try_catch.jump_inst_pos; - /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ block_code_size = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); @@ -1936,18 +1923,21 @@ static HCL_INLINE int patch_nearest_post_try (hcl_t* hcl) /* no body in try */ /* TODO: is this correct??? */ if (emit_byte_instruction(hcl, HCL_CODE_PUSH_NIL, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; - block_code_size++; } - if (emit_byte_instruction(hcl, HCL_CODE_RETURN_FROM_BLOCK, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; - block_code_size++; + /*jump_inst_pos = hcl-.code.bc.len; */ + if (emit_byte_instruction(hcl, HCL_CODE_TRY_EXIT, HCL_CNODE_GET_LOC(cf->operand)) <= -1) + if (emit_single_param_instruction(hcl, HCL_CODE_JUMP_FORWARD_0, MAX_CODE_JUMP, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; + /* HCL_CODE_LONG_PARAM_SIZE + 1 => size of the long JUMP_FORWARD instruction */ + block_code_size = hcl->code.bc.len - jip - (HCL_CODE_LONG_PARAM_SIZE + 1); + if (block_code_size > MAX_CODE_JUMP * 2) { hcl_setsynerrbfmt (hcl, HCL_SYNERR_BLKFLOOD, HCL_CNODE_GET_LOC(cf->operand), HCL_NULL, "code too big - size %zu", block_code_size); return -1; } - patch_long_jump (hcl, jip, block_code_size); + patch_long_jump (hcl, jip, block_code_size); /* patch TRY_ENTER */ #if 0 /* beginning of the elif/else block code */ @@ -1991,7 +1981,7 @@ static HCL_INLINE int compile_catch (hcl_t* hcl) hcl_setsynerrbfmt (hcl, HCL_SYNERR_ARGCOUNT, HCL_CNODE_GET_LOC(src), HCL_NULL, "no condition in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); return -1; } - else if (!HCL_CNODE_IS_CONS(obj)) + else if (!HCL_CNODE_IS_CONS(obj)) { hcl_setsynerrbfmt (hcl, HCL_SYNERR_DOTBANNED, HCL_CNODE_GET_LOC(obj), HCL_CNODE_GET_TOK(obj), "redundant cdr in %.*js", HCL_CNODE_GET_TOKLEN(cmd), HCL_CNODE_GET_TOKPTR(cmd)); return -1; diff --git a/lib/decode.c b/lib/decode.c index dbf8572..ea6d266 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -351,7 +351,13 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) /* -------------------------------------------------------- */ case HCL_CODE_TRY_ENTER: - LOG_INST_0 (hcl, "try_enter"); + FETCH_PARAM_CODE_TO (hcl, b1); + LOG_INST_1 (hcl, "try_enter %zu", b1); + break; + + case HCL_CODE_TRY_ENTER2: + FETCH_PARAM_CODE_TO (hcl, b1); + LOG_INST_1 (hcl, "try_enter2 %zu", b1); break; case HCL_CODE_TRY_EXIT: diff --git a/lib/exec.c b/lib/exec.c index 32b3696..11b1081 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -3120,7 +3120,8 @@ static int execute (hcl_t* hcl) /* -------------------------------------------------------- */ case HCL_CODE_TRY_ENTER: - LOG_INST_0 (hcl, "try_enter"); + FETCH_PARAM_CODE_TO (hcl, b1); + LOG_INST_0 (hcl, "try_enter %zu", b1); #if 0 if (call_try_catch(hcl) <= -1) { @@ -3130,6 +3131,10 @@ static int execute (hcl_t* hcl) #endif break; + case HCL_CODE_TRY_ENTER2: + FETCH_PARAM_CODE_TO (hcl, b1); + LOG_INST_0 (hcl, "try_enter2 %zu", b1); + case HCL_CODE_TRY_EXIT: LOG_INST_0 (hcl, "try_exit"); break; diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 6a0fce8..163a1b3 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -777,11 +777,12 @@ enum hcl_bcode_t HCL_CODE_CALL_X = 0xD4, /* 212 */ HCL_CODE_TRY_ENTER = 0xD5, /* 213 ## */ - HCL_CODE_TRY_EXIT = 0xD6, /* 214 */ - HCL_CODE_THROW = 0xD7, /* 215 */ - + HCL_CODE_TRY_ENTER2 = 0xD6, /* 214 */ + HCL_CODE_TRY_EXIT = 0xD7, /* 215 */ + HCL_CODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 ## */ - /* UNUSED - 0xD9 - 0xDB */ + HCL_CODE_THROW = 0xD9, /* 217 */ + /* UNUSED - 0xDA - 0xDB */ HCL_CODE_POP_INTO_CTXTEMPVAR_X = 0xDC, /* 220 ## */ /* UNUSED - 0xDD - 0xDF */