diff options
| -rw-r--r-- | include/mruby/ops.h | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 4 | ||||
| -rw-r--r-- | src/codedump.c | 6 | ||||
| -rw-r--r-- | src/string.c | 2 | ||||
| -rw-r--r-- | src/vm.c | 29 |
5 files changed, 42 insertions, 1 deletions
diff --git a/include/mruby/ops.h b/include/mruby/ops.h index 9b9fefeb0..7b5ea40ca 100644 --- a/include/mruby/ops.h +++ b/include/mruby/ops.h @@ -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 */ diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 42c93debf..a142d21ad 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -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; diff --git a/src/codedump.c b/src/codedump.c index 431771ca9..df88b37fc 100644 --- a/src/codedump.c +++ b/src/codedump.c @@ -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); diff --git a/src/string.c b/src/string.c index ac0f4a920..089c8616c 100644 --- a/src/string.c +++ b/src/string.c @@ -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]; |
