mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Implement Array#each using inline mruby bytecode.
This commit is contained in:
+9
-9
@@ -10,16 +10,16 @@ class Array
|
||||
# and pass the respective element.
|
||||
#
|
||||
# ISO 15.2.12.5.10
|
||||
def each(&block)
|
||||
return to_enum :each unless block
|
||||
# def each(&block)
|
||||
# return to_enum :each unless block
|
||||
|
||||
idx = 0
|
||||
while idx < length
|
||||
block.call(self[idx])
|
||||
idx += 1
|
||||
end
|
||||
self
|
||||
end
|
||||
# idx = 0
|
||||
# while idx < length
|
||||
# block.call(self[idx])
|
||||
# idx += 1
|
||||
# end
|
||||
# self
|
||||
# end
|
||||
|
||||
##
|
||||
# Calls the given block for each element of +self+
|
||||
|
||||
+53
@@ -9,6 +9,8 @@
|
||||
#include <mruby/class.h>
|
||||
#include <mruby/string.h>
|
||||
#include <mruby/range.h>
|
||||
#include <mruby/proc.h>
|
||||
#include <mruby/opcode.h>
|
||||
#include "value_array.h"
|
||||
|
||||
#define ARY_DEFAULT_LEN 4
|
||||
@@ -1257,6 +1259,55 @@ mrb_ary_svalue(mrb_state *mrb, mrb_value ary)
|
||||
}
|
||||
}
|
||||
|
||||
static mrb_code each_iseq[] = {
|
||||
OP_ENTER, 0x0, 0x00, 0x1, /* OP_ENTER 0:0:0:0:0:0:1 */
|
||||
OP_JMPIF, 0x1, 0x0, 19, /* OP_JMPIF R1 19 */
|
||||
OP_LOADSELF, 0x3, /* OP_LOADSELF R3 */
|
||||
OP_LOADSYM, 0x4, 0x0, /* OP_LOADSYM R4 :each*/
|
||||
OP_SEND, 0x3, 0x1, 0x1, /* OP_SEND R3 :to_enum 1 */
|
||||
OP_RETURN, 0x3, /* OP_RETURN R3 */
|
||||
OP_LOADI_0, 0x2, /* OP_LOADI_0 R2 */
|
||||
OP_JMP, 0x0, 43, /* OP_JMP 49 */
|
||||
OP_MOVE, 0x3, 0x1, /* OP_MOVE R3 R1 */
|
||||
OP_LOADSELF, 0x4, /* OP_LOADSELF R4 */
|
||||
OP_MOVE, 0x5, 0x2, /* OP_MOVE R5 R2 */
|
||||
OP_SEND, 0x4, 0x2, 0x1, /* OP_SEND R4 :[] 1 */
|
||||
OP_SEND, 0x3, 0x3, 0x1, /* OP_SEND R3 :call 1 */
|
||||
OP_ADDI, 0x2, 1, /* OP_ADDI R3 1 */
|
||||
OP_MOVE, 0x3, 0x2, /* OP_MOVE R3 R2 */
|
||||
OP_LOADSELF, 0x4, /* OP_LOADSELF R4 */
|
||||
OP_SEND, 0x4, 0x4, 0x0, /* OP_SEND R4 :length 0 */
|
||||
OP_LT, 0x3, /* OP_LT R3 */
|
||||
OP_JMPIF, 0x3, 0x0, 24, /* OP_JMPIF R3 24 */
|
||||
OP_RETURN, 0x0 /* OP_RETURN R3 */
|
||||
};
|
||||
|
||||
static void
|
||||
init_ary_each(mrb_state *mrb, struct RClass *ary)
|
||||
{
|
||||
struct RProc *p;
|
||||
mrb_method_t m;
|
||||
mrb_irep *each_irep = (mrb_irep*)mrb_malloc(mrb, sizeof(mrb_irep));
|
||||
static const mrb_irep mrb_irep_zero = { 0 };
|
||||
|
||||
*each_irep = mrb_irep_zero;
|
||||
each_irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*5);
|
||||
each_irep->syms[0] = mrb_intern_lit(mrb, "each");
|
||||
each_irep->syms[1] = mrb_intern_lit(mrb, "to_enum");
|
||||
each_irep->syms[2] = mrb_intern_lit(mrb, "[]");
|
||||
each_irep->syms[3] = mrb_intern_lit(mrb, "call");
|
||||
each_irep->syms[4] = mrb_intern_lit(mrb, "length");
|
||||
each_irep->slen = 5;
|
||||
each_irep->flags = MRB_ISEQ_NO_FREE;
|
||||
each_irep->iseq = each_iseq;
|
||||
each_irep->ilen = sizeof(each_iseq);
|
||||
each_irep->nregs = 7;
|
||||
each_irep->nlocals = 3;
|
||||
p = mrb_proc_new(mrb, each_irep);
|
||||
MRB_METHOD_FROM_PROC(m, p);
|
||||
mrb_define_method_raw(mrb, ary, mrb_intern_lit(mrb, "each"), m);
|
||||
}
|
||||
|
||||
void
|
||||
mrb_init_array(mrb_state *mrb)
|
||||
{
|
||||
@@ -1297,4 +1348,6 @@ mrb_init_array(mrb_state *mrb)
|
||||
mrb_define_method(mrb, a, "__ary_cmp", mrb_ary_cmp, MRB_ARGS_REQ(1));
|
||||
mrb_define_method(mrb, a, "__ary_index", mrb_ary_index_m, MRB_ARGS_REQ(1)); /* kept for mruby-array-ext */
|
||||
mrb_define_method(mrb, a, "__svalue", mrb_ary_svalue, MRB_ARGS_NONE());
|
||||
|
||||
init_ary_each(mrb, a);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user