mruby/ops.h: add new instructions `OP_GETIDX` and `OP_SETIDX`.

Which represent `obj[int]` and `obj[int]=val` respectively where `obj`
is either `string`, `array` or `hash`, so that index access could be
faster. When `obj` is not assumed type or `R(a+1)` is not integer, the
instructions fallback to method calls.
parent d64d8ca8
......@@ -47,6 +47,8 @@ OPCODE(GETMCNST, BB) /* R(a) = R(a)::Syms(b) */
OPCODE(SETMCNST, BB) /* R(a+1)::Syms(b) = R(a) */
OPCODE(GETUPVAR, BBB) /* R(a) = uvget(b,c) */
OPCODE(SETUPVAR, BBB) /* uvset(b,c,R(a)) */
OPCODE(GETIDX, B) /* R(a) = R(a)[R(a+1)] */
OPCODE(SETIDX, B) /* R(a)[R(a+1)] = R(a+2) */
OPCODE(JMP, S) /* pc+=a */
OPCODE(JMPIF, BS) /* if R(a) pc+=b */
OPCODE(JMPNOT, BS) /* if !R(a) pc+=b */
......
......@@ -832,6 +832,10 @@ static mrb_bool
gen_binop(codegen_scope *s, mrb_sym op, uint16_t dst)
{
if (no_peephole(s)) return FALSE;
else if (op == MRB_OPSYM_2(s->mrb, aref)) {
genop_1(s, OP_GETIDX, dst);
return TRUE;
}
else {
struct mrb_insn_data data = mrb_last_insn(s);
mrb_int n, n0;
......
......@@ -265,6 +265,12 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
printf("OP_SETCV\t%s\tR%d\t", mrb_sym_dump(mrb, irep->syms[b]), a);
print_lv_a(mrb, irep, a);
break;
CASE(OP_GETIDX, B):
printf("OP_GETIDX\tR%d\tR%d\n", a, a+1);
break;
CASE(OP_SETIDX, B):
printf("OP_SETIDX\tR%d\tR%d\tR%d\n", a, a+1, a+2);
break;
CASE(OP_JMP, S):
i = pc - irep->iseq;
printf("OP_JMP\t\t%03d\n", (int)i+(int16_t)a);
......
......@@ -1146,7 +1146,7 @@ range_arg:
return STR_OUT_OF_RANGE;
}
static mrb_value
mrb_value
mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen)
{
mrb_int beg, len;
......
......@@ -1063,6 +1063,7 @@ get_send_args(mrb_state *mrb, mrb_int argc, mrb_value *regs)
mrb_value mrb_obj_missing(mrb_state *mrb, mrb_value mod);
void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid);
mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len);
MRB_API mrb_value
mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
......@@ -1252,6 +1253,34 @@ RETRY_TRY_BLOCK:
NEXT;
}
CASE(OP_GETIDX, B) {
mrb_value va = regs[a], vb = regs[a+1];
switch (mrb_type(va)) {
case MRB_TT_ARRAY:
if (!mrb_integer_p(vb)) goto getidx_fallback;
regs[a] = mrb_ary_entry(va, mrb_integer(vb));
break;
case MRB_TT_HASH:
regs[a] = mrb_hash_get(mrb, va, vb);
break;
case MRB_TT_STRING:
regs[a] = mrb_str_aref(mrb, va, vb, mrb_undef_value());
break;
default:
getidx_fallback:
c = 1;
mid = MRB_OPSYM(aref);
goto L_SEND_SYM;
}
NEXT;
}
CASE(OP_SETIDX, B) {
c = 1;
mid = MRB_OPSYM(aset);
goto L_SEND_SYM;
}
CASE(OP_GETCONST, BB) {
mrb_value val;
mrb_sym sym = syms[b];
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment