static void ary_expand_capa(mrb_state *mrb, struct RArray *a, int len) { int capa = a->aux.capa; #ifdef INT_MAX if (len > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } #endif while(capa < len) { if (capa == 0) { capa = ARY_DEFAULT_LEN; } else { capa *= 2; } } #ifdef INT_MAX if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ #endif if (capa > a->aux.capa) { a->aux.capa = capa; a->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); } }
static void ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { mrb_int capa = a->aux.capa; if (len > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } while (capa < len) { if (capa == 0) { capa = ARY_DEFAULT_LEN; } else { capa *= 2; } } if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ if (capa > a->aux.capa) { mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); if (!expanded_ptr) { mrb_raise(mrb, E_RUNTIME_ERROR, "out of memory"); } a->aux.capa = capa; a->ptr = expanded_ptr; } }
MRB_API mrb_irep* mrb_read_irep_file(mrb_state *mrb, FILE* fp) { mrb_irep *irep = NULL; uint8_t *buf; const size_t header_size = sizeof(struct rite_binary_header); size_t buf_size = 0; uint8_t flags = 0; int result; if ((mrb == NULL) || (fp == NULL)) { return NULL; } buf = (uint8_t*)mrb_malloc(mrb, header_size); if (fread(buf, header_size, 1, fp) == 0) { goto irep_exit; } result = read_binary_header(buf, &buf_size, NULL, &flags); if (result != MRB_DUMP_OK || buf_size <= header_size) { goto irep_exit; } buf = (uint8_t*)mrb_realloc(mrb, buf, buf_size); if (fread(buf+header_size, buf_size-header_size, 1, fp) == 0) { goto irep_exit; } irep = read_irep(mrb, buf, FLAG_SRC_MALLOC); irep_exit: mrb_free(mrb, buf); return irep; }
static mrb_value mrb_file_s_readlink(mrb_state *mrb, mrb_value klass) { #if defined(_WIN32) || defined(_WIN64) mrb_raise(mrb, E_NOTIMP_ERROR, "readlink is not supported on this platform"); return mrb_nil_value(); // unreachable #else char *path, *buf, *tmp; size_t bufsize = 100; ssize_t rc; mrb_value ret; int ai = mrb_gc_arena_save(mrb); mrb_get_args(mrb, "z", &path); tmp = mrb_locale_from_utf8(path, -1); buf = (char *)mrb_malloc(mrb, bufsize); while ((rc = readlink(tmp, buf, bufsize)) == (ssize_t)bufsize && rc != -1) { bufsize *= 2; buf = (char *)mrb_realloc(mrb, buf, bufsize); } mrb_locale_free(tmp); if (rc == -1) { mrb_free(mrb, buf); mrb_sys_fail(mrb, path); } tmp = mrb_utf8_from_locale(buf, -1); ret = mrb_str_new(mrb, tmp, rc); mrb_locale_free(tmp); mrb_free(mrb, buf); mrb_gc_arena_restore(mrb, ai); return ret; #endif }
static void ary_shrink_capa(mrb_state *mrb, struct RArray *a) { mrb_int capa; if (ARY_EMBED_P(a)) return; capa = a->as.heap.aux.capa; if (capa < ARY_DEFAULT_LEN * 2) return; if (capa <= a->as.heap.len * ARY_SHRINK_RATIO) return; do { capa /= 2; if (capa < ARY_DEFAULT_LEN) { capa = ARY_DEFAULT_LEN; break; } } while (capa > a->as.heap.len * ARY_SHRINK_RATIO); if (capa > a->as.heap.len && capa < a->as.heap.aux.capa) { a->as.heap.aux.capa = capa; a->as.heap.ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); } }
static void save_backtrace_i(mrb_state *mrb, struct backtrace_location_raw *loc_raw, void *data) { mrb_backtrace_entry *entry; if (mrb->backtrace.n >= mrb->backtrace.n_allocated) { int new_n_allocated; if (mrb->backtrace.n_allocated == 0) { new_n_allocated = 8; } else { new_n_allocated = mrb->backtrace.n_allocated * 2; } mrb->backtrace.entries = (mrb_backtrace_entry *) mrb_realloc(mrb, mrb->backtrace.entries, sizeof(mrb_backtrace_entry) * new_n_allocated); mrb->backtrace.n_allocated = new_n_allocated; } entry = &mrb->backtrace.entries[mrb->backtrace.n]; entry->filename = loc_raw->filename; entry->lineno = loc_raw->lineno; entry->klass = loc_raw->klass; entry->sep = loc_raw->sep; entry->method_id = loc_raw->method_id; mrb->backtrace.n++; }
static size_t get_filename_table_size(mrb_state *mrb, mrb_irep *irep, mrb_sym **fp, uint16_t *lp) { mrb_sym *filenames = *fp; size_t i, size = 0; mrb_irep_debug_info *di = irep->debug_info; mrb_assert(lp); for (i = 0; i < di->flen; ++i) { mrb_irep_debug_info_file *file; mrb_int filename_len; file = di->files[i]; if (find_filename_index(filenames, *lp, file->filename_sym) == -1) { /* register filename */ *lp += 1; *fp = filenames = (mrb_sym *)mrb_realloc(mrb, filenames, sizeof(mrb_sym) * (*lp)); filenames[*lp - 1] = file->filename_sym; /* filename */ mrb_sym2name_len(mrb, file->filename_sym, &filename_len); size += sizeof(uint16_t) + (size_t)filename_len; } } for (i=0; i<irep->rlen; i++) { size += get_filename_table_size(mrb, irep->reps[i], fp, lp); } return size; }
void mrb_mruby_debug_step_exec_gem_init(mrb_state* mrb) { debug_state = mrb_realloc(mrb, debug_state, sizeof(struct debug_state) * (mrb_count + 1)); debug_state[mrb_count].mrb = mrb; debug_state[mrb_count].code_fetch_hook = mrb->code_fetch_hook; ++mrb_count; mrb->code_fetch_hook = code_fetch_hook; }
void* mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) { void *p = mrb_realloc(mrb, 0, nelem*len); if (len > 0) memset(p, 0, nelem*len); return p; }
static void replace_stop_with_return(mrb_state *mrb, mrb_irep *irep) { if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) { irep->iseq = mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code)); irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0); irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL); irep->ilen++; } }
mrb_value cfunc_pointer_realloc(mrb_state *mrb, mrb_value self) { struct cfunc_type_data *data = DATA_PTR(self); mrb_int alloc_size; mrb_get_args(mrb, "i", &alloc_size); set_cfunc_pointer_data(data, mrb_realloc(mrb, get_cfunc_pointer_data(data), alloc_size)); return self; }
void mrb_mruby_debug_step_exec_gem_final(mrb_state* mrb) { int i; for(i = 0; i < mrb_count; ++i) { if(debug_state[i].mrb == mrb) { mrb->code_fetch_hook = debug_state[i].code_fetch_hook; --mrb_count; memcpy(&debug_state[i], &debug_state[i + 1], (mrb_count - i)); debug_state = mrb_realloc(mrb, debug_state, sizeof(struct debug_state) * mrb_count); return; } } }
static int write_syms_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) { int result; size_t sym_no; size_t buf_size; uint8_t *cur = buf; uint16_t nlen; char *char_buf = NULL; const char *name; buf_size = MRB_DUMP_DEFAULT_STR_LEN; char_buf = (char *)mrb_malloc(mrb, buf_size); if (char_buf == NULL) { result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } cur += uint32_to_bin(irep->slen, cur); /* number of symbol */ for (sym_no = 0; sym_no < irep->slen; sym_no++) { if (irep->syms[sym_no] != 0) { size_t len; name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); if (len > UINT16_MAX) goto error_exit; nlen = (uint16_t)len; if (nlen > buf_size - 1) { buf_size = nlen + 1; char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size); if (char_buf == NULL) { result = MRB_DUMP_GENERAL_FAILURE; goto error_exit; } } memset(char_buf, 0, buf_size); memcpy(char_buf, name, len); cur += uint16_to_bin(nlen, cur); /* length of symbol name */ memcpy(cur, char_buf, nlen); /* symbol name */ cur += nlen; } else { cur += uint16_to_bin(MRB_DUMP_NULL_SYM_LEN, cur); /* length of symbol name */ } } result = (int)(cur - buf); error_exit: mrb_free(mrb, char_buf); return result; }
static int32_t read_rite_section_irep_file(mrb_state *mrb, FILE *fp) { int32_t result; size_t sirep; size_t i; uint16_t nirep; uint16_t n; uint32_t len, buf_size; uint8_t *buf = NULL; const size_t record_header_size = 1 + 4; struct rite_section_irep_header header; if (fread(&header, sizeof(struct rite_section_irep_header), 1, fp) == 0) { return MRB_DUMP_READ_FAULT; } sirep = mrb->irep_len; nirep = bin_to_uint16(header.nirep); buf_size = record_header_size; buf = (uint8_t *)mrb_malloc(mrb, buf_size); //Read Binary Data Section for (n = 0, i = sirep; n < nirep; n++, i++) { if (fread(buf, record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; goto error_exit; } buf_size = bin_to_uint32(&buf[0]); buf = (uint8_t *)mrb_realloc(mrb, buf, buf_size); if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) { result = MRB_DUMP_READ_FAULT; goto error_exit; } result = read_rite_irep_record(mrb, buf, &len); if (result != MRB_DUMP_OK) goto error_exit; } result = sirep + bin_to_uint16(header.sirep); error_exit: mrb_free(mrb, buf); if (result < MRB_DUMP_OK) { irep_free(sirep, mrb); } return result; }
void* mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) { void *p = NULL; size_t size; if (nelem <= SIZE_MAX / len) { size = nelem * len; p = mrb_realloc(mrb, 0, size); if (p && size > 0) memset(p, 0, size); } return p; }
static int write_syms_block(mrb_state *mrb, mrb_irep *irep, char *buf, int type) { int sym_no; char *buf_top = buf; char *char_buf; uint16_t buf_size =0; buf_size = MRB_DUMP_DEFAULT_STR_LEN; char_buf = (char *)mrb_malloc(mrb, buf_size); if (char_buf == NULL) goto error_exit; buf += uint32_dump((uint32_t)irep->slen, buf, type); /* number of symbol */ for (sym_no = 0; sym_no < irep->slen; sym_no++) { const char * name; uint16_t nlen =0; if (irep->syms[sym_no] != 0) { size_t len; name = mrb_sym2name_len(mrb, irep->syms[sym_no], &len); if (len > UINT16_MAX) goto error_exit; nlen = str_dump_len((char*)name, len, type); if ( nlen > buf_size - 1) { buf_size = nlen + 1; char_buf = (char *)mrb_realloc(mrb, char_buf, buf_size); if (char_buf == NULL) goto error_exit; } memset(char_buf, 0, buf_size); str_dump((char*)name, char_buf, len, type); buf += uint16_dump(nlen, buf, type); /* length of symbol name */ memcpy(buf, char_buf, nlen); /* symbol name */ buf += nlen; } else { buf += uint16_dump(MRB_DUMP_NULL_SYM_LEN, buf, type); /* length of symbol name */ } } error_exit: mrb_free(mrb, char_buf); return (int)(buf - buf_top); }
static void replace_stop_with_return(mrb_state *mrb, mrb_irep *irep) { if (irep->iseq[irep->ilen - 1] == MKOP_A(OP_STOP, 0)) { if (irep->flags == MRB_ISEQ_NO_FREE) { mrb_code* iseq = (mrb_code *)mrb_malloc(mrb, (irep->ilen + 1) * sizeof(mrb_code)); memcpy(iseq, irep->iseq, irep->ilen * sizeof(mrb_code)); irep->iseq = iseq; irep->flags &= ~MRB_ISEQ_NO_FREE; } else { irep->iseq = (mrb_code *)mrb_realloc(mrb, irep->iseq, (irep->ilen + 1) * sizeof(mrb_code)); } irep->iseq[irep->ilen - 1] = MKOP_A(OP_LOADNIL, 0); irep->iseq[irep->ilen] = MKOP_AB(OP_RETURN, 0, OP_R_NORMAL); irep->ilen++; } }
static mrb_sym sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) { mrb_sym sym; symbol_name *sname; uint8_t hash; sym_validate_len(mrb, len); hash = symhash(name, len); sym = find_symbol(mrb, name, len, hash); if (sym > 0) return sym; /* registering a new symbol */ sym = ++mrb->symidx; if (mrb->symcapa < sym) { if (mrb->symcapa == 0) mrb->symcapa = 100; else mrb->symcapa = (size_t)(mrb->symcapa * 6 / 5); mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1)); } sname = &mrb->symtbl[sym]; sname->len = (uint16_t)len; if (lit || mrb_ro_data_p(name)) { sname->name = name; sname->lit = TRUE; } else { char *p = (char *)mrb_malloc(mrb, len+1); memcpy(p, name, len); p[len] = 0; sname->name = (const char*)p; sname->lit = FALSE; } if (mrb->symhash[hash]) { mrb_sym i = sym - mrb->symhash[hash]; if (i > 0xff) sname->prev = 0xff; else sname->prev = i; } else { sname->prev = 0; } mrb->symhash[hash] = sym; return sym<<1; }
void mrb_add_irep(mrb_state *mrb, int idx) { if (!mrb->irep) { int max = 256; if (idx > max) max = idx+1; mrb->irep = mrb_malloc(mrb, sizeof(mrb_irep*)*max); mrb->irep_capa = max; } else if (mrb->irep_capa < idx) { while (mrb->irep_capa < idx) { mrb->irep_capa *= 2; } mrb->irep = mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep)*mrb->irep_capa); } }
static void gc_protect(mrb_state *mrb, mrb_gc *gc, struct RBasic *p) { #ifdef MRB_GC_FIXED_ARENA if (gc->arena_idx >= MRB_GC_ARENA_SIZE) { /* arena overflow error */ gc->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ mrb_exc_raise(mrb, mrb_obj_value(mrb->arena_err)); } #else if (gc->arena_idx >= gc->arena_capa) { /* extend arena */ gc->arena_capa = (int)(gc->arena_capa * 1.5); gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*gc->arena_capa); } #endif gc->arena[gc->arena_idx++] = p; }
static void gc_protect(mrb_state *mrb, struct RBasic *p) { #ifdef MRB_GC_FIXED_ARENA if (mrb->arena_idx >= MRB_GC_ARENA_SIZE) { /* arena overflow error */ mrb->arena_idx = MRB_GC_ARENA_SIZE - 4; /* force room in arena */ mrb_raise(mrb, E_RUNTIME_ERROR, "arena overflow error"); } #else if (mrb->arena_idx >= mrb->arena_capa) { /* extend arena */ mrb->arena_capa = (int)(mrb->arena_capa * 1.5); mrb->arena = (struct RBasic**)mrb_realloc(mrb, mrb->arena, sizeof(struct RBasic*)*mrb->arena_capa); } #endif mrb->arena[mrb->arena_idx++] = p; }
static void ary_make_shared(mrb_state *mrb, struct RArray *a) { if (!(a->flags & MRB_ARY_SHARED)) { struct mrb_shared_array *shared = (struct mrb_shared_array *)mrb_malloc(mrb, sizeof(struct mrb_shared_array)); shared->refcnt = 1; if (a->aux.capa > a->len) { a->ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1); } else { shared->ptr = a->ptr; } shared->len = a->len; a->aux.shared = shared; a->flags |= MRB_ARY_SHARED; } }
static void ary_make_shared(mrb_state *mrb, struct RArray *a) { if (!ARY_SHARED_P(a)) { mrb_shared_array *shared = (mrb_shared_array *)mrb_malloc(mrb, sizeof(mrb_shared_array)); shared->refcnt = 1; if (a->aux.capa > a->len) { a->ptr = shared->ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*a->len+1); } else { shared->ptr = a->ptr; } shared->len = a->len; a->aux.shared = shared; ARY_SET_SHARED_FLAG(a); } }
static void stack_extend(mrb_state *mrb, int room, int keep) { int size, off; if (mrb->stack + room >= mrb->stend) { mrb_value *oldbase = mrb->stbase; size = mrb->stend - mrb->stbase; off = mrb->stack - mrb->stbase; /* do not leave uninitialized malloc region */ if (keep > size) keep = size; /* Use linear stack growth. It is slightly slower than doubling thestack space, but it saves memory on small devices. */ if (room <= size) size += MRB_STACK_GROWTH; else size += room; mrb->stbase = (mrb_value *)mrb_realloc(mrb, mrb->stbase, sizeof(mrb_value) * size); mrb->stack = mrb->stbase + off; mrb->stend = mrb->stbase + size; envadjust(mrb, oldbase, mrb->stbase); /* Raise an exception if the new stack size will be too large, to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raisef has stack space to work with. */ if(size > MRB_STACK_MAX) { mrb_raisef(mrb, E_RUNTIME_ERROR, "stack level too deep. (limit=%d)", MRB_STACK_MAX); } } if (room > keep) { 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 } } }
void mrb_add_irep(mrb_state *mrb, int idx) { if (!mrb->irep) { int max = 256; if (idx > max) max = idx+1; mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*)); mrb->irep_capa = max; } else if (mrb->irep_capa <= idx) { 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)); } }
void mrb_gc_arena_restore(mrb_state *mrb, int idx) { #ifndef MRB_GC_FIXED_ARENA int capa = mrb->arena_capa; if (idx < capa / 2) { capa = (int)(capa * 0.66); if (capa < MRB_GC_ARENA_SIZE) { capa = MRB_GC_ARENA_SIZE; } if (capa != mrb->arena_capa) { mrb->arena = (struct RBasic**)mrb_realloc(mrb, mrb->arena, sizeof(struct RBasic*)*capa); mrb->arena_capa = capa; } } #endif mrb->arena_idx = idx; }
static void ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) { mrb_int capa = ARY_CAPA(a); if (len > ARY_MAX_SIZE || len < 0) { size_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } if (capa < ARY_DEFAULT_LEN) { capa = ARY_DEFAULT_LEN; } while (capa < len) { if (capa <= ARY_MAX_SIZE / 2) { capa *= 2; } else { capa = len; } } if (capa < len || capa > ARY_MAX_SIZE) { goto size_error; } if (ARY_EMBED_P(a)) { mrb_value *ptr = ARY_EMBED_PTR(a); mrb_int len = ARY_EMBED_LEN(a); mrb_value *expanded_ptr = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*capa); ARY_UNSET_EMBED_FLAG(a); array_copy(expanded_ptr, ptr, len); a->as.heap.len = len; a->as.heap.aux.capa = capa; a->as.heap.ptr = expanded_ptr; } else if (capa > a->as.heap.aux.capa) { mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->as.heap.ptr, sizeof(mrb_value)*capa); a->as.heap.aux.capa = capa; a->as.heap.ptr = expanded_ptr; } }
static mrb_sym sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) { khash_t(n2s) *h = mrb->name2sym; symbol_name *sname = mrb->symtbl; /* symtbl[0] for working memory */ khiter_t k; mrb_sym sym; char *p; sym_validate_len(mrb, len); if (sname) { sname->lit = lit; sname->len = (uint16_t)len; sname->name = name; k = kh_get(n2s, mrb, h, 0); if (k != kh_end(h)) return kh_key(h, k); } /* registering a new symbol */ sym = ++mrb->symidx; if (mrb->symcapa < sym) { if (mrb->symcapa == 0) mrb->symcapa = 100; else mrb->symcapa = (size_t)(mrb->symcapa * 1.2); mrb->symtbl = (symbol_name*)mrb_realloc(mrb, mrb->symtbl, sizeof(symbol_name)*(mrb->symcapa+1)); } sname = &mrb->symtbl[sym]; sname->len = (uint16_t)len; if (lit || mrb_ro_data_p(name)) { sname->name = name; sname->lit = TRUE; } else { p = (char *)mrb_malloc(mrb, len+1); memcpy(p, name, len); p[len] = 0; sname->name = (const char*)p; sname->lit = FALSE; } kh_put(n2s, mrb, h, sym); return sym; }
void mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f) { #ifdef MRB_FIXED_STATE_ATEXIT_STACK if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) { mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit"); } #else size_t stack_size; stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1); if (mrb->atexit_stack_len == 0) { mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size); } else { mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size); } #endif mrb->atexit_stack[mrb->atexit_stack_len++] = f; }
static mrb_callinfo* cipush(mrb_state *mrb) { int eidx = mrb->ci->eidx; int ridx = mrb->ci->ridx; if (mrb->ci + 1 == mrb->ciend) { size_t size = mrb->ci - mrb->cibase; mrb->cibase = (mrb_callinfo *)mrb_realloc(mrb, mrb->cibase, sizeof(mrb_callinfo)*size*2); mrb->ci = mrb->cibase + size; mrb->ciend = mrb->cibase + size * 2; } mrb->ci++; mrb->ci->nregs = 2; mrb->ci->eidx = eidx; mrb->ci->ridx = ridx; mrb->ci->env = 0; return mrb->ci; }