diff options
| -rw-r--r-- | include/mruby/irep.h | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 28 | ||||
| -rw-r--r-- | mrblib/class.rb | 24 | ||||
| -rw-r--r-- | src/array.c | 7 | ||||
| -rw-r--r-- | src/class.c | 15 | ||||
| -rw-r--r-- | src/error.c | 9 | ||||
| -rw-r--r-- | src/gc.c | 3 | ||||
| -rw-r--r-- | src/kernel.c | 58 | ||||
| -rw-r--r-- | src/numeric.c | 9 | ||||
| -rw-r--r-- | tasks/mrbgem_spec.rake | 7 | ||||
| -rw-r--r-- | tasks/toolchains/androideabi.rake | 2 | ||||
| -rw-r--r-- | test/t/module.rb | 139 | ||||
| -rw-r--r-- | test/t/string.rb | 4 |
13 files changed, 266 insertions, 44 deletions
diff --git a/include/mruby/irep.h b/include/mruby/irep.h index 856b12099..498b58ca3 100644 --- a/include/mruby/irep.h +++ b/include/mruby/irep.h @@ -11,10 +11,11 @@ extern "C" { #endif +/* Program data array struct */ typedef struct mrb_irep { uint32_t idx; - uint16_t nlocals; - uint16_t nregs; + uint16_t nlocals; /* Number of local variables */ + uint16_t nregs; /* Number of register variables */ uint8_t flags; mrb_code *iseq; diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index eb7194f30..3111eea8f 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -15,11 +15,19 @@ #include <mruby/data.h> #include <mruby/compile.h> #ifdef ENABLE_READLINE +#include <limits.h> #include <readline/readline.h> #include <readline/history.h> #endif #include <mruby/string.h> + +#ifdef ENABLE_READLINE +static const char *history_file_name = ".mirb_history"; +char history_path[PATH_MAX]; +#endif + + static void p(mrb_state *mrb, mrb_value obj, int prompt) { @@ -245,6 +253,7 @@ main(int argc, char **argv) int n; int code_block_open = FALSE; int ai; + char *home = NULL; /* new interpreter instance */ mrb = mrb_open(); @@ -268,6 +277,21 @@ main(int argc, char **argv) if (args.verbose) cxt->dump_result = 1; ai = mrb_gc_arena_save(mrb); + +#ifdef ENABLE_READLINE + using_history(); + home = getenv("HOME"); +#ifdef _WIN32 + if (!home) + home = getenv("USERPROFILE"); +#endif + strcpy(history_path, home); + strcat(history_path, "/"); + strcat(history_path, history_file_name); + read_history(history_path); +#endif + + while (TRUE) { #ifndef ENABLE_READLINE print_cmdline(code_block_open); @@ -361,5 +385,9 @@ main(int argc, char **argv) mrbc_context_free(mrb, cxt); mrb_close(mrb); +#ifdef ENABLE_READLINE + write_history(history_path); +#endif + return 0; } diff --git a/mrblib/class.rb b/mrblib/class.rb index 4f268b6c8..6d624ee83 100644 --- a/mrblib/class.rb +++ b/mrblib/class.rb @@ -1,18 +1,24 @@ class Module # 15.2.2.4.13 def attr_reader(*names) - names.each{|name| - name2 = ('@'+name.to_s).intern - define_method(name){self.instance_variable_get(name2)} - } + 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{|name| - name2 = ('@'+name.to_s).intern - name = (name.to_s+"=").intern - define_method(name){|v|self.instance_variable_set(name2,v)} - } + 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 def attr_accessor(*names) diff --git a/src/array.c b/src/array.c index ed087515a..526cf4973 100644 --- a/src/array.c +++ b/src/array.c @@ -19,7 +19,7 @@ #define ARY_DEFAULT_LEN 4 #define ARY_SHRINK_RATIO 5 /* must be larger than 2 */ #define ARY_C_MAX_SIZE (SIZE_MAX / sizeof(mrb_value)) -#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX) +#define ARY_MAX_SIZE ((ARY_C_MAX_SIZE < (size_t)MRB_INT_MAX) ? (mrb_int)ARY_C_MAX_SIZE : MRB_INT_MAX-1) static inline mrb_value ary_elt(mrb_value ary, mrb_int offset) @@ -40,7 +40,7 @@ ary_new_capa(mrb_state *mrb, mrb_int capa) if (capa > ARY_MAX_SIZE) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } - blen = capa * sizeof(mrb_value) ; + blen = capa * sizeof(mrb_value); if (blen < capa) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } @@ -926,7 +926,8 @@ inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list) } if (mrb_array_p(RARRAY_PTR(ary)[i])) { s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list); - } else { + } + else { s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]); } mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s)); diff --git a/src/class.c b/src/class.c index 606a54a7c..ad4c9eaa2 100644 --- a/src/class.c +++ b/src/class.c @@ -1437,7 +1437,8 @@ undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) if (!mrb_obj_respond_to(c, a)) { mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); - } else { + } + else { MRB_SET_VALUE(m, MRB_TT_PROC, value.p, 0); mrb_define_method_vm(mrb, c, a, m); } @@ -1519,7 +1520,8 @@ get_sym_or_str_arg(mrb_state *mrb) if (mrb_symbol_p(sym_or_str) || mrb_string_p(sym_or_str)) { return sym_or_str; - } else { + } + else { mrb_value obj = mrb_funcall(mrb, sym_or_str, "inspect", 0); mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); return mrb_nil_value(); @@ -1551,7 +1553,8 @@ mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) if (mrb_symbol_p(id)) { check_cv_name_sym(mrb, mrb_symbol(id)); defined_p = mrb_cv_defined(mrb, mod, mrb_symbol(id)); - } else { + } + else { mrb_value sym; check_cv_name_str(mrb, id); sym = mrb_check_intern_str(mrb, id); @@ -1703,7 +1706,8 @@ mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) id = get_sym_or_str_arg(mrb); if (mrb_symbol_p(id)) { method_defined_p = mrb_obj_respond_to(mrb_class_ptr(mod), mrb_symbol(id)); - } else { + } + else { mrb_value sym = mrb_check_intern_str(mrb, id); if (mrb_nil_p(sym)) { method_defined_p = FALSE; @@ -1787,7 +1791,8 @@ mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) if (mrb_type(id) == MRB_TT_SYMBOL) { check_const_name_sym(mrb, mrb_symbol(id)); const_defined_p = mrb_const_defined(mrb, mod, mrb_symbol(id)); - } else { + } + else { mrb_value sym; check_const_name_str(mrb, id); sym = mrb_check_intern_str(mrb, id); diff --git a/src/error.c b/src/error.c index bd3afd2e1..9f3a86cc8 100644 --- a/src/error.c +++ b/src/error.c @@ -147,7 +147,8 @@ exc_inspect(mrb_state *mrb, mrb_value exc) if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { mrb_str_cat(mrb, str, ": ", 2); mrb_str_append(mrb, str, mesg); - } else { + } + else { mrb_str_cat(mrb, str, ": ", 2); mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); } @@ -425,10 +426,12 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) sce = mrb_class_get(mrb, "SystemCallError"); if (mesg != NULL) { mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 2, mrb_fixnum_value(no), mrb_str_new_cstr(mrb, mesg)); - } else { + } + else { mrb_funcall(mrb, mrb_obj_value(sce), "_sys_fail", 1, mrb_fixnum_value(no)); } - } else { + } + else { mrb_raise(mrb, E_RUNTIME_ERROR, mesg); } } @@ -212,7 +212,8 @@ mrb_calloc(mrb_state *mrb, size_t nelem, size_t len) if (p) { memset(p, 0, size); } - } else { + } + else { p = NULL; } diff --git a/src/kernel.c b/src/kernel.c index ae8d24710..4914b7285 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -549,15 +549,38 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self) } static void -check_iv_name(mrb_state *mrb, mrb_sym id) +valid_iv_name(mrb_state *mrb, mrb_sym iv_name_id, const char* s, size_t 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; size_t len; - s = mrb_sym2name_len(mrb, id, &len); - if (len < 2 || !(s[0] == '@' && s[1] != '@')) { - mrb_name_error(mrb, id, "`%S' is not allowed as an instance variable name", mrb_sym2str(mrb, id)); + 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; + + if (mrb_string_p(iv_name)) { + iv_name_id = mrb_intern_cstr(mrb, RSTRING_PTR(iv_name)); + valid_iv_name(mrb, iv_name_id, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name)); + } + else if(mrb_symbol_p(iv_name)) { + iv_name_id = mrb_symbol(iv_name); + check_iv_name(mrb, iv_name_id); } + + return iv_name_id; } /* 15.3.1.3.20 */ @@ -582,10 +605,11 @@ 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, "n", &mid); - check_iv_name(mrb, mid); + 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); return mrb_bool_value(defined_p); @@ -614,12 +638,13 @@ mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) mrb_value mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) { - mrb_sym id; - - mrb_get_args(mrb, "n", &id); + mrb_sym iv_name_id; + mrb_value iv_name; + + mrb_get_args(mrb, "o", &iv_name); - check_iv_name(mrb, id); - return mrb_iv_get(mrb, self, id); + iv_name_id = get_valid_iv_sym(mrb, iv_name); + return mrb_iv_get(mrb, self, iv_name_id); } /* 15.3.1.3.22 */ @@ -645,12 +670,13 @@ mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) mrb_value mrb_obj_ivar_set(mrb_state *mrb, mrb_value self) { - mrb_sym id; - mrb_value val; + mrb_sym iv_name_id; + mrb_value iv_name, val; - mrb_get_args(mrb, "no", &id, &val); - check_iv_name(mrb, id); - mrb_iv_set(mrb, self, id, val); + mrb_get_args(mrb, "oo", &iv_name, &val); + + iv_name_id = get_valid_iv_sym(mrb, iv_name); + mrb_iv_set(mrb, self, iv_name_id, val); return val; } diff --git a/src/numeric.c b/src/numeric.c index e1543c089..c734a595d 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -240,7 +240,8 @@ mrb_flo_to_str(mrb_state *mrb, mrb_value flo, int max_digit) *(c++) = 'e'; if (exp > 0) { *(c++) = '+'; - } else { + } + else { *(c++) = '-'; exp = -exp; } @@ -1253,12 +1254,14 @@ mrb_fixnum_to_str(mrb_state *mrb, mrb_value x, int base) if (val == 0) { *--b = '0'; - } else if (val < 0) { + } + else if (val < 0) { do { *--b = mrb_digitmap[-(val % base)]; } while (val /= base); *--b = '-'; - } else { + } + else { do { *--b = mrb_digitmap[(int)(val % base)]; } while (val /= base); diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 3363b4885..df55e749f 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -275,13 +275,20 @@ module MRuby req_versions = dep[:requirements] # check each GEM dependency against all available GEMs + found_dep_gem = false each do |dep_g| if name == dep_g.name unless dep_g.version_ok?(req_versions) fail "#{name} version should be #{req_versions.join(' and ')} but was '#{dep_g.version}'" end + + found_dep_gem = true + break end end + + fail "The GEM '#{g.name}' depends on the GEM '#{name}' but it could not be found" unless found_dep_gem + end end end diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake index 51897667e..a20027c0d 100644 --- a/tasks/toolchains/androideabi.rake +++ b/tasks/toolchains/androideabi.rake @@ -46,6 +46,8 @@ MRuby::Toolchain.new(:androideabi) do |conf| HOST_PLATFORM = 'windows' when /darwin/i HOST_PLATFORM = 'darwin-x86' + when /x86_64-linux/i + HOST_PLATFORM = 'linux-x86_64' when /linux/i HOST_PLATFORM = 'linux-x86' else diff --git a/test/t/module.rb b/test/t/module.rb index 9d735f5da..618b57f06 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -37,6 +37,145 @@ assert('Module#append_features', '15.2.2.4.10') do assert_equal Test4AppendFeatures2.const_get(:Const4AppendFeatures2), Test4AppendFeatures2 end +assert('Module#attr NameError') do + %w[ + foo? + @foo + @@foo + $foo + ].each do |name| + module NameTest; end + + assert_raise(NameError) do + NameTest.module_eval { attr_reader name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr_writer name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr name.to_sym } + end + + assert_raise(NameError) do + NameTest.module_eval { attr_accessor name.to_sym } + end + end + +end + +assert('Module#attr', '15.2.2.4.11') do + class AttrTest + class << self + attr :cattr + def cattr_val=(val) + @cattr = val + end + end + attr :iattr + def iattr_val=(val) + @iattr = val + end + end + + test = AttrTest.new + assert_true AttrTest.respond_to?(:cattr) + assert_true test.respond_to?(:iattr) + + assert_false AttrTest.respond_to?(:vattr=) + assert_false test.respond_to?(:iattr=) + + test.iattr_val = 'test' + assert_equal 'test', test.iattr + + AttrTest.cattr_val = 'test' + assert_equal 'test', AttrTest.cattr +end + +assert('Module#attr_accessor', '15.2.2.4.12') do + class AttrTestAccessor + class << self + attr_accessor :cattr + end + attr_accessor :iattr, 'iattr2' + end + + attr_instance = AttrTestAccessor.new + assert_true AttrTestAccessor.respond_to?(:cattr=) + assert_true attr_instance.respond_to?(:iattr=) + assert_true attr_instance.respond_to?(:iattr2=) + assert_true AttrTestAccessor.respond_to?(:cattr) + assert_true attr_instance.respond_to?(:iattr) + assert_true attr_instance.respond_to?(:iattr2) + + attr_instance.iattr = 'test' + assert_equal 'test', attr_instance.iattr + + AttrTestAccessor.cattr = 'test' + assert_equal 'test', AttrTestAccessor.cattr +end + +assert('Module#attr_reader', '15.2.2.4.13') do + class AttrTestReader + class << self + attr_reader :cattr + def cattr_val=(val) + @cattr = val + end + end + attr_reader :iattr, 'iattr2' + def iattr_val=(val) + @iattr = val + end + end + + attr_instance = AttrTestReader.new + assert_true AttrTestReader.respond_to?(:cattr) + assert_true attr_instance.respond_to?(:iattr) + assert_true attr_instance.respond_to?(:iattr2) + + assert_false AttrTestReader.respond_to?(:cattr=) + assert_false attr_instance.respond_to?(:iattr=) + assert_false attr_instance.respond_to?(:iattr2=) + + attr_instance.iattr_val = 'test' + assert_equal 'test', attr_instance.iattr + + AttrTestReader.cattr_val = 'test' + assert_equal 'test', AttrTestReader.cattr +end + +assert('Module#attr_writer', '15.2.2.4.14') do + class AttrTestWriter + class << self + attr_writer :cattr + def cattr_val + @cattr + end + end + attr_writer :iattr, 'iattr2' + def iattr_val + @iattr + end + end + + attr_instance = AttrTestWriter.new + assert_true AttrTestWriter.respond_to?(:cattr=) + assert_true attr_instance.respond_to?(:iattr=) + assert_true attr_instance.respond_to?(:iattr2=) + + assert_false AttrTestWriter.respond_to?(:cattr) + assert_false attr_instance.respond_to?(:iattr) + assert_false attr_instance.respond_to?(:iattr2) + + attr_instance.iattr = 'test' + assert_equal 'test', attr_instance.iattr_val + + AttrTestWriter.cattr = 'test' + assert_equal 'test', AttrTestWriter.cattr_val +end + assert('Module#class_eval', '15.2.2.4.15') do class Test4ClassEval @a = 11 diff --git a/test/t/string.rb b/test/t/string.rb index ddae92d4a..c208835b4 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -399,12 +399,12 @@ end assert('String#to_i', '15.2.10.5.38') do a = ''.to_i - b = '123456789'.to_i + b = '32143'.to_i c = 'a'.to_i(16) d = '100'.to_i(2) assert_equal a, 0 - assert_equal b, 123456789 + assert_equal b, 32143 assert_equal c, 10 assert_equal d, 4 end |
