diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/etc.c | 1 | ||||
| -rw-r--r-- | src/gc.c | 5 | ||||
| -rw-r--r-- | src/hash.c | 2 | ||||
| -rw-r--r-- | src/numeric.c | 8 | ||||
| -rw-r--r-- | src/symbol.c | 2 | ||||
| -rw-r--r-- | src/variable.c | 4 | ||||
| -rw-r--r-- | src/vm.c | 338 |
7 files changed, 102 insertions, 258 deletions
@@ -205,7 +205,6 @@ mrb_regexp_p(mrb_state *mrb, mrb_value v) return mrb_obj_is_kind_of(mrb, v, mrb_class_get(mrb, REGEXP_CLASS)); } else { - mrb->flags |= MRB_STATE_REGEXP; mrb->flags |= MRB_STATE_NO_REGEXP; } return FALSE; @@ -10,6 +10,7 @@ #include <mruby/array.h> #include <mruby/class.h> #include <mruby/data.h> +#include <mruby/istruct.h> #include <mruby/hash.h> #include <mruby/proc.h> #include <mruby/range.h> @@ -109,8 +110,10 @@ typedef struct { struct RHash hash; struct RRange range; struct RData data; + struct RIstruct istruct; struct RProc proc; struct REnv env; + struct RFiber fiber; struct RException exc; struct RBreak brk; #ifdef MRB_WORD_BOXING @@ -396,7 +399,7 @@ mrb_gc_init(mrb_state *mrb, mrb_gc *gc) static void obj_free(mrb_state *mrb, struct RBasic *obj, int end); -void +static void free_heap(mrb_state *mrb, mrb_gc *gc) { mrb_heap_page *page = gc->heaps; diff --git a/src/hash.c b/src/hash.c index c4820513b..a9367a426 100644 --- a/src/hash.c +++ b/src/hash.c @@ -182,7 +182,7 @@ ht_index(mrb_state *mrb, htable *t) if (!index || index->capa < size) { index = (segindex*)mrb_realloc_simple(mrb, index, sizeof(segindex)+sizeof(struct segkv*)*size); if (index == NULL) { - mrb_free(mrb, index); + mrb_free(mrb, t->index); t->index = NULL; return; } diff --git a/src/numeric.c b/src/numeric.c index 742df7b76..8205e41f6 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -510,7 +510,7 @@ flo_shift(mrb_state *mrb, mrb_value x, mrb_int width) } static mrb_value -flo_lshift(mrb_state *mrb, mrb_value x) +flo_rshift(mrb_state *mrb, mrb_value x) { mrb_int width; @@ -519,7 +519,7 @@ flo_lshift(mrb_state *mrb, mrb_value x) } static mrb_value -flo_rshift(mrb_state *mrb, mrb_value x) +flo_lshift(mrb_state *mrb, mrb_value x) { mrb_int width; @@ -1608,8 +1608,8 @@ mrb_init_numeric(mrb_state *mrb) mrb_define_method(mrb, fl, "&", flo_and, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "|", flo_or, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "^", flo_xor, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, ">>", flo_lshift, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, fl, "<<", flo_rshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, ">>", flo_rshift, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, fl, "<<", flo_lshift, MRB_ARGS_REQ(1)); mrb_define_method(mrb, fl, "ceil", flo_ceil, MRB_ARGS_NONE()); /* 15.2.9.3.8 */ mrb_define_method(mrb, fl, "finite?", flo_finite_p, MRB_ARGS_NONE()); /* 15.2.9.3.9 */ mrb_define_method(mrb, fl, "floor", flo_floor, MRB_ARGS_NONE()); /* 15.2.9.3.10 */ diff --git a/src/symbol.c b/src/symbol.c index 96ca9dd17..b26f2b1fd 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -91,7 +91,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) } #endif -uint8_t +static uint8_t symhash(const char *key, size_t len) { uint32_t hash, i; diff --git a/src/variable.c b/src/variable.c index f97b09c52..983fe52f7 100644 --- a/src/variable.c +++ b/src/variable.c @@ -79,19 +79,19 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) } /* Not found */ - t->size++; if (matched_seg) { matched_seg->key[matched_idx] = sym; matched_seg->val[matched_idx] = val; + t->size++; return; } seg = (segment*)mrb_malloc(mrb, sizeof(segment)); - if (!seg) return; seg->next = NULL; seg->key[0] = sym; seg->val[0] = val; t->last_len = 1; + t->size++; if (prev) { prev->next = seg; } @@ -486,6 +486,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->argc = (int)argc; ci->target_class = c; mrb->c->stack = mrb->c->stack + n; + if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; } @@ -500,11 +501,10 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc ci->argc = -1; argc = 1; } - else { + else if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); ci->proc = p; - if (argc < 0) argc = 1; mrb_stack_extend(mrb, p->body.irep->nregs + argc); } if (voff >= 0) { @@ -520,9 +520,6 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc int ai = mrb_gc_arena_save(mrb); ci->acc = CI_ACC_DIRECT; - if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); - } val = MRB_METHOD_CFUNC(m)(mrb, self); mrb->c->stack = mrb->c->ci->stackent; cipop(mrb); @@ -2217,184 +2214,67 @@ RETRY_TRY_BLOCK: } #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) -#define OP_MATH_BODY(op,v1,v2) do {\ - v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ -} while(0) - - CASE(OP_ADD, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - mrb_value *regs_a = regs + a; - - x = mrb_fixnum(regs_a[0]); - y = mrb_fixnum(regs_a[1]); - if (mrb_int_add_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } -#else - OP_MATH_BODY(+,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x + y); - } +#define OP_MATH(op_name) \ + /* need to check if op is overridden */ \ + switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \ + OP_MATH_CASE_FIXNUM(op_name); \ + OP_MATH_CASE_FLOAT(op_name, fixnum, float); \ + OP_MATH_CASE_FLOAT(op_name, float, fixnum); \ + OP_MATH_CASE_FLOAT(op_name, float, float); \ + OP_MATH_CASE_STRING_##op_name(); \ + default: \ + c = 1; \ + mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ + goto L_SEND_SYM; \ + } \ + NEXT; +#define OP_MATH_CASE_FIXNUM(op_name) \ + case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \ + { \ + mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \ + if (mrb_int_##op_name##_overflow(x, y, &z)) \ + OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ + else \ + SET_INT_VALUE(regs[a], z); \ + } \ + break +#ifdef MRB_WITHOUT_FLOAT +#define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0 +#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z) #else - OP_MATH_BODY(+,mrb_float,mrb_float); +#define OP_MATH_CASE_FLOAT(op_name, t1, t2) \ + case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \ + { \ + mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \ + SET_FLOAT_VALUE(mrb, regs[a], z); \ + } \ + break +#define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \ + SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y) #endif - break; -#endif - case TYPES2(MRB_TT_STRING,MRB_TT_STRING): - regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); - break; - default: - c = 1; - mid = mrb_intern_lit(mrb, "+"); - goto L_SEND_SYM; - } - mrb_gc_arena_restore(mrb, ai); - NEXT; +#define OP_MATH_CASE_STRING_add() \ + case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ + regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ + mrb_gc_arena_restore(mrb, ai); \ + break +#define OP_MATH_CASE_STRING_sub() (void)0 +#define OP_MATH_CASE_STRING_mul() (void)0 +#define OP_MATH_OP_add + +#define OP_MATH_OP_sub - +#define OP_MATH_OP_mul * +#define OP_MATH_TT_fixnum MRB_TT_FIXNUM +#define OP_MATH_TT_float MRB_TT_FLOAT + + CASE(OP_ADD, B) { + OP_MATH(add); } CASE(OP_SUB, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_sub_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x - y); - } -#else - OP_MATH_BODY(-,mrb_float,mrb_float); -#endif - break; -#endif - default: - c = 1; - mid = mrb_intern_lit(mrb, "-"); - goto L_SEND_SYM; - } - NEXT; + OP_MATH(sub); } CASE(OP_MUL, B) { - /* need to check if op is overridden */ - switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): - { - mrb_int x, y, z; - - x = mrb_fixnum(regs[a]); - y = mrb_fixnum(regs[a+1]); - if (mrb_int_mul_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); - } - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_int y = mrb_fixnum(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_fixnum); -#endif - break; - case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - mrb_float y = mrb_float(regs[a+1]); - SET_FLOAT_VALUE(mrb, regs[a], x * y); - } -#else - OP_MATH_BODY(*,mrb_float,mrb_float); -#endif - break; -#endif - default: - c = 1; - mid = mrb_intern_lit(mrb, "*"); - goto L_SEND_SYM; - } - NEXT; + OP_MATH(mul); } CASE(OP_DIV, B) { @@ -2449,84 +2329,46 @@ RETRY_TRY_BLOCK: NEXT; } - CASE(OP_ADDI, BB) { - /* need to check if + is overridden */ - switch (mrb_type(regs[a])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs[a]); - mrb_int y = (mrb_int)b; - mrb_int z; - - if (mrb_int_add_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs[a], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], x + b); - } +#define OP_MATHI(op_name) \ + /* need to check if op is overridden */ \ + switch (mrb_type(regs[a])) { \ + OP_MATHI_CASE_FIXNUM(op_name); \ + OP_MATHI_CASE_FLOAT(op_name); \ + default: \ + SET_INT_VALUE(regs[a+1], b); \ + c = 1; \ + mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ + goto L_SEND_SYM; \ + } \ + NEXT; +#define OP_MATHI_CASE_FIXNUM(op_name) \ + case MRB_TT_FIXNUM: \ + { \ + mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \ + if (mrb_int_##op_name##_overflow(x, y, &z)) \ + OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ + else \ + SET_INT_VALUE(regs[a], z); \ + } \ + break +#ifdef MRB_WITHOUT_FLOAT +#define OP_MATHI_CASE_FLOAT(op_name) (void)0 #else - mrb_float(regs[a]) += b; +#define OP_MATHI_CASE_FLOAT(op_name) \ + case MRB_TT_FLOAT: \ + { \ + mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \ + SET_FLOAT_VALUE(mrb, regs[a], z); \ + } \ + break #endif - break; -#endif - default: - SET_INT_VALUE(regs[a+1], b); - c = 1; - mid = mrb_intern_lit(mrb, "+"); - goto L_SEND_SYM; - } - NEXT; + + CASE(OP_ADDI, BB) { + OP_MATHI(add); } CASE(OP_SUBI, BB) { - mrb_value *regs_a = regs + a; - - /* need to check if + is overridden */ - switch (mrb_type(regs_a[0])) { - case MRB_TT_FIXNUM: - { - mrb_int x = mrb_fixnum(regs_a[0]); - mrb_int y = (mrb_int)b; - mrb_int z; - - if (mrb_int_sub_overflow(x, y, &z)) { -#ifndef MRB_WITHOUT_FLOAT - SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y); - break; -#endif - } - SET_INT_VALUE(regs_a[0], z); - } - break; -#ifndef MRB_WITHOUT_FLOAT - case MRB_TT_FLOAT: -#ifdef MRB_WORD_BOXING - { - mrb_float x = mrb_float(regs[a]); - SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)b); - } -#else - mrb_float(regs_a[0]) -= b; -#endif - break; -#endif - default: - SET_INT_VALUE(regs_a[1], b); - c = 1; - mid = mrb_intern_lit(mrb, "-"); - goto L_SEND_SYM; - } - NEXT; + OP_MATHI(sub); } #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) |
