diff options
| -rw-r--r-- | include/mruby/array.h | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/codegen.c | 34 | ||||
| -rw-r--r-- | mrblib/array.rb | 18 | ||||
| -rw-r--r-- | src/array.c | 53 | ||||
| -rw-r--r-- | src/class.c | 14 |
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)); |
