summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/ops.h2
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c7
-rw-r--r--mrbgems/mruby-io/src/io.c5
-rw-r--r--src/codedump.c8
-rw-r--r--src/string.c2
-rw-r--r--src/vm.c29
6 files changed, 48 insertions, 5 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..5197cc7fe 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;
@@ -2765,9 +2769,6 @@ codegen(codegen_scope *s, node *tree, int val)
s2 = s2->prev;
if (!s2) break;
}
- genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf));
- push(); push(); /* ARGARY pushes two values */
- pop(); pop();
if (tree) {
node *args = tree->car;
if (args) {
diff --git a/mrbgems/mruby-io/src/io.c b/mrbgems/mruby-io/src/io.c
index 0c79660a8..3229d339a 100644
--- a/mrbgems/mruby-io/src/io.c
+++ b/mrbgems/mruby-io/src/io.c
@@ -397,6 +397,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
ofd[0] = INVALID_HANDLE_VALUE;
ofd[1] = INVALID_HANDLE_VALUE;
+ mrb->c->ci->mid = 0;
io = mrb_io_s_popen_args(mrb, klass, &cmd, &flags, &doexec,
&opt_in, &opt_out, &opt_err);
@@ -476,6 +477,7 @@ mrb_io_s_popen(mrb_state *mrb, mrb_value klass)
int pw[2] = { -1, -1 };
int saved_errno;
+ mrb->c->ci->mid = 0;
io = mrb_io_s_popen_args(mrb, klass, &cmd, &flags, &doexec,
&opt_in, &opt_out, &opt_err);
@@ -837,6 +839,7 @@ static mrb_value
mrb_io_s_sysclose(mrb_state *mrb, mrb_value klass)
{
mrb_int fd;
+ mrb->c->ci->mid = 0;
mrb_get_args(mrb, "i", &fd);
if (close((int)fd) == -1) {
mrb_sys_fail(mrb, "close");
@@ -1475,6 +1478,7 @@ mrb_io_bufread(mrb_state *mrb, mrb_value self)
mrb_value str;
mrb_int len;
+ mrb->c->ci->mid = 0;
mrb_get_args(mrb, "Si", &str, &len);
mrb_assert(RSTRING_LEN(str) > 0);
mrb_assert(RSTRING_PTR(str) != NULL);
@@ -1491,6 +1495,7 @@ mrb_io_readchar(mrb_state *mrb, mrb_value self)
unsigned char c;
#endif
+ mrb->c->ci->mid = 0;
mrb_get_args(mrb, "S", &buf);
mrb_assert(RSTRING_LEN(buf) > 0);
mrb_assert(RSTRING_PTR(buf) != NULL);
diff --git a/src/codedump.c b/src/codedump.c
index 431771ca9..64f6314cf 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);
@@ -471,7 +477,7 @@ codedump(mrb_state *mrb, const mrb_irep *irep)
print_lv_a(mrb, irep, a);
break;
CASE(OP_STRCAT, B):
- printf("OP_STRCAT\tR%d\tR%d\n", a, a+1);
+ printf("OP_STRCAT\tR%d\tR%d", a, a+1);
print_lv_a(mrb, irep, a);
break;
CASE(OP_HASH, BB):
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;
diff --git a/src/vm.c b/src/vm.c
index abb5d0c85..f3332353b 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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];