diff options
| author | Yukihiro Matsumoto <[email protected]> | 2012-07-09 11:42:24 +0900 |
|---|---|---|
| committer | Yukihiro Matsumoto <[email protected]> | 2012-07-09 11:42:24 +0900 |
| commit | c3201370554a5d48c59f97daf61a725310d4bbbc (patch) | |
| tree | 061650ef60a9d2b30929f1b3782911ea45f53e53 /src | |
| parent | 0e2a81740a284e823894ec5b1d804e282df15b7e (diff) | |
| parent | 8cef93d228ec5d2cb57b84cf0ae3945363080546 (diff) | |
| download | mruby-c3201370554a5d48c59f97daf61a725310d4bbbc.tar.gz mruby-c3201370554a5d48c59f97daf61a725310d4bbbc.zip | |
Merge branch 'master' of github.com:mruby/mruby
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 15 | ||||
| -rw-r--r-- | src/class.c | 87 | ||||
| -rw-r--r-- | src/dump.c | 7 | ||||
| -rw-r--r-- | src/gc.c | 17 | ||||
| -rw-r--r-- | src/parse.y | 3 | ||||
| -rw-r--r-- | src/state.c | 3 | ||||
| -rw-r--r-- | src/vm.c | 6 |
7 files changed, 100 insertions, 38 deletions
diff --git a/src/array.c b/src/array.c index 981da7afb..d65a99cc4 100644 --- a/src/array.c +++ b/src/array.c @@ -46,8 +46,7 @@ ary_new_capa(mrb_state *mrb, int capa) } a = (struct RArray*)mrb_obj_alloc(mrb, MRB_TT_ARRAY, mrb->array_class); - a->ptr = mrb_malloc(mrb, blen); - memset(a->ptr, 0, blen); + a->ptr = mrb_calloc(mrb, blen, 1); a->aux.capa = capa; a->len = 0; @@ -566,9 +565,11 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) /* rb_ary_s ary_modify(mrb, a); /* range check */ - if (n < 0) n += a->len; if (n < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len); + n += a->len; + if (n < 0) { + mrb_raise(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len); + } } if (a->len <= (int)n) { if (a->aux.capa <= (int)n) @@ -592,9 +593,11 @@ mrb_ary_splice(mrb_state *mrb, mrb_value ary, mrb_int head, mrb_int len, mrb_val ary_modify(mrb, a); /* range check */ - if (head < 0) head += a->len; if (head < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); + head += a->len; + if (head < 0) { + mrb_raise(mrb, E_INDEX_ERROR, "index is out of array"); + } } tail = head + len; diff --git a/src/class.c b/src/class.c index 7e0512322..9003c3bc5 100644 --- a/src/class.c +++ b/src/class.c @@ -641,32 +641,90 @@ boot_defclass(mrb_state *mrb, struct RClass *super) return c; } +static int +find_in_ancestors(struct RClass *c, struct RClass *m) +{ + while(c) { + if (c == m || c->mt == m->mt){ + return 1; + } + c = c->super; + } + return 0; +} + void mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) { - struct RClass *ic; + struct RClass *ic, *ins_pos; - if (m->super) mrb_include_module(mrb, c, m->super); - ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); - ic->c = m; - ic->mt = m->mt; - ic->iv = m->iv; - ic->super = c->super; - c->super = ic; - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)ic); + ins_pos = c; + while (m) { + if (!find_in_ancestors(c, m)) { + ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); + if (m->tt == MRB_TT_ICLASS) { + ic->c = m->c; + } + else { + ic->c = m; + } + ic->mt = m->mt; + ic->iv = m->iv; + ic->super = ins_pos->super; + ins_pos->super = ic; + mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); + ins_pos = ic; + } + m = m->super; + } } static mrb_value -mrb_mod_include(mrb_state *mrb, mrb_value klass) +mrb_mod_append_features(mrb_state *mrb, mrb_value mod) { - mrb_value mod; + mrb_value klass; - mrb_get_args(mrb, "o", &mod); mrb_check_type(mrb, mod, MRB_TT_MODULE); + mrb_get_args(mrb, "o", &klass); mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); return mod; } +static mrb_value +mrb_mod_include(mrb_state *mrb, mrb_value klass) +{ + mrb_value *argv; + int argc, i; + + mrb_get_args(mrb, "*", &argv, &argc); + for (i=0; i<argc; i++) { + mrb_check_type(mrb, argv[i], MRB_TT_MODULE); + } + while (argc--) { + mrb_funcall_argv(mrb, argv[argc], "append_features", 1, &klass); + mrb_funcall_argv(mrb, argv[argc], "included", 1, &klass); + } + + return klass; +} + +static mrb_value +mrb_mod_included_modules(mrb_state *mrb, mrb_value self) +{ + mrb_value result; + struct RClass *c = mrb_class_ptr(self); + + result = mrb_ary_new(mrb); + while (c) { + if (c->tt == MRB_TT_ICLASS) { + mrb_ary_push(mrb, result, mrb_obj_value(c->c)); + } + c = c->super; + } + + return result; +} + static struct RClass * mrb_singleton_class_ptr(mrb_state *mrb, struct RClass *c) { @@ -1323,7 +1381,10 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, ARGS_NONE()); /* 15.2.3.3.4 */ mrb_define_method(mrb, cls, "new", mrb_instance_new, ARGS_ANY()); /* 15.2.3.3.3 */ mrb_define_method(mrb, cls, "inherited", mrb_bob_init, ARGS_REQ(1)); - mrb_define_method(mrb, mod, "include", mrb_mod_include, ARGS_REQ(1)); /* 15.2.2.4.27 */ + mrb_define_method(mrb, mod, "include", mrb_mod_include, ARGS_ANY()); /* 15.2.2.4.27 */ + mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, ARGS_REQ(1)); /* 15.2.2.4.10 */ + mrb_define_method(mrb, mod, "included", mrb_bob_init, ARGS_REQ(1)); /* 15.2.2.4.29 */ + mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, ARGS_NONE()); /* 15.2.2.4.30 */ mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, ARGS_NONE()); mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, ARGS_ANY()); /* 15.2.2.4.8 */ diff --git a/src/dump.c b/src/dump.c index 0e40cf3ed..a720090fa 100644 --- a/src/dump.c +++ b/src/dump.c @@ -460,11 +460,10 @@ calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section) default: return MRB_DUMP_GENERAL_FAILURE; } - if ((buf = mrb_malloc(mrb, buf_size)) == 0) + if ((buf = mrb_calloc(mrb, 1, buf_size)) == 0) return MRB_DUMP_GENERAL_FAILURE; buf_top = buf; - memset(buf, 0, buf_size); switch (section) { case DUMP_IREP_HEADER: buf += write_irep_header(mrb, irep, buf, type); break; @@ -598,11 +597,9 @@ dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen) if (irep_record_size == 0) return MRB_DUMP_GENERAL_FAILURE; - if ((buf = mrb_malloc(mrb, irep_record_size)) == 0) + if ((buf = mrb_calloc(mrb, 1, irep_record_size)) == 0) return MRB_DUMP_GENERAL_FAILURE; - memset( buf, 0, irep_record_size); - if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK) { rc = MRB_DUMP_GENERAL_FAILURE; goto error_exit; @@ -167,10 +167,17 @@ mrb_malloc(mrb_state *mrb, size_t len) void* mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) { - void *p = mrb_realloc(mrb, 0, nelem*len); + void *p = NULL; + size_t size; + + if (nelem <= SIZE_MAX / len) { + size = nelem * len; + p = mrb_realloc(mrb, 0, size); + + if (p && size > 0) + memset(p, 0, size); + } - if (len > 0) - memset(p, 0, nelem*len); return p; } @@ -239,12 +246,10 @@ unlink_free_heap_page(mrb_state *mrb, struct heap_page *page) static void add_heap(mrb_state *mrb) { - struct heap_page *page = mrb_malloc(mrb, sizeof(struct heap_page)); + struct heap_page *page = mrb_calloc(mrb, 1, sizeof(struct heap_page)); RVALUE *p, *e; struct RBasic *prev = NULL; - memset(page, 0, sizeof(struct heap_page)); - for (p = page->objects, e=p+HEAP_PAGE_SIZE; p<e; p++) { p->as.free.tt = MRB_TT_FREE; p->as.free.next = prev; diff --git a/src/parse.y b/src/parse.y index af91f09b6..dd1738010 100644 --- a/src/parse.y +++ b/src/parse.y @@ -4792,8 +4792,7 @@ mrbc_context_new(mrb_state *mrb) { mrbc_context *c; - c = mrb_malloc(mrb, sizeof(mrbc_context)); - memset(c, 0, sizeof(mrbc_context)); + c = mrb_calloc(mrb, 1, sizeof(mrbc_context)); return c; } diff --git a/src/state.c b/src/state.c index e4729ca70..7f74606ff 100644 --- a/src/state.c +++ b/src/state.c @@ -76,8 +76,7 @@ mrb_add_irep(mrb_state *mrb, int idx) int max = 256; if (idx > max) max = idx+1; - mrb->irep = mrb_malloc(mrb, sizeof(mrb_irep*)*max); - memset(mrb->irep, 0, sizeof(mrb_irep*)*max); + mrb->irep = mrb_calloc(mrb, max, sizeof(mrb_irep*)); mrb->irep_capa = max; } else if (mrb->irep_capa <= idx) { @@ -28,16 +28,14 @@ static void stack_init(mrb_state *mrb) { /* assert(mrb->stack == NULL); */ - mrb->stbase = mrb_malloc(mrb, sizeof(mrb_value) * STACK_INIT_SIZE); - memset(mrb->stbase, 0, sizeof(mrb_value) * STACK_INIT_SIZE); + mrb->stbase = mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); mrb->stend = mrb->stbase + STACK_INIT_SIZE; mrb->stack = mrb->stbase; /* assert(mrb->ci == NULL); */ - mrb->cibase = mrb_malloc(mrb, sizeof(mrb_callinfo)*CALLINFO_INIT_SIZE); + mrb->cibase = mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); mrb->ciend = mrb->cibase + CALLINFO_INIT_SIZE; mrb->ci = mrb->cibase; - memset(mrb->ci, 0, sizeof(mrb_callinfo)); mrb->ci->target_class = mrb->object_class; } |
