diff options
| author | Daniel Bovensiepen <[email protected]> | 2012-11-01 16:12:57 +0800 |
|---|---|---|
| committer | Daniel Bovensiepen <[email protected]> | 2012-11-01 16:12:57 +0800 |
| commit | cdb72a05a294eb8521dd40c011160228496312cb (patch) | |
| tree | 283586ad23f2dc6dfd1fd1aaa354f18c23d8c0d6 /src | |
| parent | 88dfaf19aa0808f78d13133d61ea433d043923f9 (diff) | |
| parent | 57910ca5353e1feba1fb069a876b84a52f33d39f (diff) | |
| download | mruby-cdb72a05a294eb8521dd40c011160228496312cb.tar.gz mruby-cdb72a05a294eb8521dd40c011160228496312cb.zip | |
Merge remote-tracking branch 'upstream/master' into mrbgems
Diffstat (limited to 'src')
| -rw-r--r-- | src/array.c | 31 | ||||
| -rw-r--r-- | src/cdump.c | 29 | ||||
| -rw-r--r-- | src/class.c | 26 | ||||
| -rw-r--r-- | src/codegen.c | 53 | ||||
| -rw-r--r-- | src/dump.c | 74 | ||||
| -rw-r--r-- | src/error.c | 26 | ||||
| -rw-r--r-- | src/etc.c | 4 | ||||
| -rw-r--r-- | src/gc.c | 3 | ||||
| -rw-r--r-- | src/hash.c | 10 | ||||
| -rw-r--r-- | src/kernel.c | 13 | ||||
| -rw-r--r-- | src/load.c | 41 | ||||
| -rw-r--r-- | src/numeric.c | 19 | ||||
| -rw-r--r-- | src/object.c | 21 | ||||
| -rw-r--r-- | src/parse.y | 5 | ||||
| -rw-r--r-- | src/proc.c | 10 | ||||
| -rw-r--r-- | src/range.c | 4 | ||||
| -rw-r--r-- | src/sprintf.c | 30 | ||||
| -rw-r--r-- | src/state.c | 11 | ||||
| -rw-r--r-- | src/string.c | 44 | ||||
| -rw-r--r-- | src/struct.c | 29 | ||||
| -rw-r--r-- | src/time.c | 2 | ||||
| -rw-r--r-- | src/variable.c | 22 | ||||
| -rw-r--r-- | src/vm.c | 80 |
23 files changed, 400 insertions, 187 deletions
diff --git a/src/array.c b/src/array.c index 36f4af9c6..2e2536368 100644 --- a/src/array.c +++ b/src/array.c @@ -63,6 +63,17 @@ mrb_ary_new(mrb_state *mrb) return mrb_ary_new_capa(mrb, 0); } +static inline void +array_copy(mrb_value *dst, const mrb_value *src, size_t size) +{ + int i; + + for (i = 0; i < size; i++) { + dst[i] = src[i]; + } +} + + mrb_value mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals) { @@ -71,7 +82,7 @@ mrb_ary_new_from_values(mrb_state *mrb, int size, mrb_value *vals) ary = mrb_ary_new_capa(mrb, size); a = mrb_ary_ptr(ary); - memcpy(a->ptr, vals, sizeof(mrb_value)*size); + array_copy(a->ptr, vals, size); a->len = size; return ary; @@ -115,7 +126,7 @@ ary_modify(mrb_state *mrb, struct RArray *a) len = a->len * sizeof(mrb_value); ptr = (mrb_value *)mrb_malloc(mrb, len); if (p) { - memcpy(ptr, p, len); + array_copy(ptr, p, a->len); } a->ptr = ptr; a->aux.capa = a->len; @@ -213,7 +224,7 @@ ary_concat(mrb_state *mrb, struct RArray *a, mrb_value *ptr, int blen) ary_modify(mrb, a); if (a->aux.capa < len) ary_expand_capa(mrb, a, len); - memcpy(a->ptr+a->len, ptr, sizeof(mrb_value)*blen); + array_copy(a->ptr+a->len, ptr, blen); mrb_write_barrier(mrb, (struct RBasic*)a); a->len = len; } @@ -249,8 +260,8 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "a", &ptr, &blen); ary = mrb_ary_new_capa(mrb, a1->len + blen); a2 = mrb_ary_ptr(ary); - memcpy(a2->ptr, a1->ptr, sizeof(mrb_value)*a1->len); - memcpy(a2->ptr + a1->len, ptr, sizeof(mrb_value)*blen); + array_copy(a2->ptr, a1->ptr, a1->len); + array_copy(a2->ptr + a1->len, ptr, blen); a2->len = a1->len + blen; return ary; @@ -309,7 +320,7 @@ ary_replace(mrb_state *mrb, struct RArray *a, mrb_value *argv, int len) ary_modify(mrb, a); if (a->aux.capa < len) ary_expand_capa(mrb, a, len); - memcpy(a->ptr, argv, sizeof(mrb_value)*len); + array_copy(a->ptr, argv, len); mrb_write_barrier(mrb, (struct RBasic*)a); a->len = len; } @@ -352,7 +363,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) a2 = mrb_ary_ptr(ary); ptr = a2->ptr; while(times--) { - memcpy(ptr, a1->ptr, sizeof(mrb_value)*(a1->len)); + array_copy(ptr, a1->ptr, a1->len); ptr += a1->len; a2->len += a1->len; } @@ -410,7 +421,7 @@ mrb_ary_new4(mrb_state *mrb, int n, const mrb_value *elts) ary = mrb_ary_new_capa(mrb, n); if (n > 0 && elts) { - memcpy(RARRAY_PTR(ary), elts, sizeof(mrb_value)*n); + array_copy(RARRAY_PTR(ary), elts, n); RARRAY_LEN(ary) = n; } @@ -540,7 +551,7 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) ary_expand_capa(mrb, a, a->len + len); memmove(a->ptr + len, a->ptr, sizeof(mrb_value)*a->len); } - memcpy(a->ptr, vals, sizeof(mrb_value)*len); + array_copy(a->ptr, vals, len); a->len += len; mrb_write_barrier(mrb, (struct RBasic*)a); @@ -569,7 +580,7 @@ mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val) /* rb_ary_s if (n < 0) { n += a->len; if (n < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len); + mrb_raisef(mrb, E_INDEX_ERROR, "index %ld out of array", n - a->len); } } if (a->len <= (int)n) { diff --git a/src/cdump.c b/src/cdump.c index ba05a1899..b43c86ee7 100644 --- a/src/cdump.c +++ b/src/cdump.c @@ -22,7 +22,7 @@ make_cdump_isec(mrb_state *mrb, int irep_no, FILE *f) int i; mrb_irep *irep = mrb->irep[irep_no]; - if (irep == 0) + if (irep == NULL) return -1; /* dump isec struct*/ @@ -103,16 +103,17 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f) char *buf = 0; size_t buf_len, str_len; - if (irep == 0) + if (irep == NULL) return -1; buf_len = MRB_CDUMP_LINE_LEN; - if ((buf = (char *)mrb_malloc(mrb, buf_len)) == 0 ) { + if ((buf = (char *)mrb_malloc(mrb, buf_len)) == NULL) { return MRB_CDUMP_GENERAL_FAILURE; } SOURCE_CODE0 (" ai = mrb->arena_idx;"); SOURCE_CODE0 (" irep = mrb->irep[idx] = mrb_malloc(mrb, sizeof(mrb_irep));"); + SOURCE_CODE0 (" irep->flags = MRB_ISEQ_NO_FREE;"); SOURCE_CODE0 (" irep->idx = idx++;"); SOURCE_CODE (" irep->nlocals = %d;", irep->nlocals); SOURCE_CODE (" irep->nregs = %d;", irep->nregs); @@ -124,13 +125,19 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f) SOURCE_CODE (" irep->syms = mrb_malloc(mrb, sizeof(mrb_sym)*%d);", irep->slen); for (n=0; n<irep->slen; n++) if (irep->syms[n]) { - SOURCE_CODE (" irep->syms[%d] = mrb_intern(mrb, \"%s\");", n, mrb_sym2name(mrb, irep->syms[n])); + const char *name; + int len; + + name = mrb_sym2name_len(mrb, irep->syms[n], &len); + SOURCE_CODE (" irep->syms[%d] = mrb_intern2(mrb, \"%s\", %d);", n, name, len); } } else SOURCE_CODE0 (" irep->syms = NULL;"); - SOURCE_CODE (" irep->plen = %d;", irep->plen); + SOURCE_CODE0 (" irep->pool = NULL;"); + SOURCE_CODE0 (" mrb->irep_len = idx;"); + SOURCE_CODE0 (" irep->plen = 0;"); if(irep->plen > 0) { SOURCE_CODE (" irep->pool = mrb_malloc(mrb, sizeof(mrb_value)*%d);", irep->plen); for (n=0; n<irep->plen; n++) { @@ -143,21 +150,21 @@ make_cdump_irep(mrb_state *mrb, int irep_no, FILE *f) str_len = str_format_len(irep->pool[n]) + 1; if ( str_len > buf_len ) { buf_len = str_len; - if ((buf = (char *)mrb_realloc(mrb, buf, buf_len)) == 0 ) { + if ((buf = (char *)mrb_realloc(mrb, buf, buf_len)) == NULL) { return MRB_CDUMP_GENERAL_FAILURE; } } memset(buf, 0, buf_len); - SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); break; + SOURCE_CODE(" irep->pool[%d] = mrb_str_new(mrb, \"%s\", %d);", n, str_to_format(irep->pool[n], buf), RSTRING_LEN(irep->pool[n])); + SOURCE_CODE0 (" mrb->arena_idx = ai;"); + break; /* TODO MRB_TT_REGEX */ default: break; } + SOURCE_CODE0(" irep->plen++;"); } } else - SOURCE_CODE0 (" irep->pool = NULL;"); - SOURCE_CODE0 (" mrb->irep_len = idx;"); - SOURCE_CODE0 (" mrb->arena_idx = ai;"); SOURCE_CODE0(""); return MRB_CDUMP_OK; } @@ -167,7 +174,7 @@ mrb_cdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) { int irep_no, irep_num; - if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0) + if (mrb == NULL || n < 0 || n >= mrb->irep_len || f == NULL || initname == NULL) return -1; irep_num = mrb->irep_len - n; diff --git a/src/class.c b/src/class.c index fad476929..3e54afede 100644 --- a/src/class.c +++ b/src/class.c @@ -171,11 +171,11 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id c = mrb_class_ptr(v); if (!mrb_nil_p(super)) { if (mrb_type(super) != MRB_TT_CLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); } if (!c->super || mrb_class_ptr(super) != mrb_class_real(c->super)) { - mrb_raise(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %s", mrb_sym2name(mrb, id)); } } @@ -184,7 +184,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id if (!mrb_nil_p(super)) { if (mrb_type(super) != MRB_TT_CLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, super)); } s = mrb_class_ptr(super); } @@ -205,7 +205,7 @@ class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); if (mrb_type(c) != MRB_TT_MODULE && mrb_type(c) != MRB_TT_CLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "%s is not a class/module", mrb_sym2name(mrb, id)); + mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a class/module", mrb_sym2name(mrb, id)); } return mrb_class_ptr(c); } @@ -318,7 +318,7 @@ check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const tmp = mrb_check_convert_type(mrb, val, t, c, m); if (mrb_nil_p(tmp)) { - mrb_raise(mrb, E_TYPE_ERROR, "expected %s", c); + mrb_raisef(mrb, E_TYPE_ERROR, "expected %s", c); } return tmp; } @@ -618,7 +618,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } break; default: - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalide argument specifier %c", c); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalide argument specifier %c", c); break; } } @@ -786,6 +786,8 @@ mrb_singleton_class(mrb_state *mrb, mrb_value v) return mrb_obj_value(mrb->false_class); case MRB_TT_TRUE: return mrb_obj_value(mrb->true_class); + case MRB_TT_MAIN: + return mrb_obj_value(mrb->object_class); case MRB_TT_SYMBOL: case MRB_TT_FIXNUM: case MRB_TT_FLOAT: @@ -850,7 +852,9 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) m = mrb_method_search_vm(mrb, &c, mid); if (!m) { - mrb_raise(mrb, E_NOMETHOD_ERROR, "no method named %s\n", mrb_sym2name(mrb, mid)); + mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%s' for class %s", + mrb_sym2name(mrb, mid), + RSTRING_PTR(mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0))); } return m; } @@ -1006,7 +1010,9 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod) if (!SYMBOL_P(name)) { mrb_raise(mrb, E_TYPE_ERROR, "name should be a symbol"); } - mrb_raise(mrb, E_NOMETHOD_ERROR, "no method named %s", mrb_sym2name(mrb, mrb_symbol(name))); + mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%s' for %s", + mrb_sym2name(mrb, mrb_symbol(name)), + RSTRING_PTR(mrb_funcall(mrb, mod, "inspect", 0))); /* not reached */ return mrb_nil_value(); } @@ -1103,7 +1109,7 @@ void mrb_check_inheritable(mrb_state *mrb, struct RClass *super) { if (super->tt != MRB_TT_CLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", + mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%s given)", mrb_obj_classname(mrb, mrb_obj_value(super))); } if (super->tt == MRB_TT_SCLASS) { @@ -1321,7 +1327,7 @@ mrb_sym_value(mrb_state *mrb, mrb_value val) } else if(mrb_type(val) != MRB_TT_SYMBOL) { mrb_value obj = mrb_funcall(mrb, val, "inspect", 0); - mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol", + mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol", mrb_string_value_ptr(mrb, obj)); } return mrb_symbol(val); diff --git a/src/codegen.c b/src/codegen.c index 50d3e3d3b..ca2269d85 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -170,6 +170,10 @@ genop_peep(codegen_scope *s, mrb_code i, int val) switch (c1) { case OP_MOVE: + if (GETARG_A(i) == GETARG_B(i)) { + /* skip useless OP_MOVE */ + return; + } if (val) break; switch (c0) { case OP_MOVE: @@ -267,6 +271,8 @@ genop_peep(codegen_scope *s, mrb_code i, int val) break; case OP_RETURN: switch (c0) { + case OP_RETURN: + return; case OP_MOVE: s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); return; @@ -447,7 +453,10 @@ new_sym(codegen_scope *s, mrb_sym sym) } if (s->slen > 125 && s->slen < 256) { s->syms = (mrb_sym *)codegen_realloc(s, s->syms, sizeof(mrb_sym)*65536); - memset(s->syms+s->slen, 0, sizeof(mrb_sym)*(256-s->slen)); + for (i = 0; i < 256 - s->slen; i++) { + static const mrb_sym mrb_sym_zero = { 0 }; + s->syms[i + s->slen] = mrb_sym_zero; + } s->slen = 256; } s->syms[s->slen] = sym; @@ -847,8 +856,11 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val) case NODE_CALL: push(); - gen_call(s, node, attrsym(s, sym(node->cdr->car)), sp, val); - val = NOVAL; /* push should have done in gen_call() */ + gen_call(s, node, attrsym(s, sym(node->cdr->car)), sp, NOVAL); + pop(); + if (val) { + genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val); + } break; default: @@ -911,7 +923,7 @@ raise_error(codegen_scope *s, const char *msg) { int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); - genop(s, MKOP_ABx(OP_ERR, 0, idx)); + genop(s, MKOP_ABx(OP_ERR, 1, idx)); } static double @@ -951,6 +963,10 @@ codegen(codegen_scope *s, node *tree, int val) tree = tree->cdr; switch (nt) { case NODE_BEGIN: + if (val && !tree) { + genop(s, MKOP_A(OP_LOADNIL, cursp())); + push(); + } while (tree) { codegen(s, tree->car, tree->cdr ? NOVAL : val); tree = tree->cdr; @@ -968,6 +984,7 @@ codegen(codegen_scope *s, node *tree, int val) lp->pc1 = onerr; if (tree->car) { codegen(s, tree->car, val); + if (val) pop(); } lp->type = LOOP_RESCUE; noexc = new_label(s); @@ -1200,17 +1217,17 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_sBx(OP_JMP, 0)); dispatch_linked(s, pos2); } - pop(); + pop(); /* pop HEAD */ codegen(s, tree->car->cdr, val); - pop(); + if (val) pop(); tmp = new_label(s); genop(s, MKOP_sBx(OP_JMP, pos3)); pos3 = tmp; if (pos1) dispatch(s, pos1); tree = tree->cdr; - push(); + push(); /* push HEAD */ } - pop(); + pop(); /* pop HEAD */ genop(s, MKOP_A(OP_LOADNIL, cursp())); if (val) push(); if (pos3) dispatch_linked(s, pos3); @@ -1396,6 +1413,7 @@ codegen(codegen_scope *s, node *tree, int val) codegen(s, tree->cdr->cdr->car, VAL); pop(); gen_assignment(s, tree->car, cursp(), val); + if (val) pop(); dispatch(s, pos); break; } @@ -1490,6 +1508,7 @@ codegen(codegen_scope *s, node *tree, int val) else { genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); } + push(); break; case NODE_YIELD: @@ -1537,8 +1556,10 @@ codegen(codegen_scope *s, node *tree, int val) genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc)); } else { - codegen(s, tree, VAL); - pop(); + if (tree) { + codegen(s, tree, VAL); + pop(); + } genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); } if (val) push(); @@ -1722,7 +1743,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FLOAT: if (val) { char *p = (char*)tree; - mrb_float f = readfloat(p); + mrb_float f = str_to_mrb_float(p); int off = new_lit(s, mrb_float_value(f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); @@ -1738,7 +1759,7 @@ codegen(codegen_scope *s, node *tree, int val) case NODE_FLOAT: { char *p = (char*)tree; - mrb_float f = readfloat(p); + mrb_float f = str_to_mrb_float(p); int off = new_lit(s, mrb_float_value(-f)); genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); @@ -2033,11 +2054,12 @@ codegen(codegen_scope *s, node *tree, int val) static codegen_scope* scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) { + static const codegen_scope codegen_scope_zero = { 0 }; mrb_pool *pool = mrb_pool_open(mrb); codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope)); if (!p) return 0; - memset(p, 0, sizeof(codegen_scope)); + *p = codegen_scope_zero; p->mrb = mrb; p->mpool = pool; if (!prev) return p; @@ -2055,7 +2077,7 @@ scope_new(mrb_state *mrb, codegen_scope *prev, node *lv) p->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*256); p->lv = lv; - p->sp += node_len(lv)+2; + p->sp += node_len(lv)+1; /* add self */ p->nlocals = p->sp; p->ai = mrb->arena_idx; @@ -2141,6 +2163,9 @@ loop_break(codegen_scope *s, node *tree) genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); loop = loop->prev; } + while (loop->type == LOOP_RESCUE) { + loop = loop->prev; + } if (loop->type == LOOP_NORMAL) { int tmp; diff --git a/src/dump.c b/src/dump.c index 516374cd9..241c97a43 100644 --- a/src/dump.c +++ b/src/dump.c @@ -6,6 +6,7 @@ #include <string.h> #include "mruby/dump.h" +#include <ctype.h> #include "mruby/string.h" #ifdef ENABLE_REGEXP @@ -76,7 +77,7 @@ static int mrb_write_irep(mrb_state*,int,char*); static inline int -uint8_dump(unsigned char bin, char *hex, int type) +uint8_dump(uint8_t bin, char *hex, int type) { if (type == DUMP_TYPE_BIN) { *hex = bin; @@ -84,7 +85,7 @@ uint8_dump(unsigned char bin, char *hex, int type) *hex++ = bin2hex[(bin >> 4) & 0x0f]; *hex = bin2hex[bin & 0x0f]; } - return DUMP_SIZE(sizeof(char), type); + return DUMP_SIZE(MRB_DUMP_SIZE_OF_CHAR, type); } static inline int @@ -119,13 +120,16 @@ uint32_dump(uint32_t bin, char *hex, int type) } } +#define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ + static char* str_dump(char *str, char *hex, uint16_t len, int type) { if (type == DUMP_TYPE_BIN) memcpy(hex, str, len); else { - char *src, *dst; + char *src, *dst, buf[CHAR_ESC_LEN + 1]; + int n; for (src = str, dst = hex; len > 0; src++, dst++, len--) { switch (*src) { @@ -136,11 +140,19 @@ str_dump(char *str, char *hex, uint16_t len, int type) case 0x0B:/* VT */ *dst++ = '\\'; *dst = 'v'; break; case 0x0C:/* FF */ *dst++ = '\\'; *dst = 'f'; break; case 0x0D:/* CR */ *dst++ = '\\'; *dst = 'r'; break; + case 0x5C:/* \ */ *dst++ = '\\'; *dst = '\\'; break; case 0x22:/* " */ /* fall through */ case 0x27:/* ' */ /* fall through */ // case 0x3F:/* ? */ /* fall through */ - case 0x5C:/* \ */ /* fall through */ - default: *dst = *src; break; + default: + if (*src >= ' ' && *src <= '~') { + *dst = *src; + } else { + n = sprintf(buf, "\\%03o", *src & 0377); + memcpy(dst, buf, n); + dst += (n-1); + } + break; } } } @@ -167,15 +179,21 @@ str_dump_len(char *str, uint16_t len, int type) case 0x0B:/* VT */ /* fall through */ case 0x0C:/* FF */ /* fall through */ case 0x0D:/* CR */ /* fall through */ + case 0x5C:/* \ */ /* fall through */ dump_len += 2; break; case 0x22:/* " */ /* fall through */ case 0x27:/* ' */ /* fall through */ // case 0x3F:/* ? */ /* fall through */ - case 0x5C:/* \ */ /* fall through */ default: - dump_len++; break; + if (*src >= ' ' && *src <= '~') { + dump_len++; + } else { + // dump_len += sprintf(buf, "\\%03o", *src & 0377); + dump_len += 4; + } + break; } } } @@ -188,7 +206,7 @@ get_irep_header_size(mrb_state *mrb, mrb_irep *irep, int type) { uint32_t size = 0; - size += sizeof(char) * 2; + size += 2; size += DUMP_SIZE(MRB_DUMP_SIZE_OF_SHORT, type) * 4; return size; @@ -215,7 +233,7 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) char buf[32]; size += MRB_DUMP_SIZE_OF_LONG; /* plen */ - size += irep->plen * sizeof(char); /* tt(n) */ + size += irep->plen; /* tt(n) */ size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */ size += MRB_DUMP_SIZE_OF_SHORT; /* crc */ size = DUMP_SIZE(size, type); @@ -226,11 +244,11 @@ get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - len = sprintf( buf, "%d", mrb_fixnum(irep->pool[pool_no])); + len = mrb_int_to_str( buf, mrb_fixnum(irep->pool[pool_no])); size += (uint32_t)len; break; case MRB_TT_FLOAT: - len = sprintf( buf, "%.16e", mrb_float(irep->pool[pool_no])); + len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no])); size += (uint32_t)len; break; case MRB_TT_STRING: @@ -335,7 +353,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) uint16_t len =0; buf_size = MRB_DUMP_DEFAULT_STR_LEN; - if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0) + if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == NULL) goto error_exit; buf += uint32_dump((uint32_t)irep->plen, buf, type); /* number of pool */ @@ -346,19 +364,19 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) switch (mrb_type(irep->pool[pool_no])) { case MRB_TT_FIXNUM: - len = sprintf(char_buf, "%d", mrb_fixnum(irep->pool[pool_no])); + len = mrb_int_to_str(char_buf, mrb_fixnum(irep->pool[pool_no])); break; case MRB_TT_FLOAT: - len = sprintf(char_buf, "%.16e", mrb_float(irep->pool[pool_no])); + len = mrb_float_to_str(char_buf, mrb_float(irep->pool[pool_no])); break; case MRB_TT_STRING: - str = mrb_string_value( mrb, &irep->pool[pool_no]); + str = irep->pool[pool_no]; len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type); - if ( len > buf_size - 1) { + if (len > buf_size - 1) { buf_size = len + 1; - if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0) + if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == NULL) goto error_exit; memset(char_buf, 0, buf_size); } @@ -371,7 +389,7 @@ write_pool_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) len = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type); if ( len > buf_size - 1) { buf_size = len + 1; - if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == 0) + if ((char_buf = mrb_realloc(mrb, char_buf, buf_size)) == NULL) goto error_exit; memset(char_buf, 0, buf_size); } @@ -405,7 +423,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) uint16_t buf_size =0; buf_size = MRB_DUMP_DEFAULT_STR_LEN; - if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0) + if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == NULL) goto error_exit; buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */ @@ -421,7 +439,7 @@ write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) nlen = str_dump_len((char*)name, len, type); if ( nlen > buf_size - 1) { buf_size = nlen + 1; - if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0) + if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == NULL) goto error_exit; } memset(char_buf, 0, buf_size); @@ -457,7 +475,7 @@ calc_crc_section(mrb_state *mrb, mrb_irep *irep, uint16_t *crc, int section) default: return MRB_DUMP_GENERAL_FAILURE; } - if ((buf = (char *)mrb_calloc(mrb, 1, buf_size)) == 0) + if ((buf = (char *)mrb_calloc(mrb, 1, buf_size)) == NULL) return MRB_DUMP_GENERAL_FAILURE; buf_top = buf; @@ -542,7 +560,7 @@ write_irep_record(mrb_state *mrb, int irep_no, char* bin, uint32_t *rlen, int ty mrb_irep *irep = mrb->irep[irep_no]; int section; - if (irep == 0) + if (irep == NULL) return MRB_DUMP_INVALID_IREP; /* buf alloc */ @@ -586,7 +604,7 @@ dump_irep_record(mrb_state *mrb, int irep_no, FILE* fp, uint32_t *rlen) char *buf; mrb_irep *irep = mrb->irep[irep_no]; - if (irep == 0) + if (irep == NULL) return MRB_DUMP_INVALID_IREP; /* buf alloc */ @@ -594,7 +612,7 @@ 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 = (char *)mrb_calloc(mrb, 1, irep_record_size)) == 0) + if ((buf = (char *)mrb_calloc(mrb, 1, irep_record_size)) == NULL) return MRB_DUMP_GENERAL_FAILURE; if ((rc = write_irep_record(mrb, irep_no, buf, rlen, DUMP_TYPE_HEX)) != MRB_DUMP_OK) { @@ -620,7 +638,7 @@ mrb_write_irep(mrb_state *mrb, int top, char *bin) int irep_no; char *bin_top; - if (mrb == 0 || top < 0 || top >= mrb->irep_len || bin == 0) + if (mrb == NULL || top < 0 || top >= mrb->irep_len || bin == NULL) return MRB_DUMP_INVALID_ARGUMENT; bin_top = bin; @@ -648,7 +666,7 @@ mrb_dump_irep(mrb_state *mrb, int top, FILE* fp) uint32_t rlen=0; /* size of irep record */ int irep_no; - if (mrb == 0 || top < 0 || top >= mrb->irep_len || fp == 0) + if (mrb == NULL || top < 0 || top >= mrb->irep_len || fp == NULL) return MRB_DUMP_INVALID_ARGUMENT; if (fwrite(&def_rite_file_header, sizeof(rite_file_header), 1, fp) != 1) /* dummy write */ @@ -678,7 +696,7 @@ mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) int buf_size = 0; int buf_idx = 0; - if (mrb == 0 || n < 0 || n >= mrb->irep_len || f == 0 || initname == 0) + if (mrb == NULL || n < 0 || n >= mrb->irep_len || f == NULL || initname == NULL) return -1; buf_size = sizeof(rite_binary_header) + MRB_DUMP_SIZE_OF_SHORT/* crc */; @@ -686,7 +704,7 @@ mrb_bdump_irep(mrb_state *mrb, int n, FILE *f,const char *initname) buf_size += get_irep_record_size(mrb, irep_no, DUMP_TYPE_BIN); buf_size += MRB_DUMP_SIZE_OF_LONG; /* end of file */ - if ((buf = (char *)mrb_malloc(mrb, buf_size)) == 0) + if ((buf = (char *)mrb_malloc(mrb, buf_size)) == NULL) return MRB_DUMP_GENERAL_FAILURE; rc = mrb_write_irep(mrb, n, buf); diff --git a/src/error.c b/src/error.c index 1f352c853..858c70820 100644 --- a/src/error.c +++ b/src/error.c @@ -208,16 +208,24 @@ exc_debug_info(mrb_state *mrb, struct RObject *exc) void mrb_exc_raise(mrb_state *mrb, mrb_value exc) { - mrb->exc = (struct RObject*)mrb_object(exc); - exc_debug_info(mrb, mrb->exc); - if (!mrb->jmp) { - abort(); - } - longjmp(*(jmp_buf*)mrb->jmp, 1); + mrb->exc = (struct RObject*)mrb_object(exc); + exc_debug_info(mrb, mrb->exc); + if (!mrb->jmp) { + abort(); + } + longjmp(*(jmp_buf*)mrb->jmp, 1); +} + +void +mrb_raise(mrb_state *mrb, struct RClass *c, const char *msg) +{ + mrb_value mesg; + mesg = mrb_str_new2(mrb, msg); + mrb_exc_raise(mrb, mrb_exc_new3(mrb, c, mesg)); } void -mrb_raise(mrb_state *mrb, struct RClass *c, const char *fmt, ...) +mrb_raisef(mrb_state *mrb, struct RClass *c, const char *fmt, ...) { va_list args; char buf[256]; @@ -369,7 +377,7 @@ exception_call: break; default: - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..3)", argc); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 0..3)", argc); break; } if (argc > 0) { @@ -391,7 +399,7 @@ mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv) void mrb_sys_fail(mrb_state *mrb, const char *mesg) { - mrb_raise(mrb, E_RUNTIME_ERROR, "%s", mesg); + mrb_raise(mrb, E_RUNTIME_ERROR, mesg); } void @@ -44,7 +44,7 @@ mrb_check_datatype(mrb_state *mrb, mrb_value obj, const struct mrb_data_type *ty } if (DATA_TYPE(obj) != type) { const char *etype = DATA_TYPE(obj)->struct_name; - mrb_raise(mrb, E_TYPE_ERROR, mesg, etype, type->struct_name); + mrb_raisef(mrb, E_TYPE_ERROR, mesg, etype, type->struct_name); } return DATA_PTR(obj); } @@ -94,7 +94,7 @@ mrb_to_id(mrb_state *mrb, mrb_value name) tmp = mrb_check_string_type(mrb, name); if (mrb_nil_p(tmp)) { tmp = mrb_inspect(mrb, name); - mrb_raise(mrb, E_TYPE_ERROR, "%s is not a symbol", + mrb_raisef(mrb, E_TYPE_ERROR, "%s is not a symbol", RSTRING_PTR(tmp)); } name = tmp; @@ -326,6 +326,7 @@ struct RBasic* mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) { struct RBasic *p; + static const RVALUE RVALUE_zero = { { { 0 } } }; #ifdef MRB_GC_STRESS mrb_garbage_collect(mrb); @@ -345,7 +346,7 @@ mrb_obj_alloc(mrb_state *mrb, enum mrb_vtype ttype, struct RClass *cls) mrb->live++; gc_protect(mrb, p); - memset(p, 0, sizeof(RVALUE)); + *(RVALUE *)p = RVALUE_zero; p->tt = ttype; p->c = cls; paint_partial_white(mrb, p); diff --git a/src/hash.c b/src/hash.c index 92dfff186..51f85f4e8 100644 --- a/src/hash.c +++ b/src/hash.c @@ -970,9 +970,10 @@ mrb_hash_keys(mrb_state *mrb, mrb_value hash) { khash_t(ht) *h = RHASH_TBL(hash); khiter_t k; - mrb_value ary = mrb_ary_new_capa(mrb, kh_size(h)); + mrb_value ary; - if (!h) return ary; + if (!h) return mrb_ary_new(mrb); + ary = mrb_ary_new_capa(mrb, kh_size(h)); for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)) { mrb_value v = kh_key(h,k); @@ -1000,9 +1001,10 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash) { khash_t(ht) *h = RHASH_TBL(hash); khiter_t k; - mrb_value ary = mrb_ary_new_capa(mrb, kh_size(h)); + mrb_value ary; - if (!h) return ary; + if (!h) return mrb_ary_new(mrb); + ary = mrb_ary_new_capa(mrb, kh_size(h)); for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)){ mrb_value v = kh_value(h,k); diff --git a/src/kernel.c b/src/kernel.c index 5139762b7..050dd73bc 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -61,9 +61,6 @@ mrb_obj_inspect(mrb_state *mrb, mrb_value obj) if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); } - else if (mrb_nil_p(obj)) { - return mrb_str_new(mrb, "nil", 3); - } else if (mrb_type(obj) == MRB_TT_MAIN) { return mrb_str_new(mrb, "main", 4); } @@ -238,6 +235,12 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) bp = mrb->stbase + ci->stackidx + 1; ci--; if (ci <= mrb->cibase) return mrb_false_value(); + /* block_given? called within block; check upper scope */ + if (ci->proc->env && ci->proc->env->stack) { + if (ci->proc->env->stack == mrb->stbase || mrb_nil_p(ci->proc->env->stack[1])) + return mrb_false_value(); + return mrb_true_value(); + } if (ci->argc > 0) { bp += ci->argc; } @@ -345,7 +348,7 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self) struct RObject *clone; if (mrb_special_const_p(self)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't clone %s", mrb_obj_classname(mrb, self)); + mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %s", mrb_obj_classname(mrb, self)); } clone = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); clone->c = mrb_singleton_class_clone(mrb, self); @@ -380,7 +383,7 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj) mrb_value dup; if (mrb_special_const_p(obj)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj)); + mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj)); } p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); dup = mrb_obj_value(p); diff --git a/src/load.c b/src/load.c index 6c7396407..65b6004d3 100644 --- a/src/load.c +++ b/src/load.c @@ -143,7 +143,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_ uint16_t buf_size =0; buf_size = MRB_DUMP_DEFAULT_STR_LEN; - if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == 0) + if ((char_buf = (char *)mrb_malloc(mrb, buf_size)) == NULL) goto error_exit; pStart = dst; @@ -192,7 +192,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_ if ( pdl > buf_size - 1) { buf_size = pdl + 1; - if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0) + if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == NULL) goto error_exit; } memset(char_buf, '\0', buf_size); @@ -219,7 +219,7 @@ load_rite_irep_record(mrb_state *mrb, RiteFILE* rfp, unsigned char* dst, uint32_ if ( snl > buf_size - 1) { buf_size = snl + 1; - if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == 0) + if ((char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size)) == NULL) goto error_exit; } memset(char_buf, '\0', buf_size); @@ -267,7 +267,7 @@ mrb_load_irep(mrb_state *mrb, FILE* fp) dst = rite_dst; memset(dst, 0x00, len); - memcpy(dst, &bin_header, sizeof(rite_binary_header)); + *(rite_binary_header *)dst = bin_header; dst += sizeof(rite_binary_header); dst += hex_to_bin16(dst, hcrc); @@ -302,7 +302,7 @@ read_rite_header(mrb_state *mrb, unsigned char *bin, rite_binary_header* bin_he { uint16_t crc; - memcpy(bin_header, bin, sizeof(rite_binary_header)); + *bin_header = *(rite_binary_header *)bin; bin += sizeof(rite_binary_header); if (memcmp(bin_header->rbfi, RITE_FILE_IDENFIFIER, sizeof(bin_header->rbfi)) != 0) { return MRB_DUMP_INVALID_FILE_HEADER; //File identifier error @@ -405,12 +405,12 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32 switch (tt) { //pool data case MRB_TT_FIXNUM: - fix_num = strtol(buf, NULL, 10); + fix_num = str_to_mrb_int(buf); irep->pool[i] = mrb_fixnum_value(fix_num); break; case MRB_TT_FLOAT: - f = readfloat(buf); + f = str_to_mrb_float(buf); irep->pool[i] = mrb_float_value(f); break; @@ -448,7 +448,10 @@ read_rite_irep_record(mrb_state *mrb, unsigned char *src, mrb_irep *irep, uint32 goto error_exit; } - memset(irep->syms, 0, sizeof(mrb_sym)*(irep->slen)); + for (i = 0; i < irep->slen; i++) { + static const mrb_sym mrb_sym_zero = { 0 }; + *irep->syms = mrb_sym_zero; + } for (i=0; i<irep->slen; i++) { snl = bin_to_uint16(src); //symbol name length src += MRB_DUMP_SIZE_OF_SHORT; @@ -509,11 +512,12 @@ mrb_read_irep(mrb_state *mrb, const char *bin) mrb_add_irep(mrb, sirep + nirep); for (n=0,i=sirep; n<nirep; n++,i++) { + static const mrb_irep mrb_irep_zero = { 0 }; if ((mrb->irep[i] = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep))) == NULL) { ret = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } - memset(mrb->irep[i], 0, sizeof(mrb_irep)); + *mrb->irep[i] = mrb_irep_zero; } src += sizeof(bin_header) + MRB_DUMP_SIZE_OF_SHORT; //header + crc @@ -607,8 +611,8 @@ hex_to_uint32(unsigned char *hex) static char* hex_to_str(char *hex, char *str, uint16_t *str_len) { - char *src, *dst; - int escape = 0; + char *src, *dst, buf[4]; + int escape = 0, base = 0; *str_len = 0; for (src = hex, dst = str; *src != '\0'; src++) { @@ -625,7 +629,20 @@ hex_to_str(char *hex, char *str, uint16_t *str_len) case '\'': /* fall through */ case '\?': /* fall through */ case '\\': *dst++ = *src; break; - default:break; + default: + if (*src >= '0' && *src <= '7') { + base = 8; + strncpy(buf, src, 3); + } else if (*src == 'x' || *src == 'X') { + base = 16; + src++; + strncpy(buf, src, 2); + } + + char *err_ptr; + *dst++ = (unsigned char) strtol(buf, &err_ptr, base) & 0xff; + src += (err_ptr - buf - 1); + break; } escape = 0; } else { diff --git a/src/numeric.c b/src/numeric.c index acc658e5c..c1491ac51 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -245,6 +245,11 @@ flodivmod(mrb_state *mrb, mrb_float x, mrb_float y, mrb_float *divp, mrb_float * { mrb_float div, mod; + if (y == 0.0) { + *divp = str_to_mrb_float("inf"); + *modp = str_to_mrb_float("nan"); + return; + } mod = fmod(x, y); if (isinf(x) && !isinf(y) && !isnan(y)) div = x; @@ -772,6 +777,9 @@ fix_mod(mrb_state *mrb, mrb_value x) if (FIXNUM_P(y) && (b=mrb_fixnum(y)) != 0) { mrb_int mod; + if (mrb_fixnum(y) == 0) { + return mrb_float_value(str_to_mrb_float("nan")); + } fixdivmod(mrb, a, mrb_fixnum(y), 0, &mod); return mrb_fixnum_value(mod); } @@ -798,6 +806,10 @@ fix_divmod(mrb_state *mrb, mrb_value x) if (FIXNUM_P(y)) { mrb_int div, mod; + if (mrb_fixnum(y) == 0) { + return mrb_assoc_new(mrb, mrb_float_value(str_to_mrb_float("inf")), + mrb_float_value(str_to_mrb_float("nan"))); + } fixdivmod(mrb, mrb_fixnum(x), mrb_fixnum(y), &div, &mod); return mrb_assoc_new(mrb, mrb_fixnum_value(div), mrb_fixnum_value(mod)); } @@ -937,9 +949,8 @@ fix_xor(mrb_state *mrb, mrb_value x) static mrb_value lshift(mrb_state *mrb, mrb_int val, unsigned long width) { - if (width > (sizeof(mrb_int)*CHAR_BIT-1) - || ((unsigned long)abs(val))>>(sizeof(mrb_int)*CHAR_BIT-1-width) > 0) { - mrb_raise(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width, + if (width > (sizeof(mrb_int)*CHAR_BIT-1)) { + mrb_raisef(mrb, E_RANGE_ERROR, "width(%d) > (%d:sizeof(mrb_int)*CHAR_BIT-1)", width, sizeof(mrb_int)*CHAR_BIT-1); } val = val << width; @@ -1153,7 +1164,7 @@ mrb_fix2str(mrb_state *mrb, mrb_value x, int base) int neg = 0; if (base < 2 || 36 < base) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); } if (val == 0) { return mrb_str_new(mrb, "0", 1); diff --git a/src/object.c b/src/object.c index 5130f3d54..a23e397f6 100644 --- a/src/object.c +++ b/src/object.c @@ -82,7 +82,13 @@ mrb_true(mrb_state *mrb, mrb_value obj) static mrb_value nil_to_s(mrb_state *mrb, mrb_value obj) { - return mrb_str_new(mrb, 0, 0); + return mrb_str_new(mrb, 0, 0); +} + +static mrb_value +nil_inspect(mrb_state *mrb, mrb_value obj) +{ + return mrb_str_new(mrb, "nil", 3); } /*********************************************************************** @@ -272,6 +278,7 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, n, "|", false_or, ARGS_REQ(1)); /* 15.2.4.3.3 */ mrb_define_method(mrb, n, "nil?", mrb_true, ARGS_NONE()); /* 15.2.4.3.4 */ mrb_define_method(mrb, n, "to_s", nil_to_s, ARGS_NONE()); /* 15.2.4.3.5 */ + mrb_define_method(mrb, n, "inspect", nil_inspect, ARGS_NONE()); t = mrb->true_class = mrb_define_class(mrb, "TrueClass", mrb->object_class); mrb_undef_class_method(mrb, t, "new"); @@ -279,6 +286,7 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, t, "^", true_xor, ARGS_REQ(1)); /* 15.2.5.3.2 */ mrb_define_method(mrb, t, "to_s", true_to_s, ARGS_NONE()); /* 15.2.5.3.3 */ mrb_define_method(mrb, t, "|", true_or, ARGS_REQ(1)); /* 15.2.5.3.4 */ + mrb_define_method(mrb, t, "inspect", true_to_s, ARGS_NONE()); f = mrb->false_class = mrb_define_class(mrb, "FalseClass", mrb->object_class); mrb_undef_class_method(mrb, f, "new"); @@ -286,6 +294,7 @@ mrb_init_object(mrb_state *mrb) mrb_define_method(mrb, f, "^", false_xor, ARGS_REQ(1)); /* 15.2.6.3.2 */ mrb_define_method(mrb, f, "to_s", false_to_s, ARGS_NONE()); /* 15.2.6.3.3 */ mrb_define_method(mrb, f, "|", false_or, ARGS_REQ(1)); /* 15.2.6.3.4 */ + mrb_define_method(mrb, f, "inspect", false_to_s, ARGS_NONE()); } static mrb_value @@ -296,7 +305,7 @@ convert_type(mrb_state *mrb, mrb_value val, const char *tname, const char *metho m = mrb_intern(mrb, method); if (!mrb_respond_to(mrb, val, m)) { if (raise) { - mrb_raise(mrb, E_TYPE_ERROR, "can't convert %s into %s", + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s into %s", mrb_nil_p(val) ? "nil" : (mrb_type(val) == MRB_TT_TRUE) ? "true" : (mrb_type(val) == MRB_TT_FALSE) ? "false" : @@ -332,7 +341,7 @@ mrb_convert_type(mrb_state *mrb, mrb_value val, mrb_int type, const char *tname, if (mrb_type(val) == type) return val; v = convert_type(mrb, val, tname, method, 1/*Qtrue*/); if (mrb_type(v) != type) { - mrb_raise(mrb, E_TYPE_ERROR, "%s cannot be converted to %s by #%s", + mrb_raisef(mrb, E_TYPE_ERROR, "%s cannot be converted to %s by #%s", mrb_obj_classname(mrb, val), tname, method); } return v; @@ -410,12 +419,12 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) else { etype = mrb_obj_classname(mrb, x); } - mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", + mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)", etype, type->name); } type++; } - mrb_raise(mrb, E_TYPE_ERROR, "unknown type 0x%x (0x%x given)", t, mrb_type(x)); + mrb_raisef(mrb, E_TYPE_ERROR, "unknown type 0x%x (0x%x given)", t, mrb_type(x)); } } @@ -504,7 +513,7 @@ mrb_to_integer(mrb_state *mrb, mrb_value val, const char *method) v = convert_type(mrb, val, "Integer", method, TRUE); if (!mrb_obj_is_kind_of(mrb, v, mrb->fixnum_class)) { const char *cname = mrb_obj_classname(mrb, val); - mrb_raise(mrb, E_TYPE_ERROR, "can't convert %s to Integer (%s#%s gives %s)", + mrb_raisef(mrb, E_TYPE_ERROR, "can't convert %s to Integer (%s#%s gives %s)", cname, cname, method, mrb_obj_classname(mrb, v)); } return v; diff --git a/src/parse.y b/src/parse.y index af12112c7..cffb6ba09 100644 --- a/src/parse.y +++ b/src/parse.y @@ -3329,7 +3329,7 @@ read_escape(parser_state *p) break; } } - c = scan_hex(buf, i+1, &i); + c = scan_hex(buf, i, &i); if (i == 0) { yyerror(p, "Invalid escape character syntax"); return 0; @@ -4747,13 +4747,14 @@ mrb_parser_new(mrb_state *mrb) { mrb_pool *pool; parser_state *p; + static const parser_state parser_state_zero = { 0 }; pool = mrb_pool_open(mrb); if (!pool) return 0; p = (parser_state *)mrb_pool_alloc(pool, sizeof(parser_state)); if (!p) return 0; - memset(p, 0, sizeof(parser_state)); + *p = parser_state_zero; p->mrb = mrb; p->pool = pool; p->in_def = p->in_single = 0; diff --git a/src/proc.c b/src/proc.c index 0efc8d286..07834e86d 100644 --- a/src/proc.c +++ b/src/proc.c @@ -9,6 +9,10 @@ #include "mruby/class.h" #include "opcode.h" +static mrb_code call_iseq[] = { + MKOP_A(OP_CALL, 0), +}; + struct RProc * mrb_proc_new(mrb_state *mrb, mrb_irep *irep) { @@ -144,14 +148,14 @@ void mrb_init_proc(mrb_state *mrb) { struct RProc *m; - mrb_code *call_iseq = (mrb_code *)mrb_alloca(mrb, sizeof(mrb_code)); mrb_irep *call_irep = (mrb_irep *)mrb_alloca(mrb, sizeof(mrb_irep)); + static const mrb_irep mrb_irep_zero = { 0 }; if ( call_iseq == NULL || call_irep == NULL ) return; - memset(call_irep, 0, sizeof(mrb_irep)); - *call_iseq = MKOP_A(OP_CALL, 0); + *call_irep = mrb_irep_zero; + call_irep->flags = MRB_ISEQ_NO_FREE; call_irep->idx = -1; call_irep->iseq = call_iseq; call_irep->ilen = 1; diff --git a/src/range.c b/src/range.c index 98b9093ef..6fe7964fe 100644 --- a/src/range.c +++ b/src/range.c @@ -296,7 +296,7 @@ mrb_range_beg_len(mrb_state *mrb, mrb_value range, mrb_int *begp, mrb_int *lenp, out_of_range: if (err) { - mrb_raise(mrb, E_RANGE_ERROR, "%ld..%s%ld out of range", + mrb_raisef(mrb, E_RANGE_ERROR, "%ld..%s%ld out of range", b, r->excl? "." : "", e); } return OTHER; @@ -415,7 +415,7 @@ range_initialize_copy(mrb_state *mrb, mrb_value copy) if (!mrb_obj_is_instance_of(mrb, src, mrb_obj_class(mrb, copy))) { mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class"); } - memcpy(mrb_range_ptr(copy), mrb_range_ptr(src), sizeof(struct RRange)); + *mrb_range_ptr(copy) = *mrb_range_ptr(src); return copy; } diff --git a/src/sprintf.c b/src/sprintf.c index eccbff04d..2bd72ffc6 100644 --- a/src/sprintf.c +++ b/src/sprintf.c @@ -81,7 +81,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) char d; if (base != 2) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid radix %d", base); } if (val >= (1 << 10)) @@ -146,17 +146,17 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) #define GETARG() (!mrb_undef_p(nextvalue) ? nextvalue : \ posarg == -1 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with numbered", nextarg), mrb_undef_value()) : \ posarg == -2 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "unnumbered(%d) mixed with named", nextarg), mrb_undef_value()) : \ (posarg = nextarg++, GETNTHARG(posarg))) #define GETPOSARG(n) (posarg > 0 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "numbered(%d) after unnumbered(%d)", n, posarg), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%d) after unnumbered(%d)", n, posarg), mrb_undef_value()) : \ posarg == -2 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "numbered(%d) after named", n), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "numbered(%d) after named", n), mrb_undef_value()) : \ ((n < 1) ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid index - %d$", n), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid index - %d$", n), mrb_undef_value()) : \ (posarg = -1, GETNTHARG(n)))) #define GETNTHARG(nth) \ @@ -164,9 +164,9 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) #define GETNAMEARG(id, name, len) ( \ posarg > 0 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "named%.*s after unnumbered(%d)", (len), (name), posarg), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%.*s after unnumbered(%d)", (len), (name), posarg), mrb_undef_value()) : \ posarg == -1 ? \ - (mrb_raise(mrb, E_ARGUMENT_ERROR, "named%.*s after numbered", (len), (name)), mrb_undef_value()) : \ + (mrb_raisef(mrb, E_ARGUMENT_ERROR, "named%.*s after numbered", (len), (name)), mrb_undef_value()) : \ (posarg = -2, mrb_hash_fetch(mrb, get_hash(mrb, &hash, argc, argv), id, mrb_undef_value()))) #define GETNUM(n, val) \ @@ -178,7 +178,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) n = next_n; \ } \ if (p >= end) { \ - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %%*[0-9]"); \ + mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %*[0-9]"); \ } #define GETASTER(num) do { \ @@ -548,7 +548,7 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt) retry: switch (*p) { default: - mrb_raise(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "malformed format string - %%%c", *p); break; case ' ': @@ -587,7 +587,7 @@ retry: GETNUM(n, width); if (*p == '$') { if (!mrb_undef_p(nextvalue)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "value given twice - %d$", n); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "value given twice - %d$", n); } nextvalue = GETPOSARG(n); p++; @@ -607,14 +607,14 @@ retry: for (; p < end && *p != term; ) p++; if (id) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "name%.*s after <%s>", + mrb_raisef(mrb, E_ARGUMENT_ERROR, "name%.*s after <%s>", (int)(p - start + 1), start, mrb_sym2name(mrb, id)); } symname = mrb_str_new(mrb, start + 1, p - start - 1); id = mrb_intern_str(mrb, symname); nextvalue = GETNAMEARG(mrb_symbol_value(id), start, (int)(p - start + 1)); if (mrb_undef_p(nextvalue)) { - mrb_raise(mrb, E_KEY_ERROR, "key%.*s not found", (int)(p - start + 1), start); + mrb_raisef(mrb, E_KEY_ERROR, "key%.*s not found", (int)(p - start + 1), start); } if (term == '}') goto format_s; p++; @@ -658,7 +658,7 @@ retry: case '%': if (flags != FNONE) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %%"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %"); } PUSH("%", 1); break; @@ -1052,7 +1052,7 @@ retry: */ if (posarg >= 0 && nextarg < argc) { const char *mesg = "too many arguments for format string"; - if (RTEST(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, "%s", mesg); + if (RTEST(ruby_debug)) mrb_raise(mrb, E_ARGUMENT_ERROR, mesg); if (RTEST(ruby_verbose)) mrb_warn("%s", mesg); } mrb_str_resize(mrb, result, blen); diff --git a/src/state.c b/src/state.c index 40d9bfc45..8bd222fb5 100644 --- a/src/state.c +++ b/src/state.c @@ -16,10 +16,11 @@ void mrb_init_ext(mrb_state*); mrb_state* mrb_open_allocf(mrb_allocf f, void *ud) { + static const mrb_state mrb_state_zero = { 0 }; mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); if (mrb == NULL) return NULL; - memset(mrb, 0, sizeof(mrb_state)); + *mrb = mrb_state_zero; mrb->ud = ud; mrb->allocf = f; mrb->current_white_part = MRB_GC_WHITE_A; @@ -92,7 +93,8 @@ mrb_close(mrb_state *mrb) mrb_free(mrb, mrb->stbase); mrb_free(mrb, mrb->cibase); for (i=0; i<mrb->irep_len; i++) { - mrb_free(mrb, mrb->irep[i]->iseq); + if (!(mrb->irep[i]->flags & MRB_ISEQ_NO_FREE)) + mrb_free(mrb, mrb->irep[i]->iseq); mrb_free(mrb, mrb->irep[i]->pool); mrb_free(mrb, mrb->irep[i]->syms); mrb_free(mrb, mrb->irep[i]->lines); @@ -118,12 +120,15 @@ mrb_add_irep(mrb_state *mrb, int idx) mrb->irep_capa = max; } else if (mrb->irep_capa <= idx) { + int i; size_t old_capa = mrb->irep_capa; while (mrb->irep_capa <= idx) { mrb->irep_capa *= 2; } mrb->irep = (mrb_irep **)mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep*)*mrb->irep_capa); - memset(mrb->irep + old_capa, 0, sizeof(mrb_irep*) * (mrb->irep_capa - old_capa)); + for (i = old_capa; i < mrb->irep_capa - old_capa; i++) { + mrb->irep[i] = NULL; + } } } diff --git a/src/string.c b/src/string.c index 57bbbc831..8eb08562d 100644 --- a/src/string.c +++ b/src/string.c @@ -840,7 +840,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) return mrb_str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2)); } if (argc != 1) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 1)", argc); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (%d for 1)", argc); } return mrb_str_aref(mrb, str, a1); } @@ -1525,7 +1525,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) tmp = mrb_check_string_type(mrb, sub); if (mrb_nil_p(tmp)) { - mrb_raise(mrb, E_TYPE_ERROR, "type mismatch: %s given", + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %s given", mrb_obj_classname(mrb, sub)); } sub = tmp; @@ -1931,7 +1931,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) tmp = mrb_check_string_type(mrb, sub); if (mrb_nil_p(tmp)) { - mrb_raise(mrb, E_TYPE_ERROR, "type mismatch: %s given", + mrb_raisef(mrb, E_TYPE_ERROR, "type mismatch: %s given", mrb_obj_classname(mrb, sub)); } sub = tmp; @@ -2466,7 +2466,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) break; default: if (base < 2 || 36 < base) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base); } if (base <= 32) { len = 5; @@ -2494,7 +2494,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) if (badcheck) goto bad; return mrb_fixnum_value(0); } - len *= strlen(str)*sizeof(char); + len *= strlen(str); val = strtoul((char*)str, &end, base); @@ -2510,7 +2510,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) return mrb_fixnum_value(result); } bad: - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalide string for number(%s)", str); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalide string for number(%s)", str); /* not reached */ return mrb_fixnum_value(0); } @@ -2546,7 +2546,7 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, int base, int badcheck) char *p = (char *)mrb_malloc(mrb, len+1); //MEMCPY(p, s, char, len); - memcpy(p, s, sizeof(char)*len); + memcpy(p, s, len); p[len] = '\0'; s = p; } @@ -2589,7 +2589,7 @@ mrb_str_to_i(mrb_state *mrb, mrb_value self) base = mrb_fixnum(argv[0]); if (base < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "illegal radix %d", base); } return mrb_str_to_inum(mrb, self, base, 0/*Qfalse*/); } @@ -2620,7 +2620,7 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, int badcheck) if (p == end) { if (badcheck) { bad: - mrb_raise(mrb, E_ARGUMENT_ERROR, "invalide string for float(%s)", p); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalide string for float(%s)", p); /* not reached */ } return d; @@ -2682,7 +2682,7 @@ mrb_str_to_dbl(mrb_state *mrb, mrb_value str, int badcheck) if (s[len]) { /* no sentinel somehow */ char *p = (char *)mrb_malloc(mrb, len+1); - memcpy(p, s, sizeof(char)*len); + memcpy(p, s, len); p[len] = '\0'; s = p; } @@ -2989,6 +2989,29 @@ mrb_str_inspect(mrb_state *mrb, mrb_value str) return result; } +/* + * call-seq: + * str.bytes -> array of fixnums + * + * Returns an array of bytes in _str_. + * + * str = "hello" + * str.bytes #=> [104, 101, 108, 108, 111] + */ +static mrb_value +mrb_str_bytes(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + mrb_value a = mrb_ary_new_capa(mrb, s->len); + char *p = s->ptr, *pend = p + s->len; + + while (p < pend) { + mrb_ary_push(mrb, a, mrb_fixnum_value(p[0])); + p++; + } + return a; +} + /* ---------------------------*/ void mrb_init_string(mrb_state *mrb) @@ -3053,4 +3076,5 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "upcase", mrb_str_upcase, ARGS_REQ(1)); /* 15.2.10.5.42 */ mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, ARGS_REQ(1)); /* 15.2.10.5.43 */ mrb_define_method(mrb, s, "inspect", mrb_str_inspect, ARGS_NONE()); /* 15.2.10.5.46(x) */ + mrb_define_method(mrb, s, "bytes", mrb_str_bytes, ARGS_NONE()); } diff --git a/src/struct.c b/src/struct.c index a5ffe6453..2a391d0b1 100644 --- a/src/struct.c +++ b/src/struct.c @@ -11,7 +11,6 @@ #include "mruby/struct.h" #include "mruby/array.h" #include <stdarg.h> -//#include "defines.h" #ifdef ENABLE_REGEXP #include "encoding.h" @@ -20,8 +19,6 @@ #include "mruby/string.h" #include "mruby/class.h" #include "mruby/variable.h" -//#include "defines.h" -#define mrb_long2int(n) ((int)(n)) static struct RClass * @@ -73,7 +70,7 @@ mrb_struct_members(mrb_state *mrb, mrb_value s) mrb_value members = mrb_struct_s_members(mrb, mrb_obj_value(mrb_obj_class(mrb, s))); if (mrb_type(s) == MRB_TT_STRUCT) { if (RSTRUCT_LEN(s) != RARRAY_LEN(members)) { - mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", + mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", RARRAY_LEN(members), RSTRUCT_LEN(s)); } } @@ -97,6 +94,16 @@ mrb_struct_s_members_m(mrb_state *mrb, mrb_value klass) return ary; } +static inline void +struct_copy(mrb_value *dst, const mrb_value *src, size_t size) +{ + size_t i; + + for (i = 0; i < size; i++) { + dst[i] = src[i]; + } +} + /* 15.2.18.4.6 */ /* * call-seq: @@ -434,7 +441,7 @@ mrb_struct_initialize_withArg(mrb_state *mrb, int argc, mrb_value *argv, mrb_val st = RSTRUCT(self); st->ptr = (mrb_value *)mrb_calloc(mrb, sizeof(mrb_value), n); st->len = n; - memcpy(st->ptr, argv, sizeof(mrb_value)*argc); + struct_copy(st->ptr, argv, argc); return self; } @@ -533,7 +540,7 @@ mrb_struct_init_copy(mrb_state *mrb, mrb_value copy) if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) { mrb_raise(mrb, E_TYPE_ERROR, "struct size mismatch"); } - memcpy(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), sizeof(mrb_value)*RSTRUCT_LEN(copy)); + struct_copy(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), RSTRUCT_LEN(copy)); return copy; } @@ -588,10 +595,10 @@ mrb_struct_aref_n(mrb_state *mrb, mrb_value s, mrb_value idx) i = mrb_fixnum(idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) - mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", + mrb_raisef(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", i, RSTRUCT_LEN(s)); if (RSTRUCT_LEN(s) <= i) - mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", + mrb_raisef(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", i, RSTRUCT_LEN(s)); return RSTRUCT_PTR(s)[i]; } @@ -615,7 +622,7 @@ mrb_struct_aset_id(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val) len = RARRAY_LEN(members); mrb_struct_modify(s); if (RSTRUCT_LEN(s) != len) { - mrb_raise(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", + mrb_raisef(mrb, E_TYPE_ERROR, "struct size differs (%ld required %ld given)", len, RSTRUCT_LEN(s)); } ptr = RSTRUCT_PTR(s); @@ -668,11 +675,11 @@ mrb_struct_aset(mrb_state *mrb, mrb_value s) i = mrb_fixnum(idx); if (i < 0) i = RSTRUCT_LEN(s) + i; if (i < 0) { - mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", + mrb_raisef(mrb, E_INDEX_ERROR, "offset %ld too small for struct(size:%ld)", i, RSTRUCT_LEN(s)); } if (RSTRUCT_LEN(s) <= i) { - mrb_raise(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", + mrb_raisef(mrb, E_INDEX_ERROR, "offset %ld too large for struct(size:%ld)", i, RSTRUCT_LEN(s)); } mrb_struct_modify(s); diff --git a/src/time.c b/src/time.c index ea8205c7b..09ebea78a 100644 --- a/src/time.c +++ b/src/time.c @@ -559,7 +559,7 @@ mrb_time_initialize_copy(mrb_state *mrb, mrb_value copy) DATA_PTR(copy) = mrb_malloc(mrb, sizeof(struct mrb_time)); DATA_TYPE(copy) = &mrb_time_type; } - memcpy(DATA_PTR(copy), DATA_PTR(src), sizeof(struct mrb_time)); + *(struct mrb_time *)DATA_PTR(copy) = *(struct mrb_time *)DATA_PTR(src); return copy; } diff --git a/src/variable.c b/src/variable.c index 74dfc02c9..eebe81575 100644 --- a/src/variable.c +++ b/src/variable.c @@ -420,6 +420,7 @@ obj_iv_p(mrb_value obj) case MRB_TT_OBJECT: case MRB_TT_CLASS: case MRB_TT_MODULE: + case MRB_TT_SCLASS: case MRB_TT_HASH: case MRB_TT_DATA: return TRUE; @@ -673,6 +674,7 @@ mod_const_check(mrb_state *mrb, mrb_value mod) switch (mrb_type(mod)) { case MRB_TT_CLASS: case MRB_TT_MODULE: + case MRB_TT_SCLASS: break; default: mrb_raise(mrb, E_TYPE_ERROR, "constant look-up for non class/module"); @@ -698,7 +700,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) } c = c->super; } - if (!retry && base->tt == MRB_TT_MODULE) { + if (!retry && base && base->tt == MRB_TT_MODULE) { c = mrb->object_class; retry = 1; goto L_RETRY; @@ -712,7 +714,7 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym) } c = c->super; } - mrb_raise(mrb, E_NAME_ERROR, "uninitialized constant %s", + mrb_raisef(mrb, E_NAME_ERROR, "uninitialized constant %s", mrb_sym2name(mrb, sym)); /* not reached */ return mrb_nil_value(); @@ -731,6 +733,22 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym) struct RClass *c = mrb->ci->proc->target_class; if (!c) c = mrb->ci->target_class; + if (c) { + struct RClass *c2 = c; + mrb_value v; + + if (c->iv && iv_get(mrb, c->iv, sym, &v)) { + return v; + } + c2 = c; + for (;;) { + c2 = mrb_class_outer_module(mrb, c2); + if (!c2) break; + if (c2->iv && iv_get(mrb, c2->iv, sym, &v)) { + return v; + } + } + } return const_get(mrb, c, sym); } @@ -38,6 +38,16 @@ #define STACK_INIT_SIZE 128 #define CALLINFO_INIT_SIZE 32 +static inline void +stack_copy(mrb_value *dst, const mrb_value *src, size_t size) +{ + int i; + + for (i = 0; i < size; i++) { + dst[i] = src[i]; + } +} + static void stack_init(mrb_state *mrb) { @@ -90,15 +100,16 @@ stack_extend(mrb_state *mrb, int room, int keep) envadjust(mrb, oldbase, mrb->stbase); } if (room > keep) { -#ifndef MRB_NAN_BOXING - memset(mrb->stack+keep, 0, sizeof(mrb_value) * (room-keep)); -#else int i; for (i=keep; i<room; i++) { +#ifndef MRB_NAN_BOXING + static const mrb_value mrb_value_zero = { { 0 } }; + mrb->stack[i] = mrb_value_zero; +#else SET_NIL_VALUE(mrb->stack[i]); - } #endif + } } } @@ -170,7 +181,7 @@ cipop(mrb_state *mrb) mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); e->cioff = -1; - memcpy(p, e->stack, sizeof(mrb_value)*len); + stack_copy(p, e->stack, len); e->stack = p; } @@ -226,7 +237,7 @@ mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...) mrb_value argv[MRB_FUNCALL_ARGC_MAX]; if (argc > MRB_FUNCALL_ARGC_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX); } va_start(ap, argc); @@ -267,7 +278,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr } n = mrb->ci->nregs; if (argc < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc); + mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc); } c = mrb_class(mrb, self); p = mrb_method_search_vm(mrb, &c, mid); @@ -296,10 +307,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mr mrb->stack[0] = self; if (undef) { mrb->stack[1] = mrb_symbol_value(undef); - memcpy(mrb->stack+2, argv, sizeof(mrb_value)*(argc-1)); + stack_copy(mrb->stack+2, argv, argc-1); } else if (argc > 0) { - memcpy(mrb->stack+1, argv, sizeof(mrb_value)*argc); + stack_copy(mrb->stack+1, argv, argc); } mrb->stack[argc+1] = blk; @@ -351,7 +362,7 @@ mrb_yield_internal(mrb_state *mrb, mrb_value b, int argc, mrb_value *argv, mrb_v stack_extend(mrb, ci->nregs, 0); mrb->stack[0] = self; if (argc > 0) { - memcpy(mrb->stack+1, argv, sizeof(mrb_value)*argc); + stack_copy(mrb->stack+1, argv, argc); } mrb->stack[argc+1] = mrb_nil_value(); @@ -455,7 +466,6 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) int ai = mrb->arena_idx; jmp_buf *prev_jmp = (jmp_buf *)mrb->jmp; jmp_buf c_jmp; - ptrdiff_t ciidx = mrb->ci - mrb->cibase; #ifdef DIRECT_THREADED static void *optable[] = { @@ -990,12 +1000,12 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) } regs[a] = mrb_ary_new_capa(mrb, m1+len+m2); rest = mrb_ary_ptr(regs[a]); - memcpy(rest->ptr, stack, sizeof(mrb_value)*m1); + stack_copy(rest->ptr, stack, m1); if (len > 0) { - memcpy(rest->ptr+m1, pp, sizeof(mrb_value)*len); + stack_copy(rest->ptr+m1, pp, len); } if (m2 > 0) { - memcpy(rest->ptr+m1+len, stack+m1+1, sizeof(mrb_value)*m2); + stack_copy(rest->ptr+m1+len, stack+m1+1, m2); } rest->len = m1+len+m2; } @@ -1096,14 +1106,10 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci = mrb->ci; eidx = mrb->ci->eidx; if (ci == mrb->cibase) goto L_STOP; - if (ciidx == ci - mrb->cibase){ - mrb->jmp = prev_jmp; - longjmp(*(jmp_buf*)mrb->jmp, 1); - } while (ci[0].ridx == ci[-1].ridx) { cipop(mrb); ci = mrb->ci; - if (ci->acc < 0) { + if (ci[1].acc < 0 && prev_jmp) { mrb->jmp = prev_jmp; longjmp(*(jmp_buf*)mrb->jmp, 1); } @@ -1131,6 +1137,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) switch (GETARG_B(i)) { case OP_R_NORMAL: + NORMAL_RETURN: if (ci == mrb->cibase) { localjump_error(mrb, "return"); goto L_RAISE; @@ -1145,6 +1152,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) ci = mrb->ci = mrb->cibase + proc->env->cioff + 1; break; case OP_R_RETURN: + if (!proc->env) goto NORMAL_RETURN; if (proc->env->cioff < 0) { localjump_error(mrb, "return"); goto L_RAISE; @@ -1436,7 +1444,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* need to check if + is overridden */ switch (mrb_type(regs[a])) { case MRB_TT_FIXNUM: - regs[a].attr_i += GETARG_C(i); + { + mrb_int x = regs[a].attr_i; + mrb_int y = GETARG_C(i); + mrb_int z = x + y; + + if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { + /* integer overflow */ + SET_FLT_VALUE(regs[a], (mrb_float)x + (mrb_float)y); + break; + } + regs[a].attr_i = z; + } break; case MRB_TT_FLOAT: regs[a].attr_f += GETARG_C(i); @@ -1456,7 +1475,18 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) /* need to check if + is overridden */ switch (mrb_type(regs[a])) { case MRB_TT_FIXNUM: - regs[a].attr_i -= GETARG_C(i); + { + mrb_int x = regs[a].attr_i; + mrb_int y = GETARG_C(i); + mrb_int z = x - y; + + if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) { + /* integer overflow */ + SET_FLT_VALUE(regs[a], (mrb_float)x - (mrb_float)y); + break; + } + regs[a].attr_i = z; + } break; case MRB_TT_FLOAT: regs[a].attr_f -= GETARG_C(i); @@ -1820,8 +1850,14 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) CASE(OP_ERR) { /* Bx raise RuntimeError with message Lit(Bx) */ mrb_value msg = pool[GETARG_Bx(i)]; - mrb_value exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg); + mrb_value exc; + if (GETARG_A(i) == 0) { + exc = mrb_exc_new3(mrb, E_RUNTIME_ERROR, msg); + } + else { + exc = mrb_exc_new3(mrb, E_LOCALJUMP_ERROR, msg); + } mrb->exc = (struct RObject*)mrb_object(exc); goto L_RAISE; } |
