diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 44 | ||||
| -rw-r--r-- | src/class.c | 5 | ||||
| -rw-r--r-- | src/error.c | 7 | ||||
| -rw-r--r-- | src/gc.c | 16 | ||||
| -rw-r--r-- | src/kernel.c | 1 | ||||
| -rw-r--r-- | src/numeric.c | 3 | ||||
| -rw-r--r-- | src/object.c | 6 | ||||
| -rw-r--r-- | src/proc.c | 17 | ||||
| -rw-r--r-- | src/range.c | 39 | ||||
| -rw-r--r-- | src/string.c | 4 | ||||
| -rw-r--r-- | src/symbol.c | 3 | ||||
| -rw-r--r-- | src/vm.c | 14 |
12 files changed, 110 insertions, 49 deletions
diff --git a/src/array.c b/src/array.c index 106353c07..f6599bd5b 100644 --- a/src/array.c +++ b/src/array.c @@ -20,15 +20,12 @@ static struct RArray* ary_new_capa(mrb_state *mrb, mrb_int capa) { struct RArray *a; - mrb_int blen; + size_t blen; if (capa > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } blen = capa * sizeof(mrb_value); - if (blen < capa) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); - } a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); a->ptr = (mrb_value *)mrb_malloc(mrb, blen); @@ -121,7 +118,7 @@ ary_modify(mrb_state *mrb, struct RArray *a) } else { mrb_value *ptr, *p; - mrb_int len; + size_t len; p = a->ptr; len = a->len * sizeof(mrb_value); @@ -176,11 +173,13 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) capa = ARY_DEFAULT_LEN; } while (capa < len) { - capa *= 2; + if (capa <= ARY_MAX_SIZE / 2) { + capa *= 2; + } else { + capa = ARY_MAX_SIZE; + } } - if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ - if (capa > a->aux.capa) { mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); @@ -245,13 +244,20 @@ mrb_ary_s_create(mrb_state *mrb, mrb_value self) } static void -ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, mrb_int blen) +ary_concat(mrb_state *mrb, struct RArray *a, struct RArray *a2) { - mrb_int len = a->len + blen; + mrb_int len; + + if (a2->len > ARY_MAX_SIZE - a->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } + len = a->len + a2->len; ary_modify(mrb, a); - if (a->aux.capa < len) ary_expand_capa(mrb, a, len); - array_copy(a->ptr+a->len, ptr, blen); + if (a->aux.capa < len) { + ary_expand_capa(mrb, a, len); + } + array_copy(a->ptr+a->len, a2->ptr, a2->len); mrb_write_barrier(mrb, (struct RBasic*)a); a->len = len; } @@ -261,17 +267,16 @@ mrb_ary_concat(mrb_state *mrb, mrb_value self, mrb_value other) { struct RArray *a2 = mrb_ary_ptr(other); - ary_concat(mrb, mrb_ary_ptr(self), a2->ptr, a2->len); + ary_concat(mrb, mrb_ary_ptr(self), a2); } static mrb_value mrb_ary_concat_m(mrb_state *mrb, mrb_value self) { - mrb_value *ptr; - mrb_int blen; + mrb_value ary; - mrb_get_args(mrb, "a", &ptr, &blen); - ary_concat(mrb, mrb_ary_ptr(self), ptr, blen); + mrb_get_args(mrb, "A", &ary); + mrb_ary_concat(mrb, self, ary); return self; } @@ -500,6 +505,9 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) mrb_int len; mrb_get_args(mrb, "*", &vals, &len); + if (len > ARY_MAX_SIZE - a->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } if (ARY_SHARED_P(a) && a->aux.shared->refcnt == 1 /* shared only referenced from this array */ && a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ { @@ -561,7 +569,7 @@ static struct RArray* ary_dup(mrb_state *mrb, struct RArray *a) { struct RArray *d = ary_new_capa(mrb, a->len); - + ary_replace(mrb, d, a->ptr, a->len); return d; } diff --git a/src/class.c b/src/class.c index d02253c57..bac1d2984 100644 --- a/src/class.c +++ b/src/class.c @@ -1348,6 +1348,9 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class"); if (ttype == 0) ttype = MRB_TT_OBJECT; + if (ttype <= MRB_TT_CPTR) { + mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv); + } o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); return mrb_obj_value(o); } @@ -2068,7 +2071,7 @@ mrb_mod_remove_method(mrb_state *mrb, mrb_value mod) mrb_get_args(mrb, "*", &argv, &argc); while (argc--) { - remove_method(mrb, mod, mrb_symbol(*argv)); + remove_method(mrb, mod, to_sym(mrb, *argv)); argv++; } return mod; diff --git a/src/error.c b/src/error.c index 13032b136..b24aed798 100644 --- a/src/error.c +++ b/src/error.c @@ -278,6 +278,8 @@ mrb_exc_set(mrb_state *mrb, mrb_value exc) mrb->exc = 0; } else { + if (!mrb_obj_is_kind_of(mrb, exc, mrb->eException_class)) + mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); mrb->exc = mrb_obj_ptr(exc); } } @@ -463,7 +465,7 @@ exception_call: } if (argc > 0) { if (!mrb_obj_is_kind_of(mrb, mesg, mrb->eException_class)) - mrb_raise(mrb, E_TYPE_ERROR, "exception object expected"); + mrb_raise(mrb, mrb->eException_class, "exception object expected"); if (argc > 2) set_backtrace(mrb, mesg, argv[2]); } @@ -530,6 +532,9 @@ mrb_init_exception(mrb_state *mrb) mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */ runtime_error = mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */ mrb->nomem_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "Out of memory")); +#ifdef MRB_GC_FIXED_ARENA + mrb->arena_err = mrb_obj_ptr(mrb_exc_new_str_lit(mrb, runtime_error, "arena overflow error")); +#endif script_error = mrb_define_class(mrb, "ScriptError", mrb->eException_class); /* 15.2.37 */ mrb_define_class(mrb, "SyntaxError", script_error); /* 15.2.38 */ mrb_define_class(mrb, "SystemStackError", exception); @@ -403,7 +403,7 @@ gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { /* arena overflow error */ gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ - mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error"); + mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); } #else if (gc->arena_idx >= gc->arena_capa) { @@ -479,6 +479,17 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) static const RVALUE RVALUE_zero = { { { MRB_TT_FALSE } } }; mrb_gc *gc = &mrb->gc; + if (cls) { + enum mrb_vtype tt = MRB_INSTANCE_TT(cls); + if (tt != MRB_TT_FALSE && + ttype != MRB_TT_SCLASS && + ttype != MRB_TT_ICLASS && + ttype != MRB_TT_ENV && + ttype != tt) { + mrb_raisef(mrb, E_TYPE_ERROR, "allocation failure of %S", mrb_obj_value(cls)); + } + } + #ifdef MRB_GC_STRESS mrb_full_gc(mrb); #endif @@ -816,6 +827,9 @@ root_scan_phase(mrb_state *mrb, mrb_gc *gc) mrb_gc_mark(mrb, (struct RBasic*)mrb->exc); /* mark pre-allocated exception */ mrb_gc_mark(mrb, (struct RBasic*)mrb->nomem_err); +#ifdef MRB_GC_FIXED_ARENA + mrb_gc_mark(mrb, (struct RBasic*)mrb->arena_err); +#endif mark_context(mrb, mrb->root_c); if (mrb->root_c->fib) { diff --git a/src/kernel.c b/src/kernel.c index 74254e636..c63e05596 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -285,6 +285,7 @@ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) } dc->mt = kh_copy(mt, mrb, sc->mt); dc->super = sc->super; + MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); } static void diff --git a/src/numeric.c b/src/numeric.c index c86373318..25a411de8 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -13,6 +13,7 @@ #include <mruby/array.h> #include <mruby/numeric.h> #include <mruby/string.h> +#include <mruby/class.h> #ifdef MRB_USE_FLOAT #define trunc(f) truncf(f) @@ -1265,6 +1266,7 @@ mrb_init_numeric(mrb_state *mrb) /* Integer Class */ integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */ + MRB_SET_INSTANCE_TT(integer, MRB_TT_FIXNUM); mrb_undef_class_method(mrb, integer, "new"); mrb_define_method(mrb, integer, "to_i", int_to_i, MRB_ARGS_NONE()); /* 15.2.8.3.24 */ mrb_define_method(mrb, integer, "to_int", int_to_i, MRB_ARGS_NONE()); @@ -1291,6 +1293,7 @@ mrb_init_numeric(mrb_state *mrb) /* Float Class */ mrb->float_class = fl = mrb_define_class(mrb, "Float", numeric); /* 15.2.9 */ + MRB_SET_INSTANCE_TT(fl, MRB_TT_FLOAT); mrb_undef_class_method(mrb, fl, "new"); mrb_define_method(mrb, fl, "+", flo_plus, MRB_ARGS_REQ(1)); /* 15.2.9.3.1 */ mrb_define_method(mrb, fl, "-", flo_minus, MRB_ARGS_REQ(1)); /* 15.2.9.3.2 */ diff --git a/src/object.c b/src/object.c index c61feb342..eb2c23e63 100644 --- a/src/object.c +++ b/src/object.c @@ -8,6 +8,7 @@ #include <mruby/class.h> #include <mruby/numeric.h> #include <mruby/string.h> +#include <mruby/class.h> MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value v1, mrb_value v2) @@ -265,6 +266,7 @@ mrb_init_object(mrb_state *mrb) struct RClass *f; mrb->nil_class = n = mrb_define_class(mrb, "NilClass", mrb->object_class); + MRB_SET_INSTANCE_TT(n, MRB_TT_TRUE); mrb_undef_class_method(mrb, n, "new"); mrb_define_method(mrb, n, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.4.3.1 */ mrb_define_method(mrb, n, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.4.3.2 */ @@ -274,6 +276,7 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, n, "inspect", nil_inspect, MRB_ARGS_NONE()); mrb->true_class = t = mrb_define_class(mrb, "TrueClass", mrb->object_class); + MRB_SET_INSTANCE_TT(t, MRB_TT_TRUE); mrb_undef_class_method(mrb, t, "new"); mrb_define_method(mrb, t, "&", true_and, MRB_ARGS_REQ(1)); /* 15.2.5.3.1 */ mrb_define_method(mrb, t, "^", true_xor, MRB_ARGS_REQ(1)); /* 15.2.5.3.2 */ @@ -282,6 +285,7 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, t, "inspect", true_to_s, MRB_ARGS_NONE()); mrb->false_class = f = mrb_define_class(mrb, "FalseClass", mrb->object_class); + MRB_SET_INSTANCE_TT(f, MRB_TT_TRUE); mrb_undef_class_method(mrb, f, "new"); mrb_define_method(mrb, f, "&", false_and, MRB_ARGS_REQ(1)); /* 15.2.6.3.1 */ mrb_define_method(mrb, f, "^", false_xor, MRB_ARGS_REQ(1)); /* 15.2.6.3.2 */ @@ -440,7 +444,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj) mrb_str_cat_lit(mrb, str, "#<"); mrb_str_cat_cstr(mrb, str, cname); mrb_str_cat_lit(mrb, str, ":"); - mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj))); + mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_ptr(obj))); mrb_str_cat_lit(mrb, str, ">"); return str; diff --git a/src/proc.c b/src/proc.c index 1620bddf8..470547094 100644 --- a/src/proc.c +++ b/src/proc.c @@ -140,7 +140,7 @@ mrb_proc_copy(struct RProc *a, struct RProc *b) { a->flags = b->flags; a->body = b->body; - if (!MRB_PROC_CFUNC_P(a)) { + if (!MRB_PROC_CFUNC_P(a) && a->body.irep) { a->body.irep->refcnt++; } a->target_class = b->target_class; @@ -188,18 +188,13 @@ mrb_proc_call_cfunc(mrb_state *mrb, struct RProc *p, mrb_value self) return (p->body.func)(mrb, self); } -mrb_code* -mrb_proc_iseq(mrb_state *mrb, struct RProc *p) -{ - return p->body.irep->iseq; -} - /* 15.2.17.4.2 */ static mrb_value mrb_proc_arity(mrb_state *mrb, mrb_value self) { struct RProc *p = mrb_proc_ptr(self); - mrb_code *iseq = mrb_proc_iseq(mrb, p); + struct mrb_irep *irep; + mrb_code *iseq; mrb_aspec aspec; int ma, op, ra, pa, arity; @@ -208,6 +203,12 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self) return mrb_fixnum_value(-1); } + irep = p->body.irep; + if (!irep) { + return mrb_fixnum_value(0); + } + + iseq = irep->iseq; /* arity is depend on OP_ENTER */ if (GET_OPCODE(*iseq) != OP_ENTER) { return mrb_fixnum_value(0); diff --git a/src/range.c b/src/range.c index f0a976e53..417957420 100644 --- a/src/range.c +++ b/src/range.c @@ -12,6 +12,17 @@ #define RANGE_CLASS (mrb_class_get(mrb, "Range")) +MRB_API struct RRange* +mrb_range_ptr(mrb_state *mrb, mrb_value v) +{ + struct RRange *r = (struct RRange*)mrb_ptr(v); + + if (r->edges == NULL) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "uninitialized range"); + } + return r; +} + static void range_check(mrb_state *mrb, mrb_value a, mrb_value b) { @@ -57,7 +68,7 @@ mrb_range_new(mrb_state *mrb, mrb_value beg, mrb_value end, mrb_bool excl) mrb_value mrb_range_beg(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); return r->edges->beg; } @@ -76,7 +87,7 @@ mrb_range_beg(mrb_state *mrb, mrb_value range) mrb_value mrb_range_end(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); return r->edges->end; } @@ -90,7 +101,7 @@ mrb_range_end(mrb_state *mrb, mrb_value range) mrb_value mrb_range_excl(mrb_state *mrb, mrb_value range) { - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); return mrb_bool_value(r->excl); } @@ -98,7 +109,7 @@ mrb_range_excl(mrb_state *mrb, mrb_value range) static void range_init(mrb_state *mrb, mrb_value range, mrb_value beg, mrb_value end, mrb_bool exclude_end) { - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_raw_ptr(range); range_check(mrb, beg, end); r->excl = exclude_end; @@ -129,7 +140,7 @@ mrb_range_initialize(mrb_state *mrb, mrb_value range) exclusive = FALSE; } /* Ranges are immutable, so that they should be initialized only once. */ - if (mrb_range_ptr(range)->edges) { + if (mrb_range_raw_ptr(range)->edges) { mrb_name_error(mrb, mrb_intern_lit(mrb, "initialize"), "`initialize' called twice"); } range_init(mrb, range, beg, end, exclusive); @@ -164,8 +175,8 @@ mrb_range_eq(mrb_state *mrb, mrb_value range) return mrb_false_value(); } - rr = mrb_range_ptr(range); - ro = mrb_range_ptr(obj); + rr = mrb_range_ptr(mrb, range); + ro = mrb_range_ptr(mrb, obj); v1 = mrb_funcall(mrb, rr->edges->beg, "==", 1, ro->edges->beg); v2 = mrb_funcall(mrb, rr->edges->end, "==", 1, ro->edges->end); if (!mrb_bool(v1) || !mrb_bool(v2) || rr->excl != ro->excl) { @@ -222,7 +233,7 @@ mrb_value mrb_range_include(mrb_state *mrb, mrb_value range) { mrb_value val; - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); mrb_value beg, end; mrb_bool include_p; @@ -241,7 +252,7 @@ static mrb_bool range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, mrb_int len, mrb_bool trunc) { mrb_int beg, end; - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); if (mrb_type(range) != MRB_TT_RANGE) return FALSE; @@ -287,7 +298,7 @@ static mrb_value range_to_s(mrb_state *mrb, mrb_value range) { mrb_value str, str2; - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); str = mrb_obj_as_string(mrb, r->edges->beg); str2 = mrb_obj_as_string(mrb, r->edges->end); @@ -312,7 +323,7 @@ static mrb_value range_inspect(mrb_state *mrb, mrb_value range) { mrb_value str, str2; - struct RRange *r = mrb_range_ptr(range); + struct RRange *r = mrb_range_ptr(mrb, range); str = mrb_inspect(mrb, r->edges->beg); str2 = mrb_inspect(mrb, r->edges->end); @@ -352,8 +363,8 @@ range_eql(mrb_state *mrb, mrb_value range) } if (mrb_type(obj) != MRB_TT_RANGE) return mrb_false_value(); - r = mrb_range_ptr(range); - o = mrb_range_ptr(obj); + r = mrb_range_ptr(mrb, range); + o = mrb_range_ptr(mrb, obj); if (!mrb_eql(mrb, r->edges->beg, o->edges->beg) || !mrb_eql(mrb, r->edges->end, o->edges->end) || (r->excl != o->excl)) { @@ -376,7 +387,7 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy) mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - r = mrb_range_ptr(src); + r = mrb_range_ptr(mrb, src); range_init(mrb, copy, r->edges->beg, r->edges->end, r->excl); return copy; diff --git a/src/string.c b/src/string.c index 5e490bf03..f47294291 100644 --- a/src/string.c +++ b/src/string.c @@ -1235,11 +1235,13 @@ mrb_str_chomp_bang(mrb_state *mrb, mrb_value str) char *p, *pp; mrb_int rslen; mrb_int len; + mrb_int argc; struct RString *s = mrb_str_ptr(str); mrb_str_modify(mrb, s); + argc = mrb_get_args(mrb, "|S", &rs); len = RSTR_LEN(s); - if (mrb_get_args(mrb, "|S", &rs) == 0) { + if (argc == 0) { if (len == 0) return mrb_nil_value(); smart_chomp: if (RSTR_PTR(s)[len-1] == '\n') { diff --git a/src/symbol.c b/src/symbol.c index 25ae132e1..a3ab05c85 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -10,6 +10,7 @@ #include <mruby/khash.h> #include <mruby/string.h> #include <mruby/dump.h> +#include <mruby/class.h> /* ------------------------------------------------------ */ typedef struct symbol_name { @@ -481,6 +482,8 @@ mrb_init_symbol(mrb_state *mrb) struct RClass *sym; mrb->symbol_class = sym = mrb_define_class(mrb, "Symbol", mrb->object_class); /* 15.2.11 */ + MRB_SET_INSTANCE_TT(sym, MRB_TT_SYMBOL); + mrb_undef_class_method(mrb, sym, "new"); mrb_define_method(mrb, sym, "===", sym_equal, MRB_ARGS_REQ(1)); /* 15.2.11.3.1 */ mrb_define_method(mrb, sym, "id2name", mrb_sym_to_s, MRB_ARGS_NONE()); /* 15.2.11.3.2 */ @@ -2288,7 +2288,7 @@ RETRY_TRY_BLOCK: CASE(OP_CLASS) { /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ - struct RClass *c = 0; + struct RClass *c = 0, *baseclass; int a = GETARG_A(i); mrb_value base, super; mrb_sym id = syms[GETARG_B(i)]; @@ -2296,7 +2296,10 @@ RETRY_TRY_BLOCK: base = regs[a]; super = regs[a+1]; if (mrb_nil_p(base)) { - base = mrb_obj_value(mrb->c->ci->target_class); + baseclass = mrb->c->ci->proc->target_class; + if (!baseclass) baseclass = mrb->c->ci->target_class; + + base = mrb_obj_value(baseclass); } c = mrb_vm_define_class(mrb, base, super, id); regs[a] = mrb_obj_value(c); @@ -2306,14 +2309,17 @@ RETRY_TRY_BLOCK: CASE(OP_MODULE) { /* A B R(A) := newmodule(R(A),Syms(B)) */ - struct RClass *c = 0; + struct RClass *c = 0, *baseclass; int a = GETARG_A(i); mrb_value base; mrb_sym id = syms[GETARG_B(i)]; base = regs[a]; if (mrb_nil_p(base)) { - base = mrb_obj_value(mrb->c->ci->target_class); + baseclass = mrb->c->ci->proc->target_class; + if (!baseclass) baseclass = mrb->c->ci->target_class; + + base = mrb_obj_value(baseclass); } c = mrb_vm_define_module(mrb, base, id); regs[a] = mrb_obj_value(c); |
