diff options
Diffstat (limited to 'src')
| -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 |
12 files changed, 108 insertions, 83 deletions
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) { |
