diff options
| -rw-r--r-- | include/mruby/compile.h | 2 | ||||
| -rw-r--r-- | include/mruby/hash.h | 8 | ||||
| -rw-r--r-- | include/mruby/irep.h | 6 | ||||
| -rw-r--r-- | include/mruby/object.h | 5 | ||||
| -rw-r--r-- | include/mruby/proc.h | 8 | ||||
| -rw-r--r-- | include/mruby/string.h | 5 | ||||
| -rw-r--r-- | include/mruby/value.h | 2 | ||||
| -rw-r--r-- | include/mruby/variable.h | 12 | ||||
| -rw-r--r-- | mrbgems/mruby-fiber/src/fiber.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-proc-ext/src/proc.c | 43 | ||||
| -rw-r--r-- | mrbgems/mruby-sprintf/src/sprintf.c | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-string-utf8/src/string.c | 29 | ||||
| -rw-r--r-- | mrbgems/mruby-struct/src/struct.c | 54 | ||||
| -rw-r--r-- | mrblib/class.rb | 23 | ||||
| -rw-r--r-- | src/class.c | 117 | ||||
| -rw-r--r-- | src/codegen.c | 74 | ||||
| -rw-r--r-- | src/dump.c | 89 | ||||
| -rw-r--r-- | src/error.c | 2 | ||||
| -rw-r--r-- | src/gc.c | 14 | ||||
| -rw-r--r-- | src/hash.c | 26 | ||||
| -rw-r--r-- | src/kernel.c | 88 | ||||
| -rw-r--r-- | src/load.c | 86 | ||||
| -rw-r--r-- | src/numeric.c | 2 | ||||
| -rw-r--r-- | src/parse.y | 404 | ||||
| -rw-r--r-- | src/pool.c | 10 | ||||
| -rw-r--r-- | src/proc.c | 72 | ||||
| -rw-r--r-- | src/state.c | 2 | ||||
| -rw-r--r-- | src/string.c | 37 | ||||
| -rw-r--r-- | src/symbol.c | 19 | ||||
| -rw-r--r-- | src/variable.c | 32 | ||||
| -rw-r--r-- | src/vm.c | 17 |
31 files changed, 735 insertions, 563 deletions
diff --git a/include/mruby/compile.h b/include/mruby/compile.h index 5efdef213..a85939998 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -29,6 +29,7 @@ typedef struct mrbc_context { mrb_bool dump_result:1; mrb_bool no_exec:1; mrb_bool keep_lv:1; + mrb_bool no_optimize:1; } mrbc_context; mrbc_context* mrbc_context_new(mrb_state *mrb); @@ -143,6 +144,7 @@ struct mrb_parser_state { size_t nwarn; mrb_ast_node *tree; + mrb_bool no_optimize:1; mrb_bool capture_errors:1; struct mrb_parser_message error_buffer[10]; struct mrb_parser_message warn_buffer[10]; diff --git a/include/mruby/hash.h b/include/mruby/hash.h index dbad3e1fc..5339312c6 100644 --- a/include/mruby/hash.h +++ b/include/mruby/hash.h @@ -21,7 +21,7 @@ struct RHash { #define mrb_hash_value(p) mrb_obj_value((void*)(p)) MRB_API mrb_value mrb_hash_new_capa(mrb_state*, int); -mrb_value mrb_hash_new(mrb_state *mrb); +MRB_API mrb_value mrb_hash_new(mrb_state *mrb); MRB_API void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val); MRB_API mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key); @@ -43,9 +43,9 @@ MRB_API struct kh_ht * mrb_hash_tbl(mrb_state *mrb, mrb_value hash); #define MRB_RHASH_PROCDEFAULT_P(h) (RHASH(h)->flags & MRB_HASH_PROC_DEFAULT) /* GC functions */ -MRB_API void mrb_gc_mark_hash(mrb_state*, struct RHash*); -MRB_API size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); -MRB_API void mrb_gc_free_hash(mrb_state*, struct RHash*); +void mrb_gc_mark_hash(mrb_state*, struct RHash*); +size_t mrb_gc_mark_hash_size(mrb_state*, struct RHash*); +void mrb_gc_free_hash(mrb_state*, struct RHash*); #if defined(__cplusplus) } /* extern "C" { */ diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 766431e2c..f4061bb54 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -49,9 +49,9 @@ typedef struct mrb_irep { MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb); MRB_API mrb_value mrb_load_irep(mrb_state*, const uint8_t*); MRB_API mrb_value mrb_load_irep_cxt(mrb_state*, const uint8_t*, mrbc_context*); -MRB_API void mrb_irep_free(mrb_state*, struct mrb_irep*); -MRB_API void mrb_irep_incref(mrb_state*, struct mrb_irep*); -MRB_API void mrb_irep_decref(mrb_state*, struct mrb_irep*); +void mrb_irep_free(mrb_state*, struct mrb_irep*); +void mrb_irep_incref(mrb_state*, struct mrb_irep*); +void mrb_irep_decref(mrb_state*, struct mrb_irep*); #if defined(__cplusplus) } /* extern "C" { */ diff --git a/include/mruby/object.h b/include/mruby/object.h index 56917a021..fe55620fe 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -37,16 +37,13 @@ struct RBasic { MRB_OBJECT_HEADER; }; #define mrb_basic_ptr(v) ((struct RBasic*)(mrb_ptr(v))) -/* obsolete macro mrb_basic; will be removed soon */ -#define mrb_basic(v) mrb_basic_ptr(v) struct RObject { MRB_OBJECT_HEADER; struct iv_tbl *iv; }; #define mrb_obj_ptr(v) ((struct RObject*)(mrb_ptr(v))) -/* obsolete macro mrb_object; will be removed soon */ -#define mrb_object(o) mrb_obj_ptr(o) + #define mrb_immediate_p(x) (mrb_type(x) < MRB_TT_HAS_BASIC) #define mrb_special_const_p(x) mrb_immediate_p(x) diff --git a/include/mruby/proc.h b/include/mruby/proc.h index 9c25c9c46..fe5a1d2f6 100644 --- a/include/mruby/proc.h +++ b/include/mruby/proc.h @@ -54,14 +54,16 @@ struct RProc *mrb_proc_new(mrb_state*, mrb_irep*); struct RProc *mrb_closure_new(mrb_state*, mrb_irep*); MRB_API struct RProc *mrb_proc_new_cfunc(mrb_state*, mrb_func_t); MRB_API struct RProc *mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals); -MRB_API void mrb_proc_copy(struct RProc *a, struct RProc *b); +void mrb_proc_copy(struct RProc *a, struct RProc *b); /* implementation of #send method */ -mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); +MRB_API mrb_value mrb_f_send(mrb_state *mrb, mrb_value self); /* following functions are defined in mruby-proc-ext so please include it when using */ MRB_API struct RProc *mrb_proc_new_cfunc_with_env(mrb_state*, mrb_func_t, mrb_int, const mrb_value*); -MRB_API mrb_value mrb_cfunc_env_get(mrb_state*, mrb_int); +MRB_API mrb_value mrb_proc_cfunc_env_get(mrb_state*, mrb_int); +/* old name */ +#define mrb_cfunc_env_get(mrb, idx) mrb_proc_cfunc_env_get(mrb, idx) #include "mruby/khash.h" KHASH_DECLARE(mt, mrb_sym, struct RProc*, TRUE) diff --git a/include/mruby/string.h b/include/mruby/string.h index 0bd4cfc0f..5228dcbca 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -74,7 +74,7 @@ mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_EMBED_LEN_MASK 0xf8 #define MRB_STR_EMBED_LEN_SHIFT 3 -MRB_API void mrb_gc_free_str(mrb_state*, struct RString*); +void mrb_gc_free_str(mrb_state*, struct RString*); MRB_API void mrb_str_modify(mrb_state*, struct RString*); MRB_API void mrb_str_concat(mrb_state*, mrb_value, mrb_value); MRB_API mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value); @@ -107,6 +107,9 @@ mrb_int mrb_str_hash(mrb_state *mrb, mrb_value str); mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str); mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str); +void mrb_noregexp(mrb_state *mrb, mrb_value self); +void mrb_regexp_check(mrb_state *mrb, mrb_value obj); + /* For backward compatibility */ #define mrb_str_cat2(mrb, str, ptr) mrb_str_cat_cstr(mrb, str, ptr) #define mrb_str_buf_cat(mrb, str, ptr, len) mrb_str_cat(mrb, str, ptr, len) diff --git a/include/mruby/value.h b/include/mruby/value.h index b1278e3a3..859687ffc 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -7,7 +7,7 @@ #ifndef MRUBY_VALUE_H #define MRUBY_VALUE_H -typedef short mrb_sym; +typedef uint16_t mrb_sym; typedef uint8_t mrb_bool; struct mrb_state; diff --git a/include/mruby/variable.h b/include/mruby/variable.h index 0851a05bb..8758114b9 100644 --- a/include/mruby/variable.h +++ b/include/mruby/variable.h @@ -39,6 +39,8 @@ MRB_API void mrb_const_set(mrb_state*, mrb_value, mrb_sym, mrb_value); MRB_API mrb_bool mrb_const_defined(mrb_state*, mrb_value, mrb_sym); MRB_API void mrb_const_remove(mrb_state*, mrb_value, mrb_sym); +MRB_API mrb_bool mrb_iv_p(mrb_state *mrb, mrb_sym sym); +MRB_API mrb_bool mrb_iv_check(mrb_state *mrb, mrb_sym sym); MRB_API mrb_value mrb_obj_iv_get(mrb_state *mrb, struct RObject *obj, mrb_sym sym); MRB_API void mrb_obj_iv_set(mrb_state *mrb, struct RObject *obj, mrb_sym sym, mrb_value v); MRB_API mrb_bool mrb_obj_iv_defined(mrb_state *mrb, struct RObject *obj, mrb_sym sym); @@ -66,11 +68,11 @@ mrb_bool mrb_mod_cv_defined(mrb_state *mrb, struct RClass * c, mrb_sym sym); mrb_sym mrb_class_sym(mrb_state *mrb, struct RClass *c, struct RClass *outer); /* GC functions */ -MRB_API void mrb_gc_mark_gv(mrb_state*); -MRB_API void mrb_gc_free_gv(mrb_state*); -MRB_API void mrb_gc_mark_iv(mrb_state*, struct RObject*); -MRB_API size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); -MRB_API void mrb_gc_free_iv(mrb_state*, struct RObject*); +void mrb_gc_mark_gv(mrb_state*); +void mrb_gc_free_gv(mrb_state*); +void mrb_gc_mark_iv(mrb_state*, struct RObject*); +size_t mrb_gc_mark_iv_size(mrb_state*, struct RObject*); +void mrb_gc_free_iv(mrb_state*, struct RObject*); #if defined(__cplusplus) } /* extern "C" { */ diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 7b4ddfb11..de4901a87 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -291,7 +291,7 @@ fiber_transfer(mrb_state *mrb, mrb_value self) return fiber_switch(mrb, self, len, a, FALSE); } -mrb_value +MRB_API mrb_value mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a) { struct mrb_context *c = mrb->c; diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index 14b68547e..73873a360 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -5,49 +5,6 @@ #include "mruby/string.h" #include "mruby/debug.h" -MRB_API struct RProc * -mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t f, mrb_int argc, const mrb_value *argv) -{ - struct RProc *p; - struct REnv *e; - int ai, i; - - p = mrb_proc_new_cfunc(mrb, f); - ai = mrb_gc_arena_save(mrb); - e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, NULL); - p->env = e; - mrb_gc_arena_restore(mrb, ai); - - MRB_ENV_UNSHARE_STACK(e); - MRB_ENV_STACK_LEN(e) = argc; - e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); - for (i = 0; i < argc; ++i) { - e->stack[i] = argv[i]; - } - - return p; -} - -MRB_API mrb_value -mrb_cfunc_env_get(mrb_state *mrb, mrb_int idx) -{ - struct RProc *p = mrb->c->ci->proc; - struct REnv *e = p->env; - - if (!MRB_PROC_CFUNC_P(p)) { - mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); - } - if (!e) { - mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); - } - if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { - mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", - mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e))); - } - - return e->stack[idx]; -} - static mrb_value mrb_proc_lambda(mrb_state *mrb, mrb_value self) { diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index 3fce60237..d88e242c6 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -178,17 +178,18 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) } #define GETASTER(num) do { \ + mrb_value tmp_v; \ t = p++; \ n = 0; \ GETNUM(n, val); \ if (*p == '$') { \ - tmp = GETPOSARG(n); \ + tmp_v = GETPOSARG(n); \ } \ else { \ - tmp = GETARG(); \ + tmp_v = GETARG(); \ p = t; \ } \ - num = mrb_fixnum(tmp); \ + num = mrb_fixnum(tmp_v); \ } while (0) static mrb_value @@ -500,7 +501,6 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt) int nextarg = 1; int posarg = 0; mrb_value nextvalue; - mrb_value tmp; mrb_value str; mrb_value hash = mrb_undef_value(); diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index a1b779f95..b232df1c5 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -106,21 +106,6 @@ mrb_str_size(mrb_state *mrb, mrb_value str) #define RSTRING_LEN_UTF8(s) mrb_utf8_strlen(s, -1) -static mrb_value -noregexp(mrb_state *mrb, mrb_value self) -{ - mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); - return mrb_nil_value(); -} - -static void -regexp_check(mrb_state *mrb, mrb_value obj) -{ - if (mrb_regexp_p(mrb, obj)) { - noregexp(mrb, obj); - } -} - static inline mrb_int mrb_memsearch_qs(const unsigned char *xs, mrb_int m, const unsigned char *ys, mrb_int n) { @@ -270,7 +255,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { mrb_int idx; - regexp_check(mrb, indx); + mrb_regexp_check(mrb, indx); switch (mrb_type(indx)) { case MRB_TT_FIXNUM: idx = mrb_fixnum(indx); @@ -315,7 +300,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) argc = mrb_get_args(mrb, "o|o", &a1, &a2); if (argc == 2) { - regexp_check(mrb, a1); + mrb_regexp_check(mrb, a1); return str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2)); } if (argc != 1) { @@ -346,7 +331,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) sub = mrb_nil_value(); } - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); if (pos < 0) { pos += RSTRING_LEN(str); if (pos < 0) { @@ -425,7 +410,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) if (pos < 0) { pos += len; if (pos < 0) { - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); return mrb_nil_value(); } } @@ -438,7 +423,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) else sub = mrb_nil_value(); } - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); if (mrb_type(sub) == MRB_TT_FIXNUM) { sub = mrb_fixnum_chr(mrb, sub); @@ -548,7 +533,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } } else { - noregexp(mrb, str); + mrb_noregexp(mrb, str); } } @@ -618,7 +603,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) beg = ptr - temp; } else { - noregexp(mrb, str); + mrb_noregexp(mrb, str); } if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { if (RSTRING_LEN(str) == beg) { diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index 930384806..415a8a1d6 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -224,14 +224,37 @@ is_const_id(mrb_state *mrb, const char *name) return ISUPPER(name[0]); } +static void +make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c) +{ + mrb_value *ptr_members = RARRAY_PTR(members); + mrb_int i; + mrb_int len = RARRAY_LEN(members); + int ai = mrb_gc_arena_save(mrb); + + for (i=0; i<len; i++) { + mrb_sym id = mrb_symbol(ptr_members[i]); + const char *name = mrb_sym2name_len(mrb, id, NULL); + + if (is_local_id(mrb, name) || is_const_id(mrb, name)) { + if (i < N_REF_FUNC) { + mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE()); + } + else { + mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); + } + mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); + mrb_gc_arena_restore(mrb, ai); + } + } +} + static mrb_value make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * klass) { - mrb_value nstr, *ptr_members; + mrb_value nstr; mrb_sym id; - mrb_int i, len; struct RClass *c; - int ai; if (mrb_nil_p(name)) { c = mrb_class_new(mrb, klass); @@ -257,24 +280,7 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k mrb_define_class_method(mrb, c, "[]", mrb_instance_new, MRB_ARGS_ANY()); mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, MRB_ARGS_NONE()); /* RSTRUCT(nstr)->basic.c->super = c->c; */ - ptr_members = RARRAY_PTR(members); - len = RARRAY_LEN(members); - ai = mrb_gc_arena_save(mrb); - for (i=0; i< len; i++) { - mrb_sym id = mrb_symbol(ptr_members[i]); - const char *name = mrb_sym2name_len(mrb, id, NULL); - - if (is_local_id(mrb, name) || is_const_id(mrb, name)) { - if (i < N_REF_FUNC) { - mrb_define_method_id(mrb, c, id, ref_func[i], MRB_ARGS_NONE()); - } - else { - mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE()); - } - mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1)); - mrb_gc_arena_restore(mrb, ai); - } - } + make_struct_define_accessors(mrb, members, c); return nstr; } @@ -432,7 +438,7 @@ inspect_struct(mrb_state *mrb, mrb_value s, mrb_bool recur) mrb_value slot; mrb_sym id; const char *name; - mrb_int len; + mrb_int namelen; if (i > 0) { mrb_str_cat_lit(mrb, str, ", "); @@ -442,9 +448,9 @@ inspect_struct(mrb_state *mrb, mrb_value s, mrb_bool recur) } slot = ptr_members[i]; id = mrb_symbol(slot); - name = mrb_sym2name_len(mrb, id, &len); + name = mrb_sym2name_len(mrb, id, &namelen); if (is_local_id(mrb, name) || is_const_id(mrb, name)) { - mrb_str_append(mrb, str, mrb_str_new(mrb, name, len)); + mrb_str_append(mrb, str, mrb_str_new(mrb, name, namelen)); } else { mrb_str_append(mrb, str, mrb_inspect(mrb, slot)); diff --git a/mrblib/class.rb b/mrblib/class.rb index ebfb1f76d..39e0d5091 100644 --- a/mrblib/class.rb +++ b/mrblib/class.rb @@ -1,26 +1,5 @@ class Module - # 15.2.2.4.13 - def attr_reader(*names) - names.each do |name| - name = name.to_s - raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$') - - attr_name = '@'+name - define_method(name){self.instance_variable_get(attr_name)} - end - end - # 15.2.2.4.14 - def attr_writer(*names) - names.each do |name| - name = name.to_s - raise(NameError, "#{name.inspect} is not allowed as an instance variable name") if name.include?('@') || name.include?('?') || name.include?('$') - - attr_name = '@'+name - name = (name+"=").intern - define_method(name){|v|self.instance_variable_set(attr_name,v)} - end - end - # 15.2.2.4.12 + # 15.2.2.4.12 def attr_accessor(*names) attr_reader(*names) attr_writer(*names) diff --git a/src/class.c b/src/class.c index d3a2403f1..c11346223 100644 --- a/src/class.c +++ b/src/class.c @@ -393,6 +393,21 @@ to_hash(mrb_state *mrb, mrb_value val) return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); } +static mrb_sym +to_sym(mrb_state *mrb, mrb_value ss) +{ + if (mrb_type(ss) == MRB_TT_SYMBOL) { + return mrb_symbol(ss); + } + else if (mrb_string_p(ss)) { + return mrb_intern_str(mrb, to_str(mrb, ss)); + } + else { + mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); + } +} + /* retrieve arguments from mrb_state. @@ -635,16 +650,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value ss; ss = *sp++; - if (mrb_type(ss) == MRB_TT_SYMBOL) { - *symp = mrb_symbol(ss); - } - else if (mrb_string_p(ss)) { - *symp = mrb_intern_str(mrb, to_str(mrb, ss)); - } - else { - mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); - } + *symp = to_sym(mrb, ss); i++; } } @@ -958,7 +964,7 @@ mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) return mod; } -mrb_value +MRB_API mrb_value mrb_singleton_class(mrb_state *mrb, mrb_value v) { struct RBasic *obj; @@ -1051,6 +1057,91 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) } static mrb_value +attr_reader(mrb_state *mrb, mrb_value obj) +{ + mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); + return mrb_iv_get(mrb, obj, to_sym(mrb, name)); +} + +static mrb_value +mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_value *argv; + mrb_int argc, i; + int ai; + + mrb_get_args(mrb, "*", &argv, &argc); + ai = mrb_gc_arena_save(mrb); + for (i=0; i<argc; i++) { + mrb_value name, str; + mrb_sym method, sym; + + method = to_sym(mrb, argv[i]); + name = mrb_sym2str(mrb, method); + str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1); + mrb_str_cat_lit(mrb, str, "@"); + mrb_str_cat_str(mrb, str, name); + sym = mrb_intern_str(mrb, str); + mrb_iv_check(mrb, sym); + name = mrb_symbol_value(sym); + mrb_define_method_raw(mrb, c, method, + mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name)); + mrb_gc_arena_restore(mrb, ai); + } + return mrb_nil_value(); +} + +static mrb_value +attr_writer(mrb_state *mrb, mrb_value obj) +{ + mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); + mrb_value val; + + mrb_get_args(mrb, "o", &val); + mrb_iv_set(mrb, obj, to_sym(mrb, name), val); + return val; +} + +static mrb_value +mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) +{ + struct RClass *c = mrb_class_ptr(mod); + mrb_value *argv; + mrb_int argc, i; + int ai; + + mrb_get_args(mrb, "*", &argv, &argc); + ai = mrb_gc_arena_save(mrb); + for (i=0; i<argc; i++) { + mrb_value name, str, attr; + mrb_sym method, sym; + + method = to_sym(mrb, argv[i]); + + /* prepare iv name (@name) */ + name = mrb_sym2str(mrb, method); + str = mrb_str_buf_new(mrb, RSTRING_LEN(name)+1); + mrb_str_cat_lit(mrb, str, "@"); + mrb_str_cat_str(mrb, str, name); + sym = mrb_intern_str(mrb, str); + mrb_iv_check(mrb, sym); + attr = mrb_symbol_value(sym); + + /* prepare method name (name=) */ + str = mrb_str_buf_new(mrb, RSTRING_LEN(str)); + mrb_str_cat_str(mrb, str, name); + mrb_str_cat_lit(mrb, str, "="); + method = mrb_intern_str(mrb, str); + + mrb_define_method_raw(mrb, c, method, + mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr)); + mrb_gc_arena_restore(mrb, ai); + } + return mrb_nil_value(); +} + +static mrb_value mrb_instance_alloc(mrb_state *mrb, mrb_value cv) { struct RClass *c = mrb_class_ptr(cv); @@ -1409,7 +1500,7 @@ mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) * \param name1 a new name for the method * \param name2 the original name of the method */ -void +MRB_API void mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2) { mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2)); @@ -2033,6 +2124,8 @@ mrb_init_class(mrb_state *mrb) mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */ mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */ mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ + mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */ + mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */ mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE()); mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */ diff --git a/src/codegen.c b/src/codegen.c index b2b1e4150..e6f277b1b 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -81,7 +81,7 @@ static struct loopinfo *loop_push(codegen_scope *s, enum looptype t); static void loop_break(codegen_scope *s, node *tree); static void loop_pop(codegen_scope *s, int val); -static void gen_assignment(codegen_scope *s, node *node, int sp, int val); +static void gen_assignment(codegen_scope *s, node *tree, int sp, int val); static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val); static void codegen(codegen_scope *s, node *tree, int val); @@ -162,11 +162,19 @@ genop(codegen_scope *s, mrb_code i) #define NOVAL 0 #define VAL 1 +static mrb_bool +no_optimize(codegen_scope *s) +{ + if (s && s->parser && s->parser->no_optimize) + return TRUE; + return FALSE; +} + static int genop_peep(codegen_scope *s, mrb_code i, int val) { /* peephole optimization */ - if (s->lastlabel != s->pc && s->pc > 0) { + if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) { mrb_code i0 = s->iseq[s->pc-1]; int c1 = GET_OPCODE(i); int c0 = GET_OPCODE(i0); @@ -180,13 +188,13 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (val) break; switch (c0) { case OP_MOVE: - if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0) && GETARG_A(i) >= s->nlocals) { + if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { /* skip swapping OP_MOVE */ return 0; } if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { - s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)); - return 0; + s->pc--; + return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val); } break; case OP_LOADI: @@ -319,10 +327,9 @@ genop_peep(codegen_scope *s, mrb_code i, int val) } case OP_STRCAT: if (c0 == OP_STRING) { - int i = GETARG_Bx(i0); + mrb_value v = s->irep->pool[GETARG_Bx(i0)]; - if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING && - RSTRING_LEN(s->irep->pool[i]) == 0) { + if (mrb_string_p(v) && RSTRING_LEN(v) == 0) { s->pc--; return 0; } @@ -837,34 +844,34 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val) push();pop(); pop_n(n+1); { - mrb_int len; - const char *name = mrb_sym2name_len(s->mrb, sym, &len); + mrb_int symlen; + const char *symname = mrb_sym2name_len(s->mrb, sym, &symlen); - if (!noop && len == 1 && name[0] == '+') { + if (!noop && symlen == 1 && symname[0] == '+') { genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val); } - else if (!noop && len == 1 && name[0] == '-') { + else if (!noop && symlen == 1 && symname[0] == '-') { genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val); } - else if (!noop && len == 1 && name[0] == '*') { + else if (!noop && symlen == 1 && symname[0] == '*') { genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n)); } - else if (!noop && len == 1 && name[0] == '/') { + else if (!noop && symlen == 1 && symname[0] == '/') { genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n)); } - else if (!noop && len == 1 && name[0] == '<') { + else if (!noop && symlen == 1 && symname[0] == '<') { genop(s, MKOP_ABC(OP_LT, cursp(), idx, n)); } - else if (!noop && len == 2 && name[0] == '<' && name[1] == '=') { + else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=') { genop(s, MKOP_ABC(OP_LE, cursp(), idx, n)); } - else if (!noop && len == 1 && name[0] == '>') { + else if (!noop && symlen == 1 && symname[0] == '>') { genop(s, MKOP_ABC(OP_GT, cursp(), idx, n)); } - else if (!noop && len == 2 && name[0] == '>' && name[1] == '=') { + else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=') { genop(s, MKOP_ABC(OP_GE, cursp(), idx, n)); } - else if (!noop && len == 2 && name[0] == '=' && name[1] == '=') { + else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=') { genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n)); } else { @@ -883,19 +890,19 @@ gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val) } static void -gen_assignment(codegen_scope *s, node *node, int sp, int val) +gen_assignment(codegen_scope *s, node *tree, int sp, int val) { int idx; - int type = (intptr_t)node->car; + int type = (intptr_t)tree->car; - node = node->cdr; + tree = tree->cdr; switch ((intptr_t)type) { case NODE_GVAR: - idx = new_sym(s, sym(node)); + idx = new_sym(s, sym(tree)); genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val); break; case NODE_LVAR: - idx = lv_idx(s, sym(node)); + idx = lv_idx(s, sym(tree)); if (idx > 0) { if (idx != sp) { genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val); @@ -907,7 +914,7 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val) codegen_scope *up = s->prev; while (up) { - idx = lv_idx(up, sym(node)); + idx = lv_idx(up, sym(tree)); if (idx > 0) { genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val); break; @@ -918,29 +925,29 @@ gen_assignment(codegen_scope *s, node *node, int sp, int val) } break; case NODE_IVAR: - idx = new_sym(s, sym(node)); + idx = new_sym(s, sym(tree)); genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val); break; case NODE_CVAR: - idx = new_sym(s, sym(node)); + idx = new_sym(s, sym(tree)); genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val); break; case NODE_CONST: - idx = new_sym(s, sym(node)); + idx = new_sym(s, sym(tree)); genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val); break; case NODE_COLON2: - idx = new_sym(s, sym(node->cdr)); + idx = new_sym(s, sym(tree->cdr)); genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL); push(); - codegen(s, node->car, VAL); + codegen(s, tree->car, VAL); pop_n(2); genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val); break; case NODE_CALL: push(); - gen_call(s, node, attrsym(s, sym(node->cdr->car)), sp, NOVAL); + gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL); pop(); if (val) { genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val); @@ -2225,7 +2232,6 @@ codegen(codegen_scope *s, node *tree, int val) } if (n->cdr) { char *p2 = (char*)n->cdr; - int off; push(); off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); @@ -2299,7 +2305,7 @@ codegen(codegen_scope *s, node *tree, int val) { int a = new_msym(s, sym(tree->car)); int b = new_msym(s, sym(tree->cdr)); - int c = new_msym(s, mrb_intern_lit(s->mrb,"alias_method")); + int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method")); genop(s, MKOP_A(OP_TCLASS, cursp())); push(); @@ -3106,7 +3112,7 @@ mrb_codedump_all(mrb_state *mrb, struct RProc *proc) codedump_recur(mrb, proc->body.irep); } -struct RProc* +MRB_API struct RProc* mrb_generate_code(mrb_state *mrb, parser_state *p) { codegen_scope *scope = scope_new(mrb, 0, 0); diff --git a/src/dump.c b/src/dump.c index e019baa99..0ea4e5afe 100644 --- a/src/dump.c +++ b/src/dump.c @@ -13,6 +13,9 @@ #include "mruby/numeric.h" #include "mruby/debug.h" +#define FLAG_BYTEORDER_NATIVE 2 +#define FLAG_BYTEORDER_NONATIVE 0 + #ifdef ENABLE_STDIO static size_t get_irep_record_size_1(mrb_state *mrb, mrb_irep *irep); @@ -58,14 +61,20 @@ get_iseq_block_size(mrb_state *mrb, mrb_irep *irep) } static ptrdiff_t -write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf) +write_iseq_block(mrb_state *mrb, mrb_irep *irep, uint8_t *buf, uint8_t flags) { uint8_t *cur = buf; uint32_t iseq_no; cur += uint32_to_bin(irep->ilen, cur); /* number of opcode */ - for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { - cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + if (flags & FLAG_BYTEORDER_NATIVE) { + memcpy(cur, irep->iseq, irep->ilen * sizeof(mrb_code)); + cur += irep->ilen * sizeof(mrb_code); + } + else { + for (iseq_no = 0; iseq_no < irep->ilen; iseq_no++) { + cur += uint32_to_bin(irep->iseq[iseq_no], cur); /* opcode */ + } } return cur - buf; @@ -263,7 +272,7 @@ get_irep_record_size(mrb_state *mrb, mrb_irep *irep) } static int -write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size) +write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_record_size, uint8_t flags) { uint32_t i; @@ -279,7 +288,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec memset(bin, 0, *irep_record_size); bin += write_irep_header(mrb, irep, bin); - bin += write_iseq_block(mrb, irep, bin); + bin += write_iseq_block(mrb, irep, bin, flags); bin += write_pool_block(mrb, irep, bin); bin += write_syms_block(mrb, irep, bin); @@ -287,7 +296,7 @@ write_irep_record(mrb_state *mrb, mrb_irep *irep, uint8_t* bin, size_t *irep_rec int result; size_t rsize; - result = write_irep_record(mrb, irep->reps[i], bin, &rsize); + result = write_irep_record(mrb, irep->reps[i], bin, &rsize, flags); if (result != MRB_DUMP_OK) { return result; } @@ -325,7 +334,7 @@ write_section_irep_header(mrb_state *mrb, size_t section_size, uint8_t *bin) } static int -write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) +write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin, uint8_t flags) { int result; size_t section_size = 0; /* size of irep record */ @@ -339,7 +348,7 @@ write_section_irep(mrb_state *mrb, mrb_irep *irep, uint8_t *bin) cur += sizeof(struct rite_section_irep_header); section_size += sizeof(struct rite_section_irep_header); - result = write_irep_record(mrb, irep, cur, &rsize); + result = write_irep_record(mrb, irep, cur, &rsize, flags); if (result != MRB_DUMP_OK) { return result; } @@ -795,13 +804,25 @@ lv_section_exit: } static int -write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin) +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_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)); + if (flags & FLAG_BYTEORDER_NATIVE) { + uint32_t ident = 0; + size_t i; + + for(i=0; i<sizeof(ident); i++) { + ident<<=8; + ident|=RITE_BINARY_IDENTIFIER[i]; + } + memcpy(header->binary_identify, (char*)&ident, sizeof(uint32_t)); + } + else { + memcpy(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)); + } memcpy(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)); memcpy(header->compiler_name, RITE_COMPILER_NAME, sizeof(header->compiler_name)); memcpy(header->compiler_version, RITE_COMPILER_VERSION, sizeof(header->compiler_version)); @@ -841,8 +862,8 @@ is_lv_defined(mrb_irep *irep) return FALSE; } -int -mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) +static int +dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size, uint8_t flags) { int result = MRB_DUMP_GENERAL_FAILURE; size_t section_irep_size; @@ -889,12 +910,9 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz section_irep_size + section_lineno_size + section_lv_size + sizeof(struct rite_binary_footer); cur = *bin = (uint8_t*)mrb_malloc(mrb, *bin_size); - if (cur == NULL) { - goto error_exit; - } cur += sizeof(struct rite_binary_header); - result = write_section_irep(mrb, irep, cur); + result = write_section_irep(mrb, irep, cur, flags); if (result != MRB_DUMP_OK) { goto error_exit; } @@ -923,7 +941,7 @@ mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, siz } write_footer(mrb, cur); - write_rite_binary_header(mrb, *bin_size, *bin); + write_rite_binary_header(mrb, *bin_size, *bin, flags); error_exit: if (result != MRB_DUMP_OK) { @@ -940,6 +958,12 @@ error_exit: } int +mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, int debug_info, uint8_t **bin, size_t *bin_size) +{ + return dump_irep(mrb, irep, debug_info, bin, bin_size, FLAG_BYTEORDER_NONATIVE); +} + +int mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) { uint8_t *bin = NULL; @@ -950,7 +974,7 @@ mrb_dump_irep_binary(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE* fp) return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NONATIVE); if (result == MRB_DUMP_OK) { if (fwrite(bin, sizeof(bin[0]), bin_size, fp) != bin_size) { result = MRB_DUMP_WRITE_FAULT; @@ -988,15 +1012,32 @@ mrb_dump_irep_cfunc(mrb_state *mrb, mrb_irep *irep, int debug_info, FILE *fp, co return MRB_DUMP_INVALID_ARGUMENT; } - result = mrb_dump_irep(mrb, irep, debug_info, &bin, &bin_size); + result = dump_irep(mrb, irep, debug_info, &bin, &bin_size, FLAG_BYTEORDER_NATIVE); if (result == MRB_DUMP_OK) { - fprintf(fp, "#include <stdint.h>\n"); /* for uint8_t under at least Darwin */ - fprintf(fp, "const uint8_t %s[] = {", initname); + if (fprintf(fp, "#include <stdint.h>\n") < 0) { /* for uint8_t under at least Darwin */ + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + if (fprintf(fp, "const uint8_t %s[] = {", initname) < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } while (bin_idx < bin_size) { - if (bin_idx % 16 == 0) fputs("\n", fp); - fprintf(fp, "0x%02x,", bin[bin_idx++]); + if (bin_idx % 16 == 0) { + if (fputs("\n", fp) == EOF) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + if (fprintf(fp, "0x%02x,", bin[bin_idx++]) < 0) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; + } + } + if (fputs("\n};\n", fp) == EOF) { + mrb_free(mrb, bin); + return MRB_DUMP_WRITE_FAULT; } - fputs("\n};\n", fp); } mrb_free(mrb, bin); diff --git a/src/error.c b/src/error.c index fa1fcb9b7..0a1a97a0b 100644 --- a/src/error.c +++ b/src/error.c @@ -261,7 +261,7 @@ mrb_vformat(mrb_state *mrb, const char *format, va_list ap) else { size = p - b; mrb_ary_push(mrb, ary, mrb_str_new(mrb, b, size)); - return mrb_ary_join(mrb, ary, mrb_str_new(mrb,NULL,0)); + return mrb_ary_join(mrb, ary, mrb_str_new(mrb, NULL, 0)); } } @@ -227,11 +227,9 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) nelem <= SIZE_MAX / len) { size_t size; size = nelem * len; - p = mrb_realloc(mrb, 0, size); + p = mrb_malloc(mrb, size); - if (p) { - memset(p, 0, size); - } + memset(p, 0, size); } else { p = NULL; @@ -587,7 +585,7 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) } } -void +MRB_API void mrb_gc_mark(mrb_state *mrb, struct RBasic *obj) { if (obj == 0) return; @@ -1368,7 +1366,7 @@ test_mrb_field_write_barrier(void) obj = mrb_basic_ptr(mrb_ary_new(mrb)); value = mrb_basic_ptr(mrb_str_new_lit(mrb, "value")); paint_black(obj); - paint_partial_white(mrb,value); + paint_partial_white(mrb, value); puts(" in GC_STATE_MARK"); @@ -1379,7 +1377,7 @@ test_mrb_field_write_barrier(void) puts(" in GC_STATE_SWEEP"); - paint_partial_white(mrb,value); + paint_partial_white(mrb, value); mrb->gc_state = GC_STATE_SWEEP; mrb_field_write_barrier(mrb, obj, value); @@ -1390,7 +1388,7 @@ test_mrb_field_write_barrier(void) puts(" fail with black"); mrb->gc_state = GC_STATE_MARK; paint_white(obj); - paint_partial_white(mrb,value); + paint_partial_white(mrb, value); mrb_field_write_barrier(mrb, obj, value); mrb_assert(obj->color & mrb->current_white_part); diff --git a/src/hash.c b/src/hash.c index a43e8ae19..aa0322c8c 100644 --- a/src/hash.c +++ b/src/hash.c @@ -36,20 +36,20 @@ mrb_hash_ht_hash_func(mrb_state *mrb, mrb_value key) case MRB_TT_SYMBOL: h = (khint_t)mrb_symbol(key); - return kh_int_hash_func(mrb,h); + return kh_int_hash_func(mrb, h); case MRB_TT_FIXNUM: h = (khint_t)mrb_float_id((mrb_float)mrb_fixnum(key)); - return kh_int_hash_func(mrb,h); + return kh_int_hash_func(mrb, h); case MRB_TT_FLOAT: h = (khint_t)mrb_float_id(mrb_float(key)); - return kh_int_hash_func(mrb,h); + return kh_int_hash_func(mrb, h); default: hv = mrb_funcall(mrb, key, "hash", 0); h = (khint_t)t ^ mrb_fixnum(hv); - return kh_int_hash_func(mrb,h); + return kh_int_hash_func(mrb, h); } } @@ -241,11 +241,11 @@ mrb_hash_dup(mrb_state *mrb, mrb_value hash) ret_h = ret->ht; for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h,k)) { + if (kh_exist(h, k)) { int ai = mrb_gc_arena_save(mrb); - ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h,k))); + ret_k = kh_put(ht, mrb, ret_h, KEY(kh_key(h, k))); mrb_gc_arena_restore(mrb, ai); - kh_val(ret_h, ret_k) = kh_val(h,k); + kh_val(ret_h, ret_k) = kh_val(h, k); } } } @@ -555,9 +555,9 @@ mrb_hash_shift(mrb_state *mrb, mrb_value hash) mrb_hash_modify(mrb, hash); if (h && kh_size(h) > 0) { for (k = kh_begin(h); k != kh_end(h); k++) { - if (!kh_exist(h,k)) continue; + if (!kh_exist(h, k)) continue; - delKey = kh_key(h,k); + delKey = kh_key(h, k); mrb_gc_protect(mrb, delKey); delVal = mrb_hash_delete_key(mrb, hash, delKey); mrb_gc_protect(mrb, delVal); @@ -706,8 +706,8 @@ mrb_hash_keys(mrb_state *mrb, mrb_value hash) p = RARRAY_PTR(ary); for (k = kh_begin(h); k != kh_end(h); k++) { if (kh_exist(h, k)) { - mrb_value kv = kh_key(h,k); - mrb_hash_value hv = kh_value(h,k); + mrb_value kv = kh_key(h, k); + mrb_hash_value hv = kh_value(h, k); p[hv.n] = kv; } @@ -739,7 +739,7 @@ mrb_hash_values(mrb_state *mrb, mrb_value hash) 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_hash_value hv = kh_value(h,k); + mrb_hash_value hv = kh_value(h, k); mrb_ary_set(mrb, ary, hv.n, hv.v); } @@ -812,7 +812,7 @@ mrb_hash_has_value(mrb_state *mrb, mrb_value hash) for (k = kh_begin(h); k != kh_end(h); k++) { if (!kh_exist(h, k)) continue; - if (mrb_equal(mrb, kh_value(h,k).v, val)) { + if (mrb_equal(mrb, kh_value(h, k).v, val)) { return mrb_true_value(); } } diff --git a/src/kernel.c b/src/kernel.c index 8686fe6a5..2f52c7bdf 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -470,51 +470,10 @@ static mrb_value obj_is_instance_of(mrb_state *mrb, mrb_value self) { mrb_value arg; - mrb_bool instance_of_p; mrb_get_args(mrb, "C", &arg); - instance_of_p = mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)); - return mrb_bool_value(instance_of_p); -} - -static void -valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, mrb_int len) -{ - if (len < 2 || !(s[0] == '@' && s[1] != '@')) { - mrb_name_error(mrb, iv_name_id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name_id)); - } -} - -static void -check_iv_name(mrb_state *mrb, mrb_sym iv_name_id) -{ - const char *s; - mrb_int len; - - s = mrb_sym2name_len(mrb, iv_name_id, &len); - valid_iv_name(mrb, iv_name_id, s, len); -} - -static mrb_sym -get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name) -{ - mrb_sym iv_name_id; - - mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name)); - - if (mrb_string_p(iv_name)) { - char *p = RSTRING_PTR(iv_name); - mrb_int l = RSTRING_LEN(iv_name); - iv_name_id = mrb_intern(mrb, p, l); - valid_iv_name(mrb, iv_name_id, p, l); - } - else { - iv_name_id = mrb_symbol(iv_name); - check_iv_name(mrb, iv_name_id); - } - - return iv_name_id; + return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); } /* 15.3.1.3.20 */ @@ -538,15 +497,11 @@ get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name) static mrb_value mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) { - mrb_sym mid; - mrb_value sym; - mrb_bool defined_p; - - mrb_get_args(mrb, "o", &sym); - mid = get_valid_iv_sym(mrb, sym); - defined_p = mrb_obj_iv_defined(mrb, mrb_obj_ptr(self), mid); + mrb_sym sym; - return mrb_bool_value(defined_p); + mrb_get_args(mrb, "n", &sym); + mrb_iv_check(mrb, sym); + return mrb_bool_value(mrb_iv_defined(mrb, self, sym)); } /* 15.3.1.3.21 */ @@ -572,13 +527,11 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) { - mrb_sym iv_name_id; - mrb_value iv_name; + mrb_sym iv_name; - mrb_get_args(mrb, "o", &iv_name); - - iv_name_id = get_valid_iv_sym(mrb, iv_name); - return mrb_iv_get(mrb, self, iv_name_id); + mrb_get_args(mrb, "n", &iv_name); + mrb_iv_check(mrb, iv_name); + return mrb_iv_get(mrb, self, iv_name); } /* 15.3.1.3.22 */ @@ -604,13 +557,12 @@ mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) static mrb_value mrb_obj_ivar_set(mrb_state *mrb, mrb_value self) { - mrb_sym iv_name_id; - mrb_value iv_name, val; - - mrb_get_args(mrb, "oo", &iv_name, &val); + mrb_sym iv_name; + mrb_value val; - iv_name_id = get_valid_iv_sym(mrb, iv_name); - mrb_iv_set(mrb, self, iv_name_id, val); + mrb_get_args(mrb, "no", &iv_name, &val); + mrb_iv_check(mrb, iv_name); + mrb_iv_set(mrb, self, iv_name, val); return val; } @@ -645,12 +597,10 @@ static mrb_value mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) { mrb_value arg; - mrb_bool kind_of_p; mrb_get_args(mrb, "C", &arg); - kind_of_p = mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)); - return mrb_bool_value(kind_of_p); + return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))); } KHASH_DECLARE(st, mrb_sym, char, FALSE) @@ -665,7 +615,7 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) if (!h) return; for (i=0;i<kh_end(h);i++) { if (kh_exist(h, i)) { - kh_put(st, mrb, set, kh_key(h,i)); + kh_put(st, mrb, set, kh_key(h, i)); } } } @@ -694,7 +644,7 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl ary = mrb_ary_new(mrb); for (i=0;i<kh_end(set);i++) { if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i))); + mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); } } kh_destroy(st, mrb, set); @@ -726,7 +676,7 @@ mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) ary = mrb_ary_new(mrb); for (i=0;i<kh_end(set);i++) { if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i))); + mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); } } kh_destroy(st, mrb, set); @@ -911,7 +861,7 @@ mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) mrb_value val; mrb_get_args(mrb, "n", &sym); - check_iv_name(mrb, sym); + mrb_iv_check(mrb, sym); val = mrb_iv_remove(mrb, self, sym); if (mrb_undef_p(val)) { mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym)); diff --git a/src/load.c b/src/load.c index 9e8325022..30b466f6b 100644 --- a/src/load.c +++ b/src/load.c @@ -14,6 +14,11 @@ #include "mruby/debug.h" #include "mruby/error.h" +#define FLAG_BYTEORDER_NATIVE 2 +#define FLAG_BYTEORDER_NONATIVE 0 +#define FLAG_SRC_MALLOC 1 +#define FLAG_SRC_STATIC 0 + #if !defined(_WIN32) && SIZE_MAX < UINT32_MAX # define SIZE_ERROR_MUL(x, y) ((x) > SIZE_MAX / (y)) # define SIZE_ERROR(x) ((x) > SIZE_MAX) @@ -34,7 +39,7 @@ offset_crc_body(void) } static mrb_irep* -read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) +read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) { size_t i; const uint8_t *src = bin; @@ -67,10 +72,18 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all if (SIZE_ERROR_MUL(sizeof(mrb_code), irep->ilen)) { return NULL; } - irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); - for (i = 0; i < irep->ilen; i++) { - irep->iseq[i] = (size_t)bin_to_uint32(src); /* iseq */ - src += sizeof(uint32_t); + if (!(flags & FLAG_SRC_MALLOC) && + (flags & FLAG_BYTEORDER_NATIVE)) { + irep->iseq = (mrb_code*)src; + src += sizeof(uint32_t) * irep->ilen; + irep->flags |= MRB_ISEQ_NO_FREE; + } + else { + irep->iseq = (mrb_code *)mrb_malloc(mrb, sizeof(mrb_code) * irep->ilen); + for (i = 0; i < irep->ilen; i++) { + irep->iseq[i] = (mrb_code)bin_to_uint32(src); /* iseq */ + src += sizeof(uint32_t); + } } } @@ -89,7 +102,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all tt = *src++; /* pool TT */ pool_data_len = bin_to_uint16(src); /* pool data length */ src += sizeof(uint16_t); - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { s = mrb_str_new(mrb, (char *)src, pool_data_len); } else { @@ -137,7 +150,7 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all continue; } - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { irep->syms[i] = mrb_intern(mrb, (char *)src, snl); } else { @@ -159,9 +172,9 @@ read_irep_record_1(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool all } static mrb_irep* -read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc) +read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, uint8_t flags) { - mrb_irep *irep = read_irep_record_1(mrb, bin, len, alloc); + mrb_irep *irep = read_irep_record_1(mrb, bin, len, flags); size_t i; if (irep == NULL) { @@ -172,7 +185,7 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc for (i=0; i<irep->rlen; i++) { size_t rlen; - irep->reps[i] = read_irep_record(mrb, bin, &rlen, alloc); + irep->reps[i] = read_irep_record(mrb, bin, &rlen, flags); if (irep->reps[i] == NULL) { return NULL; } @@ -183,12 +196,12 @@ read_irep_record(mrb_state *mrb, const uint8_t *bin, size_t *len, mrb_bool alloc } static mrb_irep* -read_section_irep(mrb_state *mrb, const uint8_t *bin, mrb_bool alloc) +read_section_irep(mrb_state *mrb, const uint8_t *bin, uint8_t flags) { size_t len; bin += sizeof(struct rite_section_irep_header); - return read_irep_record(mrb, bin, &len, alloc); + return read_irep_record(mrb, bin, &len, flags); } static int @@ -357,7 +370,7 @@ read_debug_record(mrb_state *mrb, const uint8_t *start, mrb_irep* irep, size_t * } static int -read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) +read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) { const uint8_t *bin; ptrdiff_t diff; @@ -378,7 +391,7 @@ read_section_debug(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_boo for (i = 0; i < filenames_len; ++i) { uint16_t f_len = bin_to_uint16(bin); bin += sizeof(uint16_t); - if (alloc) { + if (flags & FLAG_SRC_MALLOC) { filenames[i] = mrb_intern(mrb, (const char *)bin, (size_t)f_len); } else { @@ -446,7 +459,7 @@ read_lv_record(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, size_t *rec } static int -read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool alloc) +read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, uint8_t flags) { const uint8_t *bin; ptrdiff_t diff; @@ -456,7 +469,8 @@ read_section_lv(mrb_state *mrb, const uint8_t *start, mrb_irep *irep, mrb_bool a int result; uint32_t syms_len; mrb_sym *syms; - mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = alloc? mrb_intern : mrb_intern_static; + mrb_sym (*intern_func)(mrb_state*, const char*, size_t) = + (flags & FLAG_SRC_MALLOC)? mrb_intern : mrb_intern_static; bin = start; header = (struct rite_section_lv_header const*)bin; @@ -489,12 +503,27 @@ lv_exit: } static int -read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc) +read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, mrb_bool *byteorder) { const struct rite_binary_header *header = (const struct rite_binary_header *)bin; + if (byteorder) *byteorder = FALSE; if (memcmp(header->binary_identify, RITE_BINARY_IDENTIFIER, sizeof(header->binary_identify)) != 0) { - return MRB_DUMP_INVALID_FILE_HEADER; + if (byteorder) { + uint32_t ident = 0; + size_t i; + + for(i=0; i<sizeof(ident); i++) { + ident<<=8; + ident|=RITE_BINARY_IDENTIFIER[i]; + } + if (memcmp(header->binary_identify, &ident, sizeof(header->binary_identify)) == 0) { + *byteorder = TRUE; + } + else { + return MRB_DUMP_INVALID_FILE_HEADER; + } + } } if (memcmp(header->binary_version, RITE_BINARY_FORMAT_VER, sizeof(header->binary_version)) != 0) { @@ -518,15 +547,20 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) uint16_t crc; size_t bin_size = 0; size_t n; + mrb_bool byteorder; + uint8_t flags = FLAG_SRC_STATIC; if ((mrb == NULL) || (bin == NULL)) { return NULL; } - result = read_binary_header(bin, &bin_size, &crc); + result = read_binary_header(bin, &bin_size, &crc, &byteorder); if (result != MRB_DUMP_OK) { return NULL; } + if (byteorder) { + flags |= FLAG_BYTEORDER_NATIVE; + } n = offset_crc_body(); if (crc != calc_crc_16_ccitt(bin + n, bin_size - n, 0)) { @@ -537,7 +571,7 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) do { section_header = (const struct rite_section_header *)bin; if (memcmp(section_header->section_identify, RITE_SECTION_IREP_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { - irep = read_section_irep(mrb, bin, FALSE); + irep = read_section_irep(mrb, bin, flags); if (!irep) return NULL; } else if (memcmp(section_header->section_identify, RITE_SECTION_LINENO_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { @@ -549,14 +583,14 @@ mrb_read_irep(mrb_state *mrb, const uint8_t *bin) } else if (memcmp(section_header->section_identify, RITE_SECTION_DEBUG_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { if (!irep) return NULL; /* corrupted data */ - result = read_section_debug(mrb, bin, irep, FALSE); + result = read_section_debug(mrb, bin, irep, flags); if (result < MRB_DUMP_OK) { return NULL; } } else if (memcmp(section_header->section_identify, RITE_SECTION_LV_IDENTIFIER, sizeof(section_header->section_identify)) == 0) { if (!irep) return NULL; - result = read_section_lv(mrb, bin, irep, FALSE); + result = read_section_lv(mrb, bin, irep, flags); if (result < MRB_DUMP_OK) { return NULL; } @@ -668,7 +702,7 @@ read_irep_record_file(mrb_state *mrb, FILE *fp) if (fread(&buf[record_header_size], buf_size - record_header_size, 1, fp) == 0) { return NULL; } - irep = read_irep_record_1(mrb, buf, &len, TRUE); + irep = read_irep_record_1(mrb, buf, &len, FLAG_SRC_MALLOC); mrb_free(mrb, ptr); if (!irep) return NULL; for (i=0; i<irep->rlen; i++) { @@ -715,7 +749,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, buf); return NULL; } - result = read_binary_header(buf, NULL, &crc); + result = read_binary_header(buf, NULL, &crc, NULL); mrb_free(mrb, buf); if (result != MRB_DUMP_OK) { return NULL; @@ -773,7 +807,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, bin); return NULL; } - result = read_section_debug(mrb, bin, irep, TRUE); + result = read_section_debug(mrb, bin, irep, FLAG_SRC_MALLOC); mrb_free(mrb, bin); } if (result < MRB_DUMP_OK) return NULL; @@ -788,7 +822,7 @@ mrb_read_irep_file(mrb_state *mrb, FILE* fp) mrb_free(mrb, bin); return NULL; } - result = read_section_lv(mrb, bin, irep, TRUE); + result = read_section_lv(mrb, bin, irep, FLAG_SRC_MALLOC); mrb_free(mrb, bin); } if (result < MRB_DUMP_OK) return NULL; diff --git a/src/numeric.c b/src/numeric.c index 5cf85fc7d..da15c92cc 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -75,7 +75,7 @@ num_pow(mrb_state *mrb, mrb_value x) * result. */ -MRB_API mrb_value +mrb_value mrb_num_div(mrb_state *mrb, mrb_value x, mrb_value y) { return mrb_float_value(mrb, mrb_to_flo(mrb, x) / mrb_to_flo(mrb, y)); diff --git a/src/parse.y b/src/parse.y index 0c0a9877f..4cab4162a 100644 --- a/src/parse.y +++ b/src/parse.y @@ -62,6 +62,7 @@ typedef unsigned int stack_type; #define CMDARG_P() BITSTACK_SET_P(p->cmdarg_stack) #define SET_LINENO(c,n) ((c)->lineno = (n)) +#define NODE_LINENO(c,n) do {if (n) ((c)->lineno = (n)->lineno);} while (0) #define sym(x) ((mrb_sym)(intptr_t)(x)) #define nsym(x) ((node*)(intptr_t)(x)) @@ -275,8 +276,9 @@ new_scope(parser_state *p, node *body) static node* new_begin(parser_state *p, node *body) { - if (body) + if (body) { return list2((node*)NODE_BEGIN, body); + } return cons((node*)NODE_BEGIN, 0); } @@ -391,14 +393,20 @@ new_self(parser_state *p) static node* new_call(parser_state *p, node *a, mrb_sym b, node *c) { - return list4((node*)NODE_CALL, a, nsym(b), c); + node *n = list4((node*)NODE_CALL, a, nsym(b), c); + NODE_LINENO(n, a); + return n; } /* (:fcall self mid args) */ static node* new_fcall(parser_state *p, mrb_sym b, node *c) { - return list4((node*)NODE_FCALL, new_self(p), nsym(b), c); + node *n = new_self(p); + NODE_LINENO(n, c); + n = list4((node*)NODE_FCALL, n, nsym(b), c); + NODE_LINENO(n, c); + return n; } /* (:super . c) */ @@ -997,25 +1005,27 @@ heredoc_end(parser_state *p) const struct vtable *vars; } -%token +%token <num> keyword_class keyword_module keyword_def - keyword_undef keyword_begin + keyword_if + keyword_unless + keyword_while + keyword_until + keyword_for + +%token + keyword_undef keyword_rescue keyword_ensure keyword_end - keyword_if - keyword_unless keyword_then keyword_elsif keyword_else keyword_case keyword_when - keyword_while - keyword_until - keyword_for keyword_break keyword_next keyword_redo @@ -1155,6 +1165,7 @@ program : { top_compstmt { p->tree = new_scope(p, $2); + NODE_LINENO(p->tree, $2); } ; @@ -1171,6 +1182,7 @@ top_stmts : none | top_stmt { $$ = new_begin(p, $1); + NODE_LINENO($$, $1); } | top_stmts terms top_stmt { @@ -1202,6 +1214,7 @@ bodystmt : compstmt { if ($2) { $$ = new_rescue(p, $1, $2, $3); + NODE_LINENO($$, $1); } else if ($3) { yywarn(p, "else without rescue is useless"); @@ -1234,10 +1247,11 @@ stmts : none | stmt { $$ = new_begin(p, $1); + NODE_LINENO($$, $1); } | stmts terms stmt { - $$ = push($1, newline_node($3)); + $$ = push($1, newline_node($3)); } | error stmt { @@ -1255,7 +1269,7 @@ stmt : keyword_alias fsym {p->lstate = EXPR_FNAME;} fsym } | stmt modifier_if expr_value { - $$ = new_if(p, cond($3), $1, 0); + $$ = new_if(p, cond($3), $1, 0); } | stmt modifier_unless expr_value { @@ -1887,6 +1901,7 @@ aref_args : none | args trailer { $$ = $1; + NODE_LINENO($$, $1); } | args ',' assocs trailer { @@ -1895,6 +1910,7 @@ aref_args : none | assocs trailer { $$ = cons(new_hash(p, $1), 0); + NODE_LINENO($$, $1); } ; @@ -1913,36 +1929,44 @@ opt_call_args : none | args ',' { $$ = cons($1,0); + NODE_LINENO($$, $1); } | args ',' assocs ',' { $$ = cons(push($1, new_hash(p, $3)), 0); + NODE_LINENO($$, $1); } | assocs ',' { $$ = cons(list1(new_hash(p, $1)), 0); + NODE_LINENO($$, $1); } ; call_args : command { $$ = cons(list1($1), 0); + NODE_LINENO($$, $1); } | args opt_block_arg { $$ = cons($1, $2); + NODE_LINENO($$, $1); } | assocs opt_block_arg { $$ = cons(list1(new_hash(p, $1)), $2); + NODE_LINENO($$, $1); } | args ',' assocs opt_block_arg { $$ = cons(push($1, new_hash(p, $3)), $4); + NODE_LINENO($$, $1); } | block_arg { $$ = cons(0, $1); + NODE_LINENO($$, $1); } ; @@ -1976,10 +2000,12 @@ opt_block_arg : ',' block_arg args : arg_value { $$ = cons($1, 0); + NODE_LINENO($$, $1); } | tSTAR arg_value { $$ = cons(new_splat(p, $2), 0); + NODE_LINENO($$, $2); } | args ',' arg_value { @@ -2026,23 +2052,23 @@ primary : literal } | keyword_begin { - $<stack>1 = p->cmdarg_stack; + $<stack>$ = p->cmdarg_stack; p->cmdarg_stack = 0; } bodystmt keyword_end { - p->cmdarg_stack = $<stack>1; + p->cmdarg_stack = $<stack>2; $$ = $3; } | tLPAREN_ARG { - $<stack>1 = p->cmdarg_stack; + $<stack>$ = p->cmdarg_stack; p->cmdarg_stack = 0; } expr {p->lstate = EXPR_ENDARG;} rparen { - p->cmdarg_stack = $<stack>1; + p->cmdarg_stack = $<stack>2; $$ = $3; } | tLPAREN_ARG {p->lstate = EXPR_ENDARG;} rparen @@ -2064,10 +2090,12 @@ primary : literal | tLBRACK aref_args ']' { $$ = new_array(p, $2); + NODE_LINENO($$, $2); } | tLBRACE assoc_list '}' { $$ = new_hash(p, $2); + NODE_LINENO($$, $2); } | keyword_return { @@ -2122,6 +2150,7 @@ primary : literal keyword_end { $$ = new_if(p, cond($2), $4, $5); + SET_LINENO($$, $1); } | keyword_unless expr_value then compstmt @@ -2129,18 +2158,21 @@ primary : literal keyword_end { $$ = new_unless(p, cond($2), $4, $5); + SET_LINENO($$, $1); } | keyword_while {COND_PUSH(1);} expr_value do {COND_POP();} compstmt keyword_end { $$ = new_while(p, cond($3), $6); + SET_LINENO($$, $1); } | keyword_until {COND_PUSH(1);} expr_value do {COND_POP();} compstmt keyword_end { $$ = new_until(p, cond($3), $6); + SET_LINENO($$, $1); } | keyword_case expr_value opt_terms case_body @@ -2160,11 +2192,9 @@ primary : literal keyword_end { $$ = new_for(p, $2, $5, $8); + SET_LINENO($$, $1); } | keyword_class - { - $<num>$ = p->lineno; - } cpath superclass { if (p->in_def || p->in_single) @@ -2174,14 +2204,11 @@ primary : literal bodystmt keyword_end { - $$ = new_class(p, $3, $4, $6); - SET_LINENO($$, $<num>2); - local_resume(p, $<nd>5); + $$ = new_class(p, $2, $3, $5); + SET_LINENO($$, $1); + local_resume(p, $<nd>4); } | keyword_class - { - $<num>$ = p->lineno; - } tLSHFT expr { $<num>$ = p->in_def; @@ -2195,16 +2222,13 @@ primary : literal bodystmt keyword_end { - $$ = new_sclass(p, $4, $8); - SET_LINENO($$, $<num>2); - local_resume(p, $<nd>7->car); - p->in_def = $<num>5; - p->in_single = (int)(intptr_t)$<nd>7->cdr; + $$ = new_sclass(p, $3, $7); + SET_LINENO($$, $1); + local_resume(p, $<nd>6->car); + p->in_def = $<num>4; + p->in_single = (int)(intptr_t)$<nd>6->cdr; } | keyword_module - { - $<num>$ = p->lineno; - } cpath { if (p->in_def || p->in_single) @@ -2214,42 +2238,50 @@ primary : literal bodystmt keyword_end { - $$ = new_module(p, $3, $5); - SET_LINENO($$, $<num>2); - local_resume(p, $<nd>4); + $$ = new_module(p, $2, $4); + SET_LINENO($$, $1); + local_resume(p, $<nd>3); } | keyword_def fname { + $<stack>$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + { p->in_def++; $<nd>$ = local_switch(p); - $<stack>1 = p->cmdarg_stack; - p->cmdarg_stack = 0; } f_arglist bodystmt keyword_end { - $$ = new_def(p, $2, $4, $5); - local_resume(p, $<nd>3); + $$ = new_def(p, $2, $5, $6); + SET_LINENO($$, $1); + local_resume(p, $<nd>4); p->in_def--; - p->cmdarg_stack = $<stack>1; + p->cmdarg_stack = $<stack>3; } - | keyword_def singleton dot_or_colon {p->lstate = EXPR_FNAME;} fname + | keyword_def singleton dot_or_colon + { + p->lstate = EXPR_FNAME; + $<stack>$ = p->cmdarg_stack; + p->cmdarg_stack = 0; + } + fname { p->in_single++; p->lstate = EXPR_ENDFN; /* force for args */ $<nd>$ = local_switch(p); - $<stack>1 = p->cmdarg_stack; - p->cmdarg_stack = 0; } f_arglist bodystmt keyword_end { $$ = new_sdef(p, $2, $5, $7, $8); + SET_LINENO($$, $1); local_resume(p, $<nd>6); p->in_single--; - p->cmdarg_stack = $<stack>1; + p->cmdarg_stack = $<stack>4; } | keyword_break { @@ -3163,6 +3195,7 @@ assoc_list : none assocs : assoc { $$ = list1($1); + NODE_LINENO($$, $1); } | assocs ',' assoc { @@ -3934,22 +3967,22 @@ parse_string(parser_state *p) if (type & STR_FUNC_REGEXP) { int f = 0; - int c; + int re_opt; char *s = strndup(tok(p), toklen(p)); char flags[3]; char *flag = flags; char *dup; newtok(p); - while (c = nextc(p), c >= 0 && ISALPHA(c)) { - switch (c) { + while (re_opt = nextc(p), re_opt >= 0 && ISALPHA(re_opt)) { + switch (re_opt) { case 'i': f |= 1; break; case 'x': f |= 2; break; case 'm': f |= 4; break; - default: tokadd(p, c); break; + default: tokadd(p, re_opt); break; } } - pushback(p, c); + pushback(p, re_opt); if (toklen(p)) { char msg[128]; tokfix(p); @@ -5210,6 +5243,7 @@ parser_yylex(parser_state *p) kw = mrb_reserved_word(tok(p), toklen(p)); if (kw) { enum mrb_lex_state_enum state = p->lstate; + yylval.num = p->lineno; p->lstate = kw->state; if (state == EXPR_FNAME) { yylval.id = intern_cstr(kw->name); @@ -5296,6 +5330,7 @@ parser_init_cxt(parser_state *p, mrbc_context *cxt) } } p->capture_errors = cxt->capture_errors; + p->no_optimize = cxt->no_optimize; if (cxt->partial_hook) { p->cxt = cxt; } @@ -5324,7 +5359,7 @@ parser_update_cxt(parser_state *p, mrbc_context *cxt) void mrb_codedump_all(mrb_state*, struct RProc*); void mrb_parser_dump(mrb_state *mrb, node *tree, int offset); -void +MRB_API void mrb_parser_parse(parser_state *p, mrbc_context *c) { struct mrb_jmpbuf buf; @@ -5357,7 +5392,7 @@ mrb_parser_parse(parser_state *p, mrbc_context *c) MRB_END_EXC(p->jmp); } -parser_state* +MRB_API parser_state* mrb_parser_new(mrb_state *mrb) { mrb_pool *pool; @@ -5399,7 +5434,7 @@ mrb_parser_new(mrb_state *mrb) return p; } -void +MRB_API void mrb_parser_free(parser_state *p) { mrb_pool_close(p->pool); } @@ -5440,7 +5475,7 @@ mrbc_partial_hook(mrb_state *mrb, mrbc_context *c, int (*func)(struct mrb_parser c->partial_data = data; } -void +MRB_API void mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) { mrb_sym sym; @@ -5468,7 +5503,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f) p->filename_table[p->filename_table_length - 1] = sym; } -char const* +MRB_API char const* mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) { if (idx >= p->filename_table_length) { return NULL; } else { @@ -5477,7 +5512,7 @@ mrb_parser_get_filename(struct mrb_parser_state* p, uint16_t idx) { } #ifdef ENABLE_STDIO -parser_state* +MRB_API parser_state* mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c) { parser_state *p; @@ -5492,7 +5527,7 @@ mrb_parse_file(mrb_state *mrb, FILE *f, mrbc_context *c) } #endif -parser_state* +MRB_API parser_state* mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c) { parser_state *p; @@ -5506,7 +5541,7 @@ mrb_parse_nstring(mrb_state *mrb, const char *s, int len, mrbc_context *c) return p; } -parser_state* +MRB_API parser_state* mrb_parse_string(mrb_state *mrb, const char *s, mrbc_context *c) { return mrb_parse_nstring(mrb, s, strlen(s), c); @@ -5569,38 +5604,38 @@ load_exec(mrb_state *mrb, parser_state *p, mrbc_context *c) } #ifdef ENABLE_STDIO -mrb_value +MRB_API mrb_value mrb_load_file_cxt(mrb_state *mrb, FILE *f, mrbc_context *c) { return load_exec(mrb, mrb_parse_file(mrb, f, c), c); } -mrb_value +MRB_API mrb_value mrb_load_file(mrb_state *mrb, FILE *f) { return mrb_load_file_cxt(mrb, f, NULL); } #endif -mrb_value +MRB_API mrb_value mrb_load_nstring_cxt(mrb_state *mrb, const char *s, int len, mrbc_context *c) { return load_exec(mrb, mrb_parse_nstring(mrb, s, len, c), c); } -mrb_value +MRB_API mrb_value mrb_load_nstring(mrb_state *mrb, const char *s, int len) { return mrb_load_nstring_cxt(mrb, s, len, NULL); } -mrb_value +MRB_API mrb_value mrb_load_string_cxt(mrb_state *mrb, const char *s, mrbc_context *c) { return mrb_load_nstring_cxt(mrb, s, strlen(s), c); } -mrb_value +MRB_API mrb_value mrb_load_string(mrb_state *mrb, const char *s) { return mrb_load_string_cxt(mrb, s, NULL); @@ -5609,8 +5644,9 @@ mrb_load_string(mrb_state *mrb, const char *s) #ifdef ENABLE_STDIO static void -dump_prefix(int offset) +dump_prefix(node *tree, int offset) { + printf("%05d ", tree->lineno); while (offset--) { putc(' ', stdout); putc(' ', stdout); @@ -5632,14 +5668,14 @@ void mrb_parser_dump(mrb_state *mrb, node *tree, int offset) { #ifdef ENABLE_STDIO - int n; + int nodetype; if (!tree) return; again: - dump_prefix(offset); - n = (int)(intptr_t)tree->car; + dump_prefix(tree, offset); + nodetype = (int)(intptr_t)tree->car; tree = tree->cdr; - switch (n) { + switch (nodetype) { case NODE_BEGIN: printf("NODE_BEGIN:\n"); dump_recur(mrb, tree, offset+1); @@ -5648,7 +5684,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_RESCUE: printf("NODE_RESCUE:\n"); if (tree->car) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->car, offset+2); } @@ -5656,22 +5692,22 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) if (tree->car) { node *n2 = tree->car; - dump_prefix(offset+1); + dump_prefix(n2, offset+1); printf("rescue:\n"); while (n2) { node *n3 = n2->car; if (n3->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("handle classes:\n"); dump_recur(mrb, n3->car, offset+3); } if (n3->cdr->car) { - dump_prefix(offset+2); + dump_prefix(n3, offset+2); printf("exc_var:\n"); mrb_parser_dump(mrb, n3->cdr->car, offset+3); } if (n3->cdr->cdr->car) { - dump_prefix(offset+2); + dump_prefix(n3, offset+2); printf("rescue body:\n"); mrb_parser_dump(mrb, n3->cdr->cdr->car, offset+3); } @@ -5680,7 +5716,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } tree = tree->cdr; if (tree->car) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("else:\n"); mrb_parser_dump(mrb, tree->car, offset+2); } @@ -5688,10 +5724,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_ENSURE: printf("NODE_ENSURE:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("ensure:\n"); mrb_parser_dump(mrb, tree->cdr->cdr, offset+2); break; @@ -5703,62 +5739,62 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_BLOCK: block: printf("NODE_BLOCK:\n"); - tree = tree->cdr; - if (tree->car) { - node *n = tree->car; + tree = tree->cdr; + if (tree->car) { + node *n = tree->car; - if (n->car) { - dump_prefix(offset+1); - printf("mandatory args:\n"); - dump_recur(mrb, n->car, offset+2); - } - n = n->cdr; - if (n->car) { - dump_prefix(offset+1); - printf("optional args:\n"); - { - node *n2 = n->car; + if (n->car) { + dump_prefix(n, offset+1); + printf("mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("optional args:\n"); + { + node *n2 = n->car; - while (n2) { - dump_prefix(offset+2); - printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); - mrb_parser_dump(mrb, n2->car->cdr, 0); - n2 = n2->cdr; + while (n2) { + dump_prefix(n2, offset+2); + printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); + mrb_parser_dump(mrb, n2->car->cdr, 0); + n2 = n2->cdr; + } } } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); + } + n = n->cdr; + if (n->car) { + dump_prefix(n, offset+1); + printf("post mandatory args:\n"); + dump_recur(mrb, n->car, offset+2); + } + n = n->cdr; + if (n) { + dump_prefix(n, offset+1); + printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); + } } - n = n->cdr; - if (n->car) { - dump_prefix(offset+1); - printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); - } - n = n->cdr; - if (n->car) { - dump_prefix(offset+1); - printf("post mandatory args:\n"); - dump_recur(mrb, n->car, offset+2); - } - n = n->cdr; - if (n) { - dump_prefix(offset+1); - printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); - } - } - dump_prefix(offset+1); - printf("body:\n"); - mrb_parser_dump(mrb, tree->cdr->car, offset+2); - break; + dump_prefix(tree, offset+1); + printf("body:\n"); + mrb_parser_dump(mrb, tree->cdr->car, offset+2); + break; case NODE_IF: printf("NODE_IF:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("cond:\n"); mrb_parser_dump(mrb, tree->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("then:\n"); mrb_parser_dump(mrb, tree->cdr->car, offset+2); if (tree->cdr->cdr->car) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("else:\n"); mrb_parser_dump(mrb, tree->cdr->cdr->car, offset+2); } @@ -5783,10 +5819,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } tree = tree->cdr; while (tree) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("case:\n"); dump_recur(mrb, tree->car->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->car->cdr, offset+2); tree = tree->cdr; @@ -5795,47 +5831,47 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_WHILE: printf("NODE_WHILE:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("cond:\n"); mrb_parser_dump(mrb, tree->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); break; case NODE_UNTIL: printf("NODE_UNTIL:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("cond:\n"); mrb_parser_dump(mrb, tree->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); break; case NODE_FOR: printf("NODE_FOR:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("var:\n"); { node *n2 = tree->car; if (n2->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("pre:\n"); dump_recur(mrb, n2->car, offset+3); } n2 = n2->cdr; if (n2) { if (n2->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("rest:\n"); mrb_parser_dump(mrb, n2->car, offset+3); } n2 = n2->cdr; if (n2) { if (n2->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("post:\n"); dump_recur(mrb, n2->car, offset+3); } @@ -5843,11 +5879,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } } tree = tree->cdr; - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("in:\n"); mrb_parser_dump(mrb, tree->car, offset+2); tree = tree->cdr; - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("do:\n"); mrb_parser_dump(mrb, tree->car, offset+2); break; @@ -5859,9 +5895,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) mrb_bool first_lval = TRUE; if (n2 && (n2->car || n2->cdr)) { - dump_prefix(offset+1); + dump_prefix(n2, offset+1); printf("local variables:\n"); - dump_prefix(offset+2); + dump_prefix(n2, offset+2); while (n2) { if (n2->car) { if (!first_lval) printf(", "); @@ -5881,17 +5917,17 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_CALL: printf("NODE_CALL:\n"); mrb_parser_dump(mrb, tree->car, offset+1); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("method='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->cdr->car)), (int)(intptr_t)tree->cdr->car); tree = tree->cdr->cdr->car; if (tree) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("args:\n"); dump_recur(mrb, tree->car, offset+2); if (tree->cdr) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("block:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); } @@ -5913,13 +5949,13 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_COLON2: printf("NODE_COLON2:\n"); mrb_parser_dump(mrb, tree->car, offset+1); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree->cdr))); break; case NODE_COLON3: printf("NODE_COLON3:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree))); break; @@ -5931,10 +5967,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_HASH: printf("NODE_HASH:\n"); while (tree) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("key:\n"); mrb_parser_dump(mrb, tree->car->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("value:\n"); mrb_parser_dump(mrb, tree->car->cdr, offset+2); tree = tree->cdr; @@ -5948,33 +5984,33 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_ASGN: printf("NODE_ASGN:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("lhs:\n"); mrb_parser_dump(mrb, tree->car, offset+2); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("rhs:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); break; case NODE_MASGN: printf("NODE_MASGN:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("mlhs:\n"); { node *n2 = tree->car; if (n2->car) { - dump_prefix(offset+2); + dump_prefix(tree, offset+2); printf("pre:\n"); dump_recur(mrb, n2->car, offset+3); } n2 = n2->cdr; if (n2) { if (n2->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("rest:\n"); if (n2->car == (node*)-1) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("(empty)\n"); } else { @@ -5984,25 +6020,25 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) n2 = n2->cdr; if (n2) { if (n2->car) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("post:\n"); dump_recur(mrb, n2->car, offset+3); } } } } - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("rhs:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); break; case NODE_OP_ASGN: printf("NODE_OP_ASGN:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("lhs:\n"); mrb_parser_dump(mrb, tree->car, offset+2); tree = tree->cdr; - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("op='%s' (%d)\n", mrb_sym2name(mrb, sym(tree->car)), (int)(intptr_t)tree->car); tree = tree->cdr; mrb_parser_dump(mrb, tree->car, offset+1); @@ -6011,11 +6047,11 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_SUPER: printf("NODE_SUPER:\n"); if (tree) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("args:\n"); dump_recur(mrb, tree->car, offset+2); if (tree->cdr) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("block:\n"); mrb_parser_dump(mrb, tree->cdr, offset+2); } @@ -6076,10 +6112,10 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_MATCH: printf("NODE_MATCH:\n"); - dump_prefix(offset + 1); + dump_prefix(tree, offset + 1); printf("lhs:\n"); mrb_parser_dump(mrb, tree->car, offset + 2); - dump_prefix(offset + 1); + dump_prefix(tree, offset + 1); printf("rhs:\n"); mrb_parser_dump(mrb, tree->cdr, offset + 2); break; @@ -6139,9 +6175,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_DREGX: printf("NODE_DREGX\n"); dump_recur(mrb, tree->car, offset+1); - dump_prefix(offset); + dump_prefix(tree, offset); printf("tail: %s\n", (char*)tree->cdr->cdr->car); - dump_prefix(offset); + dump_prefix(tree, offset); printf("opt: %s\n", (char*)tree->cdr->cdr->cdr); break; @@ -6186,24 +6222,24 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_CLASS: printf("NODE_CLASS:\n"); if (tree->car->car == (node*)0) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } else if (tree->car->car == (node*)1) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } else { mrb_parser_dump(mrb, tree->car->car, offset+1); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } if (tree->cdr->car) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("super:\n"); mrb_parser_dump(mrb, tree->cdr->car, offset+2); } - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->cdr->cdr->car->cdr, offset+2); break; @@ -6211,19 +6247,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_MODULE: printf("NODE_MODULE:\n"); if (tree->car->car == (node*)0) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf(":%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } else if (tree->car->car == (node*)1) { - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } else { mrb_parser_dump(mrb, tree->car->car, offset+1); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("::%s\n", mrb_sym2name(mrb, sym(tree->car->cdr))); } - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2); break; @@ -6231,14 +6267,14 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) case NODE_SCLASS: printf("NODE_SCLASS:\n"); mrb_parser_dump(mrb, tree->car, offset+1); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("body:\n"); mrb_parser_dump(mrb, tree->cdr->car->cdr, offset+2); break; case NODE_DEF: printf("NODE_DEF:\n"); - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf("%s\n", mrb_sym2name(mrb, sym(tree->car))); tree = tree->cdr; { @@ -6246,9 +6282,9 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) mrb_bool first_lval = TRUE; if (n2 && (n2->car || n2->cdr)) { - dump_prefix(offset+1); + dump_prefix(n2, offset+1); printf("local variables:\n"); - dump_prefix(offset+2); + dump_prefix(n2, offset+2); while (n2) { if (n2->car) { if (!first_lval) printf(", "); @@ -6265,19 +6301,19 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) node *n = tree->car; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("mandatory args:\n"); dump_recur(mrb, n->car, offset+2); } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("optional args:\n"); { node *n2 = n->car; while (n2) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); mrb_parser_dump(mrb, n2->car->cdr, 0); n2 = n2->cdr; @@ -6286,18 +6322,18 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("post mandatory args:\n"); dump_recur(mrb, n->car, offset+2); } n = n->cdr; if (n) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); } } @@ -6308,26 +6344,26 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) printf("NODE_SDEF:\n"); mrb_parser_dump(mrb, tree->car, offset+1); tree = tree->cdr; - dump_prefix(offset+1); + dump_prefix(tree, offset+1); printf(":%s\n", mrb_sym2name(mrb, sym(tree->car))); tree = tree->cdr->cdr; if (tree->car) { node *n = tree->car; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("mandatory args:\n"); dump_recur(mrb, n->car, offset+2); } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("optional args:\n"); { node *n2 = n->car; while (n2) { - dump_prefix(offset+2); + dump_prefix(n2, offset+2); printf("%s=", mrb_sym2name(mrb, sym(n2->car->car))); mrb_parser_dump(mrb, n2->car->cdr, 0); n2 = n2->cdr; @@ -6336,18 +6372,18 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("rest=*%s\n", mrb_sym2name(mrb, sym(n->car))); } n = n->cdr; if (n->car) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("post mandatory args:\n"); dump_recur(mrb, n->car, offset+2); } n = n->cdr; if (n) { - dump_prefix(offset+1); + dump_prefix(n, offset+1); printf("blk=&%s\n", mrb_sym2name(mrb, sym(n))); } } @@ -6366,7 +6402,7 @@ mrb_parser_dump(mrb_state *mrb, node *tree, int offset) break; default: - printf("node type: %d (0x%x)\n", n, (unsigned)n); + printf("node type: %d (0x%x)\n", nodetype, (unsigned)nodetype); break; } #endif diff --git a/src/pool.c b/src/pool.c index ffddd2552..60670ad4a 100644 --- a/src/pool.c +++ b/src/pool.c @@ -47,7 +47,7 @@ struct mrb_pool { # define ALIGN_PADDING(x) (0) #endif -mrb_pool* +MRB_API mrb_pool* mrb_pool_open(mrb_state *mrb) { mrb_pool *pool = (mrb_pool *)mrb_malloc_simple(mrb, sizeof(mrb_pool)); @@ -60,7 +60,7 @@ mrb_pool_open(mrb_state *mrb) return pool; } -void +MRB_API void mrb_pool_close(mrb_pool *pool) { struct mrb_pool_page *page, *tmp; @@ -91,7 +91,7 @@ page_alloc(mrb_pool *pool, size_t len) return page; } -void* +MRB_API void* mrb_pool_alloc(mrb_pool *pool, size_t len) { struct mrb_pool_page *page; @@ -119,7 +119,7 @@ mrb_pool_alloc(mrb_pool *pool, size_t len) return page->last; } -mrb_bool +MRB_API mrb_bool mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len) { struct mrb_pool_page *page; @@ -140,7 +140,7 @@ mrb_pool_can_realloc(mrb_pool *pool, void *p, size_t len) return FALSE; } -void* +MRB_API void* mrb_pool_realloc(mrb_pool *pool, void *p, size_t oldlen, size_t newlen) { struct mrb_pool_page *page; diff --git a/src/proc.c b/src/proc.c index 0b776ea80..ebdafccf8 100644 --- a/src/proc.c +++ b/src/proc.c @@ -34,17 +34,27 @@ mrb_proc_new(mrb_state *mrb, mrb_irep *irep) return p; } -static inline void +static struct REnv* +env_new(mrb_state *mrb, int nlocals) +{ + struct REnv *e; + + e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); + MRB_ENV_STACK_LEN(e) = (unsigned int)nlocals; + e->mid = mrb->c->ci->mid; + e->cioff = mrb->c->ci - mrb->c->cibase; + e->stack = mrb->c->stack; + + return e; +} + +static void closure_setup(mrb_state *mrb, struct RProc *p, int nlocals) { struct REnv *e; if (!mrb->c->ci->env) { - e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); - MRB_ENV_STACK_LEN(e) = (unsigned int)nlocals+1; /* add space for receiver */ - e->mid = mrb->c->ci->mid; - e->cioff = mrb->c->ci - mrb->c->cibase; - e->stack = mrb->c->stack; + e = env_new(mrb, nlocals); mrb->c->ci->env = e; } else { @@ -62,7 +72,7 @@ mrb_closure_new(mrb_state *mrb, mrb_irep *irep) return p; } -struct RProc * +MRB_API struct RProc * mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) { struct RProc *p; @@ -76,15 +86,55 @@ mrb_proc_new_cfunc(mrb_state *mrb, mrb_func_t func) } MRB_API struct RProc * -mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals) +mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const mrb_value *argv) { struct RProc *p = mrb_proc_new_cfunc(mrb, func); - - closure_setup(mrb, p, nlocals); + struct REnv *e; + int i; + + p->env = e = env_new(mrb, argc); + MRB_ENV_UNSHARE_STACK(e); + e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); + if (argv) { + for (i = 0; i < argc; ++i) { + e->stack[i] = argv[i]; + } + } + else { + for (i = 0; i < argc; ++i) { + SET_NIL_VALUE(e->stack[i]); + } + } return p; } -void +MRB_API struct RProc * +mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals) +{ + return mrb_proc_new_cfunc_with_env(mrb, func, nlocals, NULL); +} + +MRB_API mrb_value +mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx) +{ + struct RProc *p = mrb->c->ci->proc; + struct REnv *e = p->env; + + if (!MRB_PROC_CFUNC_P(p)) { + mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from non-cfunc proc."); + } + if (!e) { + mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); + } + if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) { + mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", + mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e))); + } + + return e->stack[idx]; +} + +MRB_API void mrb_proc_copy(struct RProc *a, struct RProc *b) { a->flags = b->flags; diff --git a/src/state.c b/src/state.c index 8d6993b6f..2efd34334 100644 --- a/src/state.c +++ b/src/state.c @@ -256,7 +256,7 @@ mrb_close(mrb_state *mrb) mrb_free(mrb, mrb); } -mrb_irep* +MRB_API mrb_irep* mrb_add_irep(mrb_state *mrb) { static const mrb_irep mrb_irep_zero = { 0 }; diff --git a/src/string.c b/src/string.c index e8632e5e4..56827922b 100644 --- a/src/string.c +++ b/src/string.c @@ -148,7 +148,7 @@ str_new(mrb_state *mrb, const char *p, size_t len) s = mrb_obj_alloc_string(mrb); if (len < RSTRING_EMBED_LEN_MAX) { RSTR_SET_EMBED_FLAG(s); - RSTR_SET_EMBED_LEN(s,len); + RSTR_SET_EMBED_LEN(s, len); if (p) { memcpy(s->as.ary, p, len); } @@ -393,7 +393,7 @@ mrb_str_concat(mrb_state *mrb, mrb_value self, mrb_value other) * * Returns a new string object containing a copy of <i>str</i>. */ -mrb_value +MRB_API mrb_value mrb_str_plus(mrb_state *mrb, mrb_value a, mrb_value b) { struct RString *s = mrb_str_ptr(a); @@ -615,7 +615,7 @@ mrb_str_equal_m(mrb_state *mrb, mrb_value str1) return mrb_bool_value(mrb_str_equal(mrb, str1, str2)); } /* ---------------------------------- */ -mrb_value +MRB_API mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str) { mrb_value s; @@ -637,18 +637,17 @@ mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr) return RSTRING_PTR(str); } -static mrb_value -noregexp(mrb_state *mrb, mrb_value self) +void +mrb_noregexp(mrb_state *mrb, mrb_value self) { mrb_raise(mrb, E_NOTIMP_ERROR, "Regexp class not implemented"); - return mrb_nil_value(); } -static void -regexp_check(mrb_state *mrb, mrb_value obj) +void +mrb_regexp_check(mrb_state *mrb, mrb_value obj) { if (mrb_regexp_p(mrb, obj)) { - noregexp(mrb, obj); + mrb_noregexp(mrb, obj); } } @@ -738,7 +737,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) { mrb_int idx; - regexp_check(mrb, indx); + mrb_regexp_check(mrb, indx); switch (mrb_type(indx)) { case MRB_TT_FIXNUM: idx = mrb_fixnum(indx); @@ -820,7 +819,7 @@ mrb_str_aref_m(mrb_state *mrb, mrb_value str) argc = mrb_get_args(mrb, "o|o", &a1, &a2); if (argc == 2) { - regexp_check(mrb, a1); + mrb_regexp_check(mrb, a1); return mrb_str_substr(mrb, str, mrb_fixnum(a1), mrb_fixnum(a2)); } if (argc != 1) { @@ -1159,7 +1158,7 @@ mrb_str_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) return mrb_obj_value(s); } -mrb_value +MRB_API mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) { if (len < 0) return mrb_nil_value(); @@ -1284,7 +1283,7 @@ mrb_str_index_m(mrb_state *mrb, mrb_value str) else sub = mrb_nil_value(); } - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); if (pos < 0) { pos += RSTRING_LEN(str); if (pos < 0) { @@ -1623,7 +1622,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) if (pos < 0) { pos += len; if (pos < 0) { - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); return mrb_nil_value(); } } @@ -1636,12 +1635,11 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) else sub = mrb_nil_value(); } - regexp_check(mrb, sub); + mrb_regexp_check(mrb, sub); switch (mrb_type(sub)) { case MRB_TT_FIXNUM: { int c = mrb_fixnum(sub); - mrb_int len = RSTRING_LEN(str); unsigned char *p = (unsigned char*)RSTRING_PTR(str); for (pos=len-1;pos>=0;pos--) { @@ -1746,7 +1744,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) } } else { - noregexp(mrb, str); + mrb_noregexp(mrb, str); } } @@ -1815,7 +1813,7 @@ mrb_str_split_m(mrb_state *mrb, mrb_value str) beg = ptr - temp; } else { - noregexp(mrb, str); + mrb_noregexp(mrb, str); } if (RSTRING_LEN(str) > 0 && (lim_p || RSTRING_LEN(str) > beg || lim < 0)) { if (RSTRING_LEN(str) == beg) { @@ -2060,9 +2058,6 @@ mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) double d; enum {max_width = 20}; -#define OutOfRange() (((w = end - p) > max_width) ? \ - (w = max_width, ellipsis = "...") : \ - (w = (int)(end - p), ellipsis = "")) if (!p) return 0.0; while (ISSPACE(*p)) p++; diff --git a/src/symbol.c b/src/symbol.c index 5e40fa315..7fcef2817 100644 --- a/src/symbol.c +++ b/src/symbol.c @@ -10,6 +10,7 @@ #include "mruby.h" #include "mruby/khash.h" #include "mruby/string.h" +#include "mruby/dump.h" /* ------------------------------------------------------ */ typedef struct symbol_name { @@ -36,7 +37,15 @@ KHASH_DECLARE(n2s, symbol_name, mrb_sym, TRUE) KHASH_DEFINE (n2s, symbol_name, mrb_sym, TRUE, sym_hash_func, sym_hash_equal) /* ------------------------------------------------------ */ -#define MRB_SYM_MAX SHRT_MAX +static void +sym_validate_len(mrb_state *mrb, size_t len) +{ + if (len >= RITE_LV_NULL_MARK) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long"); + } +} + +#define MRB_SYM_MAX UINT16_MAX static mrb_value sym_tbl_overflow_new_str(mrb_state *mrb, const char *name, size_t len) @@ -53,9 +62,7 @@ sym_intern(mrb_state *mrb, const char *name, size_t len, mrb_bool lit) mrb_sym sym; char *p; - if (len > (UINT16_MAX-1)) { /* UINT16_MAX is reverved */ - mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long"); - } + sym_validate_len(mrb, len); sname.lit = lit; sname.len = (uint16_t)len; sname.name = name; @@ -123,9 +130,7 @@ mrb_check_intern(mrb_state *mrb, const char *name, size_t len) symbol_name sname = { 0 }; khiter_t k; - if (len > UINT16_MAX) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "symbol length too long"); - } + sym_validate_len(mrb, len); sname.len = (uint16_t)len; sname.name = name; diff --git a/src/variable.c b/src/variable.c index a50256353..440a33948 100644 --- a/src/variable.c +++ b/src/variable.c @@ -542,6 +542,32 @@ mrb_iv_defined(mrb_state *mrb, mrb_value obj, mrb_sym sym) return mrb_obj_iv_defined(mrb, mrb_obj_ptr(obj), sym); } +#define identchar(c) (ISALNUM(c) || (c) == '_' || !ISASCII(c)) + +MRB_API mrb_bool +mrb_iv_p(mrb_state *mrb, mrb_sym iv_name) +{ + const char *s; + mrb_int i, len; + + s = mrb_sym2name_len(mrb, iv_name, &len); + if (len < 2) return FALSE; + if (s[0] != '@') return FALSE; + if (s[1] == '@') return FALSE; + for (i=1; i<len; i++) { + if (!identchar(s[i])) return FALSE; + } + return TRUE; +} + +MRB_API void +mrb_iv_check(mrb_state *mrb, mrb_sym iv_name) +{ + if (!mrb_iv_p(mrb, iv_name)) { + mrb_name_error(mrb, iv_name, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name)); + } +} + MRB_API void mrb_iv_copy(mrb_state *mrb, mrb_value dest, mrb_value src) { @@ -809,7 +835,7 @@ mrb_cv_defined(mrb_state *mrb, mrb_value mod, mrb_sym sym) return mrb_mod_cv_defined(mrb, mrb_class_ptr(mod), sym); } -MRB_API mrb_value +mrb_value mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) { struct RClass *c = mrb->c->ci->proc->target_class; @@ -819,7 +845,7 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym) return mrb_mod_cv_get(mrb, c, sym); } -MRB_API void +void mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v) { struct RClass *c = mrb->c->ci->proc->target_class; @@ -1093,7 +1119,7 @@ mrb_const_defined_at(mrb_state *mrb, struct RClass *klass, mrb_sym id) return mrb_const_defined_0(mrb, klass, id, TRUE, FALSE); } -mrb_value +MRB_API mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id) { return mrb_iv_get(mrb, obj, id); @@ -227,7 +227,6 @@ cipush(mrb_state *mrb) c->ciend = c->cibase + size * 2; } ci = ++c->ci; - ci->nregs = 2; /* protect method_missing arg and block */ ci->eidx = eidx; ci->ridx = ridx; ci->env = 0; @@ -253,6 +252,7 @@ cipop(mrb_state *mrb) stack_copy(p, e->stack, len); } e->stack = p; + mrb_write_barrier(mrb, (struct RBasic *)e); } c->ci--; @@ -467,6 +467,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self) ci->nregs = p->body.irep->nregs; ci = cipush(mrb); + ci->nregs = 0; ci->target_class = 0; ci->pc = p->body.irep->iseq; ci->stackent = mrb->c->stack; @@ -496,6 +497,7 @@ eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c) } ci->nregs = p->body.irep->nregs; ci = cipush(mrb); + ci->nregs = 0; ci->target_class = 0; ci->pc = p->body.irep->iseq; ci->stackent = mrb->c->stack; @@ -1248,6 +1250,7 @@ RETRY_TRY_BLOCK: mrb->c->stack[0] = recv; if (MRB_PROC_CFUNC_P(m)) { + ci->nregs = 0; mrb->c->stack[0] = m->body.func(mrb, recv); mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; @@ -2110,7 +2113,7 @@ RETRY_TRY_BLOCK: else { struct RArray *ary = mrb_ary_ptr(v); int len = ary->len; - int i; + int idx; if (len > pre + post) { regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre); @@ -2120,11 +2123,11 @@ RETRY_TRY_BLOCK: } else { regs[a++] = mrb_ary_new_capa(mrb, 0); - for (i=0; i+pre<len; i++) { - regs[a+i] = ary->ptr[pre+i]; + for (idx=0; idx+pre<len; i++) { + regs[a+i] = ary->ptr[pre+idx]; } - while (i < post) { - SET_NIL_VALUE(regs[a+i]); + while (idx < post) { + SET_NIL_VALUE(regs[a+idx]); i++; } } @@ -2253,6 +2256,7 @@ RETRY_TRY_BLOCK: ci->proc = p; if (MRB_PROC_CFUNC_P(p)) { + ci->nregs = 0; mrb->c->stack[0] = p->body.func(mrb, recv); mrb_gc_arena_restore(mrb, ai); if (mrb->exc) goto L_RAISE; @@ -2382,6 +2386,7 @@ mrb_toplevel_run_keep(mrb_state *mrb, struct RProc *proc, unsigned int stack_kee return mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep); } ci = cipush(mrb); + ci->nregs = 1; /* protect the receiver */ ci->acc = CI_ACC_SKIP; ci->target_class = mrb->object_class; v = mrb_context_run(mrb, proc, mrb_top_self(mrb), stack_keep); |
