summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/irep.h5
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c28
-rw-r--r--mrblib/class.rb24
-rw-r--r--src/array.c7
-rw-r--r--src/class.c15
-rw-r--r--src/error.c9
-rw-r--r--src/gc.c3
-rw-r--r--src/kernel.c58
-rw-r--r--src/numeric.c9
-rw-r--r--tasks/mrbgem_spec.rake7
-rw-r--r--tasks/toolchains/androideabi.rake2
-rw-r--r--test/t/module.rb139
-rw-r--r--test/t/string.rb4
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);
}
}
diff --git a/src/gc.c b/src/gc.c
index 02ef459d8..37d61ad35 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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