diff --git a/lib/comp.c b/lib/comp.c index 037363d..f4c4a03 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -1885,6 +1885,7 @@ static HCL_INLINE int compile_catch (hcl_t* hcl) patch_nearest_post_try (hcl); /* TODO: HCL_TRAIT_INTERACTIVE??? */ +/* TODO: nargs -> 1 ntmprs -> 1 */ if (emit_double_param_instruction(hcl, HCL_CODE_MAKE_BLOCK, 0, 0, HCL_CNODE_GET_LOC(cmd)) <= -1) return -1; jump_inst_pos = hcl->code.bc.len; @@ -1941,12 +1942,7 @@ static HCL_INLINE int post_catch (hcl_t* hcl) } patch_long_jump (hcl, jip, block_code_size); -#if 0 -/* beginning of the elif/else block code */ - /* to drop the result of the conditional when the conditional is false */ - if (emit_byte_instruction (hcl, HCL_CODE_POP_STACKTOP, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; -#endif -/* TODO: activate two blocks with special frame arrangement..EMIT_CALL for try...catch... with 2 args???*/ + if (emit_byte_instruction(hcl, HCL_CODE_TRY_CATCH, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; hcl->c->blk.depth--; POP_CFRAME (hcl); diff --git a/lib/decode.c b/lib/decode.c index e019b72..c874642 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -348,7 +348,10 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) handle_call: LOG_INST_1 (hcl, "call %zu", b1); break; - + /* -------------------------------------------------------- */ + case HCL_CODE_TRY_CATCH: + LOG_INST_0 (hcl, "try_catch"); + break; /* -------------------------------------------------------- */ case HCL_CODE_PUSH_CTXTEMPVAR_X: diff --git a/lib/exec.c b/lib/exec.c index 6ecb2fd..2c5e0c1 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -1905,9 +1905,32 @@ static HCL_INLINE int call_primitive (hcl_t* hcl, hcl_ooi_t nargs) return -1; } - return ((hcl_pfimpl_t)rcv->impl) (hcl, (hcl_mod_t*)rcv->mod, nargs); + return ((hcl_pfimpl_t)rcv->impl)(hcl, (hcl_mod_t*)rcv->mod, nargs); } +/* ------------------------------------------------------------------------- */ + +static HCL_INLINE int call_try_catch (hcl_t* hcl) +{ + int x; + hcl_oop_block_t rcv; + hcl_oop_context_t newctx; + hcl_ooi_t nargs = 1; + + rcv = (hcl_oop_block_t)HCL_STACK_GETRCV(hcl, nargs); + HCL_ASSERT (hcl, HCL_IS_BLOCK(hcl, rcv)); + +/* TODO: make this block a try catch block */ + x = prepare_new_block(hcl, rcv, 0, 0, &newctx); + if (HCL_UNLIKELY(x <= -1)) return -1; + + HCL_STACK_POPS (hcl, nargs + 1); /* pop arguments and receiver */ + newctx->sender = hcl->active_context; + + SWITCH_ACTIVE_CONTEXT (hcl, newctx); + return 0; +} +/* ------------------------------------------------------------------------- */ #if 0 @@ -3005,7 +3028,16 @@ static int execute (hcl_t* hcl) } break; } - + + /* -------------------------------------------------------- */ + case HCL_CODE_TRY_CATCH: + LOG_INST_0 (hcl, "try_catch"); + if (call_try_catch(hcl) <= -1) + { + supplement_errmsg (hcl, fetched_instruction_pointer); + goto oops; + } + break; /* -------------------------------------------------------- */ case HCL_CODE_PUSH_CTXTEMPVAR_X: diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index 11a6c16..68a7357 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -752,7 +752,8 @@ enum hcl_bcode_t HCL_CODE_JUMP2_BACKWARD_IF_FALSE = 0xD3, /* 211 */ HCL_CODE_CALL_X = 0xD4, /* 212 */ - /* UNUSED - 0xD5 - 0xD7 */ + HCL_CODE_TRY_CATCH = 0xD5, /* 213 */ + /* UNUSED - 0xD6 - 0xD7 */ HCL_CODE_STORE_INTO_CTXTEMPVAR_X = 0xD8, /* 216 ## */ /* UNUSED - 0xD9 - 0xDB */