From 47407768fdf118fa6fe3ead5b088b79397603ef6 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Sat, 7 Jul 2012 12:09:59 +0900 Subject: Fix underlying bugs. mrb_calloc will be crashed in case "nelem == 0" or "p == NULL" --- src/gc.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 2663e9780..5f30570de 100644 --- a/src/gc.c +++ b/src/gc.c @@ -167,10 +167,15 @@ 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; + size_t size; + + 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; } -- cgit v1.2.3 From a064038d85758c2e8add556f9aafa7823df53ef4 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Sat, 7 Jul 2012 12:38:07 +0900 Subject: Add a check for unsigned integer wrapping. --- src/gc.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/gc.c b/src/gc.c index 5f30570de..2149a2d43 100644 --- a/src/gc.c +++ b/src/gc.c @@ -167,14 +167,16 @@ mrb_malloc(mrb_state *mrb, size_t len) void* mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) { - void *p; + void *p = NULL; size_t size; - size = nelem * len; - p = mrb_realloc(mrb, 0, size); + if (nelem <= SIZE_MAX / len) { + size = nelem * len; + p = mrb_realloc(mrb, 0, size); - if (p && size > 0) - memset(p, 0, size); + if (p && size > 0) + memset(p, 0, size); + } return p; } -- cgit v1.2.3 From 312b2c7b160b4eab5a07897d36e5abd8a6748085 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Sat, 7 Jul 2012 16:30:52 +0900 Subject: Optimize range check. --- src/array.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/array.c b/src/array.c index 981da7afb..29f58d17e 100644 --- a/src/array.c +++ b/src/array.c @@ -566,9 +566,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 +594,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; -- cgit v1.2.3 From 9f814a4e6e6cadea676a875990786903e37b1a06 Mon Sep 17 00:00:00 2001 From: Masamitsu MURASE Date: Sat, 7 Jul 2012 23:04:09 +0900 Subject: Improvement of Module#include. - Add some methods: append_features, included_methods and included. - Modify Module#include to call append_features and included. --- src/class.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 74 insertions(+), 13 deletions(-) (limited to 'src') 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; itt == 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 */ -- cgit v1.2.3 From 611cf71a10051d77a7bb8998d8a7c34e26b0b1b0 Mon Sep 17 00:00:00 2001 From: Masaki Muranaka Date: Sun, 8 Jul 2012 11:33:49 +0900 Subject: Use mrb_calloc if you want zero cleard buffers. --- src/array.c | 3 +-- src/dump.c | 7 ++----- src/gc.c | 4 +--- src/parse.y | 3 +-- src/state.c | 3 +-- src/vm.c | 6 ++---- 6 files changed, 8 insertions(+), 18 deletions(-) (limited to 'src') diff --git a/src/array.c b/src/array.c index 29f58d17e..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; 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; diff --git a/src/gc.c b/src/gc.c index 2149a2d43..78d8ee6a9 100644 --- a/src/gc.c +++ b/src/gc.c @@ -246,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; pas.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) { diff --git a/src/vm.c b/src/vm.c index 62fba24d0..9ee6b9883 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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; } -- cgit v1.2.3