diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/backtrace.c | 16 | ||||
| -rw-r--r-- | src/class.c | 34 | ||||
| -rw-r--r-- | src/crc.c | 39 | ||||
| -rw-r--r-- | src/dump.c | 6 | ||||
| -rw-r--r-- | src/gc.c | 14 | ||||
| -rw-r--r-- | src/hash.c | 24 | ||||
| -rw-r--r-- | src/kernel.c | 5 | ||||
| -rw-r--r-- | src/load.c | 25 | ||||
| -rw-r--r-- | src/numeric.c | 17 | ||||
| -rw-r--r-- | src/proc.c | 12 | ||||
| -rw-r--r-- | src/symbol.c | 43 | ||||
| -rw-r--r-- | src/vm.c | 208 |
12 files changed, 185 insertions, 258 deletions
diff --git a/src/backtrace.c b/src/backtrace.c index 8b42b1e0e..a829d5cf1 100644 --- a/src/backtrace.c +++ b/src/backtrace.c @@ -30,7 +30,7 @@ mrb_value mrb_exc_inspect(mrb_state *mrb, mrb_value exc); mrb_value mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace); static void -each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtrace_func func, void *data) +each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *data) { ptrdiff_t i; @@ -51,15 +51,11 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, const mrb_code *pc0, each_backtr irep = ci->proc->body.irep; if (!irep) continue; - if (mrb->c->cibase[i].err) { - pc = mrb->c->cibase[i].err; - } - else if (i+1 <= ciidx) { - if (!mrb->c->cibase[i + 1].pc) continue; - pc = &mrb->c->cibase[i+1].pc[-1]; + if (mrb->c->cibase[i].pc) { + pc = &mrb->c->cibase[i].pc[-1]; } else { - pc = pc0; + continue; } loc.lineno = mrb_debug_get_line(mrb, irep, pc - irep->iseq); @@ -160,12 +156,12 @@ packed_backtrace(mrb_state *mrb) int size; void *ptr; - each_backtrace(mrb, ciidx, mrb->c->ci->pc, count_backtrace_i, &len); + each_backtrace(mrb, ciidx, count_backtrace_i, &len); size = len * sizeof(struct backtrace_location); ptr = mrb_malloc(mrb, size); backtrace = mrb_data_object_alloc(mrb, NULL, ptr, &bt_type); backtrace->flags = (uint32_t)len; - each_backtrace(mrb, ciidx, mrb->c->ci->pc, pack_backtrace_i, &ptr); + each_backtrace(mrb, ciidx, pack_backtrace_i, &ptr); return mrb_obj_value(backtrace); } diff --git a/src/class.c b/src/class.c index 7533ac2b0..126ac0004 100644 --- a/src/class.c +++ b/src/class.c @@ -27,7 +27,8 @@ union mt_ptr { struct mt_elem { union mt_ptr ptr; size_t func_p:1; - mrb_sym key:sizeof(mrb_sym)*8-1; + size_t noarg_p:1; + mrb_sym key:sizeof(mrb_sym)*8-2; }; /* method table structure */ @@ -51,7 +52,7 @@ mt_new(mrb_state *mrb) return t; } -static struct mt_elem *mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, union mt_ptr ptr); +static struct mt_elem *mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, size_t noarg_p, union mt_ptr ptr); static void mt_rehash(mrb_state *mrb, mt_tbl *t) @@ -72,7 +73,7 @@ mt_rehash(mrb_state *mrb, mt_tbl *t) /* key = 0 means empty or deleted */ if (slot->key != 0) { - mt_put(mrb, t, slot->key, slot->func_p, slot->ptr); + mt_put(mrb, t, slot->key, slot->func_p, slot->noarg_p, slot->ptr); } } mrb_free(mrb, old_table); @@ -82,7 +83,7 @@ mt_rehash(mrb_state *mrb, mt_tbl *t) /* Set the value for the symbol in the method table. */ static struct mt_elem* -mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, union mt_ptr ptr) +mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, size_t noarg_p, union mt_ptr ptr) { size_t hash, pos, start; struct mt_elem *dslot = NULL; @@ -97,6 +98,7 @@ mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, union mt_ptr ptr) if (slot->key == sym) { slot->func_p = func_p; + slot->noarg_p = noarg_p; slot->ptr = ptr; return slot; } @@ -105,6 +107,7 @@ mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, union mt_ptr ptr) t->size++; slot->key = sym; slot->func_p = func_p; + slot->noarg_p = noarg_p; slot->ptr = ptr; return slot; } @@ -118,6 +121,7 @@ mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, size_t func_p, union mt_ptr ptr) t->size++; dslot->key = sym; dslot->func_p = func_p; + dslot->noarg_p = noarg_p; dslot->ptr = ptr; return dslot; } @@ -203,7 +207,7 @@ mt_copy(mrb_state *mrb, mt_tbl *t) struct mt_elem *slot = &t->table[i]; if (slot->key) { - mt_put(mrb, t2, slot->key, slot->func_p, slot->ptr); + mt_put(mrb, t2, slot->key, slot->func_p, slot->noarg_p, slot->ptr); } } return t2; @@ -239,6 +243,9 @@ mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void * else { MRB_METHOD_FROM_PROC(m, slot->ptr.proc); } + if (slot->noarg_p) { + MRB_METHOD_NOARG_SET(m); + } if (fn(mrb, slot->key, m, p) != 0) return; @@ -740,7 +747,7 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_ else { ptr.func = MRB_METHOD_FUNC(m); } - mt_put(mrb, h, mid, MRB_METHOD_FUNC_P(m), ptr); + mt_put(mrb, h, mid, MRB_METHOD_FUNC_P(m), MRB_METHOD_NOARG_P(m), ptr); mc_clear(mrb); } @@ -809,7 +816,7 @@ mrb_get_argc(mrb_state *mrb) mrb_int argc = mrb->c->ci->argc; if (argc < 0) { - struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); + struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]); argc = ARY_LEN(a); } @@ -820,7 +827,7 @@ MRB_API const mrb_value* mrb_get_argv(mrb_state *mrb) { mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack + 1; + mrb_value *array_argv = mrb->c->ci->stack + 1; if (argc < 0) { struct RArray *a = mrb_ary_ptr(*array_argv); @@ -833,7 +840,7 @@ MRB_API mrb_value mrb_get_arg1(mrb_state *mrb) { mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack + 1; + mrb_value *array_argv = mrb->c->ci->stack + 1; if (argc < 0) { struct RArray *a = mrb_ary_ptr(*array_argv); @@ -888,7 +895,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_int i = 0; va_list ap; mrb_int argc = mrb->c->ci->argc; - mrb_value *array_argv = mrb->c->stack+1; + mrb_value *array_argv = mrb->c->ci->stack+1; mrb_bool argv_on_stack = argc >= 0; mrb_bool opt = FALSE; mrb_bool opt_skip = TRUE; @@ -1201,10 +1208,10 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, mrb_value*); if (mrb->c->ci->argc < 0) { - bp = mrb->c->stack + 2; + bp = mrb->c->ci->stack + 2; } else { - bp = mrb->c->stack + mrb->c->ci->argc + 1; + bp = mrb->c->ci->stack + mrb->c->ci->argc + 1; } if (altmode && mrb_nil_p(*bp)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); @@ -1748,6 +1755,9 @@ mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) else { MRB_METHOD_FROM_PROC(m, e->ptr.proc); } + if (e->noarg_p) { + MRB_METHOD_NOARG_SET(m); + } #ifndef MRB_NO_METHOD_CACHE mc->c = oc; mc->c0 = c; diff --git a/src/crc.c b/src/crc.c deleted file mode 100644 index 290b2ca0e..000000000 --- a/src/crc.c +++ /dev/null @@ -1,39 +0,0 @@ -/* -** crc.c - calculate CRC -** -** See Copyright Notice in mruby.h -*/ - -#include <limits.h> -#include <stdint.h> -#include <stddef.h> - -/* Calculate CRC (CRC-16-CCITT) -** -** 0000_0000_0000_0000_0000_0000_0000_0000 -** ^|------- CRC -------|- work --| -** carry -*/ -#define CRC_16_CCITT 0x11021ul /* x^16+x^12+x^5+1 */ -#define CRC_XOR_PATTERN (CRC_16_CCITT << 8) -#define CRC_CARRY_BIT (0x01000000) - -uint16_t -calc_crc_16_ccitt(const uint8_t *src, size_t nbytes, uint16_t crc) -{ - size_t ibyte; - uint32_t ibit; - uint32_t crcwk = crc << 8; - - for (ibyte = 0; ibyte < nbytes; ibyte++) { - crcwk |= *src++; - for (ibit = 0; ibit < CHAR_BIT; ibit++) { - crcwk <<= 1; - if (crcwk & CRC_CARRY_BIT) { - crcwk ^= CRC_XOR_PATTERN; - } - } - } - return (uint16_t)(crcwk >> 8); -} - diff --git a/src/dump.c b/src/dump.c index 45900cecd..dcd94fd45 100644 --- a/src/dump.c +++ b/src/dump.c @@ -747,8 +747,6 @@ static int write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8_t flags) { struct rite_binary_header *header = (struct rite_binary_header *)bin; - uint16_t crc; - uint32_t offset; memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); memcpy(header->major_version, RITE_BINARY_MAJOR_VER, sizeof(header->major_version)); @@ -758,10 +756,6 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8 mrb_assert(binary_size <= UINT32_MAX); uint32_to_bin((uint32_t)binary_size, header->binary_size); - offset = (uint32_t)((&(header->binary_crc[0]) - bin) + sizeof(uint16_t)); - crc = calc_crc_16_ccitt(bin + offset, binary_size - offset, 0); - uint16_to_bin(crc, header->binary_crc); - return MRB_DUMP_OK; } @@ -627,11 +627,14 @@ mark_context_stack(mrb_state *mrb, struct mrb_context *c) size_t e; mrb_value nil; - if (c->stack == NULL) return; - e = c->stack - c->stbase; + if (c->stbase == NULL) return; if (c->ci) { + e = (c->ci->stack ? c->ci->stack - c->stbase : 0); e += ci_nregs(c->ci); } + else { + e = 0; + } if (c->stbase + e > c->stend) e = c->stend - c->stbase; for (i=0; i<e; i++) { mrb_value v = c->stbase[i]; @@ -661,9 +664,8 @@ mark_context(mrb_state *mrb, struct mrb_context *c) /* mark call stack */ if (c->cibase) { for (ci = c->cibase; ci <= c->ci; ci++) { - mrb_gc_mark(mrb, (struct RBasic*)ci->env); mrb_gc_mark(mrb, (struct RBasic*)ci->proc); - mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + mrb_gc_mark(mrb, (struct RBasic*)ci->u.target_class); } } /* mark fibers */ @@ -841,7 +843,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj, int end) mrb_callinfo *ce = c->cibase; while (ce <= ci) { - struct REnv *e = ci->env; + struct REnv *e = ci->u.env; if (e && !mrb_object_dead_p(mrb, (struct RBasic*)e) && e->tt == MRB_TT_ENV && MRB_ENV_ONSTACK_P(e)) { mrb_env_unshare(mrb, e); @@ -1003,7 +1005,7 @@ gc_gray_counts(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj) if (!c || c->status == MRB_FIBER_TERMINATED) break; /* mark stack */ - i = c->stack - c->stbase; + i = c->ci->stack - c->stbase; if (c->ci) { i += ci_nregs(c->ci); diff --git a/src/hash.c b/src/hash.c index 714601b02..289f02a91 100644 --- a/src/hash.c +++ b/src/hash.c @@ -53,10 +53,10 @@ * the number of used slots and the number of empty slots. */ +#define EA_N_RESERVED_INDICES 2 /* empty and deleted */ #define EA_INCREASE_RATIO 6 / 5 + 6 #define EA_MAX_INCREASE UINT16_MAX -#define EA_MAX_CAPA /* `- 2` means reserved indices (empty and deleted) */ \ - U32(lesser(IB_MAX_CAPA - 2, MRB_INT_MAX)) +#define EA_MAX_CAPA U32(lesser(IB_MAX_CAPA - EA_N_RESERVED_INDICES, MRB_INT_MAX)) #define IB_MAX_CAPA (U32(1) << IB_MAX_BIT) #define IB_TYPE_BIT 32 #define IB_INIT_BIT ( \ @@ -363,12 +363,12 @@ ea_next_capa_for(uint32_t size, uint32_t max_capa) } else { /* - * For 32-bit CPU, the theoretical value of max EA capa is + * For 32-bit CPU, the theoretical value of maximum EA capacity is * `UINT32_MAX / sizeof (hash_entry)`. At this time, if * `EA_INCREASE_RATIO` is the current value, 32-bit range will not be * exceeded during the calculation of `capa`, so `size_t` is used. */ - size_t capa = size * EA_INCREASE_RATIO, inc = capa - size; + size_t capa = (size_t)size * EA_INCREASE_RATIO, inc = capa - size; if (EA_MAX_INCREASE < inc) capa = size + EA_MAX_INCREASE; return capa <= max_capa ? U32(capa) : max_capa; } @@ -842,12 +842,16 @@ ht_set(mrb_state *mrb, struct RHash *h, mrb_value key, mrb_value val) if (size != ht_ea_n_used(h)) ea_compress(ht_ea(h), ht_ea_n_used(h)); ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ++ib_bit_width); } - else if (ht_ea_capa(h) == ht_ea_n_used(h) && size != ht_ea_n_used(h)) { - if (size <= AR_MAX_SIZE) {ht_set_as_ar(mrb, h, key, val); return;} - if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) { - ea_compress(ht_ea(h), ht_ea_n_used(h)); - ht_adjust_ea(mrb, h, size, ht_ea_capa(h)); - ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width); + else if (size != ht_ea_n_used(h)) { + if (ib_capa - EA_N_RESERVED_INDICES <= ht_ea_n_used(h)) goto compress; + if (ht_ea_capa(h) == ht_ea_n_used(h)) { + if (size <= AR_MAX_SIZE) {ht_set_as_ar(mrb, h, key, val); return;} + if (ea_next_capa_for(size, EA_MAX_CAPA) <= ht_ea_capa(h)) { + compress: + ea_compress(ht_ea(h), ht_ea_n_used(h)); + ht_adjust_ea(mrb, h, size, ht_ea_capa(h)); + ht_init(mrb, h, size, ht_ea(h), ht_ea_capa(h), h_ht(h), ib_bit_width); + } } } ht_set_without_ib_adjustment(mrb, h, key, val); diff --git a/src/kernel.c b/src/kernel.c index 769ce58c9..05d7c7c84 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -177,8 +177,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) if (bidx < 0) return mrb_false_value(); bp = &e->stack[bidx]; } - else if (ci->env) { - e = ci->env; + else if ((e = mrb_vm_ci_env(ci)) != NULL) { /* top-level does not have block slot (always false) */ if (e->stack == mrb->c->stbase) return mrb_false_value(); bidx = env_bidx(e); @@ -187,7 +186,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) bp = &e->stack[bidx]; } else { - bp = ci[1].stackent+1; + bp = ci->stack+1; if (ci->argc >= 0) { bp += ci->argc; } diff --git a/src/load.c b/src/load.c index 1ab8c1ad6..cf8454f1c 100644 --- a/src/load.c +++ b/src/load.c @@ -37,13 +37,6 @@ return irep; \ } -static size_t -offset_crc_body(void) -{ - struct rite_binary_header header; - return ((uint8_t *)header.binary_crc - (uint8_t *)&header) + sizeof(header.binary_crc); -} - #ifndef MRB_NO_FLOAT static double str_to_double(mrb_state *mrb, const char *p) @@ -96,7 +89,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flag src += sizeof(uint16_t); /* number of child irep */ - irep->rlen = (size_t)bin_to_uint16(src); + irep->rlen = (uint8_t)bin_to_uint16(src); src += sizeof(uint16_t); /* Binary Data Section */ @@ -519,7 +512,7 @@ lv_exit: } static int -read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_t *crc, uint8_t *flags) +read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint8_t *flags) { const struct rite_binary_header *header = (const struct rite_binary_header *)bin; @@ -540,9 +533,6 @@ read_binary_header(const uint8_t *bin, size_t bufsize, size_t *bin_size, uint16_ return MRB_DUMP_INVALID_FILE_HEADER; } - if (crc) { - *crc = bin_to_uint16(header->binary_crc); - } *bin_size = (size_t)bin_to_uint32(header->binary_size); if (bufsize < *bin_size) { @@ -559,24 +549,17 @@ read_irep(mrb_state *mrb, const uint8_t *bin, size_t bufsize, uint8_t flags) struct RProc *proc = NULL; mrb_irep *irep = NULL; const struct rite_section_header *section_header; - uint16_t crc; size_t bin_size = 0; - size_t n; if ((mrb == NULL) || (bin == NULL)) { return NULL; } - result = read_binary_header(bin, bufsize, &bin_size, &crc, &flags); + result = read_binary_header(bin, bufsize, &bin_size, &flags); if (result != MRB_DUMP_OK) { return NULL; } - n = offset_crc_body(); - if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { - return NULL; - } - bin += sizeof(struct rite_binary_header); do { section_header = (const struct rite_section_header *)bin; @@ -705,7 +688,7 @@ mrb_proc_read_irep_file(mrb_state *mrb, FILE *fp) if (fread(buf, header_size, 1, fp) == 0) { goto irep_exit; } - result = read_binary_header(buf, (size_t)-1, &buf_size, NULL, &flags); + result = read_binary_header(buf, (size_t)-1, &buf_size, &flags); if (result != MRB_DUMP_OK || buf_size <= header_size) { goto irep_exit; } diff --git a/src/numeric.c b/src/numeric.c index 5e6f1b524..cef6fac96 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -40,8 +40,13 @@ mrb_to_flo(mrb_state *mrb, mrb_value val) return (mrb_float)mrb_integer(val); case MRB_TT_FLOAT: break; - default: + case MRB_TT_STRING: + case MRB_TT_FALSE: + case MRB_TT_TRUE: mrb_raise(mrb, E_TYPE_ERROR, "non float value"); + default: + val = mrb_type_convert(mrb, val, MRB_TT_FLOAT, MRB_SYM(to_f)); + break; } return mrb_float(val); } @@ -173,9 +178,15 @@ int_quo(mrb_state *mrb, mrb_value xv) if (y == 0) { int_zerodiv(mrb); } - return mrb_fixnum_value(mrb_fixnum(xv) / y); + return mrb_fixnum_value(mrb_integer(xv) / y); #else - return int_div(mrb, xv); + mrb_float y; + + mrb_get_args(mrb, "f", &y); + if (y == 0) { + int_zerodiv(mrb); + } + return mrb_float_value(mrb, mrb_integer(xv) / y); #endif } diff --git a/src/proc.c b/src/proc.c index e09fcb5b7..870d5ea16 100644 --- a/src/proc.c +++ b/src/proc.c @@ -47,7 +47,7 @@ mrb_proc_new(mrb_state *mrb, const mrb_irep *irep) tc = MRB_PROC_TARGET_CLASS(ci->proc); } if (tc == NULL) { - tc = ci->target_class; + tc = mrb_vm_ci_target_class(ci); } p->upper = ci->proc; p->e.target_class = tc; @@ -86,14 +86,14 @@ closure_setup(mrb_state *mrb, struct RProc *p) const struct RProc *up = p->upper; struct REnv *e = NULL; - if (ci && ci->env) { - e = ci->env; + if (ci && (e = mrb_vm_ci_env(ci)) != NULL) { + /* do nothing, because e is assigned already */ } else if (up) { struct RClass *tc = MRB_PROC_TARGET_CLASS(p); - e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, mrb->c->stack, tc); - ci->env = e; + e = mrb_env_new(mrb, mrb->c, ci, up->body.irep->nlocals, ci->stack, tc); + ci->u.env = e; if (MRB_PROC_ENV_P(up) && MRB_PROC_ENV(up)->cxt == NULL) { e->mid = MRB_PROC_ENV(up)->mid; } @@ -214,7 +214,7 @@ mrb_proc_s_new(mrb_state *mrb, mrb_value proc_class) proc = mrb_obj_value(p); mrb_funcall_with_block(mrb, proc, MRB_SYM(initialize), 0, NULL, proc); if (!MRB_PROC_STRICT_P(p) && - mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].env) { + mrb->c->ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb->c->ci[-1].u.env) { p->flags |= MRB_PROC_ORPHAN; } return proc; diff --git a/src/symbol.c b/src/symbol.c index 76e2abec4..e9afc1dd7 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -66,17 +66,6 @@ typedef struct symbol_name { const char *name; } symbol_name; -#ifdef MRB_USE_ALL_SYMBOLS -#define SYMBOL_SHIFT 0 -# define SYMBOL_INLINE_P(sym) FALSE -# define sym_inline_pack(name, len) 0 -# define sym_inline_unpack(sym, buf, lenp) NULL -#else -#define SYMBOL_INLINE 1 -#define SYMBOL_SHIFT 1 -# define SYMBOL_INLINE_P(sym) ((sym) & SYMBOL_INLINE) -#endif - static void sym_validate_len(mrb_state *mrb, size_t len) { @@ -85,13 +74,19 @@ sym_validate_len(mrb_state *mrb, size_t len) } } -#ifndef MRB_USE_ALL_SYMBOLS +#ifdef MRB_USE_ALL_SYMBOLS +# define SYMBOL_INLINE_P(sym) FALSE +# define sym_inline_pack(name, len) 0 +# define sym_inline_unpack(sym, buf, lenp) NULL +#else +# define SYMBOL_INLINE_P(sym) ((sym) >= (1<<24)) + static const char pack_table[] = "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; static mrb_sym sym_inline_pack(const char *name, size_t len) { - const size_t pack_length_max = (MRB_SYMBOL_BIT - 2) / 6; + const size_t pack_length_max = 5; char c; const char *p; @@ -99,6 +94,7 @@ sym_inline_pack(const char *name, size_t len) mrb_sym sym = 0; if (len > pack_length_max) return 0; /* too long */ + if (len == 0) return 0; /* empty string */ for (i=0; i<len; i++) { uint32_t bits; @@ -107,10 +103,10 @@ sym_inline_pack(const char *name, size_t len) p = strchr(pack_table, (int)c); if (p == 0) return 0; /* non alnum char */ bits = (uint32_t)(p - pack_table)+1; - if (i >= pack_length_max) break; - sym |= bits<<(i*6+SYMBOL_SHIFT); + sym |= bits<<(24-i*6); } - return sym | SYMBOL_INLINE; + mrb_assert(SYMBOL_INLINE_P(sym)); + return sym; } static const char* @@ -121,7 +117,7 @@ sym_inline_unpack(mrb_sym sym, char *buf, mrb_int *lenp) mrb_assert(SYMBOL_INLINE_P(sym)); for (i=0; i<5; i++) { - uint32_t bits = sym>>(i*6+SYMBOL_SHIFT) & ((1<<6)-1); + uint32_t bits = sym>>(24-i*6) & 0x3f; if (bits == 0) break; buf[i] = pack_table[bits-1];; } @@ -157,7 +153,7 @@ find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) #ifndef MRB_NO_PRESYM /* presym */ i = presym_find(name, len); - if (i > 0) return i<<SYMBOL_SHIFT; + if (i > 0) return i; #endif /* inline symbol */ @@ -172,14 +168,14 @@ find_symbol(mrb_state *mrb, const char *name, size_t len, uint8_t *hashp) do { sname = &mrb->symtbl[i]; if (sname->len == len && memcmp(sname->name, name, len) == 0) { - return (i+MRB_PRESYM_MAX)<<SYMBOL_SHIFT; + return (i+MRB_PRESYM_MAX); } if (sname->prev == 0xff) { i -= 0xff; sname = &mrb->symtbl[i]; while (mrb->symtbl < sname) { if (sname->len == len && memcmp(sname->name, name, len) == 0) { - return (mrb_sym)((sname - mrb->symtbl)+MRB_PRESYM_MAX)<<SYMBOL_SHIFT; + return (mrb_sym)((sname - mrb->symtbl)+MRB_PRESYM_MAX); } sname--; } @@ -235,7 +231,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) } mrb->symhash[hash] = mrb->symidx = sym; - return (sym+MRB_PRESYM_MAX)<<SYMBOL_SHIFT; + return (sym+MRB_PRESYM_MAX); } MRB_API mrb_sym @@ -314,7 +310,6 @@ sym2name_len(mrb_state *mrb, mrb_sym sym, char *buf, mrb_int *lenp) { if (SYMBOL_INLINE_P(sym)) return sym_inline_unpack(sym, buf, lenp); - sym >>= SYMBOL_SHIFT; #ifndef MRB_NO_PRESYM { const char *name = presym_sym2name(sym, lenp); @@ -346,7 +341,6 @@ mrb_bool mrb_sym_static_p(mrb_state *mrb, mrb_sym sym) { if (SYMBOL_INLINE_P(sym)) return TRUE; - sym >>= SYMBOL_SHIFT; if (sym > MRB_PRESYM_MAX) return FALSE; return TRUE; } @@ -615,8 +609,7 @@ sym_name(mrb_state *mrb, mrb_sym sym, mrb_bool dump) return name; } else { - mrb_value str = SYMBOL_INLINE_P(sym) ? - mrb_str_new(mrb, name, len) : mrb_str_new_static(mrb, name, len); + mrb_value str = mrb_str_new_static(mrb, name, len); str = mrb_str_dump(mrb, str); return RSTRING_PTR(str); } @@ -128,14 +128,13 @@ stack_init(mrb_state *mrb) /* mrb_assert(mrb->stack == NULL); */ c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value)); c->stend = c->stbase + STACK_INIT_SIZE; - c->stack = c->stbase; /* mrb_assert(ci == NULL); */ c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo)); c->ciend = c->cibase + CALLINFO_INIT_SIZE; c->ci = c->cibase; - c->ci->target_class = mrb->object_class; - c->ci->stackent = c->stack; + c->ci->u.target_class = mrb->object_class; + c->ci->stack = c->stbase; } static inline void @@ -145,7 +144,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize if (newbase == oldbase) return; while (ci <= mrb->c->ci) { - struct REnv *e = ci->env; + struct REnv *e = mrb_vm_ci_env(ci); mrb_value *st; if (e && MRB_ENV_ONSTACK_P(e) && @@ -155,7 +154,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize e->stack = newbase + off; } - if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) { + if (ci->proc && MRB_PROC_ENV_P(ci->proc) && e != MRB_PROC_ENV(ci->proc)) { e = MRB_PROC_ENV(ci->proc); if (e && MRB_ENV_ONSTACK_P(e) && @@ -166,7 +165,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize } } - ci->stackent = newbase + (ci->stackent - oldbase); + ci->stack = newbase + (ci->stack - oldbase); ci++; } } @@ -180,7 +179,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) mrb_value *newstack; size_t oldsize = mrb->c->stend - mrb->c->stbase; size_t size = oldsize; - size_t off = mrb->c->stack - mrb->c->stbase; + size_t off = mrb->c->ci->stack ? mrb->c->stend - mrb->c->ci->stack : 0; if (off > size) size = off; #ifdef MRB_STACK_EXTEND_DOUBLING @@ -205,7 +204,6 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) stack_clear(&(newstack[oldsize]), size - oldsize); envadjust(mrb, oldbase, newstack, oldsize); mrb->c->stbase = newstack; - mrb->c->stack = mrb->c->stbase + off; mrb->c->stend = mrb->c->stbase + size; /* Raise an exception if the new stack size will be too large, @@ -218,7 +216,7 @@ stack_extend_alloc(mrb_state *mrb, mrb_int room) MRB_API void mrb_stack_extend(mrb_state *mrb, mrb_int room) { - if (mrb->c->stack + room >= mrb->c->stend) { + if (!mrb->c->ci->stack || mrb->c->ci->stack + room >= mrb->c->stend) { stack_extend_alloc(mrb, room); } } @@ -241,7 +239,7 @@ uvenv(mrb_state *mrb, mrb_int up) while (cb <= ci) { if (ci->proc == proc) { - return ci->env; + return mrb_vm_ci_env(ci); } ci--; } @@ -265,7 +263,7 @@ top_proc(mrb_state *mrb, const struct RProc *proc) #define CI_ACC_RESUMED -3 static inline mrb_callinfo* -cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, +cipush(mrb_state *mrb, mrb_int push_stacks, mrb_int acc, struct RClass *target_class, const struct RProc *proc, mrb_sym mid, mrb_int argc) { struct mrb_context *c = mrb->c; @@ -280,15 +278,11 @@ cipush(mrb_state *mrb, const mrb_code *pc, mrb_int push_stacks, mrb_int acc, } ci = ++c->ci; ci->mid = mid; - ci->proc = proc; - ci->stackent = c->stack; - ci->pc = pc; + mrb_vm_ci_proc_set(ci, proc); + ci->stack = ci[-1].stack + push_stacks; ci->argc = argc; ci->acc = acc; - ci->target_class = target_class; - ci->err = 0; - ci->env = 0; - c->stack += push_stacks; + ci->u.target_class = target_class; return ci; } @@ -303,7 +297,7 @@ mrb_env_unshare(mrb_state *mrb, struct REnv *e) if (!MRB_ENV_ONSTACK_P(e)) return; if (e->cxt != mrb->c) return; - if (e == mrb->c->cibase->env) return; /* for mirb */ + if (e == mrb_vm_ci_env(mrb->c->cibase)) return; /* for mirb */ p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); if (len > 0) { stack_copy(p, e->stack, len); @@ -318,9 +312,8 @@ static inline mrb_callinfo* cipop(mrb_state *mrb) { struct mrb_context *c = mrb->c; - struct REnv *env = c->ci->env; + struct REnv *env = mrb_vm_ci_env(c->ci); - mrb->c->stack = c->ci->stackent; c->ci--; if (env) mrb_env_unshare(mrb, env); return c->ci; @@ -429,7 +422,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc mrb_int n = ci_nregs(mrb->c->ci); ptrdiff_t voff = -1; - if (!mrb->c->stack) { + if (!mrb->c->stbase) { stack_init(mrb); } if (argc < 0) { @@ -446,13 +439,13 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc } mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); mrb_stack_extend(mrb, n+2); - mrb->c->stack[n+1] = args; + mrb->c->ci->stack[n+1] = args; argc = -1; } if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } - ci = cipush(mrb, NULL, n, 0, c, NULL, mid, argc); + ci = cipush(mrb, n, 0, c, NULL, mid, argc); if (argc < 0) argc = 1; if (mrb->c->stbase <= argv && argv < mrb->c->stend) { voff = argv - mrb->c->stbase; @@ -460,7 +453,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (argc >= CALL_MAXARGS) { mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - mrb->c->stack[1] = args; + mrb->c->ci->stack[1] = args; ci->argc = -1; argc = 1; } @@ -468,7 +461,7 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); if (!MRB_PROC_CFUNC_P(p)) { mrb_stack_extend(mrb, p->body.irep->nregs + argc); } @@ -476,11 +469,11 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc if (voff >= 0) { argv = mrb->c->stbase + voff; } - mrb->c->stack[0] = self; + mrb->c->ci->stack[0] = self; if (ci->argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); + stack_copy(mrb->c->ci->stack+1, argv, argc); } - mrb->c->stack[argc+1] = blk; + mrb->c->ci->stack[argc+1] = blk; if (MRB_METHOD_CFUNC_P(m)) { ci->acc = CI_ACC_DIRECT; @@ -509,8 +502,8 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) mrb_callinfo *ci = mrb->c->ci; mrb_int keep, nregs; - mrb->c->stack[0] = self; - ci->proc = p; + mrb->c->ci->stack[0] = self; + mrb_vm_ci_proc_set(ci, p); if (MRB_PROC_CFUNC_P(p)) { return MRB_PROC_CFUNC(p)(mrb, self); } @@ -522,10 +515,10 @@ mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p) } else { mrb_stack_extend(mrb, nregs); - stack_clear(mrb->c->stack+keep, nregs-keep); + stack_clear(mrb->c->ci->stack+keep, nregs-keep); } - cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); + cipush(mrb, 0, 0, NULL, NULL, 0, 0); return self; } @@ -574,8 +567,8 @@ mrb_f_send(mrb_state *mrb, mrb_value self) } ci->mid = name; - ci->target_class = c; - regs = mrb->c->stack+1; + ci->u.target_class = c; + regs = mrb->c->ci->stack+1; /* remove first symbol from arguments */ if (ci->argc >= 0) { for (i=0,len=ci->argc; i<len; i++) { @@ -589,7 +582,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); } return MRB_METHOD_CFUNC(m)(mrb, self); } @@ -610,25 +603,25 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) if (ci->acc == CI_ACC_DIRECT) { return mrb_yield_with_class(mrb, blk, 1, &self, self, c); } - ci->target_class = c; + ci->u.target_class = c; p = mrb_proc_ptr(blk); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); ci->argc = 1; ci->mid = ci[-1].mid; if (MRB_PROC_CFUNC_P(p)) { mrb_stack_extend(mrb, 3); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - mrb->c->stack[2] = mrb_nil_value(); + mrb->c->ci->stack[0] = self; + mrb->c->ci->stack[1] = self; + mrb->c->ci->stack[2] = mrb_nil_value(); return MRB_PROC_CFUNC(p)(mrb, self); } nregs = p->body.irep->nregs; if (nregs < 3) nregs = 3; mrb_stack_extend(mrb, nregs); - mrb->c->stack[0] = self; - mrb->c->stack[1] = self; - stack_clear(mrb->c->stack+2, nregs-2); - ci = cipush(mrb, p->body.irep->iseq, 0, 0, NULL, NULL, 0, 0); + mrb->c->ci->stack[0] = self; + mrb->c->ci->stack[1] = self; + stack_clear(mrb->c->ci->stack+2, nregs-2); + ci = cipush(mrb, 0, 0, NULL, NULL, 0, 0); return self; } @@ -704,7 +697,7 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); } p = mrb_proc_ptr(b); - ci = cipush(mrb, NULL, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); + ci = cipush(mrb, n, CI_ACC_SKIP, c, p, mid, 0 /* dummy */); if (argc >= CALL_MAXARGS) { ci->argc = -1; n = 3; @@ -714,15 +707,15 @@ mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value n = argc + 2; } mrb_stack_extend(mrb, n); - mrb->c->stack[0] = self; + mrb->c->ci->stack[0] = self; if (ci->argc < 0) { - mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); + mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); argc = 1; } else if (argc > 0) { - stack_copy(mrb->c->stack+1, argv, argc); + stack_copy(mrb->c->ci->stack+1, argv, argc); } - mrb->c->stack[argc+1] = mrb_nil_value(); + mrb->c->ci->stack[argc+1] = mrb_nil_value(); if (MRB_PROC_CFUNC_P(p)) { val = MRB_PROC_CFUNC(p)(mrb, self); @@ -767,8 +760,8 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const ci = mrb->c->ci; mrb_stack_extend(mrb, 3); - mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); - mrb->c->stack[2] = mrb_nil_value(); + mrb->c->ci->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); + mrb->c->ci->stack[2] = mrb_nil_value(); ci->argc = -1; return mrb_exec_irep(mrb, self, p); } @@ -854,7 +847,7 @@ argnum_error(mrb_state *mrb, mrb_int num) mrb_int argc = mrb->c->ci->argc; if (argc < 0) { - mrb_value args = mrb->c->stack[1]; + mrb_value args = mrb->c->ci->stack[1]; if (mrb_array_p(args)) { argc = RARRAY_LEN(args); } @@ -934,8 +927,6 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb } while (0); \ } while (0) -#define ERR_PC_SET(mrb) mrb->c->ci->err = pc0; -#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; #ifdef MRB_USE_DEBUG_HOOK #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); #else @@ -957,7 +948,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #ifndef DIRECT_THREADED #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { -#define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc; +#define CASE(insn,ops) case insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; #define NEXT goto L_END_DISPATCH #define JUMP NEXT #define END_DISPATCH L_END_DISPATCH:;}} @@ -965,7 +956,7 @@ prepare_tagged_break(mrb_state *mrb, uint32_t tag, const struct RProc *proc, mrb #else #define INIT_DISPATCH JUMP; return mrb_nil_value(); -#define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); pc_save = pc; +#define CASE(insn,ops) L_ ## insn: pc++; FETCH_ ## ops (); mrb->c->ci->pc = pc; #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] #define JUMP NEXT @@ -982,14 +973,14 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta ptrdiff_t cioff = c->ci - c->cibase; mrb_int nregs = irep->nregs; - if (!c->stack) { + if (!c->stbase) { stack_init(mrb); } if (stack_keep > nregs) nregs = stack_keep; mrb_stack_extend(mrb, nregs); - stack_clear(c->stack + stack_keep, nregs - stack_keep); - c->stack[0] = self; + stack_clear(c->ci->stack + stack_keep, nregs - stack_keep); + c->ci->stack[0] = self; result = mrb_vm_exec(mrb, proc, irep->iseq); if (mrb->c != c) { if (mrb->c->fib) { @@ -1006,7 +997,7 @@ mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int sta static mrb_bool check_target_class(mrb_state *mrb) { - if (!mrb->c->ci->target_class) { + if (!mrb_vm_ci_target_class(mrb->c->ci)) { mrb_value exc = mrb_exc_new_lit(mrb, E_TYPE_ERROR, "no target class or module"); mrb_exc_set(mrb, exc); return FALSE; @@ -1020,8 +1011,6 @@ MRB_API mrb_value mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc) { /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */ - const mrb_code *pc0 = pc; - const mrb_code *volatile pc_save = pc; const mrb_irep *irep = proc->body.irep; const mrb_pool_value *pool = irep->pool; const mrb_sym *syms = irep->syms; @@ -1056,9 +1045,9 @@ RETRY_TRY_BLOCK: goto L_RAISE; } mrb->jmp = &c_jmp; - mrb->c->ci->proc = proc; + mrb_vm_ci_proc_set(mrb->c->ci, proc); -#define regs (mrb->c->stack) +#define regs (mrb->c->ci->stack) INIT_DISPATCH { CASE(OP_NOP, Z) { /* do nothing */ @@ -1203,9 +1192,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETCV, BB) { mrb_value val; - ERR_PC_SET(mrb); val = mrb_vm_cv_get(mrb, syms[b]); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1219,9 +1206,7 @@ RETRY_TRY_BLOCK: mrb_value val; mrb_sym sym = syms[b]; - ERR_PC_SET(mrb); val = mrb_vm_const_get(mrb, sym); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1234,9 +1219,7 @@ RETRY_TRY_BLOCK: CASE(OP_GETMCNST, BB) { mrb_value val; - ERR_PC_SET(mrb); val = mrb_const_get(mrb, regs[a], syms[b]); - ERR_PC_CLR(mrb); regs[a] = val; NEXT; } @@ -1438,7 +1421,6 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); - ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } if (argc >= 0) { @@ -1454,13 +1436,13 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb, pc, a, a, cls, NULL, mid, argc); + ci = cipush(mrb, a, a, cls, NULL, mid, argc); if (MRB_METHOD_CFUNC_P(m)) { if (MRB_METHOD_PROC_P(m)) { struct RProc *p = MRB_METHOD_PROC(m); - ci->proc = p; + mrb_vm_ci_proc_set(ci, p); recv = p->body.func(mrb, recv); } else if (MRB_METHOD_NOARG_P(m) && @@ -1477,11 +1459,11 @@ RETRY_TRY_BLOCK: ci = mrb->c->ci; if (mrb_proc_p(blk)) { struct RProc *p = mrb_proc_ptr(blk); - if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { + if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { p->flags |= MRB_PROC_ORPHAN; } } - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (!ci->u.target_class) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { mrb->jmp = prev_jmp; return recv; @@ -1494,15 +1476,15 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->stack[0] = recv; + mrb->c->ci->stack[0] = recv; /* pop stackpos */ + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); JUMP; } else { /* setup environment for calling method */ - proc = ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1514,13 +1496,13 @@ RETRY_TRY_BLOCK: CASE(OP_CALL, Z) { mrb_callinfo *ci; - mrb_value recv = mrb->c->stack[0]; + mrb_value recv = mrb->c->ci->stack[0]; struct RProc *m = mrb_proc_ptr(recv); /* replace callinfo */ ci = mrb->c->ci; - ci->target_class = MRB_PROC_TARGET_CLASS(m); - ci->proc = m; + ci->u.target_class = MRB_PROC_TARGET_CLASS(m); + mrb_vm_ci_proc_set(ci, m); if (MRB_PROC_ENV_P(m)) { ci->mid = MRB_PROC_ENV(m)->mid; } @@ -1532,10 +1514,9 @@ RETRY_TRY_BLOCK: mrb_gc_arena_shrink(mrb, ai); if (mrb->exc) goto L_RAISE; /* pop stackpos */ - ci = mrb->c->ci; + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); - regs[ci->acc] = recv; + regs[ci[1].acc] = recv; irep = mrb->c->ci->proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1546,7 +1527,7 @@ RETRY_TRY_BLOCK: proc = m; irep = m->body.irep; if (!irep) { - mrb->c->stack[0] = mrb_nil_value(); + mrb->c->ci->stack[0] = mrb_nil_value(); a = 0; c = OP_R_NORMAL; goto L_RETURN; @@ -1592,10 +1573,10 @@ RETRY_TRY_BLOCK: goto L_RAISE; } if (target_class->flags & MRB_FL_CLASS_IS_PREPENDED) { - target_class = ci->target_class; + target_class = mrb_vm_ci_target_class(ci); } else if (target_class->tt == MRB_TT_MODULE) { - target_class = ci->target_class; + target_class = mrb_vm_ci_target_class(ci); if (target_class->tt != MRB_TT_ICLASS) { mrb_value exc = mrb_exc_new_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); mrb_exc_set(mrb, exc); @@ -1628,7 +1609,6 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &cls, missing); if (MRB_METHOD_UNDEF_P(m)) { mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); - ERR_PC_SET(mrb); mrb_method_missing(mrb, mid, recv, args); } mid = missing; @@ -1644,23 +1624,23 @@ RETRY_TRY_BLOCK: } /* push callinfo */ - ci = cipush(mrb, pc, a, 0, cls, NULL, mid, argc); + ci = cipush(mrb, a, 0, cls, NULL, mid, argc); /* prepare stack */ - mrb->c->stack[0] = recv; + mrb->c->ci->stack[0] = recv; if (MRB_METHOD_CFUNC_P(m)) { mrb_value v; if (MRB_METHOD_PROC_P(m)) { - ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, MRB_METHOD_PROC(m)); } v = MRB_METHOD_CFUNC(m)(mrb, recv); mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; ci = mrb->c->ci; mrb_assert(!mrb_break_p(v)); - if (!ci->target_class) { /* return from context modifying method (resume/yield) */ + if (!mrb_vm_ci_target_class(ci)) { /* return from context modifying method (resume/yield) */ if (ci->acc == CI_ACC_RESUMED) { mrb->jmp = prev_jmp; return v; @@ -1673,9 +1653,9 @@ RETRY_TRY_BLOCK: syms = irep->syms; } } - mrb->c->stack[0] = v; + mrb->c->ci->stack[0] = v; + ci = cipop(mrb); pc = ci->pc; - cipop(mrb); JUMP; } else { @@ -1683,7 +1663,7 @@ RETRY_TRY_BLOCK: ci->acc = a; /* setup environment for calling method */ - proc = ci->proc = MRB_METHOD_PROC(m); + mrb_vm_ci_proc_set(ci, (proc = MRB_METHOD_PROC(m))); irep = proc->body.irep; pool = irep->pool; syms = irep->syms; @@ -1701,7 +1681,7 @@ RETRY_TRY_BLOCK: mrb_int lv = (b>>0)&0xf; mrb_value *stack; - if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) { + if (mrb->c->ci->mid == 0 || mrb_vm_ci_target_class(mrb->c->ci) == NULL) { mrb_value exc; L_NOSUPER: @@ -1952,7 +1932,7 @@ RETRY_TRY_BLOCK: struct RProc *p = mrb_proc_ptr(blk); if (!MRB_PROC_STRICT_P(p) && - ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) { + ci > mrb->c->cibase && MRB_PROC_ENV(p) == mrb_vm_ci_env(&ci[-1])) { p->flags |= MRB_PROC_ORPHAN; } } @@ -1974,13 +1954,13 @@ RETRY_TRY_BLOCK: mrb->jmp = prev_jmp; MRB_THROW(prev_jmp); } - pc = ci[1].pc; + pc = ci[0].pc; if (ci == mrb->c->cibase) { ch = catch_handler_find(mrb, ci, pc, MRB_CATCH_FILTER_ALL); if (ch == NULL) { L_FTOP: /* fiber top */ if (mrb->c == mrb->root_c) { - mrb->c->stack = mrb->c->stbase; + mrb->c->ci->stack = mrb->c->stbase; goto L_STOP; } else { @@ -2005,9 +1985,6 @@ RETRY_TRY_BLOCK: irep = proc->body.irep; pool = irep->pool; syms = irep->syms; - if (ci < ci0) { - mrb->c->stack = ci[1].stackent; - } mrb_stack_extend(mrb, irep->nregs); pc = irep->iseq + mrb_irep_catch_handler_unpack(ch->target); } @@ -2057,8 +2034,8 @@ RETRY_TRY_BLOCK: UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_RETURN_BLOCK, proc, v); } CHECKPOINT_END(RBREAK_TAG_RETURN_BLOCK); - pc = ci->pc; ci = cipop(mrb); + pc = ci->pc; } proc = ci->proc; mrb->exc = NULL; /* clear break object */ @@ -2170,7 +2147,6 @@ RETRY_TRY_BLOCK: mrb_assert(!"wrong break tag"); } } - mrb->c->stack = ci->stackent; while (mrb->c->cibase < ci && ci[-1].proc != proc->upper) { if (ci[-1].acc == CI_ACC_SKIP) { goto L_BREAK_ERROR; @@ -2182,8 +2158,8 @@ RETRY_TRY_BLOCK: UNWIND_ENSURE(mrb, ci, pc, RBREAK_TAG_BREAK_UPPER, proc, v); } CHECKPOINT_END(RBREAK_TAG_BREAK_UPPER); - pc = ci->pc; ci = cipop(mrb); + pc = ci->pc; } CHECKPOINT_RESTORE(RBREAK_TAG_BREAK_INTARGET) { /* do nothing */ @@ -2204,7 +2180,7 @@ RETRY_TRY_BLOCK: mrb_assert(ci == mrb->c->ci); mrb_assert(mrb->exc == NULL); - if (mrb->c->vmexec && !ci->target_class) { + if (mrb->c->vmexec && !mrb_vm_ci_target_class(ci)) { mrb_gc_arena_restore(mrb, ai); mrb->c->vmexec = FALSE; mrb->jmp = prev_jmp; @@ -2217,7 +2193,7 @@ RETRY_TRY_BLOCK: mrb->jmp = prev_jmp; return v; } - pc = ci[1].pc; + pc = ci[0].pc; DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); proc = mrb->c->ci->proc; irep = proc->body.irep; @@ -2751,7 +2727,7 @@ RETRY_TRY_BLOCK: p->flags |= MRB_PROC_SCOPE; /* prepare call stack */ - cipush(mrb, pc, a, a, mrb_class_ptr(recv), p, 0, 0); + cipush(mrb, a, a, mrb_class_ptr(recv), p, 0, 0); irep = p->body.irep; pool = irep->pool; @@ -2781,7 +2757,7 @@ RETRY_TRY_BLOCK: CASE(OP_TCLASS, B) { if (!check_target_class(mrb)) goto L_RAISE; - regs[a] = mrb_obj_value(mrb->c->ci->target_class); + regs[a] = mrb_obj_value(mrb_vm_ci_target_class(mrb->c->ci)); NEXT; } @@ -2789,7 +2765,7 @@ RETRY_TRY_BLOCK: struct RClass *target; if (!check_target_class(mrb)) goto L_RAISE; - target = mrb->c->ci->target_class; + target = mrb_vm_ci_target_class(mrb->c->ci); mrb_alias_method(mrb, target, syms[a], syms[b]); NEXT; } @@ -2797,7 +2773,7 @@ RETRY_TRY_BLOCK: struct RClass *target; if (!check_target_class(mrb)) goto L_RAISE; - target = mrb->c->ci->target_class; + target = mrb_vm_ci_target_class(mrb->c->ci); mrb_undef_method_id(mrb, target, syms[a]); NEXT; } @@ -2822,7 +2798,6 @@ RETRY_TRY_BLOCK: mrb_assert((pool[a].tt&IREP_TT_NFLAG)==0); exc = mrb_exc_new(mrb, E_LOCALJUMP_ERROR, pool[a].u.str, len); - ERR_PC_SET(mrb); mrb_exc_set(mrb, exc); goto L_RAISE; } @@ -2841,7 +2816,6 @@ RETRY_TRY_BLOCK: } CHECKPOINT_END(RBREAK_TAG_STOP); L_STOP: - ERR_PC_CLR(mrb); mrb->jmp = prev_jmp; if (mrb->exc) { mrb_assert(mrb->exc->tt == MRB_TT_EXCEPTION); @@ -2859,7 +2833,7 @@ RETRY_TRY_BLOCK: ci = cipop(mrb); } exc_catched = TRUE; - pc = pc_save; + pc = ci->pc; goto RETRY_TRY_BLOCK; } MRB_END_EXC(&c_jmp); @@ -2885,10 +2859,10 @@ mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, mrb_int st return mrb_vm_run(mrb, proc, self, stack_keep); } if (mrb->c->ci == mrb->c->cibase) { - mrb->c->ci->env = NULL; + mrb_vm_ci_env_set(mrb->c->ci, NULL); return mrb_vm_run(mrb, proc, self, stack_keep); } - cipush(mrb, NULL, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); + cipush(mrb, 0, CI_ACC_SKIP, mrb->object_class, NULL, 0, 0); v = mrb_vm_run(mrb, proc, self, stack_keep); return v; |
