summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/array.h6
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c34
-rw-r--r--mrblib/array.rb18
-rw-r--r--src/array.c53
-rw-r--r--src/class.c14
5 files changed, 100 insertions, 25 deletions
diff --git a/include/mruby/array.h b/include/mruby/array.h
index a58e0dcee..f8561d136 100644
--- a/include/mruby/array.h
+++ b/include/mruby/array.h
@@ -33,7 +33,9 @@ struct RArray {
} aux;
mrb_value *ptr;
} heap;
+#if defined(__cplusplus)
mrb_value ary[MRB_ARY_EMBED_LEN_MAX];
+#endif
} as;
};
@@ -46,7 +48,11 @@ struct RArray {
#define ARY_UNSET_EMBED_FLAG(a) ((a)->flags &= ~(MRB_ARY_EMBED_MASK))
#define ARY_EMBED_LEN(a) ((mrb_int)(((a)->flags & MRB_ARY_EMBED_MASK) - 1))
#define ARY_SET_EMBED_LEN(a,len) ((a)->flags = ((a)->flags&~MRB_ARY_EMBED_MASK) | ((uint32_t)(len) + 1))
+#if defined(__cplusplus)
#define ARY_EMBED_PTR(a) (a)->as.ary
+#else
+#define ARY_EMBED_PTR(a) ((mrb_value*)(&(a)->as))
+#endif
#define ARY_LEN(a) (ARY_EMBED_P(a)?ARY_EMBED_LEN(a):(a)->as.heap.len)
#define ARY_PTR(a) (ARY_EMBED_P(a)?ARY_EMBED_PTR(a):(a)->as.heap.ptr)
diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index d4031f6fd..f4dbe63a1 100644
--- a/mrbgems/mruby-compiler/core/codegen.c
+++ b/mrbgems/mruby-compiler/core/codegen.c
@@ -1578,18 +1578,17 @@ codegen(codegen_scope *s, node *tree, int val)
}
codegen(s, tree->car, VAL);
pop();
- pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
-
- codegen(s, tree->cdr->car, val);
- if (elsepart) {
- if (val) pop();
- pos2 = genjmp(s, OP_JMP, 0);
- dispatch(s, pos1);
- codegen(s, elsepart, val);
- dispatch(s, pos2);
- }
- else {
- if (val) {
+ if (tree->cdr->car) {
+ pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val);
+ codegen(s, tree->cdr->car, val);
+ if (elsepart) {
+ if (val) pop();
+ pos2 = genjmp(s, OP_JMP, 0);
+ dispatch(s, pos1);
+ codegen(s, elsepart, val);
+ dispatch(s, pos2);
+ }
+ else if (val) {
pop();
pos2 = genjmp(s, OP_JMP, 0);
dispatch(s, pos1);
@@ -1601,6 +1600,17 @@ codegen(codegen_scope *s, node *tree, int val)
dispatch(s, pos1);
}
}
+ else { /* empty then-part */
+ if (elsepart) {
+ pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val);
+ codegen(s, elsepart, val);
+ dispatch(s, pos1);
+ }
+ else if (val) {
+ genop_1(s, OP_LOADNIL, cursp());
+ push();
+ }
+ }
}
break;
diff --git a/mrblib/array.rb b/mrblib/array.rb
index 2b080564c..6535d6d83 100644
--- a/mrblib/array.rb
+++ b/mrblib/array.rb
@@ -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+
diff --git a/src/array.c b/src/array.c
index 06c23dcd3..70e2fcab7 100644
--- a/src/array.c
+++ b/src/array.c
@@ -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);
}
diff --git a/src/class.c b/src/class.c
index e4fda18fc..7e37973f6 100644
--- a/src/class.c
+++ b/src/class.c
@@ -674,7 +674,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
if (i < argc) {
- *p = mrb_to_str(mrb, ARGV[arg_i++]);
+ *p = ARGV[arg_i++];
+ mrb_to_str(mrb, *p);
i++;
}
}
@@ -735,7 +736,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
if (i < argc) {
- ss = mrb_to_str(mrb, ARGV[arg_i++]);
+ ss = ARGV[arg_i++];
+ mrb_to_str(mrb, ss);
*ps = RSTRING_PTR(ss);
*pl = RSTRING_LEN(ss);
i++;
@@ -757,7 +759,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
}
if (i < argc) {
- ss = mrb_to_str(mrb, ARGV[arg_i++]);
+ ss = ARGV[arg_i++];
+ mrb_to_str(mrb, ss);
*ps = RSTRING_CSTR(mrb, ss);
i++;
}
@@ -1537,7 +1540,10 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
}
new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
mid = mrb_intern_lit(mrb, "initialize");
- if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
+ if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
+ mrb_class_initialize(mrb, new_class);
+ }
+ else {
mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
}
mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));