From 24f8525db38ae8893fdb9111f03772a9032d2698 Mon Sep 17 00:00:00 2001 From: "hyunghwan.chung" Date: Fri, 16 Aug 2019 16:19:21 +0000 Subject: [PATCH] fixed a compiler bug in patch_forward_jump_instruction() enhanced the compiler to disallow 'goto' in an argument expression to jump out. --- moo/kernel/System.moo | 16 +++++++++++----- moo/lib/comp.c | 44 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/moo/kernel/System.moo b/moo/kernel/System.moo index 11f1853..96a943c 100644 --- a/moo/kernel/System.moo +++ b/moo/kernel/System.moo @@ -55,14 +55,20 @@ class System(Apex) // start the gc finalizer process [ self __gc_finalizer ] fork. + + // start the os signal handler process //[ self __os_sig_handler ] fork. [ :caller | self __os_sig_handler: caller ] newProcess(thisProcess) resume. - // TODO: change the method signature to variadic and pass extra arguments to perform??? - ret := class perform: method_name. + [ + // TODO: change the method signature to variadic and pass extra arguments to perform??? + ret := class perform: method_name. + ] + ensure: [ + self _setSig: 16rFF. + //// System logNl: '======= END of startup ==============='. + ]. - self _setSig: 16rFF. - //// System logNl: '======= END of startup ==============='. ^ret. } @@ -131,7 +137,7 @@ class System(Apex) //TODO: Execute Handler for tmp. System logNl: 'Interrupt dectected - signal no - ' & tmp asString. - if (tmp == 16rFF or tmp == 2) { /* TODO: terminate all processes??? */ goto done }. + if (tmp == 16rFF or tmp == 2) { /* TODO: terminate all processes except gcfin process??? */ goto done }. }. os_intr_sem wait. diff --git a/moo/lib/comp.c b/moo/lib/comp.c index a9ca8d5..99b32eb 100644 --- a/moo/lib/comp.c +++ b/moo/lib/comp.c @@ -2716,9 +2716,12 @@ static int patch_forward_jump_instruction (moo_t* moo, moo_oow_t jip, moo_oow_t cc->mth.code.ptr[jip] == BCODE_JMPOP_FORWARD_IF_FALSE || cc->mth.code.ptr[jip] == BCODE_JMPOP_FORWARD_IF_TRUE); - if (jt < jip) + if (jt <= jip) { /* backward jump */ + /* it's also backward jump if jt == jip. when the jump instruction is executed, + * the intruction pointer advances. so it should jump backward to get back to + * the same position */ MOO_STATIC_ASSERT (BCODE_JUMP_FORWARD + 10 == BCODE_JUMP_BACKWARD); MOO_STATIC_ASSERT (BCODE_JUMP_FORWARD_IF_TRUE + 10 == BCODE_JUMP_BACKWARD_IF_TRUE); MOO_STATIC_ASSERT (BCODE_JUMP_FORWARD_IF_FALSE + 10 == BCODE_JUMP_BACKWARD_IF_FALSE); @@ -5684,6 +5687,7 @@ static moo_oob_t send_message_cmd[] = static int compile_unary_message (moo_t* moo, int to_super) { + moo_cunit_class_t* cc = (moo_cunit_class_t*)moo->c->cunit; moo_oow_t index; moo_oow_t nargs; moo_ioloc_t sel_loc; @@ -5706,7 +5710,16 @@ static int compile_unary_message (moo_t* moo, int to_super) { do { - if (compile_method_expression(moo, 0) <= -1) return -1; + int n; + moo_oow_t cur_blk_id; + + /* this argument is not a real block. but change the block id + * to prevent 'goto' from jumping out of the argument expression */ + cur_blk_id = cc->mth.blk_id; + cc->mth.blk_id = cc->mth.blk_idseq++; + n = compile_method_expression(moo, 0); + cc->mth.blk_id = cur_blk_id; + if (n <= -1) return -1; nargs++; if (TOKEN_TYPE(moo) == MOO_IOTOK_RPAREN) break; @@ -5752,6 +5765,8 @@ static int compile_binary_message (moo_t* moo, int to_super) moo_oocs_t binsel; moo_oow_t saved_binsels_len, binsel_offset; moo_ioloc_t sel_loc; + moo_oow_t cur_blk_id; + int n; MOO_ASSERT (moo, TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL); @@ -5765,7 +5780,13 @@ static int compile_binary_message (moo_t* moo, int to_super) GET_TOKEN (moo); - if (compile_expression_primary(moo, MOO_NULL, MOO_NULL, 0, &to_super2) <= -1) goto oops; + /* this argument expression is not a real block. but change the block id + * to prevent 'goto' from jumping out of the argument expression */ + cur_blk_id = cc->mth.blk_id; + cc->mth.blk_id = cc->mth.blk_idseq++; + n = compile_expression_primary(moo, MOO_NULL, MOO_NULL, 0, &to_super2); + cc->mth.blk_id = cur_blk_id; + if (n <= -1) goto oops; if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT && compile_unary_message(moo, to_super2) <= -1) goto oops; @@ -5803,6 +5824,8 @@ static int compile_keyword_message (moo_t* moo, int to_super) moo_oow_t saved_kwsel_len; moo_oow_t kw_offset; moo_oow_t nargs = 0; + moo_oow_t cur_blk_id; + int n; saved_kwsel_loc = moo->c->tok.loc; saved_kwsel_len = cc->mth.kwsels.len; @@ -5815,7 +5838,13 @@ static int compile_keyword_message (moo_t* moo, int to_super) GET_TOKEN (moo); - if (compile_expression_primary(moo, MOO_NULL, MOO_NULL, 0, &to_super2) <= -1) goto oops; + /* this argument expression is not a real block. but change the block id + * to prevent 'goto' from jumping out of the argument expression */ + cur_blk_id = cc->mth.blk_id; + cc->mth.blk_id = cc->mth.blk_idseq++; + n = compile_expression_primary(moo, MOO_NULL, MOO_NULL, 0, &to_super2); + cc->mth.blk_id = cur_blk_id; + if (n <= -1) goto oops; if (TOKEN_TYPE(moo) == MOO_IOTOK_IDENT && compile_unary_message(moo, to_super2) <= -1) goto oops; if (TOKEN_TYPE(moo) == MOO_IOTOK_BINSEL && compile_binary_message(moo, to_super2) <= -1) goto oops; @@ -6872,12 +6901,15 @@ static MOO_INLINE int resolve_goto_label (moo_t* moo, moo_goto_t* _goto) if (_goto->blk_id != _label->blk_id || _goto->blk_depth != _label->blk_depth) { gtname.len = moo_count_oocstr(gtname.ptr); - moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &_goto->loc, >name, "goto disallowed to different square bracketed block/level"); + moo_setsynerrbfmt (moo, MOO_SYNERR_NAMEUNDEF, &_goto->loc, >name, "goto disallowed to different block level"); return -1; } MOO_ASSERT (moo, _goto->ip != INVALID_IP); - MOO_ASSERT (moo, _goto->ip != _label->ip); + + /*MOO_ASSERT (moo, _goto->ip != _label->ip); + in 'label: goto label', _goto->ip and _label->ip are the same. + */ if (patch_forward_jump_instruction(moo, _goto->ip, _label->ip) <= -1) {