diff options
| -rwxr-xr-x | benchmark/fib39.rb | 8 | ||||
| -rw-r--r-- | include/mruby.h | 1 | ||||
| -rw-r--r-- | include/mruby/dump.h | 5 | ||||
| -rw-r--r-- | include/mruby/numeric.h | 6 | ||||
| -rw-r--r-- | include/mruby/value.h | 2 | ||||
| -rw-r--r-- | include/mruby/variable.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-numeric-ext/src/numeric_ext.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-sprintf/src/sprintf.c | 4 | ||||
| -rw-r--r-- | mrblib/numeric.rb | 32 | ||||
| -rw-r--r-- | src/array.c | 4 | ||||
| -rw-r--r-- | src/class.c | 1 | ||||
| -rw-r--r-- | src/codegen.c | 2 | ||||
| -rw-r--r-- | src/dump.c | 7 | ||||
| -rw-r--r-- | src/gc.c | 14 | ||||
| -rw-r--r-- | src/kernel.c | 2 | ||||
| -rw-r--r-- | src/load.c | 2 | ||||
| -rw-r--r-- | src/numeric.c | 100 | ||||
| -rw-r--r-- | src/object.c | 3 | ||||
| -rw-r--r-- | src/string.c | 4 | ||||
| -rw-r--r-- | src/variable.c | 40 | ||||
| -rw-r--r-- | src/vm.c | 12 | ||||
| -rw-r--r-- | tasks/mruby_build_commands.rake | 4 | ||||
| -rw-r--r-- | test/t/array.rb | 16 | ||||
| -rw-r--r-- | test/t/class.rb | 20 | ||||
| -rw-r--r-- | test/t/comparable.rb | 10 | ||||
| -rw-r--r-- | test/t/hash.rb | 13 | ||||
| -rw-r--r-- | test/t/kernel.rb | 20 | ||||
| -rw-r--r-- | test/t/module.rb | 15 | ||||
| -rw-r--r-- | test/t/string.rb | 10 |
29 files changed, 253 insertions, 107 deletions
diff --git a/benchmark/fib39.rb b/benchmark/fib39.rb new file mode 100755 index 000000000..d5565b779 --- /dev/null +++ b/benchmark/fib39.rb @@ -0,0 +1,8 @@ +# Fib 39 + +def fib n + return n if n < 2 + fib(n-2) + fib(n-1) +end + +puts fib(39) diff --git a/include/mruby.h b/include/mruby.h index e204820a3..5272d0400 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -125,6 +125,7 @@ typedef struct mrb_state { mrb_bool gc_disabled:1; mrb_bool gc_full:1; mrb_bool is_generational_gc_mode:1; + mrb_bool out_of_memory:1; size_t majorgc_old_threshold; struct alloca_header *mems; diff --git a/include/mruby/dump.h b/include/mruby/dump.h index 2533a4c93..d1d097cd2 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -141,9 +141,8 @@ bin_to_uint8(const uint8_t *bin) } /* crc.c */ -uint32_t -calc_crc_16_ccitt(const uint8_t *src, uint32_t nbytes, uint16_t crcwk); - +uint16_t +calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc); #if defined(__cplusplus) } /* extern "C" { */ #endif diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index 4bcb43966..aac7b9920 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -15,8 +15,10 @@ extern "C" { #define NEGFIXABLE(f) ((f) >= MRB_INT_MIN) #define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f)) -mrb_value mrb_flt2big(mrb_state *mrb, mrb_float d); -mrb_value mrb_fix2str(mrb_state *mrb, mrb_value x, int base); +mrb_value mrb_flo_to_fixnum(mrb_state *mrb, mrb_value val); +mrb_value mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit); + +mrb_value mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base); mrb_value mrb_fixnum_plus(mrb_state *mrb, mrb_value x, mrb_value y); mrb_value mrb_fixnum_minus(mrb_state *mrb, mrb_value x, mrb_value y); diff --git a/include/mruby/value.h b/include/mruby/value.h index 1815f0562..1cc5263ad 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -42,7 +42,7 @@ typedef struct mrb_value { mrb_int i; mrb_sym sym; } value; - enum mrb_vtype tt:8; + enum mrb_vtype tt; } mrb_value; #define mrb_type(o) (o).tt diff --git a/include/mruby/variable.h b/include/mruby/variable.h index f699f5dfd..2845e0daa 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -49,6 +49,7 @@ mrb_bool mrb_iv_defined(mrb_state*, mrb_value, mrb_sym); mrb_value mrb_iv_remove(mrb_state *mrb, mrb_value obj, mrb_sym sym); void mrb_iv_copy(mrb_state *mrb, mrb_value dst, mrb_value src); int mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id); +mrb_value mrb_mod_constants(mrb_state *mrb, mrb_value mod); mrb_value mrb_f_global_variables(mrb_state *mrb, mrb_value self); mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym); void mrb_gv_set(mrb_state *mrb, mrb_sym sym, mrb_value val); diff --git a/mrbgems/mruby-numeric-ext/src/numeric_ext.c b/mrbgems/mruby-numeric-ext/src/numeric_ext.c index 09904c1a9..f193fb531 100644 --- a/mrbgems/mruby-numeric-ext/src/numeric_ext.c +++ b/mrbgems/mruby-numeric-ext/src/numeric_ext.c @@ -10,7 +10,7 @@ mrb_int_chr(mrb_state *mrb, mrb_value x) chr = mrb_fixnum(x); if (chr >= (1 << CHAR_BIT)) { - mrb_raisef(mrb, E_RANGE_ERROR, "%" PRIdMRB_INT " out of char range", chr); + mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", x); } c = (char)chr; diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index d2ea4c321..fed730c74 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -806,7 +806,7 @@ retry: val = mrb_fixnum_value((mrb_int)mrb_float(val)); goto bin_retry; } - val = mrb_flt2big(mrb, mrb_float(val)); + val = mrb_flo_to_fixnum(mrb, val); if (mrb_fixnum_p(val)) goto bin_retry; break; case MRB_TT_STRING: @@ -843,7 +843,7 @@ retry: dots = 1; } else { - val = mrb_fix2str(mrb, mrb_fixnum_value(v), base); + val = mrb_fixnum_to_str(mrb, mrb_fixnum_value(v), base); } v = mrb_fixnum(mrb_str_to_inum(mrb, val, 10, 0/*Qfalse*/)); } diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb index 1d701b1fc..daa35c5d6 100644 --- a/mrblib/numeric.rb +++ b/mrblib/numeric.rb @@ -5,6 +5,14 @@ class Integer ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.14 + def ceil + self + end + + ## # Calls the given block once for each Integer # from +self+ downto +num+. # @@ -19,6 +27,14 @@ class Integer end ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.17 + def floor + self + end + + ## # Calls the given block +self+ times. # # ISO 15.2.8.3.22 @@ -32,6 +48,22 @@ class Integer end ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.24 + def round + self + end + + ## + # Returns the receiver simply. + # + # ISO 15.2.8.3.26 + def truncate + self + end + + ## # Calls the given block once for each Integer # from +self+ upto +num+. # diff --git a/src/array.c b/src/array.c index 88f56f6b4..b1f05b450 100644 --- a/src/array.c +++ b/src/array.c @@ -38,11 +38,11 @@ ary_new_capa(mrb_state *mrb, mrb_int capa) mrb_int blen; if (capa > ARY_MAX_SIZE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } blen = capa * sizeof(mrb_value) ; if (blen < capa) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "ary size too big"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); diff --git a/src/class.c b/src/class.c index 9dc7b46d6..57cfae78f 100644 --- a/src/class.c +++ b/src/class.c @@ -1829,6 +1829,7 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, ARGS_REQ(1)); /* 15.2.2.4.20 */ mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, ARGS_REQ(1)); /* 15.2.2.4.21 */ mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, ARGS_REQ(2)); /* 15.2.2.4.23 */ + mrb_define_method(mrb, mod, "constants", mrb_mod_constants, ARGS_NONE()); /* 15.2.2.4.24 */ mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, ARGS_REQ(1)); /* 15.2.2.4.40 */ mrb_define_method(mrb, mod, "define_method", mod_define_method, ARGS_REQ(1)); mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, ARGS_NONE()); /* 15.2.2.4.19 */ diff --git a/src/codegen.c b/src/codegen.c index e5b1802a1..b8909e809 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1868,7 +1868,7 @@ codegen(codegen_scope *s, node *tree, int val) mrb_value str = mrb_str_buf_new(mrb, 4); mrb_str_buf_cat(mrb, str, "$", 1); - mrb_str_buf_append(mrb, str, mrb_fix2str(mrb, fix, 10)); + mrb_str_buf_append(mrb, str, mrb_fixnum_to_str(mrb, fix, 10)); sym = new_sym(s, mrb_intern_str(mrb, str)); genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); push(); diff --git a/src/dump.c b/src/dump.c index 578a22202..4714278b0 100644 --- a/src/dump.c +++ b/src/dump.c @@ -80,7 +80,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - str = mrb_fix2str(mrb, irep->pool[pool_no], 10); + str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); size += RSTRING_LEN(str); break; @@ -123,7 +123,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - str = mrb_fix2str(mrb, irep->pool[pool_no], 10); + str = mrb_fixnum_to_str(mrb, irep->pool[pool_no], 10); char_ptr = RSTRING_PTR(str); len = RSTRING_LEN(str); break; @@ -166,7 +166,7 @@ get_syms_block_size(mrb_state *mrb, mrb_irep *irep) size += sizeof(uint16_t); /* snl(n) */ if (irep->syms[sym_no] != 0) { mrb_sym2name_len(mrb, irep->syms[sym_no], &len); - size += len; /* sn(n) */ + size += len + 1; /* sn(n) + null char */ } } @@ -194,6 +194,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) cur += uint16_to_bin((uint16_t)len, cur); /* length of symbol name */ memcpy(cur, name, len); /* symbol name */ cur += (uint16_t)len; + *cur++ = '\0'; } else { cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ @@ -157,6 +157,20 @@ mrb_realloc(mrb_state *mrb, void *p, size_t len) mrb_garbage_collect(mrb); p2 = (mrb->allocf)(mrb, p, len, mrb->ud); } + + if (!p2 && len) { + if (mrb->out_of_memory) { + /* mrb_panic(mrb); */ + } + else { + mrb->out_of_memory = 1; + mrb_raise(mrb, E_RUNTIME_ERROR, "Out of memory"); + } + } + else { + mrb->out_of_memory = 0; + } + return p2; } diff --git a/src/kernel.c b/src/kernel.c index f14a94b3a..54c90dfc0 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -108,7 +108,7 @@ mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self) mrb_bool eql_p; mrb_get_args(mrb, "o", &arg); - eql_p = mrb_obj_equal(mrb, self, arg); + eql_p = mrb_equal(mrb, self, arg); return mrb_bool_value(!eql_p); } diff --git a/src/load.c b/src/load.c index a2f685742..c350cb1a3 100644 --- a/src/load.c +++ b/src/load.c @@ -131,7 +131,7 @@ read_rite_irep_record(mrb_state *mrb, const uint8_t *bin, uint32_t *len) } irep->syms[i] = mrb_intern2(mrb, (char *)src, snl); - src += snl; + src += snl + 1; mrb_gc_arena_restore(mrb, ai); } diff --git a/src/numeric.c b/src/numeric.c index 084243291..aacaed9ee 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -163,13 +163,19 @@ num_abs(mrb_state *mrb, mrb_value num) */ mrb_value -mrb_flo_to_str(mrb_state *mrb, mrb_float n, int max_digit) +mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit) { mrb_value result; + mrb_float n; if (max_digit > 40) { mrb_raise(mrb, E_RANGE_ERROR, "Too large max_digit."); } + else if (!mrb_float_p(flo)) { + mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + } + + n = mrb_float(flo); if (isnan(n)) { result = mrb_str_new(mrb, "NaN", 3); @@ -270,9 +276,9 @@ static mrb_value flo_to_s(mrb_state *mrb, mrb_value flt) { #ifdef MRB_USE_FLOAT - return mrb_flo_to_str(mrb, mrb_float(flt), 7); + return mrb_flo_to_str(mrb, flt, 7); #else - return mrb_flo_to_str(mrb, mrb_float(flt), 14); + return mrb_flo_to_str(mrb, flt, 14); #endif } @@ -665,42 +671,6 @@ flo_truncate(mrb_state *mrb, mrb_value num) return mrb_fixnum_value((mrb_int)f); } -/* 15.2.8.3.17 */ -/* - * call-seq: - * num.floor -> integer - * - * Returns the largest integer less than or equal to <i>num</i>. - * <code>Numeric</code> implements this by converting <i>anInteger</i> - * to a <code>Float</code> and invoking <code>Float#floor</code>. - * - * 1.floor #=> 1 - * (-1).floor #=> -1 - */ - -static mrb_value -num_floor(mrb_state *mrb, mrb_value num) -{ - return flo_floor(mrb, mrb_Float(mrb, num)); -} - -/* 15.2.8.3.20 */ -/* - * call-seq: - * num.round([ndigits]) -> integer or float - * - * Rounds <i>num</i> to a given precision in decimal digits (default 0 digits). - * Precision may be negative. Returns a floating point number when ndigits - * is more than zero. <code>Numeric</code> implements this by converting itself - * to a <code>Float</code> and invoking <code>Float#round</code>. - */ - -static mrb_value -num_round(mrb_state *mrb, mrb_value num) -{ - return flo_round(mrb, mrb_Float(mrb, num)); -} - /* * Document-class: Integer * @@ -710,17 +680,10 @@ num_round(mrb_state *mrb, mrb_value num) */ -/* 15.2.8.3.14 */ -/* 15.2.8.3.24 */ -/* 15.2.8.3.26 */ /* * call-seq: * int.to_i -> integer * int.to_int -> integer - * int.floor -> integer - * int.ceil -> integer - * int.round -> integer - * int.truncate -> integer * * As <i>int</i> is already an <code>Integer</code>, all these * methods simply return the receiver. @@ -1175,25 +1138,27 @@ fix_to_f(mrb_state *mrb, mrb_value num) * FloatDomainError: Infinity */ /* ------------------------------------------------------------------------*/ -static mrb_int -flt2big(mrb_state *mrb, mrb_float d) +mrb_value +mrb_flo_to_fixnum(mrb_state *mrb, mrb_value x) { mrb_int z; - if (isinf(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); + if (mrb_float_p(x)) { + mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + z = 0; /* not reached. just supress warnings. */ } - if (isnan(d)) { - mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); - } - z = (mrb_int)d; - return z; -} + else { + mrb_float d = mrb_float(x); -mrb_value -mrb_flt2big(mrb_state *mrb, mrb_float d) -{ - return mrb_fixnum_value(flt2big(mrb, d)); + if (isinf(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, d < 0 ? "-Infinity" : "Infinity"); + } + if (isnan(d)) { + mrb_raise(mrb, E_FLOATDOMAIN_ERROR, "NaN"); + } + z = (mrb_int)d; + } + return mrb_fixnum_value(z); } mrb_value @@ -1276,7 +1241,7 @@ fix_minus(mrb_state *mrb, mrb_value self) mrb_value -mrb_fix2str(mrb_state *mrb, mrb_value x, int base) +mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base) { char buf[sizeof(mrb_int)*CHAR_BIT+1]; char *b = buf + sizeof buf; @@ -1324,7 +1289,7 @@ fix_to_s(mrb_state *mrb, mrb_value self) mrb_int base = 10; mrb_get_args(mrb, "|i", &base); - return mrb_fix2str(mrb, self, base); + return mrb_fixnum_to_str(mrb, self, base); } /* 15.2.9.3.6 */ @@ -1404,6 +1369,9 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ integer = mrb_define_class(mrb, "Integer", numeric); + mrb_undef_class_method(mrb, integer, "new"); + mrb_define_method(mrb, integer, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */ + mrb_define_method(mrb, integer, "to_int", int_to_i, ARGS_NONE()); fixnum = mrb->fixnum_class = mrb_define_class(mrb, "Fixnum", integer); mrb_undef_class_method(mrb, fixnum, "new"); @@ -1419,18 +1387,13 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fixnum, "^", fix_xor, ARGS_REQ(1)); /* 15.2.8.3.11 */ mrb_define_method(mrb, fixnum, "<<", fix_lshift, ARGS_REQ(1)); /* 15.2.8.3.12 */ mrb_define_method(mrb, fixnum, ">>", fix_rshift, ARGS_REQ(1)); /* 15.2.8.3.13 */ - mrb_define_method(mrb, fixnum, "ceil", int_to_i, ARGS_NONE()); /* 15.2.8.3.14 */ mrb_define_method(mrb, fixnum, "eql?", num_eql, ARGS_REQ(1)); /* 15.2.8.3.16 */ - mrb_define_method(mrb, fixnum, "floor", num_floor, ARGS_NONE()); /* 15.2.8.3.17 */ mrb_define_method(mrb, fixnum, "hash", flo_hash, ARGS_NONE()); /* 15.2.8.3.18 */ mrb_define_method(mrb, fixnum, "next", int_succ, ARGS_NONE()); /* 15.2.8.3.19 */ - mrb_define_method(mrb, fixnum, "round", num_round, ARGS_ANY()); /* 15.2.8.3.20 */ mrb_define_method(mrb, fixnum, "succ", fix_succ, ARGS_NONE()); /* 15.2.8.3.21 */ mrb_define_method(mrb, fixnum, "to_f", fix_to_f, ARGS_NONE()); /* 15.2.8.3.23 */ - mrb_define_method(mrb, fixnum, "to_i", int_to_i, ARGS_NONE()); /* 15.2.8.3.24 */ mrb_define_method(mrb, fixnum, "to_s", fix_to_s, ARGS_NONE()); /* 15.2.8.3.25 */ mrb_define_method(mrb, fixnum, "inspect", fix_to_s, ARGS_NONE()); - mrb_define_method(mrb, fixnum, "truncate", int_to_i, ARGS_NONE()); /* 15.2.8.3.26 */ mrb_define_method(mrb, fixnum, "divmod", fix_divmod, ARGS_REQ(1)); /* 15.2.8.3.30 (x) */ /* Float Class */ @@ -1445,9 +1408,10 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "finite?", flo_finite_p, ARGS_NONE()); /* 15.2.9.3.9 */ mrb_define_method(mrb, fl, "floor", flo_floor, ARGS_NONE()); /* 15.2.9.3.10 */ mrb_define_method(mrb, fl, "infinite?", flo_infinite_p, ARGS_NONE()); /* 15.2.9.3.11 */ - mrb_define_method(mrb, fl, "round", flo_round, ARGS_ANY()); /* 15.2.9.3.12 */ + mrb_define_method(mrb, fl, "round", flo_round, ARGS_NONE()); /* 15.2.9.3.12 */ mrb_define_method(mrb, fl, "to_f", flo_to_f, ARGS_NONE()); /* 15.2.9.3.13 */ mrb_define_method(mrb, fl, "to_i", flo_truncate, ARGS_NONE()); /* 15.2.9.3.14 */ + mrb_define_method(mrb, fl, "to_int", flo_truncate, ARGS_NONE()); mrb_define_method(mrb, fl, "truncate", flo_truncate, ARGS_NONE()); /* 15.2.9.3.15 */ mrb_define_method(mrb, fl, "to_s", flo_to_s, ARGS_NONE()); /* 15.2.9.3.16(x) */ diff --git a/src/object.c b/src/object.c index bd88459ae..23786e859 100644 --- a/src/object.c +++ b/src/object.c @@ -440,6 +440,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj) mrb_str_buf_cat(mrb, str, "#<", 2); mrb_str_cat2(mrb, str, cname); + mrb_str_cat(mrb, str, ":", 1); mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_voidp(obj))); mrb_str_buf_cat(mrb, str, ">", 1); @@ -530,7 +531,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) if (FIXABLE(mrb_float(val))) { break; } - return mrb_flt2big(mrb, mrb_float(val)); + return mrb_flo_to_fixnum(mrb, val); case MRB_TT_FIXNUM: if (base != 0) goto arg_error; diff --git a/src/string.c b/src/string.c index 5b6a44abd..c4074a64f 100644 --- a/src/string.c +++ b/src/string.c @@ -2537,7 +2537,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str) const char *ptr; int len; chr = mrb_fixnum_value(c & 0xff); - octstr = mrb_fix2str(mrb, chr, 8); + octstr = mrb_fixnum_to_str(mrb, chr, 8); ptr = mrb_str_body(octstr, &len); memcpy(q, "\\000", 4); memcpy(q + 4 - len, ptr, len); @@ -2629,7 +2629,7 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) const char *ptr; int len; chr = mrb_fixnum_value(c & 0xff); - octstr = mrb_fix2str(mrb, chr, 8); + octstr = mrb_fixnum_to_str(mrb, chr, 8); ptr = mrb_str_body(octstr, &len); memcpy(buf, "\\000", 4); memcpy(buf + 4 - len, ptr, len); diff --git a/src/variable.c b/src/variable.c index 941aaf83e..a9570db02 100644 --- a/src/variable.c +++ b/src/variable.c @@ -11,6 +11,7 @@ #include "mruby/string.h" #include "mruby/variable.h" #include "error.h" +#include <ctype.h> typedef int (iv_foreach_func)(mrb_state*,mrb_sym,mrb_value,void*); @@ -919,6 +920,45 @@ mrb_define_global_const(mrb_state *mrb, const char *name, mrb_value val) mrb_define_const(mrb, mrb->object_class, name, val); } +static int +const_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) +{ + mrb_value ary; + const char* s; + size_t len; + + ary = *(mrb_value*)p; + s = mrb_sym2name_len(mrb, sym, &len); + if (len > 1 && ISUPPER(s[0])) { + mrb_ary_push(mrb, ary, mrb_symbol_value(sym)); + } + return 0; +} + +/* 15.2.2.4.24 */ +/* + * call-seq: + * mod.constants -> array + * + * Returns an array of all names of contants defined in the receiver. + */ +mrb_value +mrb_mod_constants(mrb_state *mrb, mrb_value mod) +{ + mrb_value ary; + struct RClass *c = mrb_class_ptr(mod); + + ary = mrb_ary_new(mrb); + while (c) { + if (c->iv) { + iv_foreach(mrb, c->iv, const_i, &ary); + } + c = c->super; + if (c == mrb->object_class) break; + } + return ary; +} + mrb_value mrb_gv_get(mrb_state *mrb, mrb_sym sym) { @@ -55,6 +55,9 @@ The value below allows about 60000 recursive calls in the simplest case. */ # define DEBUG(x) #endif +#define TO_STR(x) TO_STR_(x) +#define TO_STR_(x) #x + static inline void stack_clear(mrb_value *from, size_t count) { @@ -133,9 +136,9 @@ stack_extend(mrb_state *mrb, int room, int keep) mrb->stend = mrb->stbase + size; envadjust(mrb, oldbase, mrb->stbase); /* Raise an exception if the new stack size will be too large, - to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raisef has stack space to work with. */ + to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */ if (size > MRB_STACK_MAX) { - mrb_raisef(mrb, E_RUNTIME_ERROR, "stack level too deep. (limit=%S)", mrb_fixnum_value(MRB_STACK_MAX)); + mrb_raise(mrb, E_RUNTIME_ERROR, "stack level too deep. (limit=" TO_STR(MRB_STACK_MAX) ")"); } } @@ -275,7 +278,7 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) int i; if (argc > MRB_FUNCALL_ARGC_MAX) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%S)", mrb_fixnum_value(MRB_FUNCALL_ARGC_MAX)); + mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" TO_STR(MRB_FUNCALL_ARGC_MAX) ")"); } va_start(ap, argc); @@ -343,7 +346,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr ci->nregs = argc + 2; } else { - ci->nregs = p->body.irep->nregs + 2; + ci->nregs = p->body.irep->nregs + n; } ci->acc = -1; mrb->stack = mrb->stack + n; @@ -1207,6 +1210,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci = mrb->ci; if (ci[1].acc < 0 && prev_jmp) { mrb->jmp = prev_jmp; + mrb->stack = mrb->stbase + ci[1].stackidx; longjmp(*(jmp_buf*)mrb->jmp, 1); } while (eidx > mrb->ci->eidx) { diff --git a/tasks/mruby_build_commands.rake b/tasks/mruby_build_commands.rake index 0effa648b..b647ccf98 100644 --- a/tasks/mruby_build_commands.rake +++ b/tasks/mruby_build_commands.rake @@ -249,11 +249,9 @@ module MRuby def run(out, infiles, funcname) @command ||= @build.mrbcfile - commandline = "#{filename @command} #{@compile_options % {:funcname => funcname}}" - IO.popen(commandline, 'r+') do |io| + IO.popen("#{filename @command} #{@compile_options % {:funcname => funcname}}", 'r+') do |io| [infiles].flatten.each do |f| _pp "MRBC", f.relative_path, nil, :indent => 2 - log "#{commandline} ## #{f}" io.write IO.read(f) end io.close_write diff --git a/test/t/array.rb b/test/t/array.rb index 90fa85c7f..47259c268 100644 --- a/test/t/array.rb +++ b/test/t/array.rb @@ -272,7 +272,7 @@ assert('Array#unshift', '15.2.12.5.30') do a == [1,2,3] and b == [1,2,3] and c == [0,1,2,3] and d == [0,1,2,3] end -assert('Array#to_s', '15.2.12.5.31') do +assert('Array#to_s', '15.2.12.5.31 / 15.2.12.5.32') do a = [2, 3, 4, 5] r1 = a.to_s r2 = a.inspect @@ -288,6 +288,20 @@ assert('Array#==', '15.2.12.5.33') do r1 == false and r2 == true and r3 == false end +assert('Array#eql?', '15.2.12.5.34') do + a1 = [ 1, 2, 3 ] + a2 = [ 1, 2, 3 ] + a3 = [ 1.0, 2.0, 3.0 ] + + (a1.eql? a2) and (not a1.eql? a3) +end + +assert('Array#hash', '15.2.12.5.35') do + a = [ 1, 2, 3 ] + + a.hash.is_a? Integer +end + assert('Array#<=>', '15.2.12.5.36') do r1 = [ "a", "a", "c" ] <=> [ "a", "b", "c" ] #=> -1 r2 = [ 1, 2, 3, 4, 5, 6 ] <=> [ 1, 2 ] #=> +1 diff --git a/test/t/class.rb b/test/t/class.rb index 1c50853dc..72214a2fc 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -9,6 +9,26 @@ assert('Class superclass', '15.2.3.2') do Class.superclass == Module end +# Class#initialize '15.2.3.3.1' is tested in Class#new + +assert('Class#initialize_copy', '15.2.3.3.2') do + class TestClass + attr_accessor :n + def initialize(n) + @n = n + end + def initialize_copy(obj) + @n = n + end + end + + c1 = TestClass.new('Foo') + c2 = c1.dup + c3 = TestClass.new('Bar') + + c1.n == c2.n and c1.n != c3.n +end + assert('Class#new', '15.2.3.3.3') do # at the moment no exception on singleton class #e1 = nil diff --git a/test/t/comparable.rb b/test/t/comparable.rb index f3c03a9b5..c95134246 100644 --- a/test/t/comparable.rb +++ b/test/t/comparable.rb @@ -1,5 +1,5 @@ -assert('<', '15.3.3.2.1') do +assert('Comparable#<', '15.3.3.2.1') do class Foo include Comparable def <=>(x) @@ -10,7 +10,7 @@ assert('<', '15.3.3.2.1') do (Foo.new < Foo.new) == false end -assert('<=', '15.3.3.2.2') do +assert('Comparable#<=', '15.3.3.2.2') do class Foo include Comparable def <=>(x) @@ -21,7 +21,7 @@ assert('<=', '15.3.3.2.2') do (Foo.new <= Foo.new) == true end -assert('==', '15.3.3.2.3') do +assert('Comparable#==', '15.3.3.2.3') do class Foo include Comparable def <=>(x) @@ -32,7 +32,7 @@ assert('==', '15.3.3.2.3') do (Foo.new == Foo.new) == true end -assert('>', '15.3.3.2.4') do +assert('Comparable#>', '15.3.3.2.4') do class Foo include Comparable def <=>(x) @@ -43,7 +43,7 @@ assert('>', '15.3.3.2.4') do (Foo.new > Foo.new) == false end -assert('>=', '15.3.3.2.5') do +assert('Comparable#>=', '15.3.3.2.5') do class Foo include Comparable def <=>(x) diff --git a/test/t/hash.rb b/test/t/hash.rb index 04a9a1c24..5ba476e40 100644 --- a/test/t/hash.rb +++ b/test/t/hash.rb @@ -138,7 +138,18 @@ assert('Hash#include?', '15.2.13.4.15') do a.include?('abc_key') and not b.include?('cba') end -assert('Hash#initialize copy', '15.2.13.4.17') do +assert('Hash#initialize', '15.2.13.4.16') do + # Testing initialize by new. + h = Hash.new + h2 = Hash.new(:not_found) + + h.is_a? Hash and + h == { } and + h["hello"] == nil and + h2["hello"] == :not_found +end + +assert('Hash#initialize_copy', '15.2.13.4.17') do a = { 'abc_key' => 'abc_value' } b = Hash.new.initialize_copy(a) diff --git a/test/t/kernel.rb b/test/t/kernel.rb index 5caa3d7ac..835834359 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -23,6 +23,8 @@ assert('Kernel.block_given?', '15.3.1.2.2') do ((bg_try do "block" end) == "block") end +# Kernel.eval is provided by the mruby-gem mrbgem. '15.3.1.2.3' + assert('Kernel.global_variables', '15.3.1.2.4') do Kernel.global_variables.class == Array end @@ -189,6 +191,8 @@ assert('Kernel#dup', '15.3.1.3.9') do c.respond_to?(:test) == false end +# Kernel#eval is provided by mruby-eval mrbgem '15.3.1.3.12' + assert('Kernel#extend', '15.3.1.3.13') do class Test4ExtendClass end @@ -287,6 +291,10 @@ assert('Kernel#object_id', '15.3.1.3.33') do object_id.class == Fixnum end +# Kernel#p is defined in mruby-print mrbgem. '15.3.1.3.34' + +# Kernel#print is defined in mruby-print mrbgem. '15.3.1.3.35' + assert('Kernel#private_methods', '15.3.1.3.36') do private_methods.class == Array end @@ -299,6 +307,8 @@ assert('Kernel#public_methods', '15.3.1.3.38') do public_methods.class == Array end +# Kernel#puts is defined in mruby-print mrbgem. '15.3.1.3.39' + assert('Kernel#raise', '15.3.1.3.40') do e_list = [] @@ -349,3 +359,13 @@ end assert('Kernel#to_s', '15.3.1.3.46') do to_s.class == String end + +assert('Kernel#!=') do + str1 = "hello" + str2 = str1 + str3 = "world" + + (str1[1] != 'e') == false and + (str1 != str3) == true and + (str2 != str1) == false +end diff --git a/test/t/module.rb b/test/t/module.rb index 6c1c1acda..1ff9d3aea 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -129,6 +129,21 @@ assert('Module#const_get', '15.2.2.4.23') do Test4ConstSet.const_get(:Const4Test4ConstSet) == 23 end +assert('Module.constants', '15.2.2.4.24') do + $n = [] + module TestA + Const = 1 + end + class TestB + include TestA + Const2 = 1 + $n = constants.sort + end + + TestA.constants == [ :Const ] and + $n == [ :Const, :Const2 ] +end + assert('Module#include', '15.2.2.4.27') do module Test4Include Const4Include = 42 diff --git a/test/t/string.rb b/test/t/string.rb index ef6b6fae0..5f5f664cf 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -32,7 +32,7 @@ assert('String#==', '15.2.10.5.4') do 'abc' == 'abc' and not 'abc' == 'cba' end -# TODO: SEGFAULT ATM assert('String#=~', '15.2.10.5.5') +# 'String#=~', '15.2.10.5.5' will be tested in mrbgems. assert('String#[]', '15.2.10.5.6') do # length of args is 1 @@ -49,7 +49,7 @@ assert('String#[]', '15.2.10.5.6') do e1 = 'abc'[1, 2] # args is RegExp - # TODO SEGFAULT ATM + # It will be tested in mrbgems. # args is String a3 = 'abc'['bc'] @@ -251,7 +251,7 @@ assert('String#length', '15.2.10.5.26') do 'abc'.length == 3 end -# TODO Broken ATM assert('String#match', '15.2.10.5.27') do +# 'String#match', '15.2.10.5.27' will be tested in mrbgems. assert('String#replace', '15.2.10.5.28') do a = '' @@ -279,7 +279,7 @@ assert('String#rindex', '15.2.10.5.31') do 'abcabc'.rindex('a', 1) == 0 and 'abcabc'.rindex('a', 4) == 3 end -# TODO Broken ATM assert('String#scan', '15.2.10.5.32') do +# 'String#scan', '15.2.10.5.32' will be tested in mrbgems. assert('String#size', '15.2.10.5.33') do 'abc'.size == 3 @@ -303,7 +303,7 @@ assert('String#slice', '15.2.10.5.34') do e11 = e1.slice(0) # args is RegExp - # TODO SEGFAULT ATM + # It will be tested in mrbgems. # args is String a3 = 'abc'.slice('bc') |
