diff --git a/lib/comp.c b/lib/comp.c index cbffb84..212c825 100644 --- a/lib/comp.c +++ b/lib/comp.c @@ -552,7 +552,7 @@ static int emit_single_param_instruction (hcl_t* hcl, int cmd, hcl_oow_t param_1 case HCL_CODE_STORE_INTO_CLSVAR_M_X: case HCL_CODE_POP_INTO_CLSVAR_M_X: - case HCL_CODE_CLASS_SET: + case HCL_CODE_CLASS_MSTORE: case HCL_CODE_TRY_ENTER: case HCL_CODE_TRY_ENTER2: case HCL_CODE_PUSH_INTLIT: @@ -1279,7 +1279,7 @@ enum COP_EMIT_POP_STACKTOP, COP_EMIT_RETURN, COP_EMIT_SET, - COP_EMIT_CLASS_SET, + COP_EMIT_CLASS_MSTORE, COP_EMIT_THROW, COP_POST_IF_COND, @@ -4796,7 +4796,7 @@ static HCL_INLINE int post_lambda (hcl_t* hcl) if (x == 0) { /* arrange to save to the method slot */ - SWITCH_TOP_CFRAME (hcl, COP_EMIT_CLASS_SET, defun_name); + SWITCH_TOP_CFRAME (hcl, COP_EMIT_CLASS_MSTORE, defun_name); cf = GET_TOP_CFRAME(hcl); } else @@ -4904,20 +4904,20 @@ static HCL_INLINE int emit_set (hcl_t* hcl) return 0; } -static HCL_INLINE int emit_class_set (hcl_t* hcl) +static HCL_INLINE int emit_class_mstore (hcl_t* hcl) { hcl_cframe_t* cf; hcl_oop_t lit; hcl_oow_t index; cf = GET_TOP_CFRAME(hcl); - HCL_ASSERT (hcl, cf->opcode == COP_EMIT_CLASS_SET); + HCL_ASSERT (hcl, cf->opcode == COP_EMIT_CLASS_MSTORE); lit = hcl_makesymbol(hcl, HCL_CNODE_GET_TOKPTR(cf->operand), HCL_CNODE_GET_TOKLEN(cf->operand)); if (HCL_UNLIKELY(!lit)) return -1; if (add_literal(hcl, lit, &index) <= -1) return -1; - if (emit_single_param_instruction(hcl, HCL_CODE_CLASS_SET, index, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; + if (emit_single_param_instruction(hcl, HCL_CODE_CLASS_MSTORE, index, HCL_CNODE_GET_LOC(cf->operand)) <= -1) return -1; POP_CFRAME (hcl); @@ -5171,8 +5171,8 @@ int hcl_compile (hcl_t* hcl, hcl_cnode_t* obj, int flags) if (emit_set(hcl) <= -1) goto oops; break; - case COP_EMIT_CLASS_SET: - if (emit_class_set(hcl) <= -1) goto oops; + case COP_EMIT_CLASS_MSTORE: + if (emit_class_mstore(hcl) <= -1) goto oops; break; case COP_EMIT_THROW: diff --git a/lib/decode.c b/lib/decode.c index 6875257..a003d2c 100644 --- a/lib/decode.c +++ b/lib/decode.c @@ -386,9 +386,9 @@ int hcl_decode (hcl_t* hcl, hcl_oow_t start, hcl_oow_t end) LOG_INST_0 (hcl, "class_pexit"); break; - case HCL_CODE_CLASS_SET: + case HCL_CODE_CLASS_MSTORE: FETCH_PARAM_CODE_TO (hcl, b1); - LOG_INST_1 (hcl, "class_set %zu", b1); + LOG_INST_1 (hcl, "class_mstore %zu", b1); break; /* -------------------------------------------------------- */ diff --git a/lib/exec.c b/lib/exec.c index e8062e4..c3730c8 100644 --- a/lib/exec.c +++ b/lib/exec.c @@ -3356,8 +3356,7 @@ static int execute (hcl_t* hcl) { hcl_seterrbfmt (hcl, HCL_ECALL, "cannot call %O", rcv); call2_failed: - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } break; @@ -3415,8 +3414,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) hcl_seterrbfmt (hcl, HCL_ECALL, "cannot call %O", op); if (do_throw_with_internal_errmsg(hcl, fetched_instruction_pointer) >= 0) break; call_failed: - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } break; } @@ -3494,23 +3492,18 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) else ivars_str = hcl->_nil; if (b1 > 0) - { + { HCL_STACK_POP_TO (hcl, sc); /* TODO: support more than 1 later when the compiler supports more */ if (!HCL_IS_CLASS(hcl, sc)) { hcl_seterrbfmt (hcl, HCL_ECALL, "invalid superclass %O", sc); - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } } else sc = hcl->_nil; t = hcl_makeclass(hcl, sc, b2, b3, ivars_str, cvars_str); // TOOD: pass variable information... - if (HCL_UNLIKELY(!t)) - { - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; - } + if (HCL_UNLIKELY(!t)) goto oops_with_errmsg_supplement; /* push the class created to the class stack. but don't push to the normal operation stack */ HCL_CLSTACK_PUSH (hcl, t); @@ -3527,8 +3520,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (HCL_CLSTACK_IS_EMPTY(hcl)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "class stack underflow"); - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } HCL_CLSTACK_POP (hcl); break; @@ -3543,8 +3535,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (HCL_CLSTACK_IS_EMPTY(hcl)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "class stack underflow"); - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } HCL_CLSTACK_POP_TO (hcl, c); HCL_STACK_PUSH (hcl, c); @@ -3552,10 +3543,35 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) break; } - case HCL_CODE_CLASS_SET: + case HCL_CODE_CLASS_MSTORE: { + hcl_oop_t class_; + hcl_oop_t dic; + FETCH_PARAM_CODE_TO (hcl, b1); - LOG_INST_1 (hcl, "class_set %zu", b1); + LOG_INST_1 (hcl, "class_mstore %zu", b1); + + /* store the stack top in the member dictionary of the currect class with the key indicated by 'b1' */ + + HCL_ASSERT (hcl, !HCL_CLSTACK_IS_EMPTY(hcl)); + + HCL_CLSTACK_FETCH_TOP_TO (hcl, class_); + HCL_ASSERT (hcl, HCL_IS_CLASS(hcl, class_)); + + dic = ((hcl_oop_class_t)class_)->memdic; + HCL_ASSERT (hcl, HCL_IS_NIL(hcl, dic) || HCL_IS_DIC(hcl, dic)); + if (HCL_IS_NIL(hcl, dic)) + { + hcl_pushvolat (hcl, (hcl_oop_t*)&class_); + dic = hcl_makedic(hcl, 16); /* TODO: configurable initial size? */ + hcl_popvolat (hcl); + if (HCL_UNLIKELY(!dic)) goto oops_with_errmsg_supplement; + ((hcl_oop_class_t)class_)->memdic = dic; + } + +HCL_DEBUG2 (hcl, "class_mstore %O %O\n", hcl->active_function->literal_frame[b1], HCL_STACK_GETTOP(hcl)); + if (!hcl_putatdic(hcl, dic, hcl->active_function->literal_frame[b1], HCL_STACK_GETTOP(hcl))) goto oops_with_errmsg_supplement; + break; } /* -------------------------------------------------------- */ @@ -3735,8 +3751,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) hcl_seterrbfmt (hcl, HCL_ECALL, "unable to send %O to %O - invalid receiver", op, rcv); /* TODO: change to HCL_ESEND?? */ cannot_send: if (do_throw_with_internal_errmsg(hcl, fetched_instruction_pointer) >= 0) break; - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } break; } @@ -3760,9 +3775,8 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (HCL_CLSTACK_IS_EMPTY(hcl)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "empty class stack"); - supplement_errmsg (hcl, fetched_instruction_pointer); /* TODO: do throw??? instead */ - goto oops; + goto oops_with_errmsg_supplement; } HCL_CLSTACK_FETCH_TOP_TO(hcl, t); t->cvar[b1] = HCL_STACK_GETTOP(hcl); @@ -3777,9 +3791,8 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (HCL_CLSTACK_IS_EMPTY(hcl)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "empty class stack"); - supplement_errmsg (hcl, fetched_instruction_pointer); /* TODO: do throw??? instead */ - goto oops; + goto oops_with_errmsg_supplement; } HCL_CLSTACK_FETCH_TOP_TO(hcl, t); t->cvar[b1] = HCL_STACK_GETTOP(hcl); @@ -3799,9 +3812,8 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (!HCL_IS_INSTANCE(hcl, t)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver"); - supplement_errmsg (hcl, fetched_instruction_pointer); /* TODO: do throw??? instead */ - goto oops; + goto oops_with_errmsg_supplement; } t = HCL_OBJ_GET_CLASS(t); HCL_STACK_PUSH (hcl, t->cvar[b1]); @@ -3817,9 +3829,8 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (!HCL_IS_INSTANCE(hcl, t)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver"); - supplement_errmsg (hcl, fetched_instruction_pointer); /* TODO: do throw??? instead */ - goto oops; + goto oops_with_errmsg_supplement; } t = HCL_OBJ_GET_CLASS(t); t->cvar[b1] = HCL_STACK_GETTOP(hcl); @@ -3835,8 +3846,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) if (!HCL_IS_INSTANCE(hcl, t)) { hcl_seterrbfmt (hcl, HCL_ESTKUNDFLW, "non-instance receiver"); - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; + goto oops_with_errmsg_supplement; } t = HCL_OBJ_GET_CLASS(t); t->cvar[b1] = HCL_STACK_GETTOP(hcl); @@ -3928,11 +3938,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) /* create an empty array */ t = hcl_makearray(hcl, b1, 0); - if (HCL_UNLIKELY(!t)) - { - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; - } + if (HCL_UNLIKELY(!t)) goto oops_with_errmsg_supplement; HCL_STACK_PUSH (hcl, t); /* push the array created */ break; @@ -3966,11 +3972,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) /* create an empty array */ t = hcl_makebytearray(hcl, HCL_NULL, b1); - if (HCL_UNLIKELY(!t)) - { - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; - } + if (HCL_UNLIKELY(!t)) goto oops_with_errmsg_supplement; HCL_STACK_PUSH (hcl, t); /* push the byte array created */ break; @@ -4011,11 +4013,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) FETCH_PARAM_CODE_TO (hcl, b1); LOG_INST_1 (hcl, "make_dic %zu", b1); t = (hcl_oop_t)hcl_makedic(hcl, b1 + 10); - if (HCL_UNLIKELY(!t)) - { - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; - } + if (HCL_UNLIKELY(!t)) goto oops_with_errmsg_supplement; HCL_STACK_PUSH (hcl, t); break; } @@ -4041,11 +4039,7 @@ if (do_throw(hcl, hcl->_nil, fetched_instruction_pointer) <= -1) LOG_INST_0 (hcl, "make_cons"); t = hcl_makecons(hcl, hcl->_nil, hcl->_nil); - if (HCL_UNLIKELY(!t)) - { - supplement_errmsg (hcl, fetched_instruction_pointer); - goto oops; - } + if (HCL_UNLIKELY(!t)) goto oops_with_errmsg_supplement; HCL_STACK_PUSH (hcl, t); /* push the head cons cell */ HCL_STACK_PUSH (hcl, hcl->_nil); /* sentinnel */ @@ -4310,6 +4304,9 @@ done: #endif return 0; +oops_with_errmsg_supplement: + supplement_errmsg (hcl, fetched_instruction_pointer); + oops: hcl->gci.lazy_sweep = 1; diff --git a/lib/hcl-prv.h b/lib/hcl-prv.h index fd9d54e..aacb968 100644 --- a/lib/hcl-prv.h +++ b/lib/hcl-prv.h @@ -928,7 +928,7 @@ enum hcl_bcode_t HCL_CODE_CLASS_PEXIT = 0xE3, /* 227 */ HCL_CODE_PUSH_OBJVAR_X = 0xE4, /* 228 ## */ - HCL_CODE_CLASS_SET = 0xE5, /* 229 */ + HCL_CODE_CLASS_MSTORE = 0xE5, /* 229 */ /* UNUSED - 0xE6 - 0xE7 */ HCL_CODE_STORE_INTO_OBJVAR_X = 0xE8, /* 232 ## */ diff --git a/lib/hcl.h b/lib/hcl.h index 7d1cc16..9c30dbc 100644 --- a/lib/hcl.h +++ b/lib/hcl.h @@ -847,7 +847,7 @@ struct hcl_class_t { HCL_OBJ_HEADER; - hcl_oop_dic_t memdic; /* dictionary of named elements including methods and variables */ + hcl_oop_t memdic; /* nil or dictionary of named elements including methods and variables */ hcl_oop_t superclass; hcl_oop_t nivars; /* smooi. */