Commit c3201370 authored by Yukihiro Matsumoto's avatar Yukihiro Matsumoto

Merge branch 'master' of github.com:mruby/mruby

parents 0e2a8174 8cef93d2
......@@ -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;
......
......@@ -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 */
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment