summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro Matsumoto <[email protected]>2012-07-09 11:42:24 +0900
committerYukihiro Matsumoto <[email protected]>2012-07-09 11:42:24 +0900
commitc3201370554a5d48c59f97daf61a725310d4bbbc (patch)
tree061650ef60a9d2b30929f1b3782911ea45f53e53
parent0e2a81740a284e823894ec5b1d804e282df15b7e (diff)
parent8cef93d228ec5d2cb57b84cf0ae3945363080546 (diff)
downloadmruby-c3201370554a5d48c59f97daf61a725310d4bbbc.tar.gz
mruby-c3201370554a5d48c59f97daf61a725310d4bbbc.zip
Merge branch 'master' of github.com:mruby/mruby
-rw-r--r--src/array.c15
-rw-r--r--src/class.c87
-rw-r--r--src/dump.c7
-rw-r--r--src/gc.c17
-rw-r--r--src/parse.y3
-rw-r--r--src/state.c3
-rw-r--r--src/vm.c6
-rw-r--r--test/t/module.rb56
8 files changed, 154 insertions, 40 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;
diff --git a/src/gc.c b/src/gc.c
index 2663e9780..78d8ee6a9 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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) {
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;
}
diff --git a/test/t/module.rb b/test/t/module.rb
index 95fbb7a86..63c2e7dc8 100644
--- a/test/t/module.rb
+++ b/test/t/module.rb
@@ -9,6 +9,23 @@ assert('Module superclass', '15.2.2.2') do
Module.superclass == Object
end
+# TODO not implemented ATM assert('Module.constants', '15.2.2.3.1') do
+
+# TODO not implemented ATM assert('Module.nesting', '15.2.2.3.2') do
+
+assert('Module#append_features', '15.2.2.4.10') do
+ module Test4AppendFeatures
+ def self.append_features(mod)
+ Test4AppendFeatures2.const_set(:Const4AppendFeatures2, mod)
+ end
+ end
+ module Test4AppendFeatures2
+ include Test4AppendFeatures
+ end
+
+ Test4AppendFeatures2.const_get(:Const4AppendFeatures2) == Test4AppendFeatures2
+end
+
assert('Module#const_defined?', '15.2.2.4.20') do
module Test4ConstDefined
Const4Test4ConstDefined = true
@@ -56,6 +73,41 @@ assert('Module#const_get', '15.2.2.4.23') do
Test4ConstSet.const_get(:Const4Test4ConstSet) == 23
end
-# TODO not implemented ATM assert('Module.constants', '15.2.2') do
+assert('Module#include', '15.2.2.4.27') do
+ module Test4Include
+ Const4Include = 42
+ end
+ module Test4Include2
+ include Test4Include
+ end
+
+ Test4Include2.const_get(:Const4Include) == 42
+end
+
+assert('Module#included', '15.2.2.4.29') do
+ module Test4Included
+ Const4Included = 42
+ def Test4Included.included mod
+ Test4Included.const_set(:Const4Included2, mod)
+ end
+ end
+ module Test4Included2
+ include Test4Included
+ end
+
+ Test4Included2.const_get(:Const4Included) == 42 and
+ Test4Included2.const_get(:Const4Included2) == Test4Included2
+end
+
+assert('Module#included_modules', '15.2.2.4.30') do
+ r1 = true
+ module Test4includedModules
+ Const4Included = 42
+ end
+ module Test4includedModules2
+ r1 = included Test4includedModules
+ end
+
+ Test4includedModules2.included_modules.class == Array
+end
-# TODO not implemented ATM assert('Module.nesting', '15.2.2') do