summaryrefslogtreecommitdiffhomepage
path: root/src/vm.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-10-03 17:14:00 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2021-10-03 17:14:00 +0900
commit09336c5d49481d56587f6e28924014954b4c8dd2 (patch)
tree2929382ec25ac34578a3ae6ee77f2dafda7964dd /src/vm.c
parentd64d8ca8e4515a2e03165401470ef109a6097e5d (diff)
downloadmruby-09336c5d49481d56587f6e28924014954b4c8dd2.tar.gz
mruby-09336c5d49481d56587f6e28924014954b4c8dd2.zip
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.
Diffstat (limited to 'src/vm.c')
-rw-r--r--src/vm.c29
1 files changed, 29 insertions, 0 deletions
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];