From b05d736b49a6d3a99b7f75c74ffd9b6613c453d3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 29 May 2015 17:01:44 +0900 Subject: [PATCH 001/218] update mrblib/*.rb files to conform (some of) Rubocop checks --- mrblib/array.rb | 4 ++-- mrblib/hash.rb | 4 ++-- mrblib/kernel.rb | 2 +- mrblib/numeric.rb | 8 ++++---- mrblib/range.rb | 2 +- mrblib/string.rb | 6 +++--- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/mrblib/array.rb b/mrblib/array.rb index bd8d5930f..83a42c62d 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -34,7 +34,7 @@ class Array return to_enum :each_index unless block_given? idx = 0 - while(idx < length) + while idx < length block.call(idx) idx += 1 end @@ -75,7 +75,7 @@ class Array self[size - 1] = nil # allocate idx = 0 - while(idx < size) + while idx < size self[idx] = (block)? block.call(idx): obj idx += 1 end diff --git a/mrblib/hash.rb b/mrblib/hash.rb index e7c51fb1f..cb52c1ffe 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -10,7 +10,7 @@ class Hash # hash. # # ISO 15.2.13.4.1 - def == (hash) + def ==(hash) return true if self.equal?(hash) begin hash = hash.to_hash @@ -54,7 +54,7 @@ class Hash # # ISO 15.2.13.4.8 def delete(key, &block) - if block && ! self.has_key?(key) + if block && !self.has_key?(key) block.call(key) else self.__delete(key) diff --git a/mrblib/kernel.rb b/mrblib/kernel.rb index 8c9b122f2..38af3b310 100644 --- a/mrblib/kernel.rb +++ b/mrblib/kernel.rb @@ -27,7 +27,7 @@ module Kernel def loop(&block) return to_enum :loop unless block - while(true) + while true yield end rescue StopIteration diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb index 1f44a2c81..cf608b04b 100644 --- a/mrblib/numeric.rb +++ b/mrblib/numeric.rb @@ -48,7 +48,7 @@ module Integral return to_enum(:downto, num) unless block_given? i = self.to_i - while(i >= num) + while i >= num block.call(i) i -= 1 end @@ -89,7 +89,7 @@ module Integral return to_enum(:upto, num) unless block_given? i = self.to_i - while(i <= num) + while i <= num block.call(i) i += 1 end @@ -106,12 +106,12 @@ module Integral i = if num.kind_of? Float then self.to_f else self end if step > 0 - while(i <= num) + while i <= num block.call(i) i += step end else - while(i >= num) + while i >= num block.call(i) i += step end diff --git a/mrblib/range.rb b/mrblib/range.rb index 1ec9ac508..64fa0cb6c 100644 --- a/mrblib/range.rb +++ b/mrblib/range.rb @@ -32,7 +32,7 @@ class Range return self if (val <=> last) > 0 - while((val <=> last) < 0) + while (val <=> last) < 0 block.call(val) val = val.succ end diff --git a/mrblib/string.rb b/mrblib/string.rb index 1d9ea9e6a..90aad5d32 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -12,7 +12,7 @@ class String def each_line(&block) # expect that str.index accepts an Integer for 1st argument as a byte data offset = 0 - while(pos = self.index(0x0a, offset)) + while pos = self.index(0x0a, offset) block.call(self[offset, pos + 1 - offset]) offset = pos + 1 end @@ -106,7 +106,7 @@ class String # +self+. def each_char(&block) pos = 0 - while(pos < self.size) + while pos < self.size block.call(self[pos]) pos += 1 end @@ -118,7 +118,7 @@ class String def each_byte(&block) bytes = self.bytes pos = 0 - while(pos < bytes.size) + while pos < bytes.size block.call(bytes[pos]) pos += 1 end From 2554fd9c945d5b5281a52d40146b348353e3707c Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 29 May 2015 11:29:11 +0200 Subject: [PATCH 002/218] remove unreachable code It's just a copy of the code in the previous case (NODE_CALL). --- src/codegen.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index 222dec9b6..6f1f75e88 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -957,13 +957,6 @@ gen_assignment(codegen_scope *s, node *tree, int sp, int val) gen_vmassignment(s, tree->car, sp, val); break; - push(); - 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); - } - break; /* splat without assignment */ case NODE_NIL: break; From ba3a0c22a52111da15c9dfea534a68d3fffd78e3 Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 29 May 2015 12:17:13 +0200 Subject: [PATCH 003/218] add multiple assignment with rest tests --- test/t/syntax.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 5ce4e0a63..41e49d938 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -219,6 +219,21 @@ assert('Splat without assignment') do assert_equal 1, a end +assert('multiple assignment (rest)') do + *a = 0 + assert_equal [0], a +end + +assert('multiple assignment (rest+post)') do + *a, b = 0, 1, 2 + *c, d = 3 + + assert_equal [0, 1], a + assert_equal [2], b + assert_equal [], c + assert_equal [3], d +end + assert('Return values of case statements') do a = [] << case 1 when 3 then 2 From 59ea323976557408ba1c5f694213c7a31bbb6e39 Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 29 May 2015 14:51:48 +0200 Subject: [PATCH 004/218] check if outer is a class or module For modules this check didn't exist yet. Also call #inspect. --- src/class.c | 24 +++++++++++++++--------- test/t/class.rb | 5 +++++ test/t/module.rb | 4 ++++ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/class.c b/src/class.c index 3246564ec..35c3aa040 100644 --- a/src/class.c +++ b/src/class.c @@ -131,6 +131,19 @@ mrb_class_outer_module(mrb_state *mrb, struct RClass *c) return mrb_class_ptr(outer); } +static void +check_if_class_or_module(mrb_state *mrb, mrb_value obj) +{ + switch (mrb_type(obj)) { + case MRB_TT_CLASS: + case MRB_TT_SCLASS: + case MRB_TT_MODULE: + return; + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj)); + } +} + static struct RClass* define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer) { @@ -160,6 +173,7 @@ mrb_define_module(mrb_state *mrb, const char *name) MRB_API struct RClass* mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) { + check_if_class_or_module(mrb, outer); return define_module(mrb, id, mrb_class_ptr(outer)); } @@ -232,15 +246,7 @@ mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id else { s = 0; } - switch (mrb_type(outer)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - case MRB_TT_MODULE: - break; - default: - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", outer); - break; - } + check_if_class_or_module(mrb, outer); c = define_class(mrb, id, s, mrb_class_ptr(outer)); mrb_class_inherited(mrb, mrb_class_real(c->super), c); diff --git a/test/t/class.rb b/test/t/class.rb index d4ecf99d0..720fd37fa 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -383,3 +383,8 @@ assert('class variable and class << self style class method') do assert_equal("value", ClassVariableTest.class_variable) end + +assert('class with non-class/module outer raises TypeError') do + assert_raise(TypeError) { class 0::C1; end } + assert_raise(TypeError) { class []::C2; end } +end diff --git a/test/t/module.rb b/test/t/module.rb index 9852328ce..ecb969475 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -533,3 +533,7 @@ assert('Module#module_function') do assert_true M.respond_to?(:modfunc) end +assert('module with non-class/module outer raises TypeError') do + assert_raise(TypeError) { module 0::M1 end } + assert_raise(TypeError) { module []::M2 end } +end From 9ef4bbb10d827fb41edc8c2984e0b80fcdbea900 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 31 May 2015 18:29:26 +0900 Subject: [PATCH 005/218] update test/t/syntax.rb to success on CRuby --- test/t/syntax.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 41e49d938..070fcbe3b 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -229,9 +229,9 @@ assert('multiple assignment (rest+post)') do *c, d = 3 assert_equal [0, 1], a - assert_equal [2], b + assert_equal 2, b assert_equal [], c - assert_equal [3], d + assert_equal 3, d end assert('Return values of case statements') do From 6a1978c7e1f58d3cda8cca390d65e5f64580b169 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 31 May 2015 18:30:37 +0900 Subject: [PATCH 006/218] fix OP_APOST bug for no pre arg cases; fix #2810 --- src/vm.c | 37 ++++++++++++++++--------------------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/src/vm.c b/src/vm.c index dd0d0ba43..1f3b05df2 100644 --- a/src/vm.c +++ b/src/vm.c @@ -2125,33 +2125,28 @@ RETRY_TRY_BLOCK: int pre = GETARG_B(i); int post = GETARG_C(i); + struct RArray *ary; + int len, idx; + if (!mrb_array_p(v)) { - regs[a++] = mrb_ary_new_capa(mrb, 0); + v = mrb_ary_new_from_values(mrb, 1, ®s[a]); + } + ary = mrb_ary_ptr(v); + len = ary->len; + if (len > pre + post) { + regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre); while (post--) { - SET_NIL_VALUE(regs[a]); - a++; + regs[a++] = ary->ptr[len-post-1]; } } else { - struct RArray *ary = mrb_ary_ptr(v); - int len = ary->len; - int idx; - - if (len > pre + post) { - regs[a++] = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre); - while (post--) { - regs[a++] = ary->ptr[len-post-1]; - } + regs[a++] = mrb_ary_new_capa(mrb, 0); + for (idx=0; idx+preptr[pre+idx]; } - else { - regs[a++] = mrb_ary_new_capa(mrb, 0); - for (idx=0; idx+preptr[pre+idx]; - } - while (idx < post) { - SET_NIL_VALUE(regs[a+idx]); - idx++; - } + while (idx < post) { + SET_NIL_VALUE(regs[a+idx]); + idx++; } } ARENA_RESTORE(mrb, ai); From 5cd877be7f875546dcc03d80aeeddd4bbbcffe3d Mon Sep 17 00:00:00 2001 From: cremno Date: Sun, 31 May 2015 13:30:49 +0200 Subject: [PATCH 007/218] fix masgn nosplat array rhs bug The rest lhs variable has to be an empty array if rhs is an array with less elements than pre + post lhs variables. The codegen generated OP_ARRAY with an invalid length (such as 127 for *a, b = []) because rn was negative. --- src/codegen.c | 8 +++++++- test/t/syntax.rb | 14 ++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/codegen.c b/src/codegen.c index 6f1f75e88..be630b9a8 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1615,8 +1615,14 @@ codegen(codegen_scope *s, node *tree, int val) } } if (t->car) { /* rest (len - pre - post) */ - int rn = len - post - n; + int rn; + if (len < post + n) { + rn = 0; + } + else { + rn = len - post - n; + } genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn)); gen_assignment(s, t->car, cursp(), NOVAL); n += rn; diff --git a/test/t/syntax.rb b/test/t/syntax.rb index 070fcbe3b..dc1a4a3b9 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -234,6 +234,20 @@ assert('multiple assignment (rest+post)') do assert_equal 3, d end +assert('multiple assignment (nosplat array rhs)') do + a, *b = [] + *c, d = [0] + e, *f, g = [1, 2] + + assert_nil a + assert_equal [], b + assert_equal [], c + assert_equal 0, d + assert_equal 1, e + assert_equal [], f + assert_equal 2, g +end + assert('Return values of case statements') do a = [] << case 1 when 3 then 2 From bd2686d82d233774003fe683e9396f366b152b6d Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 1 Jun 2015 00:13:12 +0900 Subject: [PATCH 008/218] singleton_class should not be cloned; close #2815 --- src/kernel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel.c b/src/kernel.c index d1e10a7f8..9d056178e 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -330,6 +330,9 @@ mrb_obj_clone(mrb_state *mrb, mrb_value self) if (mrb_immediate_p(self)) { mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); } + if (mrb_type(self) == MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); + } p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); p->c = mrb_singleton_class_clone(mrb, self); clone = mrb_obj_value(p); From 7284d1d295c0eaaa2e36ce52e9dd65f8221ed8b2 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Sun, 31 May 2015 23:26:33 -0400 Subject: [PATCH 009/218] Update mruby.h.md Added documentation of more of the C API functions found inside mruby.h --- doc/api/mruby.h.md | 139 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index f537b6482..36712e5dc 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -67,3 +67,142 @@ char|mruby type|retrieve types|note `?`|optional given|`mrb_bool`|True if preceding argument is given. Used to check optional argument is given. The passing variadic arguments must be a pointer of retrieving type. + +### mrb_define_class +```C +MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*); +``` +Creates a new class. If you're creating a gem it may look something like this: + +```C +void mrb_example_gem_init(mrb_state* mrb) { + struct RClass *example_class; + example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` +### mrb_define_method + +```C +MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); +``` + +Creates a global function in ruby. If you're creating a gem it may look something like this: + +```C +mrb_value example_method(mrb_state* mrb, mrb_value self){ + puts("Executing example commad!"); + return self; +} + +void mrb_example_gem_init(mrb_state* mrb) { + mrb_define_method(mrb, mrb->kernel_module, "example_method", example_method, MRB_ARGS_NONE()); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` + +Or maybe you want to create a class method for a class? It might look something like this: + +```C +mrb_value example_method(mrb_state* mrb, mrb_value self){ + puts("Examples are like pizza..."); + return self; +} + +void mrb_example_gem_init(mrb_state* mrb) { + struct RClass *example_class; + example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class); + mrb_define_method(mrb, example_class, "example_method", example_method, MRB_ARGS_NONE()); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` +### mrb_define_module + +```C +MRB_API struct RClass *mrb_define_module(mrb_state *, const char*); +``` + +Creates a module in ruby. If you're creating a gem it may look something like this: + +```C +mrb_value example_method(mrb_state* mrb, mrb_value self){ + puts("Examples are like tacos..."); + return self; +} + +void mrb_example_gem_init(mrb_state* mrb) { + struct RClass *example_module; + example_module = mrb_define_module(mrb, "Example_Module"); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` + +### mrb_define_module_function + +```C +MRB_API void mrb_define_module_function(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); +``` + +Defines a module function. If you're creating a gem it may look something like this: + + +```C +mrb_value example_method(mrb_state* mrb, mrb_value self){ + puts("Examples are like hot wings..."); + return self; +} + +void mrb_example_gem_init(mrb_state* mrb) { + struct RClass *example_module; + example_module = mrb_define_module(mrb, "Example_Module"); + mrb_define_module_function(mrb, example_module, "example_method", example_method, MRB_ARGS_NONE()); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` + +### mrb_define_const + +```C +MRB_API void mrb_define_const(mrb_state*, struct RClass*, const char *name, mrb_value); +``` + +Defines a constant. If you're creating a gem it may look something like this: + +```C +mrb_value example_method(mrb_state* mrb, mrb_value self){ + puts("Examples are like hot wings..."); + return self; +} + +void mrb_example_gem_init(mrb_state* mrb) { + mrb_define_const(mrb, mrb->kernel_module, "EXAPMLE_CONSTANT", mrb_fixnum_value(0x00000001)); +} + +void mrb_example_gem_final(mrb_state* mrb) { + //free(TheAnimals); +} +``` + + + + + + + + + From 4959e4958abca0404c60fe54a4c700bfd1a25eb6 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Sun, 31 May 2015 23:27:12 -0400 Subject: [PATCH 010/218] Update mruby.h.md --- doc/api/mruby.h.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index 36712e5dc..88fa2c7e5 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -94,7 +94,7 @@ Creates a global function in ruby. If you're creating a gem it may look somethin ```C mrb_value example_method(mrb_state* mrb, mrb_value self){ - puts("Executing example commad!"); + puts("Executing example command!"); return self; } From d90ccd7e6d06582ddb3d3c02e8337551a35b67d8 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Sun, 31 May 2015 23:33:36 -0400 Subject: [PATCH 011/218] Update mruby.h.md --- doc/api/mruby.h.md | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index 88fa2c7e5..5a71f5cd4 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -72,7 +72,7 @@ The passing variadic arguments must be a pointer of retrieving type. ```C MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass*); ``` -Creates a new class. If you're creating a gem it may look something like this: +Defines a new class. If you're creating a gem it may look something like this: ```C void mrb_example_gem_init(mrb_state* mrb) { @@ -90,7 +90,7 @@ void mrb_example_gem_final(mrb_state* mrb) { MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); ``` -Creates a global function in ruby. If you're creating a gem it may look something like this: +Defines a global function in ruby. If you're creating a gem it may look something like this: ```C mrb_value example_method(mrb_state* mrb, mrb_value self){ @@ -131,7 +131,7 @@ void mrb_example_gem_final(mrb_state* mrb) { MRB_API struct RClass *mrb_define_module(mrb_state *, const char*); ``` -Creates a module in ruby. If you're creating a gem it may look something like this: +Defines a module. If you're creating a gem it may look something like this: ```C mrb_value example_method(mrb_state* mrb, mrb_value self){ @@ -198,11 +198,12 @@ void mrb_example_gem_final(mrb_state* mrb) { } ``` - - - - - - +### mrb_str_new_cstr + +```C +MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); +``` + +Turns a C string into a Ruby string value. From 1400c6e88ba20a07980770aa9217387a2cbd89bd Mon Sep 17 00:00:00 2001 From: Mav7 Date: Sun, 31 May 2015 23:50:56 -0400 Subject: [PATCH 012/218] Added a .md file for value.h --- doc/api/value.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/value.h.md diff --git a/doc/api/value.h.md b/doc/api/value.h.md new file mode 100644 index 000000000..e69de29bb From 297b6fe6e6f97bc8e4ca95d47fa6b02f7eab6396 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 1 Jun 2015 00:42:23 -0400 Subject: [PATCH 013/218] Update value.h.md Wrote documentation for functions found in the value.h file. --- doc/api/value.h.md | 233 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 233 insertions(+) diff --git a/doc/api/value.h.md b/doc/api/value.h.md index e69de29bb..dd1c4b238 100644 --- a/doc/api/value.h.md +++ b/doc/api/value.h.md @@ -0,0 +1,233 @@ +### mrb_float_value +```C +static inline mrb_value mrb_float_value(struct mrb_state *mrb, mrb_float f) +``` + +Returns a float in Ruby. + +##### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. In this case we are passing in mrb_float f = 0.09. Alternatively +double i = 0.09 could also be used. + + +example.c +```C +#include +#include +#include "mruby/compile.h" +#include "mruby/string.h" + +int +main(void) +{ + mrb_float f = 0.09;// or double i = 0.09; + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, mrb_float_value(mrb, f)); + fclose(fp); + mrb_close(mrb); +} + +``` + +test.rb +```Ruby +class My_Class + def method_name(s) + puts s + puts s.class + end +end +a = My_Class.new +``` + +### mrb_fixnum_value + +```C +static inline mrb_value mrb_fixnum_value(mrb_int i) +``` + +Returns a fixnum in Ruby. + +##### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. In this case we are passing in mrb_int i = 99. Alternativly int i = 99 +could also be used. + + +example.c +```C +#include +#include +#include "mruby/compile.h" + +int +main(void) +{ + mrb_int i = 99; // or int i = 99; + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i)); + fclose(fp); + mrb_close(mrb); +} + +``` + +test.rb +```Ruby +class My_Class + def method_name(s) + puts s + puts s.class + end +end +a = My_Class.new +``` + + + +### mrb_nil_value + +```C +static inline mrb_value mrb_nil_value(void) +``` + +Returns nil in Ruby. + +##### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. In this case we are passing in nothing and we will get NillClass. + + +example.c +```C +#include +#include +#include "mruby/compile.h" + +int +main(void) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, mrb_nil_value()); + fclose(fp); + mrb_close(mrb); +} + +``` + +test.rb +```Ruby +class My_Class + def method_name(s) + puts s + puts s.class + end +end +a = My_Class.new +``` + + +### mrb_false_value + +```C +static inline mrb_value mrb_false_value(void) +``` + +Returns false in Ruby. + +##### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. In this case we are passing in nothing and we will get FalseClass. + + +example.c +```C +#include +#include +#include "mruby/compile.h" + +int +main(void) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, mrb_false_value()); + fclose(fp); + mrb_close(mrb); +} + +``` + +test.rb +```Ruby +class My_Class + def method_name(s) + puts s + puts s.class + end +end +a = My_Class.new +``` + + + +### mrb_true_value + +```C +static inline mrb_value mrb_true_value(void) +``` + +Returns true in Ruby. + +##### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. In this case we are passing in nothing and we will get TrueClass. + + +example.c +```C +#include +#include +#include "mruby/compile.h" + +int +main(void) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, mrb_true_value()); + fclose(fp); + mrb_close(mrb); +} + +``` + +test.rb +```Ruby +class My_Class + def method_name(s) + puts s + puts s.class + end +end +a = My_Class.new +``` From 1d90018cfa93e63366f4f1fe600bb356dabf8c3b Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 1 Jun 2015 00:44:34 -0400 Subject: [PATCH 014/218] Update mruby.h.md --- doc/api/mruby.h.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index 5a71f5cd4..8862fee2c 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -207,3 +207,9 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); Turns a C string into a Ruby string value. +### mrb_value mrb_funcall + +```C +MRB_API mrb_value mrb_funcall(mrb_state*, mrb_value, const char*, mrb_int,...); +``` +Call existing ruby functions. From f8b1de0ab47f3f0bae861bf11f73635aa8c02ba6 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 1 Jun 2015 00:54:30 -0400 Subject: [PATCH 015/218] Update README.md --- doc/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/README.md b/doc/api/README.md index 131e50515..78dbc087d 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -25,6 +25,6 @@ Header name|Features [mruby/range.h](./mruby.range.h.md)|`Range` class. [mruby/re.h](./mruby.re.h.md)|`Regexp` class. [mruby/string.h](./mruby.string.h.md)|`String` class. -[mruby/value.h](./mruby.value.h.md)|`mrb_value` functions and macros. +[mruby/value.h](./value.h.md)|`mrb_value` functions and macros. [mruby/variable.h](./mruby.variable.h.md)|Functions to access to mruby variables. [mruby/version.h](./mruby.version.h.md)|Macros of mruby version. From b357a6320d8dad87c29b7315d7aa5ed6c4e9fc7a Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 1 Jun 2015 00:59:22 -0400 Subject: [PATCH 016/218] Update AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index c78258915..ea8bb5ad6 100644 --- a/AUTHORS +++ b/AUTHORS @@ -26,6 +26,7 @@ Original Authors "mruby developers" are: Hiroshi Mimaki Satoshi Odawara Mitsubishi Electric Micro-Computer Application Software Co.,Ltd. + Ralph Desir(Mav7) Hiroyuki Matsuzaki Yuhei Okazaki Manycolors, Inc. From dc0e33566410489db639a0523b9cb25b04f73080 Mon Sep 17 00:00:00 2001 From: cremno Date: Mon, 1 Jun 2015 13:23:43 +0200 Subject: [PATCH 017/218] fix two potential cases of signed integer overflow --- src/array.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/array.c b/src/array.c index 48dc1ff10..1ca7dd2a4 100644 --- a/src/array.c +++ b/src/array.c @@ -298,6 +298,9 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) mrb_int blen; mrb_get_args(mrb, "a", &ptr, &blen); + if (ARY_MAX_SIZE - blen < a1->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } ary = mrb_ary_new_capa(mrb, a1->len + blen); a2 = mrb_ary_ptr(ary); array_copy(a2->ptr, a1->ptr, a1->len); @@ -351,7 +354,9 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } if (times == 0) return mrb_ary_new(mrb); - + if (ARY_MAX_SIZE / times < a1->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } ary = mrb_ary_new_capa(mrb, a1->len * times); a2 = mrb_ary_ptr(ary); ptr = a2->ptr; From 7e8fb15457f08faf0fd6b7e1d0823140ecee2a60 Mon Sep 17 00:00:00 2001 From: cremno Date: Mon, 1 Jun 2015 13:54:20 +0200 Subject: [PATCH 018/218] only generate gets of non-local vars in VAL mode This fixes a crash for code like "#{@a;1}". Unlike CRuby globals are excluded too since mruby doesn't implement hooking. --- src/codegen.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/codegen.c b/src/codegen.c index be630b9a8..16233347c 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -1911,7 +1911,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_GVAR: - { + if (val) { int sym = new_sym(s, sym(tree)); genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); @@ -1920,7 +1920,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_IVAR: - { + if (val) { int sym = new_sym(s, sym(tree)); genop(s, MKOP_ABx(OP_GETIV, cursp(), sym)); @@ -1929,7 +1929,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_CVAR: - { + if (val) { int sym = new_sym(s, sym(tree)); genop(s, MKOP_ABx(OP_GETCV, cursp(), sym)); @@ -1951,7 +1951,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_BACK_REF: - { + if (val) { char buf[2] = { '$' }; mrb_value str; int sym; @@ -1965,7 +1965,7 @@ codegen(codegen_scope *s, node *tree, int val) break; case NODE_NTH_REF: - { + if (val) { int sym; mrb_state *mrb = s->mrb; mrb_value fix = mrb_fixnum_value((intptr_t)tree); From b6121adc7dbedcf0e6fd262de536c2f8c9217120 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 1 Jun 2015 21:30:07 +0900 Subject: [PATCH 019/218] singleton_class should not be duped; fix #2815 --- src/kernel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/kernel.c b/src/kernel.c index 9d056178e..b5b13f874 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -369,6 +369,9 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj) if (mrb_immediate_p(obj)) { mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj); } + if (mrb_type(obj) == MRB_TT_SCLASS) { + mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); + } p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); dup = mrb_obj_value(p); init_copy(mrb, dup, obj); From 6460ef77bcceb17d80d1b46a07b28fada19737c8 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 6 Apr 2015 15:20:13 +0900 Subject: [PATCH 020/218] Compile mruby compiler as mrbgem. Compiler codes is moved to "mruby-compiler". Executable `mrbc` is moved to "mruby-bin-mrbc". --- Rakefile | 1 - mrbgems/mruby-bin-mrbc/mrbgem.rake | 16 +++++ .../mruby-bin-mrbc/tools}/mrbc/mrbc.c | 0 .../mruby-compiler/bintest}/mrbc.rb | 0 .../mruby-compiler/core}/codegen.c | 0 {src => mrbgems/mruby-compiler/core}/keywords | 0 {src => mrbgems/mruby-compiler/core}/lex.def | 0 {src => mrbgems/mruby-compiler/core}/node.h | 0 {src => mrbgems/mruby-compiler/core}/parse.y | 0 mrbgems/mruby-compiler/mrbgem.rake | 40 ++++++++++++ mrbgems/mruby-eval/mrbgem.rake | 2 + src/mruby_core.rake | 63 +------------------ tasks/mruby_build.rake | 41 +++++++++++- tools/mrbc/mrbc.rake | 14 ----- travis_config.rb | 4 ++ 15 files changed, 103 insertions(+), 78 deletions(-) create mode 100644 mrbgems/mruby-bin-mrbc/mrbgem.rake rename {tools => mrbgems/mruby-bin-mrbc/tools}/mrbc/mrbc.c (100%) rename {bintest => mrbgems/mruby-compiler/bintest}/mrbc.rb (100%) rename {src => mrbgems/mruby-compiler/core}/codegen.c (100%) rename {src => mrbgems/mruby-compiler/core}/keywords (100%) rename {src => mrbgems/mruby-compiler/core}/lex.def (100%) rename {src => mrbgems/mruby-compiler/core}/node.h (100%) rename {src => mrbgems/mruby-compiler/core}/parse.y (100%) create mode 100644 mrbgems/mruby-compiler/mrbgem.rake delete mode 100644 tools/mrbc/mrbc.rake diff --git a/Rakefile b/Rakefile index 66f54a4e2..0f33c5ee8 100644 --- a/Rakefile +++ b/Rakefile @@ -21,7 +21,6 @@ end # load custom rules load "#{MRUBY_ROOT}/src/mruby_core.rake" load "#{MRUBY_ROOT}/mrblib/mrblib.rake" -load "#{MRUBY_ROOT}/tools/mrbc/mrbc.rake" load "#{MRUBY_ROOT}/tasks/mrbgems.rake" load "#{MRUBY_ROOT}/tasks/libmruby.rake" diff --git a/mrbgems/mruby-bin-mrbc/mrbgem.rake b/mrbgems/mruby-bin-mrbc/mrbgem.rake new file mode 100644 index 000000000..e710b5a49 --- /dev/null +++ b/mrbgems/mruby-bin-mrbc/mrbgem.rake @@ -0,0 +1,16 @@ +MRuby::Gem::Specification.new 'mruby-bin-mrbc' do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby compiler executable' + + spec.add_dependency 'mruby-compiler', :core => 'mruby-compiler' + + exec = exefile("#{build.build_dir}/bin/mrbc") + mrbc_objs = Dir.glob("#{spec.dir}/tools/mrbc/*.c").map { |f| objfile(f.pathmap("#{spec.build_dir}/tools/mrbc/%n")) }.flatten + + file exec => mrbc_objs + [libfile("#{build.build_dir}/lib/libmruby_core")] do |t| + build.linker.run t.name, t.prerequisites + end + + build.bins << 'mrbc' unless build.bins.find { |v| v == 'mrbc' } +end diff --git a/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c similarity index 100% rename from tools/mrbc/mrbc.c rename to mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c diff --git a/bintest/mrbc.rb b/mrbgems/mruby-compiler/bintest/mrbc.rb similarity index 100% rename from bintest/mrbc.rb rename to mrbgems/mruby-compiler/bintest/mrbc.rb diff --git a/src/codegen.c b/mrbgems/mruby-compiler/core/codegen.c similarity index 100% rename from src/codegen.c rename to mrbgems/mruby-compiler/core/codegen.c diff --git a/src/keywords b/mrbgems/mruby-compiler/core/keywords similarity index 100% rename from src/keywords rename to mrbgems/mruby-compiler/core/keywords diff --git a/src/lex.def b/mrbgems/mruby-compiler/core/lex.def similarity index 100% rename from src/lex.def rename to mrbgems/mruby-compiler/core/lex.def diff --git a/src/node.h b/mrbgems/mruby-compiler/core/node.h similarity index 100% rename from src/node.h rename to mrbgems/mruby-compiler/core/node.h diff --git a/src/parse.y b/mrbgems/mruby-compiler/core/parse.y similarity index 100% rename from src/parse.y rename to mrbgems/mruby-compiler/core/parse.y diff --git a/mrbgems/mruby-compiler/mrbgem.rake b/mrbgems/mruby-compiler/mrbgem.rake new file mode 100644 index 000000000..3a22762fa --- /dev/null +++ b/mrbgems/mruby-compiler/mrbgem.rake @@ -0,0 +1,40 @@ +MRuby::Gem::Specification.new 'mruby-compiler' do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby compiler library' + + current_dir = spec.dir + current_build_dir = spec.build_dir + + lex_def = "#{current_dir}/core/lex.def" + core_objs = Dir.glob("#{current_dir}/core/*.c").map { |f| + next nil if build.cxx_abi_enabled? and f =~ /(codegen).c$/ + objfile(f.pathmap("#{current_build_dir}/core/%n")) + }.compact + + if build.cxx_abi_enabled? + core_objs << + build.compile_as_cxx("#{current_build_dir}/core/y.tab.c", "#{current_build_dir}/core/y.tab.cxx", + objfile("#{current_build_dir}/y.tab"), ["#{current_dir}/core"]) << + build.compile_as_cxx("#{current_dir}/core/codegen.c", "#{current_build_dir}/core/codegen.cxx") + else + core_objs << objfile("#{current_build_dir}/core/y.tab") + file objfile("#{current_build_dir}/core/y.tab") => "#{current_build_dir}/core/y.tab.c" do |t| + cc.run t.name, t.prerequisites.first, [], ["#{current_dir}/core"] + end + end + file objfile("#{current_build_dir}/core/y.tab") => lex_def + + # Parser + file "#{current_build_dir}/core/y.tab.c" => ["#{current_dir}/core/parse.y"] do |t| + yacc.run t.name, t.prerequisites.first + end + + # Lexical analyzer + file lex_def => "#{current_dir}/core/keywords" do |t| + gperf.run t.name, t.prerequisites.first + end + + file libfile("#{build.build_dir}/lib/libmruby_core") => core_objs + build.libmruby << core_objs +end diff --git a/mrbgems/mruby-eval/mrbgem.rake b/mrbgems/mruby-eval/mrbgem.rake index 7c6acc534..cb8835b32 100644 --- a/mrbgems/mruby-eval/mrbgem.rake +++ b/mrbgems/mruby-eval/mrbgem.rake @@ -2,4 +2,6 @@ MRuby::Gem::Specification.new('mruby-eval') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' spec.summary = 'standard Kernel#eval method' + + add_dependency 'mruby-compiler', :core => 'mruby-compiler' end diff --git a/src/mruby_core.rake b/src/mruby_core.rake index 88fca83fc..abde441d5 100644 --- a/src/mruby_core.rake +++ b/src/mruby_core.rake @@ -3,76 +3,17 @@ MRuby.each_target do relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) current_build_dir = "#{build_dir}/#{relative_from_root}" - lex_def = "#{current_dir}/lex.def" objs = Dir.glob("#{current_dir}/*.c").map { |f| - next nil if cxx_abi_enabled? and f =~ /(codegen|error|vm).c$/ + next nil if cxx_abi_enabled? and f =~ /(error|vm).c$/ objfile(f.pathmap("#{current_build_dir}/%n")) }.compact if cxx_abi_enabled? - cxx_abi_dependency = %w(codegen error vm) - cxx_abi_objs = cxx_abi_dependency.map { |v| - src = "#{current_build_dir}/#{v}.cxx" - file src => ["#{current_dir}/#{v}.c", __FILE__] do |t| - File.open(t.name, 'w') do |f| - f.write < src do |t| - cxx.run t.name, t.prerequisites.first, [], [current_dir] - end - - objfile src - } - cxx_abi_objs << objfile("#{current_build_dir}/y.tab") - - file "#{current_build_dir}/y.tab.cxx" => ["#{current_build_dir}/y.tab.c", __FILE__] do |t| - File.open(t.name, 'w') do |f| - f.write < ["#{current_build_dir}/y.tab.cxx", lex_def] do |t| - cxx.run t.name, t.prerequisites.first, [], [current_dir] - end - - objs += cxx_abi_objs - else - objs += [objfile("#{current_build_dir}/y.tab")] - file objfile("#{current_build_dir}/y.tab") => ["#{current_build_dir}/y.tab.c", lex_def] do |t| - cc.run t.name, t.prerequisites.first, [], [current_dir] - end + objs += %w(vm error).map { |v| compile_as_cxx "#{current_dir}/#{v}.c", "#{current_build_dir}/#{v}.cxx" } end self.libmruby << objs file libfile("#{build_dir}/lib/libmruby_core") => objs do |t| archiver.run t.name, t.prerequisites end - - # Parser - file "#{current_build_dir}/y.tab.c" => ["#{current_dir}/parse.y"] do |t| - yacc.run t.name, t.prerequisites.first - end - - # Lexical analyzer - file lex_def => "#{current_dir}/keywords" do |t| - gperf.run t.name, t.prerequisites.first - end end diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 66608286d..50bed0fbe 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -80,7 +80,7 @@ module MRuby @git = Command::Git.new(self) @mrbc = Command::Mrbc.new(self) - @bins = %w(mrbc) + @bins = [] @gems, @libmruby = MRuby::Gem::List.new, [] @build_mrbtest_lib_only = false @cxx_abi_enabled = false @@ -92,6 +92,8 @@ module MRuby MRuby::Build.current = MRuby.targets[@name] MRuby.targets[@name].instance_eval(&block) + + build_mrbc_exec if name == 'host' end def enable_debug @@ -119,6 +121,33 @@ module MRuby @cxx_abi_enabled = true end + def compile_as_cxx src, cxx_src, obj = nil, includes = [] + src = File.absolute_path src + cxx_src = File.absolute_path cxx_src + obj = objfile(cxx_src) if obj.nil? + + file cxx_src => [src, __FILE__] do |t| + File.open(t.name, 'w') do |f| + f.write < cxx_src do |t| + cxx.run t.name, t.prerequisites.first, [], ["#{MRUBY_ROOT}/src"] + includes + end + + obj + end + def enable_bintest @enable_bintest = true end @@ -142,8 +171,16 @@ module MRuby MRUBY_ROOT end + def build_mrbc_exec + gem :core => 'mruby-bin-mrbc' + end + def mrbcfile - MRuby.targets[@name].exefile("#{MRuby.targets[@name].build_dir}/bin/mrbc") + return @mrbcfile if @mrbcfile + + mrbc_build = MRuby.targets['host'] + gems.each { |v| mrbc_build = self if v.name == 'mruby-bin-mrbc' } + @mrbcfile = mrbc_build.exefile("#{mrbc_build.build_dir}/bin/mrbc") end def compilers diff --git a/tools/mrbc/mrbc.rake b/tools/mrbc/mrbc.rake deleted file mode 100644 index 1a0309a0d..000000000 --- a/tools/mrbc/mrbc.rake +++ /dev/null @@ -1,14 +0,0 @@ -MRuby.each_target do - current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) - relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) - current_build_dir = "#{build_dir}/#{relative_from_root}" - - if bins.find { |s| s.to_s == 'mrbc' } - exec = exefile("#{build_dir}/bin/mrbc") - objs = Dir.glob("#{current_dir}/*.c").map { |f| objfile(f.pathmap("#{current_build_dir}/%n")) }.flatten - - file exec => objs + [libfile("#{build_dir}/lib/libmruby_core")] do |t| - linker.run t.name, t.prerequisites - end - end -end diff --git a/travis_config.rb b/travis_config.rb index fadafd8c1..2b4059cf1 100644 --- a/travis_config.rb +++ b/travis_config.rb @@ -8,6 +8,8 @@ MRuby::Build.new('debug') do |conf| conf.compilers.each do |c| c.defines += %w(MRB_GC_STRESS MRB_GC_FIXED_ARENA) end + + build_mrbc_exec end MRuby::Build.new do |conf| @@ -33,4 +35,6 @@ MRuby::Build.new('cxx_abi') do |conf| conf.enable_bintest enable_cxx_abi + + build_mrbc_exec end From 2f635f56cb701293c59cc2e4f41b653cae2cb3af Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 1 Jun 2015 21:57:53 +0900 Subject: [PATCH 021/218] update lex.def using gperf 3.0.4 --- mrbgems/mruby-compiler/core/lex.def | 92 ++++++++++++++--------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/mrbgems/mruby-compiler/core/lex.def b/mrbgems/mruby-compiler/core/lex.def index ea456a843..58e302965 100644 --- a/mrbgems/mruby-compiler/core/lex.def +++ b/mrbgems/mruby-compiler/core/lex.def @@ -1,5 +1,5 @@ -/* ANSI-C code produced by gperf version 3.0.3 */ -/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' src/keywords */ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -L ANSI-C -C -p -j1 -i 1 -g -o -t -N mrb_reserved_word -k'1,3,$' /home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords */ #if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ @@ -28,13 +28,13 @@ #error "gperf generated tables don't work with this execution character set. Please report a bug to ." #endif -#line 1 "src/keywords" +#line 1 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" struct kwtable {const char *name; int id[2]; enum mrb_lex_state_enum state;}; const struct kwtable *mrb_reserved_word(const char *, unsigned int); static const struct kwtable *reserved_word(const char *, unsigned int); #define mrb_reserved_word(str, len) reserved_word(str, len) -#line 8 "src/keywords" +#line 8 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" struct kwtable; #define TOTAL_KEYWORDS 40 @@ -100,7 +100,7 @@ hash (register const char *str, register unsigned int len) #ifdef __GNUC__ __inline -#ifdef __GNUC_STDC_INLINE__ +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ __attribute__ ((__gnu_inline__)) #endif #endif @@ -110,87 +110,87 @@ mrb_reserved_word (register const char *str, register unsigned int len) static const struct kwtable wordlist[] = { {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, -#line 18 "src/keywords" +#line 18 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"break", {keyword_break, keyword_break}, EXPR_MID}, -#line 23 "src/keywords" +#line 23 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"else", {keyword_else, keyword_else}, EXPR_BEG}, -#line 33 "src/keywords" +#line 33 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"nil", {keyword_nil, keyword_nil}, EXPR_END}, -#line 26 "src/keywords" +#line 26 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"ensure", {keyword_ensure, keyword_ensure}, EXPR_BEG}, -#line 25 "src/keywords" +#line 25 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"end", {keyword_end, keyword_end}, EXPR_END}, -#line 42 "src/keywords" +#line 42 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"then", {keyword_then, keyword_then}, EXPR_BEG}, -#line 34 "src/keywords" +#line 34 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"not", {keyword_not, keyword_not}, EXPR_ARG}, -#line 27 "src/keywords" +#line 27 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"false", {keyword_false, keyword_false}, EXPR_END}, -#line 40 "src/keywords" +#line 40 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"self", {keyword_self, keyword_self}, EXPR_END}, -#line 24 "src/keywords" +#line 24 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"elsif", {keyword_elsif, keyword_elsif}, EXPR_VALUE}, -#line 37 "src/keywords" +#line 37 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"rescue", {keyword_rescue, modifier_rescue}, EXPR_MID}, -#line 43 "src/keywords" +#line 43 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"true", {keyword_true, keyword_true}, EXPR_END}, -#line 46 "src/keywords" +#line 46 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"until", {keyword_until, modifier_until}, EXPR_VALUE}, -#line 45 "src/keywords" +#line 45 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"unless", {keyword_unless, modifier_unless}, EXPR_VALUE}, -#line 39 "src/keywords" +#line 39 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"return", {keyword_return, keyword_return}, EXPR_MID}, -#line 21 "src/keywords" +#line 21 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"def", {keyword_def, keyword_def}, EXPR_FNAME}, -#line 16 "src/keywords" +#line 16 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"and", {keyword_and, keyword_and}, EXPR_VALUE}, -#line 22 "src/keywords" +#line 22 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"do", {keyword_do, keyword_do}, EXPR_BEG}, -#line 49 "src/keywords" +#line 49 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"yield", {keyword_yield, keyword_yield}, EXPR_ARG}, -#line 28 "src/keywords" +#line 28 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"for", {keyword_for, keyword_for}, EXPR_VALUE}, -#line 44 "src/keywords" +#line 44 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"undef", {keyword_undef, keyword_undef}, EXPR_FNAME}, -#line 35 "src/keywords" +#line 35 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"or", {keyword_or, keyword_or}, EXPR_VALUE}, -#line 30 "src/keywords" +#line 30 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"in", {keyword_in, keyword_in}, EXPR_VALUE}, -#line 47 "src/keywords" +#line 47 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"when", {keyword_when, keyword_when}, EXPR_VALUE}, -#line 38 "src/keywords" +#line 38 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"retry", {keyword_retry, keyword_retry}, EXPR_END}, -#line 29 "src/keywords" +#line 29 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"if", {keyword_if, modifier_if}, EXPR_VALUE}, -#line 19 "src/keywords" +#line 19 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"case", {keyword_case, keyword_case}, EXPR_VALUE}, -#line 36 "src/keywords" +#line 36 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"redo", {keyword_redo, keyword_redo}, EXPR_END}, -#line 32 "src/keywords" +#line 32 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"next", {keyword_next, keyword_next}, EXPR_MID}, -#line 41 "src/keywords" +#line 41 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"super", {keyword_super, keyword_super}, EXPR_ARG}, -#line 31 "src/keywords" +#line 31 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"module", {keyword_module, keyword_module}, EXPR_VALUE}, -#line 17 "src/keywords" +#line 17 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"begin", {keyword_begin, keyword_begin}, EXPR_BEG}, -#line 12 "src/keywords" +#line 12 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"__LINE__", {keyword__LINE__, keyword__LINE__}, EXPR_END}, -#line 11 "src/keywords" +#line 11 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"__FILE__", {keyword__FILE__, keyword__FILE__}, EXPR_END}, -#line 10 "src/keywords" +#line 10 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"__ENCODING__", {keyword__ENCODING__, keyword__ENCODING__}, EXPR_END}, -#line 14 "src/keywords" +#line 14 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"END", {keyword_END, keyword_END}, EXPR_END}, -#line 15 "src/keywords" +#line 15 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"alias", {keyword_alias, keyword_alias}, EXPR_FNAME}, -#line 13 "src/keywords" +#line 13 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"BEGIN", {keyword_BEGIN, keyword_BEGIN}, EXPR_END}, {""}, -#line 20 "src/keywords" +#line 20 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"class", {keyword_class, keyword_class}, EXPR_CLASS}, {""}, {""}, -#line 48 "src/keywords" +#line 48 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" {"while", {keyword_while, modifier_while}, EXPR_VALUE} }; @@ -208,5 +208,5 @@ mrb_reserved_word (register const char *str, register unsigned int len) } return 0; } -#line 50 "src/keywords" +#line 50 "/home/matz/work/mruby/mrbgems/mruby-compiler/core/keywords" From b721d449e6c9ad905e62a7632037ceb9900f812f Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 2 Jun 2015 07:57:27 +0200 Subject: [PATCH 022/218] push only after OP_GETCONST in VAL mode; ref #2769 --- mrbgems/mruby-compiler/core/codegen.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index 16233347c..d2eeef203 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -1942,7 +1942,9 @@ codegen(codegen_scope *s, node *tree, int val) int sym = new_sym(s, sym(tree)); genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym)); - push(); + if (val) { + push(); + } } break; From 599d141cc8fa7b04398d564b09893f6754906f3e Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 2 Jun 2015 08:34:36 +0200 Subject: [PATCH 023/218] directly call ary_new_capa() --- src/array.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/src/array.c b/src/array.c index 1ca7dd2a4..f2584114d 100644 --- a/src/array.c +++ b/src/array.c @@ -88,15 +88,12 @@ array_copy(mrb_value *dst, const mrb_value *src, mrb_int size) MRB_API mrb_value mrb_ary_new_from_values(mrb_state *mrb, mrb_int size, const mrb_value *vals) { - mrb_value ary; - struct RArray *a; + struct RArray *a = ary_new_capa(mrb, size); - ary = mrb_ary_new_capa(mrb, size); - a = mrb_ary_ptr(ary); array_copy(a->ptr, vals, size); a->len = size; - return ary; + return mrb_obj_value(a); } MRB_API mrb_value @@ -293,7 +290,6 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value ary; mrb_value *ptr; mrb_int blen; @@ -301,13 +297,12 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) if (ARY_MAX_SIZE - blen < a1->len) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } - ary = mrb_ary_new_capa(mrb, a1->len + blen); - a2 = mrb_ary_ptr(ary); + a2 = ary_new_capa(mrb, a1->len + blen); array_copy(a2->ptr, a1->ptr, a1->len); array_copy(a2->ptr + a1->len, ptr, blen); a2->len = a1->len + blen; - return ary; + return mrb_obj_value(a2); } static void @@ -345,7 +340,6 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) { struct RArray *a1 = mrb_ary_ptr(self); struct RArray *a2; - mrb_value ary; mrb_value *ptr; mrb_int times; @@ -357,8 +351,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) if (ARY_MAX_SIZE / times < a1->len) { mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } - ary = mrb_ary_new_capa(mrb, a1->len * times); - a2 = mrb_ary_ptr(ary); + a2 = ary_new_capa(mrb, a1->len * times); ptr = a2->ptr; while (times--) { array_copy(ptr, a1->ptr, a1->len); @@ -366,7 +359,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) a2->len += a1->len; } - return ary; + return mrb_obj_value(a2); } static mrb_value @@ -393,11 +386,8 @@ mrb_ary_reverse_bang(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_reverse(mrb_state *mrb, mrb_value self) { - struct RArray *a = mrb_ary_ptr(self), *b; - mrb_value ary; + struct RArray *a = mrb_ary_ptr(self), *b = ary_new_capa(mrb, a->len); - ary = mrb_ary_new_capa(mrb, a->len); - b = mrb_ary_ptr(ary); if (a->len > 0) { mrb_value *p1, *p2, *e; @@ -409,7 +399,7 @@ mrb_ary_reverse(mrb_state *mrb, mrb_value self) } b->len = a->len; } - return ary; + return mrb_obj_value(b); } MRB_API void From ef0fc90cd007d613be6c268cc6adbecc8d7a0a8f Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 2 Jun 2015 08:56:41 +0200 Subject: [PATCH 024/218] remove unnecessary mrb_immediate_p() `!mrb_array_p(ary2)` and `mrb_type(obj) != MRB_TT_DATA` are sufficient. --- src/array.c | 2 -- src/etc.c | 4 ++-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/array.c b/src/array.c index 1ca7dd2a4..c97e7a53b 100644 --- a/src/array.c +++ b/src/array.c @@ -1052,7 +1052,6 @@ mrb_ary_eq(mrb_state *mrb, mrb_value ary1) mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_true_value(); - if (mrb_immediate_p(ary2)) return mrb_false_value(); if (!mrb_array_p(ary2)) { return mrb_false_value(); } @@ -1068,7 +1067,6 @@ mrb_ary_cmp(mrb_state *mrb, mrb_value ary1) mrb_get_args(mrb, "o", &ary2); if (mrb_obj_equal(mrb, ary1, ary2)) return mrb_fixnum_value(0); - if (mrb_immediate_p(ary2)) return mrb_nil_value(); if (!mrb_array_p(ary2)) { return mrb_nil_value(); } diff --git a/src/etc.c b/src/etc.c index 635052b67..a8a21e740 100644 --- a/src/etc.c +++ b/src/etc.c @@ -26,7 +26,7 @@ mrb_data_object_alloc(mrb_state *mrb, struct RClass *klass, void *ptr, const mrb MRB_API void mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) { - if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) { + if (mrb_type(obj) != MRB_TT_DATA) { mrb_check_type(mrb, obj, MRB_TT_DATA); } if (DATA_TYPE(obj) != type) { @@ -48,7 +48,7 @@ mrb_data_check_type(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) MRB_API void* mrb_data_check_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) { - if (mrb_immediate_p(obj) || (mrb_type(obj) != MRB_TT_DATA)) { + if (mrb_type(obj) != MRB_TT_DATA) { return NULL; } if (DATA_TYPE(obj) != type) { From cd38bcf074cbac24be458b4f14b111335f5a87db Mon Sep 17 00:00:00 2001 From: Mav7 Date: Thu, 4 Jun 2015 23:34:03 -0400 Subject: [PATCH 025/218] Adding an array readme markdown. --- doc/api/array.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/array.h.md diff --git a/doc/api/array.h.md b/doc/api/array.h.md new file mode 100644 index 000000000..e69de29bb From b735c0d9dfece2b1cc53947a4057c535bbcb773f Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 4 Jun 2015 23:37:41 -0400 Subject: [PATCH 026/218] Update README.md --- doc/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/README.md b/doc/api/README.md index 78dbc087d..131e50515 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -25,6 +25,6 @@ Header name|Features [mruby/range.h](./mruby.range.h.md)|`Range` class. [mruby/re.h](./mruby.re.h.md)|`Regexp` class. [mruby/string.h](./mruby.string.h.md)|`String` class. -[mruby/value.h](./value.h.md)|`mrb_value` functions and macros. +[mruby/value.h](./mruby.value.h.md)|`mrb_value` functions and macros. [mruby/variable.h](./mruby.variable.h.md)|Functions to access to mruby variables. [mruby/version.h](./mruby.version.h.md)|Macros of mruby version. From 5d63350a3b7074694f0a7a361900814b513e01cf Mon Sep 17 00:00:00 2001 From: Mav7 Date: Thu, 4 Jun 2015 23:46:32 -0400 Subject: [PATCH 027/218] testing something. --- doc/api/{ => mruby}/array.h.md | 0 doc/api/{ => mruby}/value.h.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename doc/api/{ => mruby}/array.h.md (100%) rename doc/api/{ => mruby}/value.h.md (100%) diff --git a/doc/api/array.h.md b/doc/api/mruby/array.h.md similarity index 100% rename from doc/api/array.h.md rename to doc/api/mruby/array.h.md diff --git a/doc/api/value.h.md b/doc/api/mruby/value.h.md similarity index 100% rename from doc/api/value.h.md rename to doc/api/mruby/value.h.md From d768dcc42c1e62d82ef639012b7e748af105676e Mon Sep 17 00:00:00 2001 From: Mav7 Date: Thu, 4 Jun 2015 23:49:43 -0400 Subject: [PATCH 028/218] Adding an array readme markdown. --- doc/api/{mruby => }/array.h.md | 0 doc/api/{mruby => }/value.h.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename doc/api/{mruby => }/array.h.md (100%) rename doc/api/{mruby => }/value.h.md (100%) diff --git a/doc/api/mruby/array.h.md b/doc/api/array.h.md similarity index 100% rename from doc/api/mruby/array.h.md rename to doc/api/array.h.md diff --git a/doc/api/mruby/value.h.md b/doc/api/value.h.md similarity index 100% rename from doc/api/mruby/value.h.md rename to doc/api/value.h.md From e63962c0a4df07897fe31966a8d768fc994f6da7 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 4 Jun 2015 23:53:15 -0400 Subject: [PATCH 029/218] Update array.h.md --- doc/api/array.h.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index e69de29bb..d96d854b8 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -0,0 +1,2 @@ +### mrb_ary_new(mrb_state *mrb); +mrb_value mrb_ary_new(mrb_state *mrb); From 8a14073207dc43072003206be2b4f212d96051b2 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 4 Jun 2015 23:54:27 -0400 Subject: [PATCH 030/218] Update array.h.md --- doc/api/array.h.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index d96d854b8..d3f5a12fa 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -1,2 +1 @@ -### mrb_ary_new(mrb_state *mrb); -mrb_value mrb_ary_new(mrb_state *mrb); + From b9716c59c7f32664ad6c27487766e81be8bdc2b2 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 00:05:41 -0400 Subject: [PATCH 031/218] Update array.h.md --- doc/api/array.h.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index d3f5a12fa..717522c62 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -1 +1,14 @@ +### mrb_ary_new +```C +mrb_value mrb_ary_new(mrb_state *mrb); +``` + +Initializes an array. + +#### Example + +example.c +```C + +``` From 88342b2709d9b795faeda5ba9d526bf600d351e8 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 00:17:42 -0400 Subject: [PATCH 032/218] Update array.h.md --- doc/api/array.h.md | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index 717522c62..d3f5a12fa 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -1,14 +1 @@ -### mrb_ary_new -```C -mrb_value mrb_ary_new(mrb_state *mrb); -``` - -Initializes an array. - -#### Example - -example.c -```C - -``` From 12b307396a9696d253232e7ac7c3c3a1cb53430c Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 02:42:48 -0400 Subject: [PATCH 033/218] Added more function documentation for arrays. --- doc/api/array.h.md | 250 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 250 insertions(+) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index d3f5a12fa..714eacda0 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -1 +1,251 @@ +### mrb_ary_new() +```C +mrb_value mrb_ary_new(mrb_state *mrb); +``` +Initializes an array. +#### Example +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we are declaring a variable new_ary of data type mrb_value. Then we are initializing it with the mrb_ary_new function which only takes an mruby state as an argument. +```C +#include +#include +#include "mruby/array.h" // Need the array header. +#include "mruby/compile.h" + + +int main(int argc, char *argv[]) +{ + mrb_value new_ary; // Declare variable. + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` +test.rb +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` + +### mrb_ary_push() +```C +void mrb_ary_push(mrb_state*, mrb_value, mrb_value); +``` +Pushes given value into an array. +#### Example +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case after initializing our array. We are declaring two variables with the mrb_int data type random_value1 & random_value2 and we initialize them 70 and 60 respectively. Then we use the mrb_ary_push function to push values those values into the array. +```C +#include +#include +#include "mruby/array.h" // Need the array header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` +test.rb +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` +#### Result +After compiling you should get these results. +```Ruby +[70, 60] +Array +``` + +## mrb_ary_pop() +```C +mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary); +``` +Pops the last element from the array. +#### Example +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case after initializing our array. We are declaring two variables with the mrb_int data type random_value1 & random_value2 and we initialize them 70 and 60 respectively. Then we use the mrb_ary_push function to push values those values into the array. Now here in the Ruby files we add another method +called pop_ary that will return the array alone(just to be clean) and you should see the last element gone. +```C +#include +#include +#include "mruby/array.h" // Need the array header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + mrb_ary_pop(mrb, new_ary); // Pops the last element of the array. In this case 60. + mrb_funcall(mrb, obj, "pop_ary", 1, new_ary); // Calls the method again to show the results. + fclose(fp); + mrb_close(mrb); + return 0; +} +``` +test.rb +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end + def pop_ary(a) + puts a + end +end +Example_Class.new +``` +#### Result +After compiling you should get these results. +```Ruby +[70, 60] +Array +[70] +``` +## mrb_ary_ref() +```C +mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); +``` +Returns a reference to an element of the array. Specified by the value given to mrb_int n. +#### Example +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we're declaring a variable ary_ref with the data type of mrb_value. Then we assign mrb_ary_ref to it getting new_ary's value at index 1. +```C +#include +#include +#include "mruby/array.h" // Need the array header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_value ary_ref; // Declare variable. + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + ary_ref = mrb_ary_ref(mrb, new_ary, 1); // Gets the value of new_ary's second element at index 1. + mrb_value obj = mrb_load_file(mrb,fp); + /* Passing the value from ary_ref to the method method_name.*/ + mrb_funcall(mrb, obj, "method_name", 1, ary_ref); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` +test.rb +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` +#### Result +After compiling you should get these results. +```Ruby +60 +Fixnum +``` + +### mrb_ary_set +```C +void mrb_ary_set(mrb_state *mrb, mrb_value ary, mrb_int n, mrb_value val); +``` +Sets a value to an index. +#### Example +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument and what class the passed in value is. In this case we're declaring a variable ary_ref with the data type of mrb_value. Then we assign mrb_ary_ref to it getting new_ary's value at index 1. +```C +#include +#include +#include "mruby/array.h" // Need the array header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_value new_ary; + mrb_value ary_obj; + mrb_int random_value1 = 70; + mrb_int random_value2 = 60; + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + /* Sets the fixnum value of 7 to the second index of the array.*/ + mrb_ary_set(mrb, new_ary, 2, mrb_fixnum_value(7)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "before_after", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` +test.rb +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end + def before_after(a) + puts a + end +end +Example_Class.new +``` +#### Result +After compiling you should get these results. +```Ruby +[70, 60, 7] +``` From a3a18cd7a691b3382c41ae5e73ef85bcdbabca3d Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 02:43:54 -0400 Subject: [PATCH 034/218] Update array.h.md --- doc/api/array.h.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index 714eacda0..33466e149 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -1,4 +1,4 @@ -### mrb_ary_new() +### mrb_ary_new ```C mrb_value mrb_ary_new(mrb_state *mrb); @@ -38,7 +38,7 @@ end Example_Class.new ``` -### mrb_ary_push() +### mrb_ary_push ```C void mrb_ary_push(mrb_state*, mrb_value, mrb_value); ``` @@ -88,7 +88,7 @@ After compiling you should get these results. Array ``` -## mrb_ary_pop() +## mrb_ary_pop ```C mrb_value mrb_ary_pop(mrb_state *mrb, mrb_value ary); ``` @@ -144,7 +144,7 @@ After compiling you should get these results. Array [70] ``` -## mrb_ary_ref() +## mrb_ary_ref ```C mrb_value mrb_ary_ref(mrb_state *mrb, mrb_value ary, mrb_int n); ``` From e1795cb72dad87c163a38a59915b86ac83c09563 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 02:51:37 -0400 Subject: [PATCH 035/218] Update value.h.md --- doc/api/value.h.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/api/value.h.md b/doc/api/value.h.md index dd1c4b238..f3ae2d421 100644 --- a/doc/api/value.h.md +++ b/doc/api/value.h.md @@ -30,6 +30,7 @@ main(void) mrb_funcall(mrb, obj, "method_name", 1, mrb_float_value(mrb, f)); fclose(fp); mrb_close(mrb); + return 0; } ``` @@ -77,6 +78,7 @@ main(void) mrb_funcall(mrb, obj, "method_name", 1, mrb_fixnum_value(i)); fclose(fp); mrb_close(mrb); + return 0; } ``` @@ -124,6 +126,7 @@ main(void) mrb_funcall(mrb, obj, "method_name", 1, mrb_nil_value()); fclose(fp); mrb_close(mrb); + return 0; } ``` @@ -170,6 +173,7 @@ main(void) mrb_funcall(mrb, obj, "method_name", 1, mrb_false_value()); fclose(fp); mrb_close(mrb); + return 0; } ``` @@ -217,6 +221,7 @@ main(void) mrb_funcall(mrb, obj, "method_name", 1, mrb_true_value()); fclose(fp); mrb_close(mrb); + return 0; } ``` From 0f93d9b7dbdc74f485617051b5db81db09c7b726 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 5 Jun 2015 02:54:11 -0400 Subject: [PATCH 036/218] Update array.h.md --- doc/api/array.h.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/api/array.h.md b/doc/api/array.h.md index 33466e149..e1fb0003d 100644 --- a/doc/api/array.h.md +++ b/doc/api/array.h.md @@ -9,7 +9,7 @@ In this example we read from a Ruby file inside C. The Ruby code will print what ```C #include #include -#include "mruby/array.h" // Need the array header. +#include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" @@ -48,7 +48,7 @@ In this example we read from a Ruby file inside C. The Ruby code will print what ```C #include #include -#include "mruby/array.h" // Need the array header. +#include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" int main(int argc, char *argv[]) @@ -99,7 +99,7 @@ called pop_ary that will return the array alone(just to be clean) and you should ```C #include #include -#include "mruby/array.h" // Need the array header. +#include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" int main(int argc, char *argv[]) @@ -154,7 +154,7 @@ In this example we read from a Ruby file inside C. The Ruby code will print what ```C #include #include -#include "mruby/array.h" // Need the array header. +#include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" int main(int argc, char *argv[]) @@ -207,7 +207,7 @@ In this example we read from a Ruby file inside C. The Ruby code will print what ```C #include #include -#include "mruby/array.h" // Need the array header. +#include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" int main(int argc, char *argv[]) From 3bcf570a17d25783187c8aa3413bf48425b29619 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Sat, 6 Jun 2015 08:57:33 +0900 Subject: [PATCH 037/218] Fix build on MIPS of linux MIPS of Linux platform is supported frexpl(3). This fixes to use the frexpl that are provided with gcc if user wants to build on MIPS of Linux platform. Signe-doff-by: Nobuhiro Iwamatsu --- src/fmt_fp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmt_fp.c b/src/fmt_fp.c index ef2f19dd5..a634edb34 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -90,7 +90,7 @@ fmt_u(uint32_t x, char *s) typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -#if defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips) +#if (defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__) static long double frexpl (long double x, int *eptr) { From 5dd2b8e16f33b84773cdebeec4b6a86a511e8e9c Mon Sep 17 00:00:00 2001 From: Tomoyuki Sahara Date: Mon, 8 Jun 2015 17:32:14 +0900 Subject: [PATCH 038/218] gsub/sub supports back references in substitutes. fixes #2816. This implementation is compatible with CRuby's String#gsub/sub except \1 ... \9 and \+. They are useless without Regexp library. --- mrblib/string.rb | 39 +++++++++++++++++++++++++++++++++++++-- test/t/string.rb | 18 ++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/mrblib/string.rb b/mrblib/string.rb index 90aad5d32..ee097ad6d 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -20,6 +20,30 @@ class String self end + # private method for gsub/sub + def __sub_replace(pre, m, post) + s = "" + i = 0 + while j = index("\\", i) + break if j == length-1 + t = case self[j+1] + when "\\" + "\\" + when "`" + pre + when "&", "0" + m + when "'" + post + else + self[j, 2] + end + s += self[i, j-i] + t + i = j + 2 + end + s + self[i, length-i] + end + ## # Replace all matches of +pattern+ with +replacement+. # Call block (if given) for each match and replace @@ -29,7 +53,17 @@ class String # ISO 15.2.10.5.18 def gsub(*args, &block) if args.size == 2 - split(args[0], -1).join(args[1]) + s = "" + i = 0 + while j = index(args[0], i) + seplen = args[0].length + k = j + seplen + pre = self[0, j] + post = self[k, length-k] + s += self[i, j-i] + args[1].__sub_replace(pre, args[0], post) + i = k + end + s + self[i, length-i] elsif args.size == 1 && block split(args[0], -1).join(block.call(args[0])) else @@ -76,7 +110,8 @@ class String # ISO 15.2.10.5.36 def sub(*args, &block) if args.size == 2 - split(args[0], 2).join(args[1]) + pre, post = split(args[0], 2) + pre + args[1].__sub_replace(pre, args[0], post) + post elsif args.size == 1 && block split(args[0], 2).join(block.call(args[0])) else diff --git a/test/t/string.rb b/test/t/string.rb index 63e4af000..ee6fe0848 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -254,6 +254,15 @@ assert('String#gsub', '15.2.10.5.18') do assert_equal('A', 'a'.gsub('a'){|w| w.capitalize }) end +assert('String#gsub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cd<\\>ef', s.gsub('X', '<\\\\>') + assert_equal 'abcdef', s.gsub('X', '<\\&>') + assert_equal 'abcdef', s.gsub('X', '<\\0>') + assert_equal 'abcdef', s.gsub('X', '<\\`>') + assert_equal 'abcdef', s.gsub('X', '<\\\'>') +end + assert('String#gsub!', '15.2.10.5.19') do a = 'abcabc' a.gsub!('b', 'B') @@ -416,6 +425,15 @@ assert('String#sub', '15.2.10.5.36') do assert_equal 'aa$', 'aa#'.sub('#', '$') end +assert('String#sub with backslash') do + s = 'abXcdXef' + assert_equal 'ab<\\>cdXef', s.sub('X', '<\\\\>') + assert_equal 'abcdXef', s.sub('X', '<\\&>') + assert_equal 'abcdXef', s.sub('X', '<\\0>') + assert_equal 'abcdXef', s.sub('X', '<\\`>') + assert_equal 'abcdXef', s.sub('X', '<\\\'>') +end + assert('String#sub!', '15.2.10.5.37') do a = 'abcabc' a.sub!('b', 'B') From be2c156876c5b6cd4c9937c2d266f1862597af58 Mon Sep 17 00:00:00 2001 From: Huei-Horng Yo Date: Tue, 9 Jun 2015 21:07:12 +0800 Subject: [PATCH 039/218] Detect if ncurses' backend is terminfo or termcap. fixes #2662 Borrowed from @mattn's code at: https://github.com/mruby/mruby/issues/2662#issuecomment-65535705 Signed-off-by: Huei-Horng Yo --- Rakefile | 1 + mrbgems/mruby-bin-mirb/mrbgem.rake | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Rakefile b/Rakefile index 0f33c5ee8..89dab05e7 100644 --- a/Rakefile +++ b/Rakefile @@ -3,6 +3,7 @@ # basic build file for mruby MRUBY_ROOT = File.dirname(File.expand_path(__FILE__)) MRUBY_BUILD_HOST_IS_CYGWIN = RUBY_PLATFORM.include?('cygwin') +MRUBY_BUILD_HOST_IS_OPENBSD = RUBY_PLATFORM.include?('openbsd') # load build systems load "#{MRUBY_ROOT}/tasks/ruby_ext.rake" diff --git a/mrbgems/mruby-bin-mirb/mrbgem.rake b/mrbgems/mruby-bin-mirb/mrbgem.rake index 98df38499..e77114515 100644 --- a/mrbgems/mruby-bin-mirb/mrbgem.rake +++ b/mrbgems/mruby-bin-mirb/mrbgem.rake @@ -6,10 +6,16 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec| if spec.build.cc.search_header_path 'readline/readline.h' spec.cc.defines << "ENABLE_READLINE" if spec.build.cc.search_header_path 'termcap.h' - if MRUBY_BUILD_HOST_IS_CYGWIN then - spec.linker.libraries << 'ncurses' - else - spec.linker.libraries << 'termcap' + if MRUBY_BUILD_HOST_IS_CYGWIN || MRUBY_BUILD_HOST_IS_OPENBSD + if spec.build.cc.search_header_path 'termcap.h' + if MRUBY_BUILD_HOST_IS_CYGWIN then + spec.linker.libraries << 'ncurses' + elsif spec.linker.has_library('libterminfo') then + spec.linker.libraries << 'terminfo' + else + spec.linker.libraries << 'termcap' + end + end end end if RUBY_PLATFORM.include?('netbsd') From 2f4f36b3343872e7797768b4cd5f7e6b6a4505bb Mon Sep 17 00:00:00 2001 From: Huei-Horng Yo Date: Wed, 10 Jun 2015 12:40:18 +0800 Subject: [PATCH 040/218] Remove unused libterminfo detection code. The detection code is unused even on OpenBSD 5.7, because of the standard installation is libtermcap be installed, not libterminfo. This fixes #2829 Tested on Arch Linux (x86_64) & OpenBSD 5.7 (amd64). Signed-off-by: Huei-Horng Yo --- mrbgems/mruby-bin-mirb/mrbgem.rake | 2 -- 1 file changed, 2 deletions(-) diff --git a/mrbgems/mruby-bin-mirb/mrbgem.rake b/mrbgems/mruby-bin-mirb/mrbgem.rake index e77114515..dce832d98 100644 --- a/mrbgems/mruby-bin-mirb/mrbgem.rake +++ b/mrbgems/mruby-bin-mirb/mrbgem.rake @@ -10,8 +10,6 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec| if spec.build.cc.search_header_path 'termcap.h' if MRUBY_BUILD_HOST_IS_CYGWIN then spec.linker.libraries << 'ncurses' - elsif spec.linker.has_library('libterminfo') then - spec.linker.libraries << 'terminfo' else spec.linker.libraries << 'termcap' end From 5e8d2a4b841d59ceab9f6fcf3ae294d93b8332b5 Mon Sep 17 00:00:00 2001 From: cremno Date: Sat, 13 Jun 2015 14:59:57 +0200 Subject: [PATCH 041/218] refactor code to call mrb_inspect() instead mrb_inspect() also calls mrb_obj_as_string() after #inspect to ensure the mrb_value is a string. --- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 6 +----- src/print.c | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 44ad9bb06..141ea151b 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -11,12 +11,8 @@ static void p(mrb_state *mrb, mrb_value obj) { - mrb_value val; + mrb_value val = mrb_inspect(mrb, obj); - val = mrb_funcall(mrb, obj, "inspect", 0); - if (!mrb_string_p(val)) { - val = mrb_obj_as_string(mrb, obj); - } fwrite(RSTRING_PTR(val), RSTRING_LEN(val), 1, stdout); putc('\n', stdout); } diff --git a/src/print.c b/src/print.c index b43936b13..c7c1ccd39 100644 --- a/src/print.c +++ b/src/print.c @@ -27,12 +27,8 @@ MRB_API void mrb_p(mrb_state *mrb, mrb_value obj) { #ifdef ENABLE_STDIO - mrb_value val; + mrb_value val = mrb_inspect(mrb, obj); - val = mrb_funcall(mrb, obj, "inspect", 0); - if (!mrb_string_p(val)) { - val = mrb_obj_as_string(mrb, obj); - } printstr(mrb, val); putc('\n', stdout); #endif From 95fa22a65cf0866afaf3efd933a180509922f047 Mon Sep 17 00:00:00 2001 From: Lukas Joeressen Date: Mon, 15 Jun 2015 15:03:44 +0200 Subject: [PATCH 042/218] Rounding errors could make time_alloc imprecise --- mrbgems/mruby-time/src/time.c | 5 +++-- mrbgems/mruby-time/test/time.rb | 8 ++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index b377f3e33..36bbbe00a 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -6,6 +6,7 @@ #include #include +#include #include "mruby.h" #include "mruby/class.h" #include "mruby/data.h" @@ -208,12 +209,12 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) out_of_range: mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); } - tm->usec = (time_t)((sec - tm->sec) * 1.0e6 + usec); + tm->usec = (time_t)llrint((sec - tm->sec) * 1.0e6 + usec); while (tm->usec < 0) { tm->sec--; tm->usec += 1000000; } - while (tm->usec > 1000000) { + while (tm->usec >= 1000000) { tm->sec++; tm->usec -= 1000000; } diff --git a/mrbgems/mruby-time/test/time.rb b/mrbgems/mruby-time/test/time.rb index ba9b48fab..759e2881d 100644 --- a/mrbgems/mruby-time/test/time.rb +++ b/mrbgems/mruby-time/test/time.rb @@ -203,3 +203,11 @@ assert('day of week methods') do assert_false t.friday? assert_false t.saturday? end + +assert('2000 times 500us make a second') do + t = Time.utc 2015 + 2000.times do + t += 0.0005 + end + t.usec == 0 +end From 47c61cf5027ed46a51ef0a261c3192700700a350 Mon Sep 17 00:00:00 2001 From: Lukas Joeressen Date: Tue, 16 Jun 2015 09:24:27 +0200 Subject: [PATCH 043/218] Changed llrint to llround --- mrbgems/mruby-time/src/time.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 36bbbe00a..da3451d22 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -4,9 +4,9 @@ ** See Copyright Notice in mruby.h */ +#include #include #include -#include #include "mruby.h" #include "mruby/class.h" #include "mruby/data.h" @@ -209,7 +209,7 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) out_of_range: mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); } - tm->usec = (time_t)llrint((sec - tm->sec) * 1.0e6 + usec); + tm->usec = (time_t)llround((sec - tm->sec) * 1.0e6 + usec); while (tm->usec < 0) { tm->sec--; tm->usec += 1000000; From 6a796cb4ccd53a35c93c89c1074d556186207966 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 17 Jun 2015 09:19:09 +0900 Subject: [PATCH 044/218] Added a check for 64 bit time_t overflow; based on a patch from @kext; close #2836 --- mrbgems/mruby-time/src/time.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index da3451d22..081e84c1c 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -201,11 +201,14 @@ time_alloc(mrb_state *mrb, double sec, double usec, enum mrb_timezone timezone) struct mrb_time *tm; tm = (struct mrb_time *)mrb_malloc(mrb, sizeof(struct mrb_time)); - tm->sec = (time_t)sec; if (sizeof(time_t) == 4 && (sec > (double)INT32_MAX || (double)INT32_MIN > sec)) { goto out_of_range; } - else if ((sec > 0 && tm->sec < 0) || (sec < 0 && (double)tm->sec > sec)) { + if (sizeof(time_t) == 8 && (sec > (double)INT64_MAX || (double)INT64_MIN > sec)) { + goto out_of_range; + } + tm->sec = (time_t)sec; + if ((sec > 0 && tm->sec < 0) || (sec < 0 && (double)tm->sec > sec)) { out_of_range: mrb_raisef(mrb, E_ARGUMENT_ERROR, "%S out of Time range", mrb_float_value(mrb, sec)); } From d1e6d647bd3a91d58567657471f3d945836cde85 Mon Sep 17 00:00:00 2001 From: yui-knk Date: Fri, 19 Jun 2015 20:34:32 +0900 Subject: [PATCH 045/218] [ci skip] Remove some Srting#split samples mruby not support regexp, so remove these samples. --- src/string.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/string.c b/src/string.c index 16e7f9ffd..e3a359b49 100644 --- a/src/string.c +++ b/src/string.c @@ -1714,10 +1714,8 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) * " now's the time".split #=> ["now's", "the", "time"] * " now's the time".split(' ') #=> ["now's", "the", "time"] * " now's the time".split(/ /) #=> ["", "now's", "", "the", "time"] - * "1, 2.34,56, 7".split(%r{,\s*}) #=> ["1", "2.34", "56", "7"] * "hello".split(//) #=> ["h", "e", "l", "l", "o"] * "hello".split(//, 3) #=> ["h", "e", "llo"] - * "hi mom".split(%r{\s*}) #=> ["h", "i", "m", "o", "m"] * * "mellow yellow".split("ello") #=> ["m", "w y", "w"] * "1,2,,3,4,,".split(',') #=> ["1", "2", "", "3", "4"] From dcc316d3b84691f88158c3a3d2c43e612a995f6e Mon Sep 17 00:00:00 2001 From: Anton Davydov Date: Fri, 19 Jun 2015 15:52:23 +0300 Subject: [PATCH 046/218] Fix typos in documentation and error messages [skip ci] --- CONTRIBUTING.md | 2 +- mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c | 2 +- mrbgems/mruby-fiber/src/fiber.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d4de00b9..6bababb89 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,7 +45,7 @@ on-demand. #### Don't use C++ style comments - /* This is the prefered comment style */ + /* This is the preferred comment style */ Use C++ style comments only for temporary comment e.g. commenting out some code lines. diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c index b40915909..f52514851 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/cmdmisc.c @@ -33,7 +33,7 @@ static help_msg help_msg_list[] = { "\n" "Continue program stopped by a breakpoint.\n" "If N, which is non negative value, is passed,\n" - "proceed program until the N-th breakpoint is comming.\n" + "proceed program until the N-th breakpoint is coming.\n" "If N is not passed, N is assumed 1.\n" }, { diff --git a/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c index 2e5cd82e9..93b3f1227 100644 --- a/mrbgems/mruby-fiber/src/fiber.c +++ b/mrbgems/mruby-fiber/src/fiber.c @@ -167,7 +167,7 @@ fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mr } } if (resume && c->status == MRB_FIBER_TRANSFERRED) { - mrb_raise(mrb, E_FIBER_ERROR, "resuming transfered fiber"); + mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); } if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMING) { mrb_raise(mrb, E_FIBER_ERROR, "double resume"); @@ -265,8 +265,8 @@ fiber_eq(mrb_state *mrb, mrb_value self) * call-seq: * fiber.transfer(args, ...) -> obj * - * Transfers control to reciever fiber of the method call. - * Unlike resume the reciever wouldn't be pushed to call + * Transfers control to receiver fiber of the method call. + * Unlike resume the receiver wouldn't be pushed to call * stack of fibers. Instead it will switch to the call stack of * transferring fiber. * When resuming a fiber that was transferred to another fiber it would From 111602319bdecde9a9cfbe74b48b3b93debc35df Mon Sep 17 00:00:00 2001 From: Anton Davydov Date: Sat, 20 Jun 2015 13:27:36 +0300 Subject: [PATCH 047/218] Fix repository link to mruby/mruby [skip ci] --- doc/debugger/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/debugger/README.md b/doc/debugger/README.md index 56230e429..a13e91cec 100755 --- a/doc/debugger/README.md +++ b/doc/debugger/README.md @@ -13,7 +13,7 @@ This file documents the mruby debugger ('mrdb') methods. The trunk of the mruby source tree, with the most recent mrdb, can be checked out with the following command: ```bash -$ git clone https://github.com/mruby-Forum/mruby.git +$ git clone https://github.com/mruby/mruby.git ``` To run the `make` command: From 8d54977d259137b61a4e391a3928374d1b29aca3 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 02:23:11 +0900 Subject: [PATCH 048/218] Add :mgem gem loader to load mrbgem from mgem-list ( https://github.com/mruby/mgem-list ). --- tasks/mruby_build_gem.rake | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index dbbade487..d9d2575bd 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -52,6 +52,26 @@ module MRuby else params[:git] = "https://bitbucket.org/#{params[:bitbucket]}.git" end + elsif params[:mgem] + mgem_list_dir = "#{gem_clone_dir}/mgem-list" + mgem_list_url = 'https://github.com/mruby/mgem-list.git' + if File.exist? mgem_list_dir + git.run_pull mgem_list_dir, mgem_list_url if $pull_gems + else + FileUtils.mkdir_p mgem_list_dir + git.run_clone mgem_list_dir, mgem_list_url + end + + require 'yaml' + + conf_path = "#{mgem_list_dir}/#{params[:mgem]}.gem" + conf_path = "#{mgem_list_dir}/mruby-#{params[:mgem]}.gem" unless File.exist? conf_path + fail "mgem not found: #{params[:mgem]}" unless File.exist? conf_path + conf = YAML.load File.read conf_path + + fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git' + params[:git] = conf['repository'] + params[:branch] = conf['branch"] if conf["branch'] end if params[:core] From 0c8fa845e4faf83c50b0df0272c58870832d9e62 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 02:23:52 +0900 Subject: [PATCH 049/218] Load missing dependencies from core or mgem-list. --- tasks/mrbgem_spec.rake | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index e6e17e182..e22a39e19 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -304,7 +304,14 @@ module MRuby default_gems = [] each do |g| g.dependencies.each do |dep| - default_gems << dep if dep[:default] and not gem_table.key? dep[:gem] + unless gem_table.key? dep[:gem] + if dep[:default]; default_gems << dep + elsif File.exist? "#{root}/mrbgems/#{dep[:gem]}" # check core + default_gems << { :gem => dep[:gem], :default => { :core => dep[:gem] } } + else # fallback to mgem-list + default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } } + end + end end end @@ -316,7 +323,11 @@ module MRuby spec.setup spec.dependencies.each do |dep| - default_gems << dep if dep[:default] and not gem_table.key? dep[:gem] + unless gem_table.key? dep[:gem] + if dep[:default]; default_gems << dep + else default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } } + end + end end gem_table[spec.name] = spec end From 078d24d4d3f7b5aac436fb70e341e1a7668fdbbb Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 02:24:15 +0900 Subject: [PATCH 050/218] Add documentation to new mgem features. --- doc/mrbgems/README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md index 101177b13..b24be74e0 100644 --- a/doc/mrbgems/README.md +++ b/doc/mrbgems/README.md @@ -26,6 +26,15 @@ conf.gem :github => 'masuidrive/mrbgems-example', :branch => 'master' conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' ``` +To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option: +```ruby +conf.gem :mgem => 'mruby-yaml' +conf.gem :mgem => 'yaml' # 'mruby-' prefix could be ignored +``` + +If there is missing dependencies, mrbgem dependencies solver will reference +mrbgem from core or mgem-list. + To pull all gems from remote GIT repository on build, call ```./minirake -p```, or ```./minirake --pull-gems```. From e344c6ab6d7b3d6a8ffcec6f7f96aeba6c5fdeda Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 22 Jun 2015 10:09:04 +0900 Subject: [PATCH 051/218] [ci skip] replace "ignored" by "omitted"; ref #2846 --- doc/mrbgems/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md index b24be74e0..e0c60daf2 100644 --- a/doc/mrbgems/README.md +++ b/doc/mrbgems/README.md @@ -29,7 +29,7 @@ conf.gem :bitbucket => 'mruby/mrbgems-example', :branch => 'master' To use mrbgem from [mgem-list](https://github.com/mruby/mgem-list) use `:mgem` option: ```ruby conf.gem :mgem => 'mruby-yaml' -conf.gem :mgem => 'yaml' # 'mruby-' prefix could be ignored +conf.gem :mgem => 'yaml' # 'mruby-' prefix could be omitted ``` If there is missing dependencies, mrbgem dependencies solver will reference @@ -151,7 +151,7 @@ MRuby::Gem::Specification.new('c_and_ruby_extension_example') do |spec| # Use any version of mruby-uv from github. spec.add_dependency('mruby-uv', '>= 0.0.0', :github => 'mattn/mruby-uv') - # Use latest mruby-onig-regexp from github. (version requirements can be ignored) + # Use latest mruby-onig-regexp from github. (version requirements can be omitted) spec.add_dependency('mruby-onig-regexp', :github => 'mattn/mruby-onig-regexp') end ``` From f0eaf9eaf53ce659c44ce6beeedbeb8bfc5b4efa Mon Sep 17 00:00:00 2001 From: cremno Date: Mon, 22 Jun 2015 13:34:24 +0200 Subject: [PATCH 052/218] fix arity of lambdas with optional arguments From the CRuby 2.2.2 Proc#arity documentation: If the block has optional arguments, returns -n-1, where n is the number of mandatory arguments, with the exception for blocks that are not lambdas and have only a finite number of optional arguments; in this latter case, returns n. --- src/proc.c | 2 +- test/t/proc.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/proc.c b/src/proc.c index 4cb9ffe18..61524f00c 100644 --- a/src/proc.c +++ b/src/proc.c @@ -216,7 +216,7 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self) ma = MRB_ASPEC_REQ(aspec); ra = MRB_ASPEC_REST(aspec); pa = MRB_ASPEC_POST(aspec); - arity = ra ? -(ma + pa + 1) : ma + pa; + arity = ra || MRB_PROC_STRICT_P(p) ? -(ma + pa + 1) : ma + pa; return mrb_fixnum_value(arity); } diff --git a/test/t/proc.rb b/test/t/proc.rb index 22ccceb68..888b7d56a 100644 --- a/test/t/proc.rb +++ b/test/t/proc.rb @@ -36,6 +36,14 @@ assert('Proc#arity', '15.2.17.4.2') do assert_equal(-3, b) assert_equal 1, c assert_equal 1, d + + e = ->(x=0, y){}.arity + f = ->((x, y), z=0){}.arity + g = ->(x=0){}.arity + + assert_equal(-2, e) + assert_equal(-2, f) + assert_equal(-1, g) end assert('Proc#call', '15.2.17.4.3') do From 69b4c1648a71d7c275a98de7b9ebdc635a5fe438 Mon Sep 17 00:00:00 2001 From: cremno Date: Mon, 22 Jun 2015 16:35:54 +0200 Subject: [PATCH 053/218] Proc#curry should preserve lambdas --- mrbgems/mruby-proc-ext/mrblib/proc.rb | 4 +++- mrbgems/mruby-proc-ext/test/proc.rb | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-proc-ext/mrblib/proc.rb b/mrbgems/mruby-proc-ext/mrblib/proc.rb index 5dd9981df..b71663938 100644 --- a/mrbgems/mruby-proc-ext/mrblib/proc.rb +++ b/mrbgems/mruby-proc-ext/mrblib/proc.rb @@ -13,9 +13,11 @@ class Proc end def curry(arity=self.arity) + type = :proc abs = lambda {|a| a < 0 ? -a - 1 : a} arity = abs[arity] if lambda? + type = :lambda self_arity = self.arity if (self_arity >= 0 && arity != self_arity) || (self_arity < 0 && abs[self_arity] > arity) @@ -25,7 +27,7 @@ class Proc pproc = self make_curry = proc do |given_args=[]| - proc do |*args| + send(type) do |*args| new_args = given_args + args if new_args.size >= arity pproc[*new_args] diff --git a/mrbgems/mruby-proc-ext/test/proc.rb b/mrbgems/mruby-proc-ext/test/proc.rb index bca9b463a..75e11dd93 100644 --- a/mrbgems/mruby-proc-ext/test/proc.rb +++ b/mrbgems/mruby-proc-ext/test/proc.rb @@ -41,6 +41,9 @@ assert('Proc#curry') do assert_raise(ArgumentError) { b.curry[1, 2][3, 4] } assert_raise(ArgumentError) { b.curry(5) } assert_raise(ArgumentError) { b.curry(1) } + + assert_false(proc{}.curry.lambda?) + assert_true(lambda{}.curry.lambda?) end assert('Proc#parameters') do From 7e087d7191507b1ad5c47b6a621ec499e6010543 Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Mon, 22 Jun 2015 13:01:15 -0400 Subject: [PATCH 054/218] Need mruby-compiler to build mruby-bin-mruby and mruby-bin-mirb for cross compiles --- mrbgems/default.gembox | 3 +++ mrbgems/mruby-bin-mirb/mrbgem.rake | 1 + mrbgems/mruby-bin-mruby/mrbgem.rake | 1 + 3 files changed, 5 insertions(+) diff --git a/mrbgems/default.gembox b/mrbgems/default.gembox index 06609d9e7..30dcc1abc 100644 --- a/mrbgems/default.gembox +++ b/mrbgems/default.gembox @@ -70,4 +70,7 @@ MRuby::GemBox.new do |conf| # Use extensional Kernel module conf.gem :core => "mruby-kernel-ext" + + # Use mruby-compiler to build other mrbgems + conf.gem :core => "mruby-compiler" end diff --git a/mrbgems/mruby-bin-mirb/mrbgem.rake b/mrbgems/mruby-bin-mirb/mrbgem.rake index dce832d98..7d45409c9 100644 --- a/mrbgems/mruby-bin-mirb/mrbgem.rake +++ b/mrbgems/mruby-bin-mirb/mrbgem.rake @@ -26,4 +26,5 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec| end spec.bins = %w(mirb) + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') end diff --git a/mrbgems/mruby-bin-mruby/mrbgem.rake b/mrbgems/mruby-bin-mruby/mrbgem.rake index 4e2f6a142..ba7fad1fa 100644 --- a/mrbgems/mruby-bin-mruby/mrbgem.rake +++ b/mrbgems/mruby-bin-mruby/mrbgem.rake @@ -3,4 +3,5 @@ MRuby::Gem::Specification.new('mruby-bin-mruby') do |spec| spec.author = 'mruby developers' spec.summary = 'mruby command' spec.bins = %w(mruby) + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') end From 338ca305ae558e4c6f929fdb619f586fb030ba7f Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 18:37:14 -0700 Subject: [PATCH 055/218] Calling mrb_str_to_str in mrb_string_value_cstr. Fixes #2847 --- src/string.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 0a28f2565..9a1a6fba1 100644 --- a/src/string.c +++ b/src/string.c @@ -1985,7 +1985,8 @@ bad: MRB_API const char* mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) { - struct RString *ps = mrb_str_ptr(*ptr); + mrb_value str = mrb_str_to_str(mrb, *ptr); + struct RString *ps = mrb_str_ptr(str); mrb_int len = mrb_str_strlen(mrb, ps); char *p = RSTR_PTR(ps); From 9553e20d34c204826fde86620d2f433b3d59f1c1 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 19:07:25 -0700 Subject: [PATCH 056/218] Removing redundant mrb_str_to_str call --- src/string.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/string.c b/src/string.c index 9a1a6fba1..9f753a0cf 100644 --- a/src/string.c +++ b/src/string.c @@ -2003,7 +2003,6 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) const char *s; mrb_int len; - str = mrb_str_to_str(mrb, str); if (badcheck) { s = mrb_string_value_cstr(mrb, &str); } From 264a059aef01b079d9788c8569182482edeab82a Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 19:15:52 -0700 Subject: [PATCH 057/218] Removing unneeded bad_checks for verified strings --- mrbgems/mruby-sprintf/src/sprintf.c | 2 +- src/object.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index d88e242c6..ca4ecfbbd 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -808,7 +808,7 @@ retry: if (mrb_fixnum_p(val)) goto bin_retry; break; case MRB_TT_STRING: - val = mrb_str_to_inum(mrb, val, 0, TRUE); + val = mrb_str_to_inum(mrb, val, 0, FALSE); goto bin_retry; case MRB_TT_FIXNUM: v = mrb_fixnum(val); diff --git a/src/object.c b/src/object.c index c5fb74575..df7d77b9e 100644 --- a/src/object.c +++ b/src/object.c @@ -539,7 +539,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) case MRB_TT_STRING: string_conv: - return mrb_str_to_inum(mrb, val, base, TRUE); + return mrb_str_to_inum(mrb, val, base, FALSE); default: break; From cfcca2a727e2af8aa789d7a29bbe612628e84893 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 19:49:12 -0700 Subject: [PATCH 058/218] Reverting overzealous changes --- mrbgems/mruby-sprintf/src/sprintf.c | 2 +- src/object.c | 2 +- src/string.c | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index ca4ecfbbd..d88e242c6 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -808,7 +808,7 @@ retry: if (mrb_fixnum_p(val)) goto bin_retry; break; case MRB_TT_STRING: - val = mrb_str_to_inum(mrb, val, 0, FALSE); + val = mrb_str_to_inum(mrb, val, 0, TRUE); goto bin_retry; case MRB_TT_FIXNUM: v = mrb_fixnum(val); diff --git a/src/object.c b/src/object.c index df7d77b9e..c5fb74575 100644 --- a/src/object.c +++ b/src/object.c @@ -539,7 +539,7 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) case MRB_TT_STRING: string_conv: - return mrb_str_to_inum(mrb, val, base, FALSE); + return mrb_str_to_inum(mrb, val, base, TRUE); default: break; diff --git a/src/string.c b/src/string.c index 9f753a0cf..9a1a6fba1 100644 --- a/src/string.c +++ b/src/string.c @@ -2003,6 +2003,7 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) const char *s; mrb_int len; + str = mrb_str_to_str(mrb, str); if (badcheck) { s = mrb_string_value_cstr(mrb, &str); } From 9ad632559efc6392d4650eedb27090ec27f78776 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 20:49:09 -0700 Subject: [PATCH 059/218] *Correctly* removing extra mrb_str_to_str call --- src/string.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/string.c b/src/string.c index 9a1a6fba1..22a289ade 100644 --- a/src/string.c +++ b/src/string.c @@ -2003,12 +2003,12 @@ mrb_str_to_inum(mrb_state *mrb, mrb_value str, mrb_int base, mrb_bool badcheck) const char *s; mrb_int len; - str = mrb_str_to_str(mrb, str); if (badcheck) { + /* Raises if the string contains a null character (the badcheck) */ s = mrb_string_value_cstr(mrb, &str); } else { - s = RSTRING_PTR(str); + s = mrb_string_value_ptr(mrb, str); } if (s) { len = RSTRING_LEN(str); From 937b5b546201b874e7aba6a371f28456a784b39a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 23 Jun 2015 14:42:58 +0900 Subject: [PATCH 060/218] fix Proc#curry test failure; ref #2848 --- src/proc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/proc.c b/src/proc.c index 61524f00c..f98998f68 100644 --- a/src/proc.c +++ b/src/proc.c @@ -200,7 +200,7 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self) struct RProc *p = mrb_proc_ptr(self); mrb_code *iseq = mrb_proc_iseq(mrb, p); mrb_aspec aspec; - int ma, ra, pa, arity; + int ma, op, ra, pa, arity; if (MRB_PROC_CFUNC_P(p)) { /* TODO cfunc aspec not implemented yet */ @@ -214,9 +214,10 @@ mrb_proc_arity(mrb_state *mrb, mrb_value self) aspec = GETARG_Ax(*iseq); ma = MRB_ASPEC_REQ(aspec); + op = MRB_ASPEC_OPT(aspec); ra = MRB_ASPEC_REST(aspec); pa = MRB_ASPEC_POST(aspec); - arity = ra || MRB_PROC_STRICT_P(p) ? -(ma + pa + 1) : ma + pa; + arity = ra || (MRB_PROC_STRICT_P(p) && op) ? -(ma + pa + 1) : ma + pa; return mrb_fixnum_value(arity); } From 9781580c7134fcee7bf5a6d4356bc47593549da8 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Mon, 22 Jun 2015 23:19:58 -0700 Subject: [PATCH 061/218] Fixes #912 --- src/class.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/class.c b/src/class.c index 35c3aa040..05b549b3e 100644 --- a/src/class.c +++ b/src/class.c @@ -1174,11 +1174,11 @@ mrb_instance_alloc(mrb_state *mrb, mrb_value cv) * call-seq: * class.new(args, ...) -> obj * - * Calls allocate to create a new object of - * class's class, then invokes that object's - * initialize method, passing it args. - * This is the method that ends up getting called whenever - * an object is constructed using .new. + * Creates a new object of class's class, then + * invokes that object's initialize method, + * passing it args. This is the method that ends + * up getting called whenever an object is constructed using + * `.new`. * */ From e90f0d51a3b2ac52aa76fa3c8b803bcc75433468 Mon Sep 17 00:00:00 2001 From: furunkel Date: Tue, 23 Jun 2015 10:35:02 +0200 Subject: [PATCH 062/218] Move deprecated macros and functions to dedicated header file --- include/mruby.h | 15 +++++---------- include/mruby/deprecated.h | 10 ++++++++++ 2 files changed, 15 insertions(+), 10 deletions(-) create mode 100644 include/mruby/deprecated.h diff --git a/include/mruby.h b/include/mruby.h index 6eb3af844..69bb21704 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -192,10 +192,13 @@ typedef struct mrb_state { # define mrb_noreturn _Noreturn #elif defined __GNUC__ && !defined __STRICT_ANSI__ # define mrb_noreturn __attribute__((noreturn)) +# define mrb_deprecated __attribute__((deprecated)) #elif defined _MSC_VER # define mrb_noreturn __declspec(noreturn) +# define mrb_deprecated __declspec(deprecated) #else # define mrb_noreturn +# define mrb_deprecated #endif typedef mrb_value (*mrb_func_t)(mrb_state *mrb, mrb_value); @@ -250,16 +253,6 @@ MRB_API struct RClass * mrb_define_module_under(mrb_state *mrb, struct RClass *o /* accept no arguments */ #define MRB_ARGS_NONE() ((mrb_aspec)0) -/* compatibility macros; will be removed */ -#define ARGS_REQ(n) MRB_ARGS_REQ(n) -#define ARGS_OPT(n) MRB_ARGS_OPT(n) -#define ARGS_REST() MRB_ARGS_REST() -#define ARGS_POST(n) MRB_ARGS_POST() -#define ARGS_KEY(n1,n2) MRB_ARGS_KEY(n1,n2) -#define ARGS_BLOCK() MRB_ARGS_BLOCK() -#define ARGS_ANY() MRB_ARGS_ANY() -#define ARGS_NONE() MRB_ARGS_NONE() - MRB_API mrb_int mrb_get_args(mrb_state *mrb, const char *format, ...); /* `strlen` for character string literals (use with caution or `strlen` instead) @@ -459,6 +452,8 @@ MRB_API void mrb_show_copyright(mrb_state *mrb); MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); +#include "mruby/deprecated.h" + #if defined(__cplusplus) } /* extern "C" { */ #endif diff --git a/include/mruby/deprecated.h b/include/mruby/deprecated.h new file mode 100644 index 000000000..ac1c81b7e --- /dev/null +++ b/include/mruby/deprecated.h @@ -0,0 +1,10 @@ +/* Deprecated macros and functions */ + +#define ARGS_REQ(n) MRB_ARGS_REQ(n) +#define ARGS_OPT(n) MRB_ARGS_OPT(n) +#define ARGS_REST() MRB_ARGS_REST() +#define ARGS_POST(n) MRB_ARGS_POST() +#define ARGS_KEY(n1,n2) MRB_ARGS_KEY(n1,n2) +#define ARGS_BLOCK() MRB_ARGS_BLOCK() +#define ARGS_ANY() MRB_ARGS_ANY() +#define ARGS_NONE() MRB_ARGS_NONE() From 6ed64e23678620f99e836eb07a58903760cf657c Mon Sep 17 00:00:00 2001 From: cremno Date: Tue, 23 Jun 2015 12:44:28 +0200 Subject: [PATCH 063/218] rewrite printstr() to get rid of code duplication --- src/print.c | 36 ++++++++++++------------------------ 1 file changed, 12 insertions(+), 24 deletions(-) diff --git a/src/print.c b/src/print.c index c7c1ccd39..077fa4f06 100644 --- a/src/print.c +++ b/src/print.c @@ -8,45 +8,35 @@ #include "mruby/string.h" #include "mruby/variable.h" -static void -printstr(mrb_state *mrb, mrb_value obj) -{ #ifdef ENABLE_STDIO - char *s; - int len; - +static void +printstr(mrb_value obj, FILE *stream) +{ if (mrb_string_p(obj)) { - s = RSTRING_PTR(obj); - len = RSTRING_LEN(obj); - fwrite(s, len, 1, stdout); + fwrite(RSTRING_PTR(obj), RSTRING_LEN(obj), 1, stream); + putc('\n', stream); } -#endif } +#else +# define printstr(obj, stream) (void)0 +#endif MRB_API void mrb_p(mrb_state *mrb, mrb_value obj) { -#ifdef ENABLE_STDIO mrb_value val = mrb_inspect(mrb, obj); - printstr(mrb, val); - putc('\n', stdout); -#endif + printstr(val, stdout); } MRB_API void mrb_print_error(mrb_state *mrb) { -#ifdef ENABLE_STDIO mrb_value s; mrb_print_backtrace(mrb); s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0); - if (mrb_string_p(s)) { - fwrite(RSTRING_PTR(s), RSTRING_LEN(s), 1, stderr); - putc('\n', stderr); - } -#endif + printstr(s, stderr); } MRB_API void @@ -55,8 +45,7 @@ mrb_show_version(mrb_state *mrb) mrb_value msg; msg = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_DESCRIPTION")); - printstr(mrb, msg); - printstr(mrb, mrb_str_new_lit(mrb, "\n")); + printstr(msg, stdout); } MRB_API void @@ -65,6 +54,5 @@ mrb_show_copyright(mrb_state *mrb) mrb_value msg; msg = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), mrb_intern_lit(mrb, "MRUBY_COPYRIGHT")); - printstr(mrb, msg); - printstr(mrb, mrb_str_new_lit(mrb, "\n")); + printstr(msg, stdout); } From 0006a8cd4a15e52de7bb02fc89287183f2ef2209 Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Tue, 23 Jun 2015 12:35:31 -0400 Subject: [PATCH 064/218] add host_target/build_target options for CrossBuild'ng native extensions --- tasks/mruby_build.rake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 50bed0fbe..947b4ba77 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -283,6 +283,10 @@ EOS class CrossBuild < Build attr_block %w(test_runner) + # cross compiling targets for building native extensions. + # host - arch of where the built binary will run + # build - arch of the machine building the binary + attr_accessor :host_target, :build_target def initialize(name, build_dir=nil, &block) @test_runner = Command::CrossTestRunner.new(self) From e88e7dc8db4ff129de6698727fd87904b67ed0e0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 24 Jun 2015 10:05:05 +0900 Subject: [PATCH 065/218] remove deprecated.h --- include/mruby.h | 2 -- include/mruby/deprecated.h | 10 ---------- 2 files changed, 12 deletions(-) delete mode 100644 include/mruby/deprecated.h diff --git a/include/mruby.h b/include/mruby.h index 69bb21704..1b792ce90 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -452,8 +452,6 @@ MRB_API void mrb_show_copyright(mrb_state *mrb); MRB_API mrb_value mrb_format(mrb_state *mrb, const char *format, ...); -#include "mruby/deprecated.h" - #if defined(__cplusplus) } /* extern "C" { */ #endif diff --git a/include/mruby/deprecated.h b/include/mruby/deprecated.h deleted file mode 100644 index ac1c81b7e..000000000 --- a/include/mruby/deprecated.h +++ /dev/null @@ -1,10 +0,0 @@ -/* Deprecated macros and functions */ - -#define ARGS_REQ(n) MRB_ARGS_REQ(n) -#define ARGS_OPT(n) MRB_ARGS_OPT(n) -#define ARGS_REST() MRB_ARGS_REST() -#define ARGS_POST(n) MRB_ARGS_POST() -#define ARGS_KEY(n1,n2) MRB_ARGS_KEY(n1,n2) -#define ARGS_BLOCK() MRB_ARGS_BLOCK() -#define ARGS_ANY() MRB_ARGS_ANY() -#define ARGS_NONE() MRB_ARGS_NONE() From 25885072858582d3d2f985b405a8e84d58f716e8 Mon Sep 17 00:00:00 2001 From: Franck Verrot Date: Wed, 24 Jun 2015 13:07:07 +0200 Subject: [PATCH 066/218] Remove unnecessary backticks. Dr Markus Kuhn published in 1999 an article [1] explaining in details why we shouldn't use the ASCII grave accent (0x60) as a left quotation. Backticks have been used most notably to produce nice-looking LaTeX documents but it doesn't seem to be an issue on modern platforms and for the oldest ones, there are workarounds as mentioned by Dr Kuhn. [1]: https://www.cl.cam.ac.uk/~mgk25/ucs/quotes.html --- include/mruby/compile.h | 4 +- include/mruby/opcode.h | 2 +- mrbgems/mruby-compiler/core/parse.y | 14 ++--- mrbgems/mruby-hash-ext/mrblib/hash.rb | 2 +- mrbgems/mruby-sprintf/src/sprintf.c | 80 +++++++++++++-------------- mrbgems/mruby-struct/src/struct.c | 8 +-- mrblib/array.rb | 2 +- src/class.c | 8 +-- src/numeric.c | 4 +- src/object.c | 2 +- src/string.c | 6 +- src/variable.c | 2 +- 12 files changed, 67 insertions(+), 67 deletions(-) diff --git a/include/mruby/compile.h b/include/mruby/compile.h index e20473298..1fb81782d 100644 --- a/include/mruby/compile.h +++ b/include/mruby/compile.h @@ -55,8 +55,8 @@ enum mrb_lex_state_enum { EXPR_CMDARG, /* newline significant, +/- is an operator. */ EXPR_MID, /* newline significant, +/- is an operator. */ EXPR_FNAME, /* ignore newline, no reserved words. */ - EXPR_DOT, /* right after `.' or `::', no reserved words. */ - EXPR_CLASS, /* immediate after `class', no here document. */ + EXPR_DOT, /* right after '.' or '::', no reserved words. */ + EXPR_CLASS, /* immediate after 'class', no here document. */ EXPR_VALUE, /* alike EXPR_BEG but label is disallowed. */ EXPR_MAX_STATE }; diff --git a/include/mruby/opcode.h b/include/mruby/opcode.h index 4774e78c6..9dfa7f75d 100644 --- a/include/mruby/opcode.h +++ b/include/mruby/opcode.h @@ -8,7 +8,7 @@ #define MRUBY_OPCODE_H #define MAXARG_Bx (0xffff) -#define MAXARG_sBx (MAXARG_Bx>>1) /* `sBx' is signed */ +#define MAXARG_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */ /* instructions: packed 32 bit */ /* ------------------------------- */ diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 5b17649a9..f6a43d32b 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -4204,7 +4204,7 @@ parser_yylex(parser_state *p) } pushback(p, c); if (IS_SPCARG(c)) { - yywarning(p, "`*' interpreted as argument prefix"); + yywarning(p, "'*' interpreted as argument prefix"); c = tSTAR; } else if (IS_BEG()) { @@ -4455,7 +4455,7 @@ parser_yylex(parser_state *p) } pushback(p, c); if (IS_SPCARG(c)) { - yywarning(p, "`&' interpreted as argument prefix"); + yywarning(p, "'&' interpreted as argument prefix"); c = tAMPER; } else if (IS_BEG()) { @@ -4761,7 +4761,7 @@ parser_yylex(parser_state *p) nondigit = c; break; - case '_': /* `_' in number just ignored */ + case '_': /* '_' in number just ignored */ if (nondigit) goto decode_num; nondigit = c; break; @@ -4776,7 +4776,7 @@ parser_yylex(parser_state *p) pushback(p, c); if (nondigit) { trailing_uc: - yyerror_i(p, "trailing `%c' in number", nondigit); + yyerror_i(p, "trailing '%c' in number", nondigit); } tokfix(p); if (is_float) { @@ -5157,10 +5157,10 @@ parser_yylex(parser_state *p) } else if (isdigit(c)) { if (p->bidx == 1) { - yyerror_i(p, "`@%c' is not allowed as an instance variable name", c); + yyerror_i(p, "'@%c' is not allowed as an instance variable name", c); } else { - yyerror_i(p, "`@@%c' is not allowed as a class variable name", c); + yyerror_i(p, "'@@%c' is not allowed as a class variable name", c); } return 0; } @@ -5176,7 +5176,7 @@ parser_yylex(parser_state *p) default: if (!identchar(c)) { - yyerror_i(p, "Invalid char `\\x%02X' in expression", c); + yyerror_i(p, "Invalid char '\\x%02X' in expression", c); goto retry; } diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index ea5e6bc1b..c970b9d02 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -119,7 +119,7 @@ class Hash # # produces: # - # prog.rb:2:in `fetch': key not found (KeyError) + # prog.rb:2:in 'fetch': key not found (KeyError) # from prog.rb:2 # diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index d88e242c6..de216f69f 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -234,20 +234,20 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * ------+-------------------------------------------------------------- * b | Convert argument as a binary number. * | Negative numbers will be displayed as a two's complement - * | prefixed with `..1'. - * B | Equivalent to `b', but uses an uppercase 0B for prefix + * | prefixed with '..1'. + * B | Equivalent to 'b', but uses an uppercase 0B for prefix * | in the alternative format by #. * d | Convert argument as a decimal number. - * i | Identical to `d'. + * i | Identical to 'd'. * o | Convert argument as an octal number. * | Negative numbers will be displayed as a two's complement - * | prefixed with `..7'. - * u | Identical to `d'. + * | prefixed with '..7'. + * u | Identical to 'd'. * x | Convert argument as a hexadecimal number. * | Negative numbers will be displayed as a two's complement - * | prefixed with `..f' (representing an infinite string of + * | prefixed with '..f' (representing an infinite string of * | leading 'ff's). - * X | Equivalent to `x', but uses uppercase letters. + * X | Equivalent to 'x', but uses uppercase letters. * * Field | Float Format * ------+-------------------------------------------------------------- @@ -255,7 +255,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * | with one digit before the decimal point as [-]d.dddddde[+-]dd. * | The precision specifies the number of digits after the decimal * | point (defaulting to six). - * E | Equivalent to `e', but uses an uppercase E to indicate + * E | Equivalent to 'e', but uses an uppercase E to indicate * | the exponent. * f | Convert floating point argument as [-]ddd.dddddd, * | where the precision specifies the number of digits after @@ -264,11 +264,11 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * | if the exponent is less than -4 or greater than or * | equal to the precision, or in dd.dddd form otherwise. * | The precision specifies the number of significant digits. - * G | Equivalent to `g', but use an uppercase `E' in exponent form. + * G | Equivalent to 'g', but use an uppercase 'E' in exponent form. * a | Convert floating point argument as [-]0xh.hhhhp[+-]dd, * | which is consisted from optional sign, "0x", fraction part * | as hexadecimal, "p", and exponential part as decimal. - * A | Equivalent to `a', but use uppercase `X' and `P'. + * A | Equivalent to 'a', but use uppercase 'X' and 'P'. * * Field | Other Format * ------+-------------------------------------------------------------- @@ -287,7 +287,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * ---------+---------------+----------------------------------------- * space | bBdiouxX | Leave a space at the start of * | aAeEfgG | non-negative numbers. - * | (numeric fmt) | For `o', `x', `X', `b' and `B', use + * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use * | | a minus sign with absolute value for * | | negative values. * ---------+---------------+----------------------------------------- @@ -297,27 +297,27 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * | | sprintf string. * ---------+---------------+----------------------------------------- * # | bBoxX | Use an alternative format. - * | aAeEfgG | For the conversions `o', increase the precision - * | | until the first digit will be `0' if + * | aAeEfgG | For the conversions 'o', increase the precision + * | | until the first digit will be '0' if * | | it is not formatted as complements. - * | | For the conversions `x', `X', `b' and `B' - * | | on non-zero, prefix the result with ``0x'', - * | | ``0X'', ``0b'' and ``0B'', respectively. - * | | For `a', `A', `e', `E', `f', `g', and 'G', + * | | For the conversions 'x', 'X', 'b' and 'B' + * | | on non-zero, prefix the result with "0x", + * | | "0X", "0b" and "0B", respectively. + * | | For 'a', 'A', 'e', 'E', 'f', 'g', and 'G', * | | force a decimal point to be added, * | | even if no digits follow. - * | | For `g' and 'G', do not remove trailing zeros. + * | | For 'g' and 'G', do not remove trailing zeros. * ---------+---------------+----------------------------------------- * + | bBdiouxX | Add a leading plus sign to non-negative * | aAeEfgG | numbers. - * | (numeric fmt) | For `o', `x', `X', `b' and `B', use + * | (numeric fmt) | For 'o', 'x', 'X', 'b' and 'B', use * | | a minus sign with absolute value for * | | negative values. * ---------+---------------+----------------------------------------- * - | all | Left-justify the result of this conversion. * ---------+---------------+----------------------------------------- * 0 (zero) | bBdiouxX | Pad with zeros, not spaces. - * | aAeEfgG | For `o', `x', `X', `b' and `B', radix-1 + * | aAeEfgG | For 'o', 'x', 'X', 'b' and 'B', radix-1 * | (numeric fmt) | is used for negative numbers formatted as * | | complements. * ---------+---------------+----------------------------------------- @@ -328,21 +328,21 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * * Examples of flags: * - * # `+' and space flag specifies the sign of non-negative numbers. + * # '+' and space flag specifies the sign of non-negative numbers. * sprintf("%d", 123) #=> "123" * sprintf("%+d", 123) #=> "+123" * sprintf("% d", 123) #=> " 123" * - * # `#' flag for `o' increases number of digits to show `0'. - * # `+' and space flag changes format of negative numbers. + * # '#' flag for 'o' increases number of digits to show '0'. + * # '+' and space flag changes format of negative numbers. * sprintf("%o", 123) #=> "173" * sprintf("%#o", 123) #=> "0173" * sprintf("%+o", -123) #=> "-173" * sprintf("%o", -123) #=> "..7605" * sprintf("%#o", -123) #=> "..7605" * - * # `#' flag for `x' add a prefix `0x' for non-zero numbers. - * # `+' and space flag disables complements for negative numbers. + * # '#' flag for 'x' add a prefix '0x' for non-zero numbers. + * # '+' and space flag disables complements for negative numbers. * sprintf("%x", 123) #=> "7b" * sprintf("%#x", 123) #=> "0x7b" * sprintf("%+x", -123) #=> "-7b" @@ -350,12 +350,12 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * sprintf("%#x", -123) #=> "0x..f85" * sprintf("%#x", 0) #=> "0" * - * # `#' for `X' uses the prefix `0X'. + * # '#' for 'X' uses the prefix '0X'. * sprintf("%X", 123) #=> "7B" * sprintf("%#X", 123) #=> "0X7B" * - * # `#' flag for `b' add a prefix `0b' for non-zero numbers. - * # `+' and space flag disables complements for negative numbers. + * # '#' flag for 'b' add a prefix '0b' for non-zero numbers. + * # '+' and space flag disables complements for negative numbers. * sprintf("%b", 123) #=> "1111011" * sprintf("%#b", 123) #=> "0b1111011" * sprintf("%+b", -123) #=> "-1111011" @@ -363,19 +363,19 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * sprintf("%#b", -123) #=> "0b..10000101" * sprintf("%#b", 0) #=> "0" * - * # `#' for `B' uses the prefix `0B'. + * # '#' for 'B' uses the prefix '0B'. * sprintf("%B", 123) #=> "1111011" * sprintf("%#B", 123) #=> "0B1111011" * - * # `#' for `e' forces to show the decimal point. + * # '#' for 'e' forces to show the decimal point. * sprintf("%.0e", 1) #=> "1e+00" * sprintf("%#.0e", 1) #=> "1.e+00" * - * # `#' for `f' forces to show the decimal point. + * # '#' for 'f' forces to show the decimal point. * sprintf("%.0f", 1234) #=> "1234" * sprintf("%#.0f", 1234) #=> "1234." * - * # `#' for `g' forces to show the decimal point. + * # '#' for 'g' forces to show the decimal point. * # It also disables stripping lowest zeros. * sprintf("%g", 123.4) #=> "123.4" * sprintf("%#g", 123.4) #=> "123.400" @@ -409,7 +409,7 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * * Examples of precisions: * - * # precision for `d', 'o', 'x' and 'b' is + * # precision for 'd', 'o', 'x' and 'b' is * # minimum number of digits <------> * sprintf("%20.8d", 123) #=> " 00000123" * sprintf("%20.8o", 123) #=> " 00000173" @@ -420,8 +420,8 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * sprintf("%20.8x", -123) #=> " ..ffff85" * sprintf("%20.8b", -11) #=> " ..110101" * - * # "0x" and "0b" for `#x' and `#b' is not counted for - * # precision but "0" for `#o' is counted. <------> + * # "0x" and "0b" for '#x' and '#b' is not counted for + * # precision but "0" for '#o' is counted. <------> * sprintf("%#20.8d", 123) #=> " 00000123" * sprintf("%#20.8o", 123) #=> " 00000173" * sprintf("%#20.8x", 123) #=> " 0x0000007b" @@ -431,22 +431,22 @@ get_hash(mrb_state *mrb, mrb_value *hash, int argc, const mrb_value *argv) * sprintf("%#20.8x", -123) #=> " 0x..ffff85" * sprintf("%#20.8b", -11) #=> " 0b..110101" * - * # precision for `e' is number of + * # precision for 'e' is number of * # digits after the decimal point <------> * sprintf("%20.8e", 1234.56789) #=> " 1.23456789e+03" * - * # precision for `f' is number of + * # precision for 'f' is number of * # digits after the decimal point <------> * sprintf("%20.8f", 1234.56789) #=> " 1234.56789000" * - * # precision for `g' is number of + * # precision for 'g' is number of * # significant digits <-------> * sprintf("%20.8g", 1234.56789) #=> " 1234.5679" * * # <-------> * sprintf("%20.8g", 123456789) #=> " 1.2345679e+08" * - * # precision for `s' is + * # precision for 's' is * # maximum number of characters <------> * sprintf("%20.8s", "string test") #=> " string t" * @@ -539,7 +539,7 @@ mrb_str_format(mrb_state *mrb, int argc, const mrb_value *argv, mrb_value fmt) if (t >= end) goto sprint_exit; /* end of fmt string */ - p = t + 1; /* skip `%' */ + p = t + 1; /* skip '%' */ width = prec = -1; nextvalue = mrb_undef_value(); diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c index d2187a2d1..ce8d8d832 100644 --- a/mrbgems/mruby-struct/src/struct.c +++ b/mrbgems/mruby-struct/src/struct.c @@ -114,7 +114,7 @@ mrb_struct_getmember(mrb_state *mrb, mrb_value obj, mrb_sym id) return ptr[i]; } } - mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, id)); + mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, id)); return mrb_nil_value(); /* not reached */ } @@ -193,7 +193,7 @@ mrb_struct_set(mrb_state *mrb, mrb_value obj, mrb_value val) return ptr[i] = val; } } - mrb_raisef(mrb, E_INDEX_ERROR, "`%S' is not a struct member", mrb_sym2str(mrb, mid)); + mrb_raisef(mrb, E_INDEX_ERROR, "'%S' is not a struct member", mrb_sym2str(mrb, mid)); return mrb_nil_value(); /* not reached */ } @@ -749,8 +749,8 @@ mrb_struct_values_at(mrb_state *mrb, mrb_value self) * The Struct class is a generator of specific classes, * each one of which is defined to hold a set of variables and their * accessors. In these examples, we'll call the generated class - * ``CustomerClass,'' and we'll show an example instance of that - * class as ``CustomerInst.'' + * "CustomerClass," and we'll show an example instance of that + * class as "CustomerInst." * * In the descriptions that follow, the parameter symbol refers * to a symbol, which is either a quoted string or a diff --git a/mrblib/array.rb b/mrblib/array.rb index 83a42c62d..933f822db 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -146,7 +146,7 @@ class Array # equal, then that inequality is the return value. If all the # values found are equal, then the return is based on a # comparison of the array lengths. Thus, two arrays are - # ``equal'' according to Array#<=> if and only if they have + # "equal" according to Array#<=> if and only if they have # the same length and the value of each element is equal to the # value of the corresponding element in the other array. # diff --git a/src/class.c b/src/class.c index 05b549b3e..e9cbc592d 100644 --- a/src/class.c +++ b/src/class.c @@ -212,7 +212,7 @@ MRB_API struct RClass* mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super) { if (!super) { - mrb_warn(mrb, "no super class for `%S', Object assumed", mrb_sym2str(mrb, name)); + mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name)); } return define_class(mrb, name, super, mrb->object_class); } @@ -311,7 +311,7 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s #if 0 if (!super) { - mrb_warn(mrb, "no super class for `%S::%S', Object assumed", + mrb_warn(mrb, "no super class for '%S::%S', Object assumed", mrb_obj_value(outer), mrb_sym2str(mrb, id)); } #endif @@ -1658,7 +1658,7 @@ check_cv_name_str(mrb_state *mrb, mrb_value str) mrb_int len = RSTRING_LEN(str); if (len < 3 || !(s[0] == '@' && s[1] == '@')) { - mrb_name_error(mrb, mrb_intern_str(mrb, str), "`%S' is not allowed as a class variable name", str); + mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str); } } @@ -1846,7 +1846,7 @@ remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) } } - mrb_name_error(mrb, mid, "method `%S' not defined in %S", + mrb_name_error(mrb, mid, "method '%S' not defined in %S", mrb_sym2str(mrb, mid), mod); } diff --git a/src/numeric.c b/src/numeric.c index 8b6ec4c88..013273232 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -110,8 +110,8 @@ num_div(mrb_state *mrb, mrb_value x) * * Returns a string containing a representation of self. As well as a * fixed or exponential form of the number, the call may return - * ``NaN'', ``Infinity'', and - * ``-Infinity''. + * "NaN", "Infinity", and + * "-Infinity". */ static mrb_value diff --git a/src/object.c b/src/object.c index c5fb74575..f8f41bfe8 100644 --- a/src/object.c +++ b/src/object.c @@ -428,7 +428,7 @@ mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t) * Returns a string representing obj. The default * to_s prints the object's class and an encoding of the * object id. As a special case, the top-level object that is the - * initial execution context of Ruby programs returns ``main.'' + * initial execution context of Ruby programs returns "main." */ MRB_API mrb_value diff --git a/src/string.c b/src/string.c index 22a289ade..8df79d4c0 100644 --- a/src/string.c +++ b/src/string.c @@ -1100,7 +1100,7 @@ mrb_str_downcase_bang(mrb_state *mrb, mrb_value str) * * Returns a copy of str with all uppercase letters replaced with their * lowercase counterparts. The operation is locale insensitive---only - * characters ``A'' to ``Z'' are affected. + * characters 'A' to 'Z' are affected. * * "hEllO".downcase #=> "hello" */ @@ -1703,7 +1703,7 @@ mrb_str_rindex_m(mrb_state *mrb, mrb_value str) * * If pattern is omitted, the value of $; is used. If * $; is nil (which is the default), str is - * split on whitespace as if ` ' were specified. + * split on whitespace as if ' ' were specified. * * If the limit parameter is omitted, trailing null fields are * suppressed. If limit is a positive number, at most that number of @@ -2211,7 +2211,7 @@ mrb_str_upcase_bang(mrb_state *mrb, mrb_value str) * * Returns a copy of str with all lowercase letters replaced with their * uppercase counterparts. The operation is locale insensitive---only - * characters ``a'' to ``z'' are affected. + * characters 'a' to 'z' are affected. * * "hEllO".upcase #=> "HELLO" */ diff --git a/src/variable.c b/src/variable.c index 3e451df05..1b2ad56a7 100644 --- a/src/variable.c +++ b/src/variable.c @@ -563,7 +563,7 @@ 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_name_error(mrb, iv_name, "'%S' is not allowed as an instance variable name", mrb_sym2str(mrb, iv_name)); } } From a15e99d2b62127e05df50d6c9ba00d42e1de731f Mon Sep 17 00:00:00 2001 From: mattn Date: Thu, 25 Jun 2015 00:19:04 +0900 Subject: [PATCH 067/218] add_dependency doesn't work --- tasks/mrbgem_spec.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index e22a39e19..04a9c39f0 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -306,7 +306,7 @@ module MRuby g.dependencies.each do |dep| unless gem_table.key? dep[:gem] if dep[:default]; default_gems << dep - elsif File.exist? "#{root}/mrbgems/#{dep[:gem]}" # check core + elsif File.exist? "#{MRUBY_ROOT}/mrbgems/#{dep[:gem]}" # check core default_gems << { :gem => dep[:gem], :default => { :core => dep[:gem] } } else # fallback to mgem-list default_gems << { :gem => dep[:gem], :default => { :mgem => dep[:gem] } } From 427cc64de0d3db4fa4c03d14c2785c37f91da12b Mon Sep 17 00:00:00 2001 From: Franck Verrot Date: Fri, 26 Jun 2015 14:37:57 +0200 Subject: [PATCH 068/218] Respect the directory structure of `include` As mentioned in the README, two files have been put under the `mruby` directory. --- doc/api/README.md | 40 +++++++++++++++++----------------- doc/api/{ => mruby}/array.h.md | 0 doc/api/{ => mruby}/value.h.md | 0 3 files changed, 20 insertions(+), 20 deletions(-) rename doc/api/{ => mruby}/array.h.md (100%) rename doc/api/{ => mruby}/value.h.md (100%) diff --git a/doc/api/README.md b/doc/api/README.md index 131e50515..a83330d82 100644 --- a/doc/api/README.md +++ b/doc/api/README.md @@ -8,23 +8,23 @@ Header name|Features -----------|-------- [mrbconf.h](../mrbconf/README.md)|Defines macros for mruby configurations. [mruby.h](./mruby.h.md)|Main header of mruby C API. Include this first. -[mruby/array.h](./mruby.array.h.md)|`Array` class. -[mruby/class.h](./mruby.class.h.md)|`Class` class. -[mruby/compile.h](./mruby.compile.h.md)|mruby compiler. -[mruby/data.h](./mruby.data.h.md)|User defined object. -[mruby/debug.h](./mruby.debug.h.md)|Debugging. -[mruby/dump.h](./mruby.dump.h.md)|Dumping compiled mruby script. -[mruby/error.h](./mruby.error.h.md)|Error handling. -[mruby/gc.h](./mruby.gc.h.md)|Uncommon memory management stuffs. -[mruby/hash.h](./mruby.hash.h.md)|`Hash` class. -[mruby/irep.h](./mruby.irep.h.md)|Compiled mruby script. -[mruby/khash.h](./mruby.khash.h.md)|Defines of khash which is used in hash table of mruby. -[mruby/numeric.h](./mruby.numeric.h.md)|`Numeric` class and sub-classes of it. -[mruby/opode.h](./mruby.opcode.h.md)|Operation codes used in mruby VM. -[mruby/proc.h](./mruby.proc.h.md)|`Proc` class. -[mruby/range.h](./mruby.range.h.md)|`Range` class. -[mruby/re.h](./mruby.re.h.md)|`Regexp` class. -[mruby/string.h](./mruby.string.h.md)|`String` class. -[mruby/value.h](./mruby.value.h.md)|`mrb_value` functions and macros. -[mruby/variable.h](./mruby.variable.h.md)|Functions to access to mruby variables. -[mruby/version.h](./mruby.version.h.md)|Macros of mruby version. +[mruby/array.h](./mruby/array.h.md)|`Array` class. +[mruby/class.h](./mruby/class.h.md)|`Class` class. +[mruby/compile.h](./mruby/compile.h.md)|mruby compiler. +[mruby/data.h](./mruby/data.h.md)|User defined object. +[mruby/debug.h](./mruby/debug.h.md)|Debugging. +[mruby/dump.h](./mruby/dump.h.md)|Dumping compiled mruby script. +[mruby/error.h](./mruby/error.h.md)|Error handling. +[mruby/gc.h](./mruby/gc.h.md)|Uncommon memory management stuffs. +[mruby/hash.h](./mruby/hash.h.md)|`Hash` class. +[mruby/irep.h](./mruby/irep.h.md)|Compiled mruby script. +[mruby/khash.h](./mruby/khash.h.md)|Defines of khash which is used in hash table of mruby. +[mruby/numeric.h](./mruby/numeric.h.md)|`Numeric` class and sub-classes of it. +[mruby/opode.h](./mruby/opcode.h.md)|Operation codes used in mruby VM. +[mruby/proc.h](./mruby/proc.h.md)|`Proc` class. +[mruby/range.h](./mruby/range.h.md)|`Range` class. +[mruby/re.h](./mruby/re.h.md)|`Regexp` class. +[mruby/string.h](./mruby/string.h.md)|`String` class. +[mruby/value.h](./mruby/value.h.md)|`mrb_value` functions and macros. +[mruby/variable.h](./mruby/variable.h.md)|Functions to access to mruby variables. +[mruby/version.h](./mruby/version.h.md)|Macros of mruby version. diff --git a/doc/api/array.h.md b/doc/api/mruby/array.h.md similarity index 100% rename from doc/api/array.h.md rename to doc/api/mruby/array.h.md diff --git a/doc/api/value.h.md b/doc/api/mruby/value.h.md similarity index 100% rename from doc/api/value.h.md rename to doc/api/mruby/value.h.md From 449ec101f61a912f3b4b45e7378a18be784401a5 Mon Sep 17 00:00:00 2001 From: Thiago Scalone Date: Fri, 26 Jun 2015 14:22:09 -0300 Subject: [PATCH 069/218] =?UTF-8?q?Add=20=E2=80=94-recursive=20option=20to?= =?UTF-8?q?=20automatically=20update=20submodules=20from=20git=20mgems.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tasks/mruby_build_gem.rake | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index d9d2575bd..27d4f8886 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -91,6 +91,7 @@ module MRuby end else options = [params[:options]] || [] + options << "--recursive" options << "--branch \"#{branch}\"" options << "--depth 1" unless params[:checksum_hash] FileUtils.mkdir_p "#{gem_clone_dir}" From fa4b88b89316380750a3621261bf2909d15d3c3f Mon Sep 17 00:00:00 2001 From: Thiago Scalone Date: Fri, 26 Jun 2015 14:35:34 -0300 Subject: [PATCH 070/218] Fix quotes use during load special path gem of gem. --- tasks/mruby_build_gem.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index d9d2575bd..68de28761 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -71,7 +71,7 @@ module MRuby fail "unknown mgem protocol: #{conf['protocol']}" if conf['protocol'] != 'git' params[:git] = conf['repository'] - params[:branch] = conf['branch"] if conf["branch'] + params[:branch] = conf['branch'] if conf['branch'] end if params[:core] From c69d1201e1be22f28453dae212ba64346e02c0e2 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sat, 27 Jun 2015 23:58:43 +0900 Subject: [PATCH 071/218] Fix typo; Replace extensional with extended --- mrbgems/default.gembox | 20 ++++++++++---------- mrbgems/mruby-array-ext/mrbgem.rake | 2 +- mrbgems/mruby-enum-ext/mrbgem.rake | 2 +- mrbgems/mruby-hash-ext/mrbgem.rake | 2 +- mrbgems/mruby-kernel-ext/mrbgem.rake | 2 +- mrbgems/mruby-numeric-ext/mrbgem.rake | 2 +- mrbgems/mruby-object-ext/mrbgem.rake | 2 +- mrbgems/mruby-proc-ext/mrbgem.rake | 2 +- mrbgems/mruby-range-ext/mrbgem.rake | 2 +- mrbgems/mruby-string-ext/mrbgem.rake | 2 +- mrbgems/mruby-symbol-ext/mrbgem.rake | 2 +- 11 files changed, 20 insertions(+), 20 deletions(-) diff --git a/mrbgems/default.gembox b/mrbgems/default.gembox index 30dcc1abc..d18a49d81 100644 --- a/mrbgems/default.gembox +++ b/mrbgems/default.gembox @@ -14,34 +14,34 @@ MRuby::GemBox.new do |conf| # Use standard Struct class conf.gem :core => "mruby-struct" - # Use extensional Enumerable module + # Use extended Enumerable module conf.gem :core => "mruby-enum-ext" - # Use extensional String class + # Use extended String class conf.gem :core => "mruby-string-ext" - # Use extensional Numeric class + # Use extended Numeric class conf.gem :core => "mruby-numeric-ext" - # Use extensional Array class + # Use extended Array class conf.gem :core => "mruby-array-ext" - # Use extensional Hash class + # Use extended Hash class conf.gem :core => "mruby-hash-ext" - # Use extensional Range class + # Use extended Range class conf.gem :core => "mruby-range-ext" - # Use extensional Proc class + # Use extended Proc class conf.gem :core => "mruby-proc-ext" - # Use extensional Symbol class + # Use extended Symbol class conf.gem :core => "mruby-symbol-ext" # Use Random class conf.gem :core => "mruby-random" - # Use extensional Object class + # Use extended Object class conf.gem :core => "mruby-object-ext" # Use ObjectSpace class @@ -68,7 +68,7 @@ MRuby::GemBox.new do |conf| # Generate mruby-strip command conf.gem :core => "mruby-bin-strip" - # Use extensional Kernel module + # Use extended Kernel module conf.gem :core => "mruby-kernel-ext" # Use mruby-compiler to build other mrbgems diff --git a/mrbgems/mruby-array-ext/mrbgem.rake b/mrbgems/mruby-array-ext/mrbgem.rake index e4b5938c7..6d7e634fb 100644 --- a/mrbgems/mruby-array-ext/mrbgem.rake +++ b/mrbgems/mruby-array-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-array-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Array class' + spec.summary = 'extended Array class' end diff --git a/mrbgems/mruby-enum-ext/mrbgem.rake b/mrbgems/mruby-enum-ext/mrbgem.rake index 0c9d88fa2..33faad31a 100644 --- a/mrbgems/mruby-enum-ext/mrbgem.rake +++ b/mrbgems/mruby-enum-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-enum-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Enumerable module' + spec.summary = 'extended Enumerable module' end diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake index 663de2166..dcc279125 100644 --- a/mrbgems/mruby-hash-ext/mrbgem.rake +++ b/mrbgems/mruby-hash-ext/mrbgem.rake @@ -1,7 +1,7 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Hash class' + spec.summary = 'extended Hash class' spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' end diff --git a/mrbgems/mruby-kernel-ext/mrbgem.rake b/mrbgems/mruby-kernel-ext/mrbgem.rake index ab610c02b..a81e3aee7 100644 --- a/mrbgems/mruby-kernel-ext/mrbgem.rake +++ b/mrbgems/mruby-kernel-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Kernel module' + spec.summary = 'extended Kernel module' end diff --git a/mrbgems/mruby-numeric-ext/mrbgem.rake b/mrbgems/mruby-numeric-ext/mrbgem.rake index 3d8be7cd5..974848079 100644 --- a/mrbgems/mruby-numeric-ext/mrbgem.rake +++ b/mrbgems/mruby-numeric-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Numeric class' + spec.summary = 'extended Numeric class' end diff --git a/mrbgems/mruby-object-ext/mrbgem.rake b/mrbgems/mruby-object-ext/mrbgem.rake index 91a6e7ff1..df402d3ff 100644 --- a/mrbgems/mruby-object-ext/mrbgem.rake +++ b/mrbgems/mruby-object-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-object-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Object class' + spec.summary = 'extended Object class' end diff --git a/mrbgems/mruby-proc-ext/mrbgem.rake b/mrbgems/mruby-proc-ext/mrbgem.rake index 41d964bd9..0808d468e 100644 --- a/mrbgems/mruby-proc-ext/mrbgem.rake +++ b/mrbgems/mruby-proc-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-proc-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Proc class' + spec.summary = 'extended Proc class' end diff --git a/mrbgems/mruby-range-ext/mrbgem.rake b/mrbgems/mruby-range-ext/mrbgem.rake index bcf3de202..3c1543e6f 100644 --- a/mrbgems/mruby-range-ext/mrbgem.rake +++ b/mrbgems/mruby-range-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-range-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Range class' + spec.summary = 'extended Range class' end diff --git a/mrbgems/mruby-string-ext/mrbgem.rake b/mrbgems/mruby-string-ext/mrbgem.rake index 688589933..e2f1cd678 100644 --- a/mrbgems/mruby-string-ext/mrbgem.rake +++ b/mrbgems/mruby-string-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-string-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional String class' + spec.summary = 'extended String class' end diff --git a/mrbgems/mruby-symbol-ext/mrbgem.rake b/mrbgems/mruby-symbol-ext/mrbgem.rake index b937a0742..b188cd869 100644 --- a/mrbgems/mruby-symbol-ext/mrbgem.rake +++ b/mrbgems/mruby-symbol-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extensional Symbol class' + spec.summary = 'extended Symbol class' end From 4e4929bc727ea5ab4a90b8bf828ac6c1f1567ba6 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sun, 28 Jun 2015 11:15:24 +0900 Subject: [PATCH 072/218] Rename extended xxxx class or module to xxxx class or module extension --- mrbgems/default.gembox | 22 +++++++++++----------- mrbgems/mruby-array-ext/mrbgem.rake | 2 +- mrbgems/mruby-enum-ext/mrbgem.rake | 2 +- mrbgems/mruby-hash-ext/mrbgem.rake | 2 +- mrbgems/mruby-kernel-ext/mrbgem.rake | 2 +- mrbgems/mruby-numeric-ext/mrbgem.rake | 2 +- mrbgems/mruby-object-ext/mrbgem.rake | 2 +- mrbgems/mruby-proc-ext/mrbgem.rake | 2 +- mrbgems/mruby-range-ext/mrbgem.rake | 2 +- mrbgems/mruby-string-ext/mrbgem.rake | 2 +- mrbgems/mruby-symbol-ext/mrbgem.rake | 2 +- mrbgems/mruby-toplevel-ext/mrbgem.rake | 2 +- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/mrbgems/default.gembox b/mrbgems/default.gembox index d18a49d81..0960ba979 100644 --- a/mrbgems/default.gembox +++ b/mrbgems/default.gembox @@ -14,34 +14,34 @@ MRuby::GemBox.new do |conf| # Use standard Struct class conf.gem :core => "mruby-struct" - # Use extended Enumerable module + # Use Enumerable module extension conf.gem :core => "mruby-enum-ext" - # Use extended String class + # Use String class extension conf.gem :core => "mruby-string-ext" - # Use extended Numeric class + # Use Numeric class extension conf.gem :core => "mruby-numeric-ext" - # Use extended Array class + # Use Array class extension conf.gem :core => "mruby-array-ext" - # Use extended Hash class + # Use Hash class extension conf.gem :core => "mruby-hash-ext" - # Use extended Range class + # Use Range class extension conf.gem :core => "mruby-range-ext" - # Use extended Proc class + # Use Proc class extension conf.gem :core => "mruby-proc-ext" - # Use extended Symbol class + # Use Symbol class extension conf.gem :core => "mruby-symbol-ext" # Use Random class conf.gem :core => "mruby-random" - # Use extended Object class + # Use Object class extension conf.gem :core => "mruby-object-ext" # Use ObjectSpace class @@ -56,7 +56,7 @@ MRuby::GemBox.new do |conf| # Use Enumerable::Lazy class (require mruby-enumerator) conf.gem :core => "mruby-enum-lazy" - # Use extended toplevel object (main) methods + # Use toplevel object (main) methods extension conf.gem :core => "mruby-toplevel-ext" # Generate mirb command @@ -68,7 +68,7 @@ MRuby::GemBox.new do |conf| # Generate mruby-strip command conf.gem :core => "mruby-bin-strip" - # Use extended Kernel module + # Use Kernel module extension conf.gem :core => "mruby-kernel-ext" # Use mruby-compiler to build other mrbgems diff --git a/mrbgems/mruby-array-ext/mrbgem.rake b/mrbgems/mruby-array-ext/mrbgem.rake index 6d7e634fb..882caf1ab 100644 --- a/mrbgems/mruby-array-ext/mrbgem.rake +++ b/mrbgems/mruby-array-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-array-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Array class' + spec.summary = 'Array class extension' end diff --git a/mrbgems/mruby-enum-ext/mrbgem.rake b/mrbgems/mruby-enum-ext/mrbgem.rake index 33faad31a..d5816b80f 100644 --- a/mrbgems/mruby-enum-ext/mrbgem.rake +++ b/mrbgems/mruby-enum-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-enum-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Enumerable module' + spec.summary = 'Enumerable module extension' end diff --git a/mrbgems/mruby-hash-ext/mrbgem.rake b/mrbgems/mruby-hash-ext/mrbgem.rake index dcc279125..f01033a6c 100644 --- a/mrbgems/mruby-hash-ext/mrbgem.rake +++ b/mrbgems/mruby-hash-ext/mrbgem.rake @@ -1,7 +1,7 @@ MRuby::Gem::Specification.new('mruby-hash-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Hash class' + spec.summary = 'Hash class extension' spec.add_dependency 'mruby-enum-ext', :core => 'mruby-enum-ext' spec.add_dependency 'mruby-array-ext', :core => 'mruby-array-ext' end diff --git a/mrbgems/mruby-kernel-ext/mrbgem.rake b/mrbgems/mruby-kernel-ext/mrbgem.rake index a81e3aee7..fcb3a83b0 100644 --- a/mrbgems/mruby-kernel-ext/mrbgem.rake +++ b/mrbgems/mruby-kernel-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-kernel-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Kernel module' + spec.summary = 'Kernel module extension' end diff --git a/mrbgems/mruby-numeric-ext/mrbgem.rake b/mrbgems/mruby-numeric-ext/mrbgem.rake index 974848079..6db7e589e 100644 --- a/mrbgems/mruby-numeric-ext/mrbgem.rake +++ b/mrbgems/mruby-numeric-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-numeric-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Numeric class' + spec.summary = 'Numeric class extension' end diff --git a/mrbgems/mruby-object-ext/mrbgem.rake b/mrbgems/mruby-object-ext/mrbgem.rake index df402d3ff..6d14b4a51 100644 --- a/mrbgems/mruby-object-ext/mrbgem.rake +++ b/mrbgems/mruby-object-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-object-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Object class' + spec.summary = 'Object class extension' end diff --git a/mrbgems/mruby-proc-ext/mrbgem.rake b/mrbgems/mruby-proc-ext/mrbgem.rake index 0808d468e..e4d15a140 100644 --- a/mrbgems/mruby-proc-ext/mrbgem.rake +++ b/mrbgems/mruby-proc-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-proc-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Proc class' + spec.summary = 'Proc class extension' end diff --git a/mrbgems/mruby-range-ext/mrbgem.rake b/mrbgems/mruby-range-ext/mrbgem.rake index 3c1543e6f..e6fa7df5f 100644 --- a/mrbgems/mruby-range-ext/mrbgem.rake +++ b/mrbgems/mruby-range-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-range-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Range class' + spec.summary = 'Range class extension' end diff --git a/mrbgems/mruby-string-ext/mrbgem.rake b/mrbgems/mruby-string-ext/mrbgem.rake index e2f1cd678..f2df5a783 100644 --- a/mrbgems/mruby-string-ext/mrbgem.rake +++ b/mrbgems/mruby-string-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-string-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended String class' + spec.summary = 'String class extension' end diff --git a/mrbgems/mruby-symbol-ext/mrbgem.rake b/mrbgems/mruby-symbol-ext/mrbgem.rake index b188cd869..4f3fa43bb 100644 --- a/mrbgems/mruby-symbol-ext/mrbgem.rake +++ b/mrbgems/mruby-symbol-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-symbol-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended Symbol class' + spec.summary = 'Symbol class extension' end diff --git a/mrbgems/mruby-toplevel-ext/mrbgem.rake b/mrbgems/mruby-toplevel-ext/mrbgem.rake index eb6951f6c..ce77e0bcf 100644 --- a/mrbgems/mruby-toplevel-ext/mrbgem.rake +++ b/mrbgems/mruby-toplevel-ext/mrbgem.rake @@ -1,5 +1,5 @@ MRuby::Gem::Specification.new('mruby-toplevel-ext') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'extended toplevel object (main) methods' + spec.summary = 'toplevel object (main) methods extension' end From a41f5eb23fad13ce8037050b7a2331c1c7dd9e6f Mon Sep 17 00:00:00 2001 From: Jurriaan Pruis Date: Sun, 28 Jun 2015 13:30:03 +0200 Subject: [PATCH 073/218] Fix segfault found using afl-fuzz --- mrbgems/mruby-compiler/core/codegen.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index d2eeef203..cefde8b7b 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -2652,13 +2652,17 @@ loop_break(codegen_scope *s, node *tree) } loop = s->loop; - while (loop->type == LOOP_BEGIN) { + while (loop && loop->type == LOOP_BEGIN) { genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); loop = loop->prev; } - while (loop->type == LOOP_RESCUE) { + while (loop && loop->type == LOOP_RESCUE) { loop = loop->prev; } + if (!loop) { + codegen_error(s, "unexpected break"); + } + if (loop->type == LOOP_NORMAL) { int tmp; From 52db92de53a9af1adbac9e116bd19aeecd2485c1 Mon Sep 17 00:00:00 2001 From: Kouhei Sutou Date: Mon, 29 Jun 2015 14:39:30 +0900 Subject: [PATCH 074/218] Fix a crash bug when GC is ran while creating a proc with env mrb_proc_new_cfunc_with_env() allocates RProc with RProc::env as NULL then allocates REnv and sets it to RProc::env of the allocated RProc. If incremental GC is ran before "allocates REnv and sets it to RProc::env of the allocated RProc", the allocated RProc's GC status is "marked" (Black) and the allocated REnv's GC status is "unmarked" (White). The next incremental GC sweeps the allocated REnv without re-marking the allocated RProc. Because the RProc is Black and the REnv is White. We need to implement write barrier for the case. We can force to cause the above situation by the following patch: diff --git a/src/proc.c b/src/proc.c index f98998f..4f4e25c 100644 --- a/src/proc.c +++ b/src/proc.c @@ -92,6 +92,7 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const struct REnv *e; int i; + mrb_incremental_gc(mrb); p->env = e = env_new(mrb, argc); MRB_ENV_UNSHARE_STACK(e); e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); With this patch, "rake test" causes segmentation fault. --- src/proc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/proc.c b/src/proc.c index f98998f68..8a2b6bbb6 100644 --- a/src/proc.c +++ b/src/proc.c @@ -93,6 +93,7 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t func, mrb_int argc, const int i; p->env = e = env_new(mrb, argc); + mrb_field_write_barrier(mrb, (struct RBasic *)p, (struct RBasic *)p->env); MRB_ENV_UNSHARE_STACK(e); e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); if (argv) { From d6865a9cc76c67b39bb29def7a62f9b9f752363c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20G=C3=A9nier?= Date: Mon, 29 Jun 2015 13:37:16 -0400 Subject: [PATCH 075/218] Avoid a narrowing cast in flo_round under MRB_INT64. --- src/numeric.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/numeric.c b/src/numeric.c index 013273232..b9aef51d9 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -436,7 +436,7 @@ flo_round(mrb_state *mrb, mrb_value num) { double number, f; mrb_int ndigits = 0; - int i; + mrb_int i; mrb_get_args(mrb, "|i", &ndigits); number = mrb_float(num); @@ -451,7 +451,7 @@ flo_round(mrb_state *mrb, mrb_value num) } f = 1.0; - i = abs(ndigits); + i = ndigits >= 0 ? ndigits : -ndigits; while (--i >= 0) f = f*10.0; From a4f63caa7947c049ad310e9e5016404b377ebe6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 2 Jul 2015 20:47:22 +0200 Subject: [PATCH 076/218] Fix incorrect memory allocation of mrdb_state_new. As detected in a Coverity scan. https://scan8.coverity.com/reports.htm#v26153/p11375/fileInstanceId=6844472&defectInstanceId=2516000&mergedDefectId=75866 --- mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c index da235fad8..3e43fdb4a 100755 --- a/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c +++ b/mrbgems/mruby-bin-debugger/tools/mrdb/mrdb.c @@ -222,9 +222,9 @@ mrb_debug_context_free(mrb_state *mrb) static mrdb_state* mrdb_state_new(mrb_state *mrb) { - mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrb_state)); + mrdb_state *mrdb = mrb_malloc(mrb, sizeof(mrdb_state)); - memset(mrdb, 0, sizeof(mrb_state)); + memset(mrdb, 0, sizeof(mrdb_state)); mrdb->dbg = mrb_debug_context_get(mrb); mrdb->command = mrb_malloc(mrb, MAX_COMMAND_LINE+1); From 6a74b8bf0dd55441b87077f97e90ba29252edc53 Mon Sep 17 00:00:00 2001 From: cremno Date: Thu, 2 Jul 2015 22:11:21 +0200 Subject: [PATCH 077/218] add missing fall through comments --- mrbgems/mruby-compiler/core/parse.y | 2 ++ mrbgems/mruby-string-utf8/src/string.c | 1 + 2 files changed, 3 insertions(+) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index f6a43d32b..64f0a8821 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -4802,6 +4802,7 @@ parser_yylex(parser_state *p) case ')': case ']': p->paren_nest--; + /* fall through */ case '}': COND_LEXPOP(); CMDARG_LEXPOP(); @@ -5133,6 +5134,7 @@ parser_yylex(parser_state *p) pushback(p, c); return '$'; } + /* fall through */ case '0': tokadd(p, '$'); } diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c index e21101df9..25a638ea3 100644 --- a/mrbgems/mruby-string-utf8/src/string.c +++ b/mrbgems/mruby-string-utf8/src/string.c @@ -259,6 +259,7 @@ mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx) switch (mrb_type(indx)) { case MRB_TT_FLOAT: indx = mrb_flo_to_fixnum(mrb, indx); + /* fall through */ case MRB_TT_FIXNUM: idx = mrb_fixnum(indx); From 43df1d7e3937162dd406dafeab79cd54dea13762 Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 3 Jul 2015 01:14:06 +0200 Subject: [PATCH 078/218] remove unnecessary default case --- src/dump.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index d9410ec18..2f2e5edcb 100644 --- a/src/dump.c +++ b/src/dump.c @@ -819,7 +819,6 @@ write_rite_binary_header(mrb_state *mrb, size_t binary_size, uint8_t *bin, uint8 uint32_t offset; switch (flags & DUMP_ENDIAN_NAT) { - default: endian_big: case DUMP_ENDIAN_BIG: memcpy(header->binary_ident, RITE_BINARY_IDENT, sizeof(header->binary_ident)); From 24583a7a1806dd1845700e12e8b0b823688e9879 Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 3 Jul 2015 01:30:54 +0200 Subject: [PATCH 079/218] fix oob write by actually truncating buffer Found by Coverity scan of polyfox-moon: CID 121927 (#1 of 1): Out-of-bounds write (OVERRUN) --- mrbgems/mruby-compiler/core/parse.y | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index f6a43d32b..26062967d 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -3604,10 +3604,13 @@ toklast(parser_state *p) static void tokfix(parser_state *p) { - if (p->bidx >= MRB_PARSER_BUF_SIZE) { + int i = p->bidx, imax = MRB_PARSER_BUF_SIZE - 1; + + if (i > imax) { + i = imax; yyerror(p, "string too long (truncated)"); } - p->buf[p->bidx] = '\0'; + p->buf[i] = '\0'; } static const char* From 7206a8c4f91bd54390b6e244d6a32f9766b8e05f Mon Sep 17 00:00:00 2001 From: cremno Date: Fri, 3 Jul 2015 02:48:22 +0200 Subject: [PATCH 080/218] fix dangling pointer CID 75872 (#3-2 of 3): Pointer to local outside scope (RETURN_LOCAL) 38. use_invalid: Using p, which points to an out-of-scope variable buf. --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 8df79d4c0..757317bdc 100644 --- a/src/string.c +++ b/src/string.c @@ -2057,6 +2057,7 @@ MRB_API double mrb_cstr_to_dbl(mrb_state *mrb, const char * p, mrb_bool badcheck) { char *end; + char buf[DBL_DIG * 4 + 10]; double d; enum {max_width = 20}; @@ -2077,7 +2078,6 @@ bad: return d; } if (*end) { - char buf[DBL_DIG * 4 + 10]; char *n = buf; char *e = buf + sizeof(buf) - 1; char prev = 0; From 03ae38df4e18c33e6ce4f5614bd4ec7b1ba9f192 Mon Sep 17 00:00:00 2001 From: Anton Davydov Date: Sun, 5 Jul 2015 13:49:37 +0300 Subject: [PATCH 081/218] Fix typo in comment in String#mrb_cstr_to_inum [skip ci] --- src/string.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/string.c b/src/string.c index 8df79d4c0..57b5eef9a 100644 --- a/src/string.c +++ b/src/string.c @@ -1927,7 +1927,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) } break; } /* end of switch (base) { */ - if (*str == '0') { /* squeeze preceeding 0s */ + if (*str == '0') { /* squeeze preceding 0s */ uscore = 0; while ((c = *++str) == '0' || c == '_') { if (c == '_') { From 0b50b4a5005c3233b88b09f196034352ebdfc515 Mon Sep 17 00:00:00 2001 From: xuejianqing Date: Mon, 6 Jul 2015 12:51:57 +0800 Subject: [PATCH 082/218] fix androideabi cross-compile error : undefined reference to 'frexpl' --- src/fmt_fp.c | 9 +++------ tasks/toolchains/androideabi.rake | 4 ++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/fmt_fp.c b/src/fmt_fp.c index a634edb34..b467435a3 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -90,12 +90,9 @@ fmt_u(uint32_t x, char *s) typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -#if (defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__) -static long double -frexpl (long double x, int *eptr) -{ - return frexp(x, eptr); -} +#if ((defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__)) || defined(__android__) +#undef frexpl +#define frexpl frexp #endif static int diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake index 61881ca31..7cdb9e43a 100644 --- a/tasks/toolchains/androideabi.rake +++ b/tasks/toolchains/androideabi.rake @@ -109,8 +109,8 @@ MRuby::Toolchain.new(:androideabi) do |conf| ANDROID_CC = path_to_toolchain + '/bin/' + toolchain_prefix + 'gcc' ANDROID_LD = path_to_toolchain + '/bin/' + toolchain_prefix + 'gcc' ANDROID_AR = path_to_toolchain + '/bin/' + toolchain_prefix + 'ar' - ANDROID_CFLAGS = GCC_COMMON_CFLAGS + %W(-mandroid --sysroot="#{SYSROOT}") + ARCH_CFLAGS - ANDROID_LDFLAGS = GCC_COMMON_LDFLAGS + %W(-mandroid --sysroot="#{SYSROOT}") + ARCH_LDFLAGS + ANDROID_CFLAGS = GCC_COMMON_CFLAGS + %W(-D__android__ -mandroid --sysroot="#{SYSROOT}") + ARCH_CFLAGS + ANDROID_LDFLAGS = GCC_COMMON_LDFLAGS + %W(-D__android__ -mandroid --sysroot="#{SYSROOT}") + ARCH_LDFLAGS when 'clang' then # clang is not supported yet. when 'clang31', 'clang3.1' then From 40252169fc9762f222106f116f2bcc510b038bf9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 7 Jul 2015 10:32:37 +0900 Subject: [PATCH 083/218] method_missing definition may be undefined; fix #2878 --- src/vm.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/vm.c b/src/vm.c index 1f3b05df2..15a3926e3 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1074,9 +1074,14 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &c, mid); if (!m) { mrb_value sym = mrb_symbol_value(mid); + mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); - mid = mrb_intern_lit(mrb, "method_missing"); - m = mrb_method_search_vm(mrb, &c, mid); + m = mrb_method_search_vm(mrb, &c, missing); + if (!m) { + mrb_no_method_error(mrb, mid, n, regs+a+1, + "undefined method '%S' for %S", mrb_sym2str(mrb, mid), recv); + } + mid = missing; if (n == CALL_MAXARGS) { mrb_ary_unshift(mrb, regs[a+1], sym); } From 2523ed473af8d9e97c641f7263286d1af40a69a3 Mon Sep 17 00:00:00 2001 From: Mav7 Date: Wed, 8 Jul 2015 04:50:01 -0400 Subject: [PATCH 084/218] Added new markdowns. --- doc/api/mruby/hash.h.md | 0 doc/api/mruby/range.h.md | 0 doc/api/mruby/string.h.md | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/mruby/hash.h.md create mode 100644 doc/api/mruby/range.h.md create mode 100644 doc/api/mruby/string.h.md diff --git a/doc/api/mruby/hash.h.md b/doc/api/mruby/hash.h.md new file mode 100644 index 000000000..e69de29bb diff --git a/doc/api/mruby/range.h.md b/doc/api/mruby/range.h.md new file mode 100644 index 000000000..e69de29bb diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md new file mode 100644 index 000000000..e69de29bb From 82380780db07e9d776d3d7983a229a114f30ecb8 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Wed, 8 Jul 2015 05:35:37 -0400 Subject: [PATCH 085/218] Update hash.h.md --- doc/api/mruby/hash.h.md | 96 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/doc/api/mruby/hash.h.md b/doc/api/mruby/hash.h.md index e69de29bb..1d713d59e 100644 --- a/doc/api/mruby/hash.h.md +++ b/doc/api/mruby/hash.h.md @@ -0,0 +1,96 @@ +### mrb_hash_new + +```C +mrb_value mrb_hash_new(mrb_state *mrb); +``` + +Initializes a hash. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example initializes a hash. In pure Ruby doing this is equivalent +to Hash.new. + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +``` Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` + +### mrb_hash_set + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable. + mrb_sym hash_key = mrb_intern_cstr(mrb, "da_key"); // Declare a symbol. + mrb_int hash_value = 80; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key), mrb_fixnum_value(hash_value)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` + +#### Result + +After compiling you should get these results. + +```Ruby +{:da_key=>80} +Hash +``` + + From 1167fd1ae440aa2b2b3d2cee5cb5a266d83f46e8 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Wed, 8 Jul 2015 18:25:52 +0900 Subject: [PATCH 086/218] use round for llround. some platform (ex: mingw32) doesn't have llround. --- mrbgems/mruby-time/src/time.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mrbgems/mruby-time/src/time.c b/mrbgems/mruby-time/src/time.c index 081e84c1c..c18ac7568 100644 --- a/mrbgems/mruby-time/src/time.c +++ b/mrbgems/mruby-time/src/time.c @@ -11,6 +11,10 @@ #include "mruby/class.h" #include "mruby/data.h" +#if !defined(__MINGW64__) && defined(_WIN32) +# define llround(x) round(x) +#endif + #if defined(__MINGW64__) || defined(__MINGW32__) # include #endif From bdbd696c486f88a2239420a027f7e1772713bbe0 Mon Sep 17 00:00:00 2001 From: jbreeden Date: Sat, 11 Jul 2015 21:03:04 -0700 Subject: [PATCH 087/218] Patching array join --- src/array.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/array.c b/src/array.c index f48719310..ff0bb8a85 100644 --- a/src/array.c +++ b/src/array.c @@ -295,7 +295,7 @@ mrb_ary_plus(mrb_state *mrb, mrb_value self) mrb_get_args(mrb, "a", &ptr, &blen); if (ARY_MAX_SIZE - blen < a1->len) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } a2 = ary_new_capa(mrb, a1->len + blen); array_copy(a2->ptr, a1->ptr, a1->len); @@ -349,7 +349,7 @@ mrb_ary_times(mrb_state *mrb, mrb_value self) } if (times == 0) return mrb_ary_new(mrb); if (ARY_MAX_SIZE / times < a1->len) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } a2 = ary_new_capa(mrb, a1->len * times); ptr = a2->ptr; @@ -1031,7 +1031,13 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) { mrb_value sep = mrb_nil_value(); - mrb_get_args(mrb, "|S", &sep); + mrb_get_args(mrb, "|o", &sep); + if (mrb_nil_p(sep)) { + sep = mrb_str_to_str(mrb, sep); + } else if (mrb_type(sep) != MRB_TT_STRING) { + mrb_raise(mrb, E_TYPE_ERROR, "expected String"); + return mrb_nil_value(); + } return mrb_ary_join(mrb, ary, sep); } From dd558a108d20d2198cb52cf743e2ecfc868cfa1c Mon Sep 17 00:00:00 2001 From: jbreeden Date: Sat, 11 Jul 2015 21:15:33 -0700 Subject: [PATCH 088/218] Removing unndeeded to_s --- src/array.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/array.c b/src/array.c index ff0bb8a85..2fb662c92 100644 --- a/src/array.c +++ b/src/array.c @@ -1032,9 +1032,7 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) mrb_value sep = mrb_nil_value(); mrb_get_args(mrb, "|o", &sep); - if (mrb_nil_p(sep)) { - sep = mrb_str_to_str(mrb, sep); - } else if (mrb_type(sep) != MRB_TT_STRING) { + if (!(mrb_nil_p(sep) || mrb_type(sep) == MRB_TT_STRING)) { mrb_raise(mrb, E_TYPE_ERROR, "expected String"); return mrb_nil_value(); } From 9c311ddc938ad2cc88e4119374e47cd496e15a94 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Jul 2015 07:08:01 +0900 Subject: [PATCH 089/218] refactor mrb_bob_missing to share raising NoMethodError code; fix #2878 Note: arguments of mrb_no_method_error() has changed. You need to replace 3rd and 4th argument (say n, argv) to mrb_ary_new_from_values(mrb, n, argv). --- include/mruby/error.h | 2 +- src/class.c | 45 +++++++++++++++++++++++++------------------ src/error.c | 5 ++--- src/vm.c | 13 +++++++++++-- 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/include/mruby/error.h b/include/mruby/error.h index 52f6772bd..282be0a24 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -24,7 +24,7 @@ MRB_API mrb_value mrb_exc_new_str(mrb_state *mrb, struct RClass* c, mrb_value st MRB_API mrb_value mrb_make_exception(mrb_state *mrb, int argc, const mrb_value *argv); MRB_API mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc); MRB_API mrb_value mrb_get_backtrace(mrb_state *mrb); -MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, const char *fmt, ...); +MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, const char *fmt, ...); /* declaration for fail method */ MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); diff --git a/src/class.c b/src/class.c index e9cbc592d..0f9a77b2a 100644 --- a/src/class.c +++ b/src/class.c @@ -1262,6 +1262,31 @@ mrb_bob_not(mrb_state *mrb, mrb_value cv) return mrb_bool_value(!mrb_test(cv)); } +void +mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) +{ + mrb_sym inspect; + mrb_value repr; + + inspect = mrb_intern_lit(mrb, "inspect"); + if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { + /* method missing in inspect; avoid recursion */ + repr = mrb_any_to_s(mrb, self); + } + else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 64) { + repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); + if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { + repr = mrb_any_to_s(mrb, self); + } + } + else { + repr = mrb_any_to_s(mrb, self); + } + + mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", + mrb_sym2str(mrb, name), repr); +} + /* 15.3.1.3.30 */ /* * call-seq: @@ -1301,27 +1326,9 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod) mrb_sym name; mrb_value *a; mrb_int alen; - mrb_sym inspect; - mrb_value repr; mrb_get_args(mrb, "n*", &name, &a, &alen); - - inspect = mrb_intern_lit(mrb, "inspect"); - if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { - /* method missing in inspect; avoid recursion */ - repr = mrb_any_to_s(mrb, mod); - } - else if (mrb_respond_to(mrb, mod, inspect) && mrb->c->ci - mrb->c->cibase < 64) { - repr = mrb_funcall_argv(mrb, mod, inspect, 0, 0); - if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { - repr = mrb_any_to_s(mrb, mod); - } - } - else { - repr = mrb_any_to_s(mrb, mod); - } - - mrb_no_method_error(mrb, name, alen, a, "undefined method '%S' for %S", mrb_sym2str(mrb, name), repr); + mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); /* not reached */ return mrb_nil_value(); } diff --git a/src/error.c b/src/error.c index a800f77f9..20c63bd43 100644 --- a/src/error.c +++ b/src/error.c @@ -424,15 +424,14 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg) } MRB_API mrb_noreturn void -mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_int argc, const mrb_value *argv, char const* fmt, ...) +mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_value args, char const* fmt, ...) { mrb_value exc; va_list ap; va_start(ap, fmt); exc = mrb_funcall(mrb, mrb_obj_value(E_NOMETHOD_ERROR), "new", 3, - mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), - mrb_ary_new_from_values(mrb, argc, argv)); + mrb_vformat(mrb, fmt, ap), mrb_symbol_value(id), args); va_end(ap); mrb_exc_raise(mrb, exc); } diff --git a/src/vm.c b/src/vm.c index 15a3926e3..22ea177e0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -723,6 +723,8 @@ argnum_error(mrb_state *mrb, mrb_int num) #define CALL_MAXARGS 127 +void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args); + MRB_API mrb_value mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep) { @@ -1078,8 +1080,15 @@ RETRY_TRY_BLOCK: m = mrb_method_search_vm(mrb, &c, missing); if (!m) { - mrb_no_method_error(mrb, mid, n, regs+a+1, - "undefined method '%S' for %S", mrb_sym2str(mrb, mid), recv); + mrb_value args; + + if (n == CALL_MAXARGS) { + args = regs[a+1]; + } + else { + args = mrb_ary_new_from_values(mrb, n, regs+a+1); + } + mrb_method_missing(mrb, mid, recv, args); } mid = missing; if (n == CALL_MAXARGS) { From 02474daa14623f3ee24a5235e9b7b88c33d43455 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Jul 2015 11:14:50 +0900 Subject: [PATCH 090/218] allow '!' after 'S' specifier of mrb_get_args() that allow nil. thus "S!" means String|nil type. you have to check nil before dereferencing the value. this is added to address #2882 while keeping code simplicity. besides that current #2882 fix lose polymorphism provided by mrb_get_args(). --- src/class.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index 0f9a77b2a..8a9fdaca6 100644 --- a/src/class.c +++ b/src/class.c @@ -435,7 +435,7 @@ to_sym(mrb_state *mrb, mrb_value ss) ---------------------------------------------------------------------------------------------- o: Object [mrb_value] C: class/module [mrb_value] - S: String [mrb_value] + S: String [mrb_value] when ! follows the value may be nil A: Array [mrb_value] H: Hash [mrb_value] s: String [char*,mrb_int] Receive two arguments. @@ -525,6 +525,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value *p; p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (mrb_nil_p(*sp)) { + *p = *sp++; + i++; + break; + } + } if (i < argc) { *p = to_str(mrb, *sp++); i++; From d0e67aada795620c2bce49db8c73e87718753614 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 13 Jul 2015 11:18:44 +0900 Subject: [PATCH 091/218] use "S!" specifier of mrb_get_args() to improve #2882 fix. --- src/array.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/array.c b/src/array.c index 2fb662c92..0a99040c0 100644 --- a/src/array.c +++ b/src/array.c @@ -1031,11 +1031,7 @@ mrb_ary_join_m(mrb_state *mrb, mrb_value ary) { mrb_value sep = mrb_nil_value(); - mrb_get_args(mrb, "|o", &sep); - if (!(mrb_nil_p(sep) || mrb_type(sep) == MRB_TT_STRING)) { - mrb_raise(mrb, E_TYPE_ERROR, "expected String"); - return mrb_nil_value(); - } + mrb_get_args(mrb, "|S!", &sep); return mrb_ary_join(mrb, ary, sep); } From f962890a928b566c0f5ca7fdff5ef4ce19207e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Thu, 9 Jul 2015 23:46:54 +0200 Subject: [PATCH 092/218] Implement Module#prepend. --- include/mruby/class.h | 1 + src/class.c | 67 +++++++++++++++++++++++++++++++++++++++++-- test/t/module.rb | 33 +++++++++++++++++++++ 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/include/mruby/class.h b/include/mruby/class.h index 9d5260a24..60310ae9d 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -16,6 +16,7 @@ struct RClass { struct iv_tbl *iv; struct kh_mt *mt; struct RClass *super; + struct RClass *origin; }; #define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v))) diff --git a/src/class.c b/src/class.c index 8a9fdaca6..3b1ea2321 100644 --- a/src/class.c +++ b/src/class.c @@ -194,6 +194,7 @@ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass * if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { c = class_from_sym(mrb, outer, name); + c = c->origin; if (super && mrb_class_real(c->super) != super) { mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", mrb_sym2str(mrb, name), @@ -763,12 +764,13 @@ boot_defclass(mrb_state *mrb, struct RClass *super) else { c->super = mrb->object_class; } + c->origin = c; c->mt = kh_init(mt, mrb); return c; } -MRB_API void -mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) +MRB_API inline void +include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *m, int search_super) { struct RClass *ins_pos; @@ -782,6 +784,7 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) } while (p) { if (c != p && p->tt == MRB_TT_CLASS) { + if (!search_super) break; superclass_seen = 1; } else if (p->mt == m->mt) { @@ -810,6 +813,63 @@ mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) } } +MRB_API void +mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) +{ + include_module_at(mrb, c, m, FALSE); +} + +MRB_API void +mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) +{ + struct RClass *origin; + int changed = 0; + + origin = c->origin; + if (origin == c) { + origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); + //OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */ + origin->super = c->super; + c->super = origin; + c->origin = origin; + origin->mt = c->mt; + c->mt = kh_init(mt, mrb); + } + include_module_at(mrb, c, m, FALSE); // changed = + if (changed) { + //rb_vm_check_redefinition_by_prepend(klass); + } +} + +static mrb_value +mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod) +{ + mrb_value klass; + + mrb_check_type(mrb, mod, MRB_TT_MODULE); + mrb_get_args(mrb, "C", &klass); + mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); + return mod; +} + +static mrb_value +mrb_mod_prepend(mrb_state *mrb, mrb_value klass) +{ + mrb_value *argv; + mrb_int argc, i; + + mrb_get_args(mrb, "*", &argv, &argc); + for (i=0; i Date: Fri, 10 Jul 2015 20:17:16 +0200 Subject: [PATCH 093/218] Rename classes because of conflicts --- test/t/module.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 9faaf6e2c..3c87c122b 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -491,18 +491,18 @@ assert('Module#prepend') do def m1; [:M4, super, :M4] end end - class C0 + class P0 include M0 prepend M1 def m1; [:C0, super, :C0] end end - class C1 < C0 + class P1 < P0 prepend M2, M3 include M4 def m1; [:C1, super, :C1] end end - obj = C1.new + obj = P1.new expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2] assert_equal(expected, obj.m1) end From ad9f32c5a876d5f230584b3c9abe77833943e6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 10 Jul 2015 21:00:14 +0200 Subject: [PATCH 094/218] Expose insert position, which should be at origin for include and klass for prepend. --- src/class.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/class.c b/src/class.c index 3b1ea2321..c1d377e86 100644 --- a/src/class.c +++ b/src/class.c @@ -770,11 +770,8 @@ boot_defclass(mrb_state *mrb, struct RClass *super) } MRB_API inline void -include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *m, int search_super) +include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) { - struct RClass *ins_pos; - - ins_pos = c; while (m) { struct RClass *p = c, *ic; int superclass_seen = 0; @@ -816,7 +813,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *m, int search MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) { - include_module_at(mrb, c, m, FALSE); + include_module_at(mrb, c, c->origin, m, FALSE); } MRB_API void @@ -835,7 +832,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) origin->mt = c->mt; c->mt = kh_init(mt, mrb); } - include_module_at(mrb, c, m, FALSE); // changed = + include_module_at(mrb, c, c, m, FALSE); // changed = if (changed) { //rb_vm_check_redefinition_by_prepend(klass); } From 2e617e37e134b428ce7a979446cc2d768d1cf2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 10 Jul 2015 21:14:28 +0200 Subject: [PATCH 095/218] origin must be initialized --- src/class.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/class.c b/src/class.c index c1d377e86..9f21ae395 100644 --- a/src/class.c +++ b/src/class.c @@ -76,6 +76,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) if (o->c->tt == MRB_TT_SCLASS) return; sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); + sc->origin = sc; sc->mt = 0; sc->iv = 0; if (o->tt == MRB_TT_CLASS) { @@ -799,6 +800,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru else { ic->c = m; } + ic->origin = ic; ic->mt = m->mt; ic->iv = m->iv; ic->super = ins_pos->super; @@ -825,6 +827,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) origin = c->origin; if (origin == c) { origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); + origin->origin = origin; //OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */ origin->super = c->super; c->super = origin; @@ -1547,6 +1550,7 @@ MRB_API struct RClass* mrb_module_new(mrb_state *mrb) { struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); + m->origin = m; m->mt = kh_init(mt, mrb); return m; From 97529c2a9a7b75a838234a420bbe2c6dc59c56ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Fri, 10 Jul 2015 22:01:07 +0200 Subject: [PATCH 096/218] Comment in a refactor to match MRI, but that fails 320 tests. --- src/class.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index 9f21ae395..ca4582041 100644 --- a/src/class.c +++ b/src/class.c @@ -776,11 +776,25 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru while (m) { struct RClass *p = c, *ic; int superclass_seen = 0; - + + //if (m->origin != m) + // goto skip; if (c->mt && c->mt == m->mt) { mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); } while (p) { + /*if (p->tt == MRB_TT_ICLASS) { + if (!superclass_seen) { + ins_pos = p; // move insert point + } + goto skip; + } else if (p->tt == MRB_TT_CLASS) { + if (p->mt == m->mt) { + if (!search_super) break; + superclass_seen = 1; + } + }*/ + // if (c != p && p->tt == MRB_TT_CLASS) { if (!search_super) break; superclass_seen = 1; From 005cacf18b8ce2cf854872aa8cb803819478a47d Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 11:15:18 +0200 Subject: [PATCH 097/218] Additional patches to make this work --- src/class.c | 129 ++++++++++++++++++++++++++++----------------------- src/kernel.c | 12 +++++ 2 files changed, 83 insertions(+), 58 deletions(-) diff --git a/src/class.c b/src/class.c index ca4582041..73e6687c0 100644 --- a/src/class.c +++ b/src/class.c @@ -325,9 +325,16 @@ mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, s MRB_API void mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) { - khash_t(mt) *h = c->mt; + khash_t(mt) *h; khiter_t k; + if (!c->origin) { + printf("Warning, class %s does not have valid origin\n", mrb_class_name(mrb, c)); + mrb_raisef(mrb, E_RUNTIME_ERROR, "Invalid origin"); + c->origin = c; + } + h = c->origin->mt; + if (!h) h = c->mt = kh_init(mt, mrb); k = kh_put(mt, mrb, h, mid); kh_value(h, k) = p; @@ -758,6 +765,7 @@ boot_defclass(mrb_state *mrb, struct RClass *super) struct RClass *c; c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); + c->origin = c; if (super) { c->super = super; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); @@ -765,71 +773,74 @@ boot_defclass(mrb_state *mrb, struct RClass *super) else { c->super = mrb->object_class; } - c->origin = c; c->mt = kh_init(mt, mrb); return c; } -MRB_API inline void -include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) +static struct RClass* +include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) { - while (m) { - struct RClass *p = c, *ic; + struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); + if (m->tt == MRB_TT_ICLASS) { + m = m->c; + } + ic->origin = ic; + ic->iv = m->iv; + ic->mt = m->origin->mt; + ic->super = super; + if (m->tt == MRB_TT_ICLASS) { + ic->c = m->c; + } else { + ic->c = m; + } + return ic; +} + +MRB_API int +include_module_at(mrb_state *mrb, struct RClass *klass, struct RClass *c, struct RClass *module, int search_super) +{ + struct RClass *p, *iclass; + void *klass_mt = klass->origin->mt; + + while (module) { int superclass_seen = 0; - - //if (m->origin != m) - // goto skip; - if (c->mt && c->mt == m->mt) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); - } - while (p) { - /*if (p->tt == MRB_TT_ICLASS) { - if (!superclass_seen) { - ins_pos = p; // move insert point + + if (module->origin != module) + goto skip; + + if (klass_mt && klass_mt == module->mt) + return -1; + + p = klass->super; + while(p) { + if (p->tt == MRB_TT_ICLASS) { + if (p->mt == module->mt) { + if (!superclass_seen) { + c = p; // move insert point + } + goto skip; } - goto skip; } else if (p->tt == MRB_TT_CLASS) { - if (p->mt == m->mt) { - if (!search_super) break; - superclass_seen = 1; - } - }*/ - // - if (c != p && p->tt == MRB_TT_CLASS) { if (!search_super) break; superclass_seen = 1; } - else if (p->mt == m->mt) { - if (p->tt == MRB_TT_ICLASS && !superclass_seen) { - ins_pos = p; - } - goto skip; - } p = p->super; } - ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); - if (m->tt == MRB_TT_ICLASS) { - ic->c = m->c; - } - else { - ic->c = m; - } - ic->origin = ic; - ic->mt = m->mt; - ic->iv = m->iv; - ic->super = ins_pos->super; - ins_pos->super = ic; - mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); - ins_pos = ic; + + iclass = include_class_new(mrb, module, c->super); + c->super = iclass; + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)c->super); + c = iclass; skip: - m = m->super; + module = module->super; } + return 0; } MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) { - include_module_at(mrb, c, c->origin, m, FALSE); + include_module_at(mrb, c, c->origin, m, 1); } MRB_API void @@ -842,16 +853,16 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) if (origin == c) { origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); origin->origin = origin; - //OBJ_WB_UNPROTECT(origin); /* TODO: conservative shading. Need more survey. */ origin->super = c->super; c->super = origin; c->origin = origin; origin->mt = c->mt; c->mt = kh_init(mt, mrb); + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)c->origin); } - include_module_at(mrb, c, c, m, FALSE); // changed = - if (changed) { - //rb_vm_check_redefinition_by_prepend(klass); + changed = include_module_at(mrb, c, c, m, 0); + if (changed < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected"); } } @@ -955,15 +966,12 @@ mrb_mod_ancestors(mrb_state *mrb, mrb_value self) { mrb_value result; struct RClass *c = mrb_class_ptr(self); - result = mrb_ary_new(mrb); - mrb_ary_push(mrb, result, mrb_obj_value(c)); - c = c->super; while (c) { if (c->tt == MRB_TT_ICLASS) { mrb_ary_push(mrb, result, mrb_obj_value(c->c)); } - else if (c->tt != MRB_TT_SCLASS) { + else if (c->origin == c) { mrb_ary_push(mrb, result, mrb_obj_value(c)); } c = c->super; @@ -1005,9 +1013,14 @@ mrb_mod_initialize(mrb_state *mrb, mrb_value mod) { mrb_value b; + /* hack, fix missing module->origin */ + struct RClass *m = mrb_class_ptr(mod); + if (!m->origin) + m->origin = m; + mrb_get_args(mrb, "&", &b); if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &mod, mod, mrb_class_ptr(mod)); + mrb_yield_with_class(mrb, b, 1, &mod, mod, m); } return mod; } @@ -1324,9 +1337,9 @@ mrb_class_superclass(mrb_state *mrb, mrb_value klass) struct RClass *c; c = mrb_class_ptr(klass); - c = c->super; + c = c->origin->super; while (c && c->tt == MRB_TT_ICLASS) { - c = c->super; + c = c->origin->super; } if (!c) return mrb_nil_value(); return mrb_obj_value(c); @@ -1925,7 +1938,7 @@ static void remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) { struct RClass *c = mrb_class_ptr(mod); - khash_t(mt) *h = c->mt; + khash_t(mt) *h = c->origin->mt; khiter_t k; if (h) { diff --git a/src/kernel.c b/src/kernel.c index b5b13f874..bafab6e76 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -248,6 +248,11 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); } + if (klass->origin != klass) + clone->origin = klass->origin; + else + clone->origin = clone; + clone->super = klass->super; if (klass->iv) { mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); @@ -269,6 +274,13 @@ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) { struct RClass *dc = mrb_class_ptr(dst); struct RClass *sc = mrb_class_ptr(src); + /* if the origin is not the same as the class, then the origin and + the current class need to be copied */ + if (sc->origin != sc) { + dc->origin = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(sc->origin))); + } else { + dc->origin = dc; + } dc->mt = kh_copy(mt, mrb, sc->mt); dc->super = sc->super; } From ce6672717706365929b1c2c3c2c278e75a3c4be4 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 08:16:04 -0500 Subject: [PATCH 098/218] Remove some remnant debug code --- src/class.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/class.c b/src/class.c index 73e6687c0..e9df1dae4 100644 --- a/src/class.c +++ b/src/class.c @@ -327,12 +327,6 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro { khash_t(mt) *h; khiter_t k; - - if (!c->origin) { - printf("Warning, class %s does not have valid origin\n", mrb_class_name(mrb, c)); - mrb_raisef(mrb, E_RUNTIME_ERROR, "Invalid origin"); - c->origin = c; - } h = c->origin->mt; if (!h) h = c->mt = kh_init(mt, mrb); From 40f48034d512a8e4f24f8d67373f18093e96513c Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 08:25:43 -0500 Subject: [PATCH 099/218] Added changed check to the mrb_include_module --- src/class.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index e9df1dae4..4a64e5b23 100644 --- a/src/class.c +++ b/src/class.c @@ -834,7 +834,10 @@ include_module_at(mrb_state *mrb, struct RClass *klass, struct RClass *c, struct MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) { - include_module_at(mrb, c, c->origin, m, 1); + int changed = include_module_at(mrb, c, c->origin, m, 1); + if (changed < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); + } } MRB_API void From d4b009b394d3933ee1b828d0e91d3c6aaa522339 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 11:09:13 -0500 Subject: [PATCH 100/218] Fixed Modules not being fully initialized before #initialize was called --- src/class.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/class.c b/src/class.c index 4a64e5b23..d83216cb4 100644 --- a/src/class.c +++ b/src/class.c @@ -77,7 +77,7 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) if (o->c->tt == MRB_TT_SCLASS) return; sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); sc->origin = sc; - sc->mt = 0; + sc->mt = kh_init(mt, mrb); sc->iv = 0; if (o->tt == MRB_TT_CLASS) { c = (struct RClass*)o; @@ -771,6 +771,13 @@ boot_defclass(mrb_state *mrb, struct RClass *super) return c; } +static void +boot_initmod(mrb_state *mrb, struct RClass *mod) +{ + mod->origin = mod; + mod->mt = kh_init(mt, mrb); +} + static struct RClass* include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) { @@ -1012,10 +1019,8 @@ mrb_mod_initialize(mrb_state *mrb, mrb_value mod) /* hack, fix missing module->origin */ struct RClass *m = mrb_class_ptr(mod); - if (!m->origin) - m->origin = m; - - mrb_get_args(mrb, "&", &b); + boot_initmod(mrb, m); // bootstrap a newly initialized module + mrb_get_args(mrb, "|&", &b); if (!mrb_nil_p(b)) { mrb_yield_with_class(mrb, b, 1, &mod, mod, m); } @@ -1574,9 +1579,7 @@ MRB_API struct RClass* mrb_module_new(mrb_state *mrb) { struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); - m->origin = m; - m->mt = kh_init(mt, mrb); - + boot_initmod(mrb, m); return m; } From 99aff17075905738a8e45d8b213b92a291588053 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 11:09:52 -0500 Subject: [PATCH 101/218] Ported a bit more of the MRI Module#prepend tests over Currently kind_of fails miserably, still looking for the reason --- test/t/module.rb | 94 ++++++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 26 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 3c87c122b..6fa22e8b4 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -474,38 +474,80 @@ end # Not ISO specified +# @!group prepend assert('Module#prepend') do - module M0 - def m1; [:M0] end - end - module M1 - def m1; [:M1, super, :M1] end - end - module M2 - def m1; [:M2, super, :M2] end - end - M3 = Module.new do - def m1; [:M3, super, :M3] end - end - module M4 - def m1; [:M4, super, :M4] end + assert('test_prepend') do + module M0 + def m1; [:M0] end + end + module M1 + def m1; [:M1, super, :M1] end + end + module M2 + def m1; [:M2, super, :M2] end + end + M3 = Module.new do + def m1; [:M3, super, :M3] end + end + module M4 + def m1; [:M4, super, :M4] end + end + + class P0 + include M0 + prepend M1 + def m1; [:C0, super, :C0] end + end + class P1 < P0 + prepend M2, M3 + include M4 + def m1; [:C1, super, :C1] end + end + + obj = P1.new + expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2] + assert_equal(expected, obj.m1) end - class P0 - include M0 - prepend M1 - def m1; [:C0, super, :C0] end - end - class P1 < P0 - prepend M2, M3 - include M4 - def m1; [:C1, super, :C1] end + # mruby shouldn't be affected by this since there is + # no visibility control (yet) + assert('test_public_prepend') do + assert_nothing_raised('ruby/ruby #8846') do + Class.new.prepend(Module.new) + end end - obj = P1.new - expected = [:M2,[:M3,[:C1,[:M4,[:M1,[:C0,[:M0],:C0],:M1],:M4],:C1],:M3],:M2] - assert_equal(expected, obj.m1) + assert('test_prepend_inheritance') do + bug6654 = '[ruby-core:45914]' + a = Module.new + b = Module.new { include a } + c = Module.new { prepend b } + + assert bug6654 do + # the Module#< operator should be used here instead, but we don't have it + assert_include(c.ancestors, a) + assert_include(c.ancestors, b) + end + + bug8357 = '[ruby-core:54736] [Bug #8357]' + b = Module.new { prepend a } + c = Class.new { include b } + + assert bug8357 do + # the Module#< operator should be used here instead, but we don't have it + assert_include(c.ancestors, a) + assert_include(c.ancestors, b) + end + + bug8357 = '[ruby-core:54742] [Bug #8357]' + t_print c.new.kind_of?(b) + t_print "\n" + t_print [b, b.ancestors, c, c.ancestors].inspect + t_print "\n" + assert_kind_of(b, c.new, bug8357) + end end +# @!endgroup prepend assert('Module#to_s') do module Test4to_sModules From 319553f0ef310b4f098773db713e7fcee18f69be Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 11:11:12 -0500 Subject: [PATCH 102/218] Removed some debug prints from the test --- test/t/module.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 6fa22e8b4..5baaadd2e 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -540,10 +540,6 @@ assert('Module#prepend') do end bug8357 = '[ruby-core:54742] [Bug #8357]' - t_print c.new.kind_of?(b) - t_print "\n" - t_print [b, b.ancestors, c, c.ancestors].inspect - t_print "\n" assert_kind_of(b, c.new, bug8357) end end From 47264bf2898fbfa5cae6709074b5e5564dbbe99c Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Sat, 11 Jul 2015 11:32:20 -0500 Subject: [PATCH 103/218] Ported all MRI prepend tests And of course, some of them fail miserably --- test/t/module.rb | 231 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 226 insertions(+), 5 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 5baaadd2e..7314d140f 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -1,6 +1,26 @@ ## # Module ISO Test +def labeled_module(name, &block) + Module.new do + singleton_class.class_eval do + define_method(:to_s) { name } + alias_method :inspect, :to_s + end + class_eval(&block) if block + end +end + +def labeled_class(name, supklass = Object, &block) + Class.new(supklass) do + singleton_class.class_eval do + define_method(:to_s) { name } + alias_method :inspect, :to_s + end + class_eval(&block) if block + end +end + assert('Module', '15.2.2') do assert_equal Class, Module.class end @@ -519,9 +539,9 @@ assert('Module#prepend') do assert('test_prepend_inheritance') do bug6654 = '[ruby-core:45914]' - a = Module.new - b = Module.new { include a } - c = Module.new { prepend b } + a = labeled_module('a') + b = labeled_module('b') { include a } + c = labeled_module('c') { prepend b } assert bug6654 do # the Module#< operator should be used here instead, but we don't have it @@ -530,8 +550,8 @@ assert('Module#prepend') do end bug8357 = '[ruby-core:54736] [Bug #8357]' - b = Module.new { prepend a } - c = Class.new { include b } + b = labeled_module('b') { prepend a } + c = labeled_class('c') { include b } assert bug8357 do # the Module#< operator should be used here instead, but we don't have it @@ -542,6 +562,207 @@ assert('Module#prepend') do bug8357 = '[ruby-core:54742] [Bug #8357]' assert_kind_of(b, c.new, bug8357) end + + assert('test_prepend_instance_methods') do + bug6655 = '[ruby-core:45915]' + assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655) + end + + assert 'test_prepend_singleton_methods' do + o = Object.new + o.singleton_class.class_eval {prepend Module.new} + assert_equal([], o.singleton_methods) + end + + assert 'test_prepend_remove_method' do + c = Class.new do + prepend Module.new { def foo; end } + end + assert_raise(NameError) do + c.class_eval do + remove_method(:foo) + end + end + c.class_eval do + def foo; end + end + removed = nil + c.singleton_class.class_eval do + define_method(:method_removed) {|id| removed = id} + end + assert_nothing_raised(NoMethodError, NameError, '[Bug #7843]') do + c.class_eval do + remove_method(:foo) + end + end + assert_equal(:foo, removed) + end + + assert 'test_prepend_class_ancestors' do + bug6658 = '[ruby-core:45919]' + m = labeled_module("m") + c = labeled_class("c") {prepend m} + assert_equal([m, c], c.ancestors[0, 2], bug6658) + + bug6662 = '[ruby-dev:45868]' + c2 = labeled_class("c2", c) + anc = c2.ancestors + assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662) + end + + # this assertion causes the mrbtest to segfault + #assert 'test_prepend_module_ancestors' do + # bug6659 = '[ruby-dev:45861]' + # m0 = labeled_module("m0") { def x; [:m0, *super] end } + # m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } + # m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 } + # c0 = labeled_class("c0") { def x; [:c0] end } + # c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 } + # c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 } + # # + # assert_equal([m0, m1], m1.ancestors, bug6659) + # # + # bug6662 = '[ruby-dev:45868]' + # assert_equal([m0, m1, m2], m2.ancestors, bug6662) + # assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662) + # assert_equal([:m0, :m1, :m2, :c1], c1.new.x) + # assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662) + # assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x) + # # + # m3 = labeled_module("m3") { include m1; prepend m1 } + # assert_equal([m3, m0, m1], m3.ancestors) + # m3 = labeled_module("m3") { prepend m1; include m1 } + # assert_equal([m0, m1, m3], m3.ancestors) + # m3 = labeled_module("m3") { prepend m1; prepend m1 } + # assert_equal([m0, m1, m3], m3.ancestors) + # m3 = labeled_module("m3") { include m1; include m1 } + # assert_equal([m3, m0, m1], m3.ancestors) + #end + + assert 'test_prepend_instance_methods_false' do + bug6660 = '[ruby-dev:45863]' + assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660) + assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660) + end + + assert 'test_cyclic_prepend' do + bug7841 = '[ruby-core:52205] [Bug #7841]' + m1 = Module.new + m2 = Module.new + m1.instance_eval { prepend(m2) } + assert_raise(ArgumentError, bug7841) do + m2.instance_eval { prepend(m1) } + end + end + + # these assertions will not run without a #assert_seperately method + #assert 'test_prepend_optmethod' do + # bug7983 = '[ruby-dev:47124] [Bug #7983]' + # assert_separately [], %{ + # module M + # def /(other) + # to_f / other + # end + # end + # Fixnum.send(:prepend, M) + # assert_equal(0.5, 1 / 2, "#{bug7983}") + # } + # assert_equal(0, 1 / 2) + #end + + #assert 'test_prepend_visibility' do + # bug8005 = '[ruby-core:53106] [Bug #8005]' + # c = Class.new do + # prepend Module.new {} + # def foo() end + # protected :foo + # end + # a = c.new + # assert_respond_to a, [:foo, true], bug8005 + # assert_nothing_raised(NoMethodError, bug8005) {a.send :foo} + #end + + #assert 'test_prepend_visibility_inherited' do + # bug8238 = '[ruby-core:54105] [Bug #8238]' + # assert_separately [], <<-"end;", timeout: 20 + # class A + # def foo() A; end + # private :foo + # end + # class B < A + # public :foo + # prepend Module.new + # end + # assert_equal(A, B.new.foo, "#{bug8238}") + # end; + #end + + assert 'test_prepend_included_modules' do + bug8025 = '[ruby-core:53158] [Bug #8025]' + mixin = labeled_module("mixin") + c = labeled_module("c") {prepend mixin} + im = c.included_modules + assert_not_include(im, c, bug8025) + assert_include(im, mixin, bug8025) + c1 = labeled_class("c1") {prepend mixin} + c2 = labeled_class("c2", c1) + im = c2.included_modules + assert_not_include(im, c1, bug8025) + assert_not_include(im, c2, bug8025) + assert_include(im, mixin, bug8025) + end + + assert 'test_prepend_super_in_alias' do + bug7842 = '[Bug #7842]' + + p = labeled_module("P") do + def m; "P"+super; end + end + a = labeled_class("A") do + def m; "A"; end + end + b = labeled_class("B", a) do + def m; "B"+super; end + alias m2 m + prepend p + alias m3 m + end + assert_equal("BA", b.new.m2, bug7842) + assert_equal("PBA", b.new.m3, bug7842) + end + + assert 'test_prepend_each_classes' do + m = labeled_module("M") + c1 = labeled_class("C1") {prepend m} + c2 = labeled_class("C2", c1) {prepend m} + assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each classes") + end + + assert 'test_prepend_no_duplication' do + m = labeled_module("M") + c = labeled_class("C") {prepend m; prepend m} + assert_equal([m, c], c.ancestors[0, 2], "should never duplicate") + end + + assert 'test_prepend_in_superclass' do + m = labeled_module("M") + c1 = labeled_class("C1") + c2 = labeled_class("C2", c1) {prepend m} + c1.class_eval {prepend m} + assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should accesisble prepended module in superclass") + end + + # requires #assert_seperately + #assert 'test_prepend_call_super' do + # assert_separately([], <<-'end;') #do + # bug10847 = '[ruby-core:68093] [Bug #10847]' + # module M; end + # Float.prepend M + # assert_nothing_raised(SystemStackError, bug10847) do + # 0.3.numerator + # end + # end; + #end end # @!endgroup prepend From a725cb909333335ad178997795e84c332e555c65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 12 Jul 2015 22:07:16 +0200 Subject: [PATCH 104/218] Include prepended methods in the instance_methods list. --- src/kernel.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/kernel.c b/src/kernel.c index bafab6e76..36ad683ee 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -653,13 +653,19 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl { khint_t i; mrb_value ary; + mrb_bool prepended; struct RClass* oldklass; khash_t(st)* set = kh_init(st, mrb); + if (!recur && klass->origin != klass) { + klass = klass->origin; + prepended = 1; + } + oldklass = 0; while (klass && (klass != oldklass)) { method_entry_loop(mrb, klass, set); - if ((klass->tt == MRB_TT_ICLASS) || + if ((klass->tt == MRB_TT_ICLASS && !prepended) || (klass->tt == MRB_TT_SCLASS)) { } else { From 11dad715784a61174b68fba57f6dc6c5311e22e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Sun, 12 Jul 2015 22:57:29 +0200 Subject: [PATCH 105/218] Enable visibility prepend tests again --- test/t/module.rb | 52 +++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 25 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 7314d140f..89cc257a6 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -670,32 +670,34 @@ assert('Module#prepend') do # assert_equal(0, 1 / 2) #end - #assert 'test_prepend_visibility' do - # bug8005 = '[ruby-core:53106] [Bug #8005]' - # c = Class.new do - # prepend Module.new {} - # def foo() end - # protected :foo - # end - # a = c.new - # assert_respond_to a, [:foo, true], bug8005 - # assert_nothing_raised(NoMethodError, bug8005) {a.send :foo} - #end + # mruby has no visibility control + assert 'test_prepend_visibility' do + bug8005 = '[ruby-core:53106] [Bug #8005]' + c = Class.new do + prepend Module.new {} + def foo() end + protected :foo + end + a = c.new + assert_true a.respond_to?(:foo), bug8005 + assert_nothing_raised(NoMethodError, bug8005) {a.send :foo} + end - #assert 'test_prepend_visibility_inherited' do - # bug8238 = '[ruby-core:54105] [Bug #8238]' - # assert_separately [], <<-"end;", timeout: 20 - # class A - # def foo() A; end - # private :foo - # end - # class B < A - # public :foo - # prepend Module.new - # end - # assert_equal(A, B.new.foo, "#{bug8238}") - # end; - #end + # mruby has no visibility control + assert 'test_prepend_visibility_inherited' do + bug8238 = '[ruby-core:54105] [Bug #8238]' + module Test4PrependVisibilityInherited + class A + def foo() A; end + private :foo + end + class B < A + public :foo + prepend Module.new + end + end + assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}") + end assert 'test_prepend_included_modules' do bug8025 = '[ruby-core:53158] [Bug #8025]' From 668153092f48275279f85d2618fff6eb9730332c Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Mon, 13 Jul 2015 09:38:24 -0500 Subject: [PATCH 106/218] Added Module#method_removed hook --- src/class.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/class.c b/src/class.c index d83216cb4..0b00a6484 100644 --- a/src/class.c +++ b/src/class.c @@ -1945,6 +1945,7 @@ remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) k = kh_get(mt, mrb, h, mid); if (k != kh_end(h)) { kh_del(mt, mrb, h, k); + mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid)); return; } } @@ -2197,6 +2198,7 @@ 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, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); /* 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()); From 1f678a4acefc14531a2ed25c33f62a0d628b1474 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Mon, 13 Jul 2015 09:40:40 -0500 Subject: [PATCH 107/218] Removed comment beside method_removed Not sure if this apart of the ISO standard, so make sure its not misrepresented --- src/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index 0b00a6484..a13da63ac 100644 --- a/src/class.c +++ b/src/class.c @@ -2198,7 +2198,7 @@ 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, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.41 */ + mrb_define_method(mrb, mod, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); 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()); From 199a808e36197bd6f893112bbd43f18f2c25345f Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Mon, 13 Jul 2015 09:49:18 -0500 Subject: [PATCH 108/218] Bugfix, included_modules would include classes --- src/class.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index a13da63ac..5450f3a20 100644 --- a/src/class.c +++ b/src/class.c @@ -1004,7 +1004,9 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self) result = mrb_ary_new(mrb); while (c) { if (c->tt == MRB_TT_ICLASS) { - mrb_ary_push(mrb, result, mrb_obj_value(c->c)); + if (c->c->tt == MRB_TT_MODULE) { + mrb_ary_push(mrb, result, mrb_obj_value(c->c)); + } } c = c->super; } From 81a2b3431c63c969f73e6c0eeaa968acbace0e44 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Mon, 13 Jul 2015 09:49:51 -0500 Subject: [PATCH 109/218] included_modules, origin fix Prepended modules would include their origin ICLASS --- src/class.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index 5450f3a20..cde5736e0 100644 --- a/src/class.c +++ b/src/class.c @@ -1000,10 +1000,11 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self) { mrb_value result; struct RClass *c = mrb_class_ptr(self); + struct RClass *origin = c->origin; result = mrb_ary_new(mrb); while (c) { - if (c->tt == MRB_TT_ICLASS) { + if (c != origin && c->tt == MRB_TT_ICLASS) { if (c->c->tt == MRB_TT_MODULE) { mrb_ary_push(mrb, result, mrb_obj_value(c->c)); } From 11cb41770dc7b36edac0af1e6784bd40d1c8243c Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Mon, 13 Jul 2015 10:42:33 -0500 Subject: [PATCH 110/218] Space out test_prepend_super_in_alias assert Also tried to fix it, however the problem lies with how aliased methods are done and their internal structure. mruby simply aliases methods by grabbing the RProc and giving it a new name, super then determines the original method to call by using the name so a method called m, aliased as m2, will call the m2 super method instead of m --- test/t/module.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 89cc257a6..605ca28a7 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -720,17 +720,25 @@ assert('Module#prepend') do p = labeled_module("P") do def m; "P"+super; end end + a = labeled_class("A") do def m; "A"; end end + b = labeled_class("B", a) do def m; "B"+super; end alias m2 m prepend p alias m3 m end - assert_equal("BA", b.new.m2, bug7842) - assert_equal("PBA", b.new.m3, bug7842) + + assert_nothing_raised do + assert_equal("BA", b.new.m2, bug7842) + end + + assert_nothing_raised do + assert_equal("PBA", b.new.m3, bug7842) + end end assert 'test_prepend_each_classes' do From b0fb9ccfd8cb5986ea153142687cfbed1a876d6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 13 Jul 2015 23:25:01 +0200 Subject: [PATCH 111/218] Enable test_prepend_module_ancestors because it seems to pass. --- test/t/module.rb | 54 ++++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 605ca28a7..7b4a8fec7 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -611,33 +611,33 @@ assert('Module#prepend') do end # this assertion causes the mrbtest to segfault - #assert 'test_prepend_module_ancestors' do - # bug6659 = '[ruby-dev:45861]' - # m0 = labeled_module("m0") { def x; [:m0, *super] end } - # m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } - # m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 } - # c0 = labeled_class("c0") { def x; [:c0] end } - # c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 } - # c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 } - # # - # assert_equal([m0, m1], m1.ancestors, bug6659) - # # - # bug6662 = '[ruby-dev:45868]' - # assert_equal([m0, m1, m2], m2.ancestors, bug6662) - # assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662) - # assert_equal([:m0, :m1, :m2, :c1], c1.new.x) - # assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662) - # assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x) - # # - # m3 = labeled_module("m3") { include m1; prepend m1 } - # assert_equal([m3, m0, m1], m3.ancestors) - # m3 = labeled_module("m3") { prepend m1; include m1 } - # assert_equal([m0, m1, m3], m3.ancestors) - # m3 = labeled_module("m3") { prepend m1; prepend m1 } - # assert_equal([m0, m1, m3], m3.ancestors) - # m3 = labeled_module("m3") { include m1; include m1 } - # assert_equal([m3, m0, m1], m3.ancestors) - #end + assert 'test_prepend_module_ancestors' do + bug6659 = '[ruby-dev:45861]' + m0 = labeled_module("m0") { def x; [:m0, *super] end } + m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } + m2 = labeled_module("m2") { def x; [:m2, *super] end; prepend m1 } + c0 = labeled_class("c0") { def x; [:c0] end } + c1 = labeled_class("c1") { def x; [:c1] end; prepend m2 } + c2 = labeled_class("c2", c0) { def x; [:c2, *super] end; include m2 } + # + assert_equal([m0, m1], m1.ancestors, bug6659) + # + bug6662 = '[ruby-dev:45868]' + assert_equal([m0, m1, m2], m2.ancestors, bug6662) + assert_equal([m0, m1, m2, c1], c1.ancestors[0, 4], bug6662) + assert_equal([:m0, :m1, :m2, :c1], c1.new.x) + assert_equal([c2, m0, m1, m2, c0], c2.ancestors[0, 5], bug6662) + assert_equal([:c2, :m0, :m1, :m2, :c0], c2.new.x) + # + m3 = labeled_module("m3") { include m1; prepend m1 } + assert_equal([m3, m0, m1], m3.ancestors) + m3 = labeled_module("m3") { prepend m1; include m1 } + assert_equal([m0, m1, m3], m3.ancestors) + m3 = labeled_module("m3") { prepend m1; prepend m1 } + assert_equal([m0, m1, m3], m3.ancestors) + m3 = labeled_module("m3") { include m1; include m1 } + assert_equal([m3, m0, m1], m3.ancestors) + end assert 'test_prepend_instance_methods_false' do bug6660 = '[ruby-dev:45863]' From 8c13e2b7c6e6c1c02771e4f9e5aebda109892503 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 13 Jul 2015 23:35:30 +0200 Subject: [PATCH 112/218] Set origin when doing kind_of? comparisons --- src/object.c | 1 + test/t/module.rb | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/object.c b/src/object.c index f8f41bfe8..c834ee04f 100644 --- a/src/object.c +++ b/src/object.c @@ -487,6 +487,7 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) mrb_raise(mrb, E_TYPE_ERROR, "class or module required"); } + c = c->origin; while (cl) { if (cl == c || cl->mt == c->mt) return TRUE; diff --git a/test/t/module.rb b/test/t/module.rb index 7b4a8fec7..a1996f5f6 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -543,21 +543,21 @@ assert('Module#prepend') do b = labeled_module('b') { include a } c = labeled_module('c') { prepend b } - assert bug6654 do + #assert bug6654 do # the Module#< operator should be used here instead, but we don't have it assert_include(c.ancestors, a) assert_include(c.ancestors, b) - end + #end bug8357 = '[ruby-core:54736] [Bug #8357]' b = labeled_module('b') { prepend a } c = labeled_class('c') { include b } - assert bug8357 do + #assert bug8357 do # the Module#< operator should be used here instead, but we don't have it assert_include(c.ancestors, a) assert_include(c.ancestors, b) - end + #end bug8357 = '[ruby-core:54742] [Bug #8357]' assert_kind_of(b, c.new, bug8357) From 8c4da7accd98fb36e3f1f5f9e4ea069244345858 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 13 Jul 2015 23:38:37 +0200 Subject: [PATCH 113/218] assert() cannot be nested --- test/t/module.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index a1996f5f6..5aba53c46 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -495,7 +495,6 @@ end # Not ISO specified # @!group prepend -assert('Module#prepend') do assert('test_prepend') do module M0 def m1; [:M0] end @@ -773,7 +772,6 @@ assert('Module#prepend') do # end # end; #end -end # @!endgroup prepend assert('Module#to_s') do From 78462c9181ccbc92d26a466c5a3f06aec2d2f714 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bla=C5=BE=20Hrastnik?= Date: Mon, 13 Jul 2015 23:46:25 +0200 Subject: [PATCH 114/218] Clean up tests --- test/t/module.rb | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/test/t/module.rb b/test/t/module.rb index 5aba53c46..4bde20fbe 100644 --- a/test/t/module.rb +++ b/test/t/module.rb @@ -495,7 +495,7 @@ end # Not ISO specified # @!group prepend - assert('test_prepend') do + assert('Module#prepend') do module M0 def m1; [:M0] end end @@ -530,13 +530,13 @@ end # mruby shouldn't be affected by this since there is # no visibility control (yet) - assert('test_public_prepend') do + assert('Module#prepend public') do assert_nothing_raised('ruby/ruby #8846') do Class.new.prepend(Module.new) end end - assert('test_prepend_inheritance') do + assert('Module#prepend inheritance') do bug6654 = '[ruby-core:45914]' a = labeled_module('a') b = labeled_module('b') { include a } @@ -562,18 +562,18 @@ end assert_kind_of(b, c.new, bug8357) end - assert('test_prepend_instance_methods') do + assert('Moduler#prepend + #instance_methods') do bug6655 = '[ruby-core:45915]' assert_equal(Object.instance_methods, Class.new {prepend Module.new}.instance_methods, bug6655) end - assert 'test_prepend_singleton_methods' do + assert 'Module#prepend + #singleton_methods' do o = Object.new o.singleton_class.class_eval {prepend Module.new} assert_equal([], o.singleton_methods) end - assert 'test_prepend_remove_method' do + assert 'Module#prepend + #remove_method' do c = Class.new do prepend Module.new { def foo; end } end @@ -597,7 +597,7 @@ end assert_equal(:foo, removed) end - assert 'test_prepend_class_ancestors' do + assert 'Module#prepend + Class#ancestors' do bug6658 = '[ruby-core:45919]' m = labeled_module("m") c = labeled_class("c") {prepend m} @@ -609,8 +609,7 @@ end assert_equal([c2, m, c, Object], anc[0..anc.index(Object)], bug6662) end - # this assertion causes the mrbtest to segfault - assert 'test_prepend_module_ancestors' do + assert 'Module#prepend + Module#ancestors' do bug6659 = '[ruby-dev:45861]' m0 = labeled_module("m0") { def x; [:m0, *super] end } m1 = labeled_module("m1") { def x; [:m1, *super] end; prepend m0 } @@ -638,13 +637,13 @@ end assert_equal([m3, m0, m1], m3.ancestors) end - assert 'test_prepend_instance_methods_false' do + assert 'Module#prepend #instance_methods(false)' do bug6660 = '[ruby-dev:45863]' assert_equal([:m1], Class.new{ prepend Module.new; def m1; end }.instance_methods(false), bug6660) assert_equal([:m1], Class.new(Class.new{def m2;end}){ prepend Module.new; def m1; end }.instance_methods(false), bug6660) end - assert 'test_cyclic_prepend' do + assert 'cyclic Module#prepend' do bug7841 = '[ruby-core:52205] [Bug #7841]' m1 = Module.new m2 = Module.new @@ -670,7 +669,7 @@ end #end # mruby has no visibility control - assert 'test_prepend_visibility' do + assert 'Module#prepend visibility' do bug8005 = '[ruby-core:53106] [Bug #8005]' c = Class.new do prepend Module.new {} @@ -683,7 +682,7 @@ end end # mruby has no visibility control - assert 'test_prepend_visibility_inherited' do + assert 'Module#prepend inherited visibility' do bug8238 = '[ruby-core:54105] [Bug #8238]' module Test4PrependVisibilityInherited class A @@ -698,7 +697,7 @@ end assert_equal(Test4PrependVisibilityInherited::A, Test4PrependVisibilityInherited::B.new.foo, "#{bug8238}") end - assert 'test_prepend_included_modules' do + assert 'Module#prepend + #included_modules' do bug8025 = '[ruby-core:53158] [Bug #8025]' mixin = labeled_module("mixin") c = labeled_module("c") {prepend mixin} @@ -713,7 +712,8 @@ end assert_include(im, mixin, bug8025) end - assert 'test_prepend_super_in_alias' do + assert 'Module#prepend super in alias' do + skip "super does not currently work in aliased methods" bug7842 = '[Bug #7842]' p = labeled_module("P") do @@ -740,20 +740,20 @@ end end end - assert 'test_prepend_each_classes' do + assert 'Module#prepend each class' do m = labeled_module("M") c1 = labeled_class("C1") {prepend m} c2 = labeled_class("C2", c1) {prepend m} - assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each classes") + assert_equal([m, c2, m, c1], c2.ancestors[0, 4], "should be able to prepend each class") end - assert 'test_prepend_no_duplication' do + assert 'Module#prepend no duplication' do m = labeled_module("M") c = labeled_class("C") {prepend m; prepend m} assert_equal([m, c], c.ancestors[0, 2], "should never duplicate") end - assert 'test_prepend_in_superclass' do + assert 'Module#prepend in superclass' do m = labeled_module("M") c1 = labeled_class("C1") c2 = labeled_class("C2", c1) {prepend m} @@ -762,7 +762,7 @@ end end # requires #assert_seperately - #assert 'test_prepend_call_super' do + #assert 'Module#prepend call super' do # assert_separately([], <<-'end;') #do # bug10847 = '[ruby-core:68093] [Bug #10847]' # module M; end From a0754986134fbe6b65992b19338c97d596f4ef60 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 14 Jul 2015 13:22:42 +0900 Subject: [PATCH 115/218] mrb_get_args: allow A,H,s,z,a,d specifiers to take ! to accept nil. S,A,H gives nil, s,z,a,d gives NULL for nil argument. ref 02474da --- src/class.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 4 deletions(-) diff --git a/src/class.c b/src/class.c index 8a9fdaca6..b5f5f5287 100644 --- a/src/class.c +++ b/src/class.c @@ -435,9 +435,9 @@ to_sym(mrb_state *mrb, mrb_value ss) ---------------------------------------------------------------------------------------------- o: Object [mrb_value] C: class/module [mrb_value] - S: String [mrb_value] when ! follows the value may be nil - A: Array [mrb_value] - H: Hash [mrb_value] + S: String [mrb_value] when ! follows, the value may be nil + A: Array [mrb_value] when ! follows, the value may be nil + H: Hash [mrb_value] when ! follows, the value may be nil s: String [char*,mrb_int] Receive two arguments. z: String [char*] NUL terminated string. a: Array [mrb_value*,mrb_int] Receive two arguments. @@ -527,7 +527,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, mrb_value*); if (*format == '!') { format++; - if (mrb_nil_p(*sp)) { + if (i < argc && mrb_nil_p(*sp)) { *p = *sp++; i++; break; @@ -544,6 +544,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value *p; p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *p = *sp++; + i++; + break; + } + } if (i < argc) { *p = to_ary(mrb, *sp++); i++; @@ -555,6 +563,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) mrb_value *p; p = va_arg(ap, mrb_value*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *p = *sp++; + i++; + break; + } + } if (i < argc) { *p = to_hash(mrb, *sp++); i++; @@ -569,6 +585,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) ps = va_arg(ap, char**); pl = va_arg(ap, mrb_int*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *ps = NULL; + *pl = 0; + i++; + break; + } + } if (i < argc) { ss = to_str(mrb, *sp++); *ps = RSTRING_PTR(ss); @@ -583,6 +608,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) const char **ps; ps = va_arg(ap, const char**); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *ps = NULL; + i++; + break; + } + } if (i < argc) { ss = to_str(mrb, *sp++); *ps = mrb_string_value_cstr(mrb, &ss); @@ -599,6 +632,15 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) pb = va_arg(ap, mrb_value**); pl = va_arg(ap, mrb_int*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *pb = 0; + *pl = 0; + i++; + break; + } + } if (i < argc) { aa = to_ary(mrb, *sp++); a = mrb_ary_ptr(aa); From 4e7050fe0c56a9403f182d3f79a22a4196d377f0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 14 Jul 2015 13:34:21 +0900 Subject: [PATCH 116/218] mrb_get_args: allow d! --- src/class.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/class.c b/src/class.c index b5f5f5287..b306cb489 100644 --- a/src/class.c +++ b/src/class.c @@ -726,6 +726,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) datap = va_arg(ap, void**); type = va_arg(ap, struct mrb_data_type const*); + if (*format == '!') { + format++; + if (i < argc && mrb_nil_p(*sp)) { + *datap = 0; + i++; + break; + } + } if (i < argc) { *datap = mrb_data_get_ptr(mrb, *sp++, type); ++i; From 53a81da0fafc2adbc791d9f161207faa29bccb4e Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 14 Jul 2015 13:35:06 +0900 Subject: [PATCH 117/218] mrb_get_args: improve function description about ! --- src/class.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/class.c b/src/class.c index b306cb489..1d54c91f4 100644 --- a/src/class.c +++ b/src/class.c @@ -438,9 +438,9 @@ to_sym(mrb_state *mrb, mrb_value ss) S: String [mrb_value] when ! follows, the value may be nil A: Array [mrb_value] when ! follows, the value may be nil H: Hash [mrb_value] when ! follows, the value may be nil - s: String [char*,mrb_int] Receive two arguments. - z: String [char*] NUL terminated string. - a: Array [mrb_value*,mrb_int] Receive two arguments. + s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil + z: String [char*] NUL terminated string; z! gives NULL for nil + a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil f: Float [mrb_float] i: Integer [mrb_int] b: Boolean [mrb_bool] From 510e53d89f447b900a028f75c51ba18cb95d1670 Mon Sep 17 00:00:00 2001 From: jbreeden Date: Mon, 13 Jul 2015 23:21:19 -0700 Subject: [PATCH 118/218] Add ! documentation to mruby.h.md --- doc/api/mruby.h.md | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index 8862fee2c..8236b8244 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -43,20 +43,22 @@ Deletes `mrb_state`. int mrb_get_args(mrb_state *mrb, const char *format, ...); ``` Retrieve arguments from `mrb_state`. +When applicable, implicit conversions (such as `to_str`, +`to_ary`, `to_hash`) are be applied to received arguments. Use it inside a function pointed by `mrb_func_t`. -It returns number of function retrieved. -`format` is a list of following format specifier: +It returns the number of arguments retrieved. +`format` is a list of following format specifiers: char|mruby type|retrieve types|note :---:|----------|--------------|--- `o`|`Object`|`mrb_value`|Could be used to retrieve any type of argument `C`|`Class`/`Module`|`mrb_value`| -`S`|`String`|`mrb_value`| -`A`|`Array`|`mrb_value`| -`H`|`Hash`|`mrb_value`| -`s`|`String`|`char*`, `mrb_int`| -`z`|`String`|`char*`| -`a`|`Array`|`mrb_value*`, `mrb_int`| +`S`|`String`|`mrb_value`|when ! follows, the value may be nil +`A`|`Array`|`mrb_value`|when ! follows, the value may be nil +`H`|`Hash`|`mrb_value`|when ! follows, the value may be nil +`s`|`String`|`char*`, `mrb_int`|Receive two arguments; s! gives (NULL,0) for nil +`z`|`String`|`char*`|NUL terminated string; z! gives NULL for nil +`a`|`Array`|`mrb_value*`, `mrb_int`|Receive two arguments; a! gives (NULL,0) for nil `f`|`Float`|`mrb_float`| `i`|`Integer`|`mrb_int`| `b`|boolean|`mrb_bool`| @@ -118,7 +120,7 @@ mrb_value example_method(mrb_state* mrb, mrb_value self){ void mrb_example_gem_init(mrb_state* mrb) { struct RClass *example_class; example_class = mrb_define_class(mrb, "Example_Class", mrb->object_class); - mrb_define_method(mrb, example_class, "example_method", example_method, MRB_ARGS_NONE()); + mrb_define_method(mrb, example_class, "example_method", example_method, MRB_ARGS_NONE()); } void mrb_example_gem_final(mrb_state* mrb) { From e92da7b76c75b0270fc4a9bfd8c8dd20985e1f00 Mon Sep 17 00:00:00 2001 From: jbreeden Date: Mon, 13 Jul 2015 23:26:29 -0700 Subject: [PATCH 119/218] Fix typo --- doc/api/mruby.h.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md index 8236b8244..06bab2d56 100644 --- a/doc/api/mruby.h.md +++ b/doc/api/mruby.h.md @@ -44,7 +44,7 @@ int mrb_get_args(mrb_state *mrb, const char *format, ...); ``` Retrieve arguments from `mrb_state`. When applicable, implicit conversions (such as `to_str`, -`to_ary`, `to_hash`) are be applied to received arguments. +`to_ary`, `to_hash`) are applied to received arguments. Use it inside a function pointed by `mrb_func_t`. It returns the number of arguments retrieved. `format` is a list of following format specifiers: From f0e920baf07e17fd1073566d7e9605f9192d766d Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Tue, 14 Jul 2015 08:55:53 -0500 Subject: [PATCH 120/218] Renamed parameters in include_module_at --- src/class.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/class.c b/src/class.c index cde5736e0..14d81495e 100644 --- a/src/class.c +++ b/src/class.c @@ -798,26 +798,26 @@ include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) } MRB_API int -include_module_at(mrb_state *mrb, struct RClass *klass, struct RClass *c, struct RClass *module, int search_super) +include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) { - struct RClass *p, *iclass; - void *klass_mt = klass->origin->mt; + struct RClass *p, *ic; + void *klass_mt = c->origin->mt; - while (module) { + while (m) { int superclass_seen = 0; - if (module->origin != module) + if (m->origin != m) goto skip; - if (klass_mt && klass_mt == module->mt) + if (klass_mt && klass_mt == m->mt) return -1; - p = klass->super; + p = c->super; while(p) { if (p->tt == MRB_TT_ICLASS) { - if (p->mt == module->mt) { + if (p->mt == m->mt) { if (!superclass_seen) { - c = p; // move insert point + ins_pos = p; // move insert point } goto skip; } @@ -828,12 +828,12 @@ include_module_at(mrb_state *mrb, struct RClass *klass, struct RClass *c, struct p = p->super; } - iclass = include_class_new(mrb, module, c->super); - c->super = iclass; - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)c->super); - c = iclass; + ic = include_class_new(mrb, m, ins_pos->super); + ins_pos->super = ic; + mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ins_pos->super); + ins_pos = ic; skip: - module = module->super; + m = m->super; } return 0; } From eb172c28d79b4fdf978e78fc7e929caa855dd29b Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Tue, 14 Jul 2015 09:44:04 -0500 Subject: [PATCH 121/218] Applied gc patch to fix ORIGIN ICLASS method table leak Based on the gc patch by ko1 https://github.com/ruby/ruby/commit/5922c954614e5947a548780bb3b894626affe6dd --- include/mruby/class.h | 7 +++++-- include/mruby/object.h | 2 ++ src/class.c | 1 + src/gc.c | 12 ++++++++++-- 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/mruby/class.h b/include/mruby/class.h index 60310ae9d..9f2c32bb0 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -49,8 +49,11 @@ mrb_class(mrb_state *mrb, mrb_value v) } } -#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~0xff) | (char)tt) -#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & 0xff) +// TODO: figure out where to put user flags +#define MRB_FLAG_IS_ORIGIN (1 << 20) +#define MRB_FLAG_IS_INSTANCE (0xFF) +#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_FLAG_IS_INSTANCE) | (char)tt) +#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_FLAG_IS_INSTANCE) MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); diff --git a/include/mruby/object.h b/include/mruby/object.h index fe55620fe..6633a23e8 100644 --- a/include/mruby/object.h +++ b/include/mruby/object.h @@ -14,6 +14,8 @@ struct RClass *c;\ struct RBasic *gcnext +#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & flag) + /* white: 011, black: 100, gray: 000 */ #define MRB_GC_GRAY 0 #define MRB_GC_WHITE_A 1 diff --git a/src/class.c b/src/class.c index 14d81495e..58742299b 100644 --- a/src/class.c +++ b/src/class.c @@ -856,6 +856,7 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) origin = c->origin; if (origin == c) { origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); + origin->flags |= MRB_FLAG_IS_ORIGIN; origin->origin = origin; origin->super = c->super; c->super = origin; diff --git a/src/gc.c b/src/gc.c index 8bd8243f1..15e1bd423 100644 --- a/src/gc.c +++ b/src/gc.c @@ -498,7 +498,12 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) mrb_gc_mark(mrb, (struct RBasic*)obj->c); switch (obj->tt) { case MRB_TT_ICLASS: - mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); + { + struct RClass *c = (struct RClass*)obj; + if (MRB_FLAG_TEST(c, MRB_FLAG_IS_ORIGIN)) + mrb_gc_mark_mt(mrb, c); + mrb_gc_mark(mrb, (struct RBasic*)((struct RClass*)obj)->super); + } break; case MRB_TT_CLASS: @@ -624,7 +629,10 @@ obj_free(mrb_state *mrb, struct RBasic *obj) mrb_gc_free_mt(mrb, (struct RClass*)obj); mrb_gc_free_iv(mrb, (struct RObject*)obj); break; - + case MRB_TT_ICLASS: + if (MRB_FLAG_TEST(obj, MRB_FLAG_IS_ORIGIN)) + mrb_gc_free_mt(mrb, (struct RClass*)obj); + break; case MRB_TT_ENV: { struct REnv *e = (struct REnv*)obj; From dbbf2e26231c04d76badb1889627869d1f9361bb Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Tue, 14 Jul 2015 14:12:23 -0500 Subject: [PATCH 122/218] Remove non-applicable "hack" comment --- src/class.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/class.c b/src/class.c index 58742299b..f342ded20 100644 --- a/src/class.c +++ b/src/class.c @@ -1020,8 +1020,6 @@ static mrb_value mrb_mod_initialize(mrb_state *mrb, mrb_value mod) { mrb_value b; - - /* hack, fix missing module->origin */ struct RClass *m = mrb_class_ptr(mod); boot_initmod(mrb, m); // bootstrap a newly initialized module mrb_get_args(mrb, "|&", &b); From 2e4bc2de8889a321fbde9898bc9afc9daefd8f76 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 00:05:07 +0900 Subject: [PATCH 123/218] Refactor `Build#compile_as_cxx`. --- tasks/mruby_build.rake | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 947b4ba77..9f8b4eda5 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -127,8 +127,8 @@ module MRuby obj = objfile(cxx_src) if obj.nil? file cxx_src => [src, __FILE__] do |t| - File.open(t.name, 'w') do |f| - f.write < cxx_src do |t| From cdd72d9c3783749c979edf62522cf9636681538d Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 00:05:45 +0900 Subject: [PATCH 124/218] Implement `mrb_protect`, `mrb_ensure`, `mrb_rescue`, `mrb_rescue_exceptions`. (`mrb_rescue_exceptions` is mruby implementation of `rb_rescue2`.) Closes #2844, closes #2837. --- include/mruby/error.h | 8 ++ mrbgems/mruby-error/mrbgem.rake | 10 +++ mrbgems/mruby-error/src/exception.c | 102 ++++++++++++++++++++++++++ mrbgems/mruby-error/test/exception.c | 57 ++++++++++++++ mrbgems/mruby-error/test/exception.rb | 53 +++++++++++++ 5 files changed, 230 insertions(+) create mode 100644 mrbgems/mruby-error/mrbgem.rake create mode 100644 mrbgems/mruby-error/src/exception.c create mode 100644 mrbgems/mruby-error/test/exception.c create mode 100644 mrbgems/mruby-error/test/exception.rb diff --git a/include/mruby/error.h b/include/mruby/error.h index 282be0a24..3a985236a 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -29,6 +29,14 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va /* declaration for fail method */ MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); +MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state); +MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t ensure, mrb_value e_data); +MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data); +MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data, ...); + #if defined(__cplusplus) } /* extern "C" { */ #endif diff --git a/mrbgems/mruby-error/mrbgem.rake b/mrbgems/mruby-error/mrbgem.rake new file mode 100644 index 000000000..b8281b17e --- /dev/null +++ b/mrbgems/mruby-error/mrbgem.rake @@ -0,0 +1,10 @@ +MRuby::Gem::Specification.new('mruby-error') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'extensional error handling' + + if build.cxx_abi_enabled? + @objs << build.compile_as_cxx("#{spec.dir}/src/exception.c", "#{spec.build_dir}/src/exception.cxx") + @objs.delete_if { |v| v == objfile("#{spec.build_dir}/src/exception") } + end +end diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c new file mode 100644 index 000000000..abd03bc29 --- /dev/null +++ b/mrbgems/mruby-error/src/exception.c @@ -0,0 +1,102 @@ +#include +#include "mruby.h" +#include "mruby/throw.h" +#include "mruby/error.h" + +MRB_API mrb_value +mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result = mrb_nil_value(); + + if (state) { *state = FALSE; } + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + mrb->exc = NULL; + if (state) { *state = TRUE; } + } MRB_END_EXC(&c_jmp); + + mrb_gc_protect(mrb, result); + return result; +} + +MRB_API mrb_value +mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, b_data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + ensure(mrb, e_data); + MRB_THROW(mrb->jmp); /* rethrow catched exceptions */ + } MRB_END_EXC(&c_jmp); + + ensure(mrb, e_data); + mrb_gc_protect(mrb, result); + return result; +} + +MRB_API mrb_value +mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, + mrb_func_t rescue, mrb_value r_data) +{ + return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, mrb->eStandardError_class, NULL); +} + +MRB_API mrb_value +mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, ...) +{ + struct mrb_jmpbuf *prev_jmp = mrb->jmp; + struct mrb_jmpbuf c_jmp; + mrb_value result; + va_list excs; + struct RClass *cls; + mrb_bool error_matched = FALSE; + + MRB_TRY(&c_jmp) { + mrb->jmp = &c_jmp; + result = body(mrb, b_data); + mrb->jmp = prev_jmp; + } MRB_CATCH(&c_jmp) { + mrb->jmp = prev_jmp; + + va_start(excs, r_data); + while((cls = va_arg(excs, struct RClass*))) { + if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), cls)) { + error_matched = TRUE; + break; + } + } + va_end(excs); + + if (!error_matched) { MRB_THROW(mrb->jmp); } + + mrb->exc = NULL; + result = rescue(mrb, r_data); + } MRB_END_EXC(&c_jmp); + + mrb_gc_protect(mrb, result); + return result; +} + +void +mrb_mruby_error_gem_init(mrb_state *mrb) +{ +} + +void +mrb_mruby_error_gem_final(mrb_state *mrb) +{ +} diff --git a/mrbgems/mruby-error/test/exception.c b/mrbgems/mruby-error/test/exception.c new file mode 100644 index 000000000..7c15fb457 --- /dev/null +++ b/mrbgems/mruby-error/test/exception.c @@ -0,0 +1,57 @@ +#include "mruby.h" +#include "mruby/error.h" +#include "mruby/array.h" + +static mrb_value +protect_cb(mrb_state *mrb, mrb_value b) +{ + return mrb_yield_argv(mrb, b, 0, NULL); +} + +static mrb_value +run_protect(mrb_state *mrb, mrb_value self) +{ + mrb_value b; + mrb_value ret[2]; + mrb_bool state; + mrb_get_args(mrb, "&", &b); + ret[0] = mrb_protect(mrb, protect_cb, b, &state); + ret[1] = mrb_bool_value(state); + return mrb_ary_new_from_values(mrb, 2, ret); +} + +static mrb_value +run_ensure(mrb_state *mrb, mrb_value self) +{ + mrb_value b, e; + mrb_get_args(mrb, "oo", &b, &e); + return mrb_ensure(mrb, protect_cb, b, protect_cb, e); +} + +static mrb_value +run_rescue(mrb_state *mrb, mrb_value self) +{ + mrb_value b, r; + mrb_get_args(mrb, "oo", &b, &r); + return mrb_rescue(mrb, protect_cb, b, protect_cb, r); +} + +static mrb_value +run_rescue_exceptions(mrb_state *mrb, mrb_value self) +{ + mrb_value b, r; + mrb_get_args(mrb, "oo", &b, &r); + return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, E_TYPE_ERROR, NULL); +} + +void +mrb_mruby_error_gem_test(mrb_state *mrb) +{ + struct RClass *cls; + + cls = mrb_define_class(mrb, "ExceptionTest", mrb->object_class); + mrb_define_module_function(mrb, cls, "mrb_protect", run_protect, MRB_ARGS_NONE() | MRB_ARGS_BLOCK()); + mrb_define_module_function(mrb, cls, "mrb_ensure", run_ensure, MRB_ARGS_REQ(2)); + mrb_define_module_function(mrb, cls, "mrb_rescue", run_rescue, MRB_ARGS_REQ(2)); + mrb_define_module_function(mrb, cls, "mrb_rescue_exceptions", run_rescue_exceptions, MRB_ARGS_REQ(2)); +} diff --git a/mrbgems/mruby-error/test/exception.rb b/mrbgems/mruby-error/test/exception.rb new file mode 100644 index 000000000..b5ea719a2 --- /dev/null +++ b/mrbgems/mruby-error/test/exception.rb @@ -0,0 +1,53 @@ +assert 'mrb_protect' do + assert_equal ['test', false] do + ExceptionTest.mrb_protect { 'test' } + end + assert_equal [nil, true] do + ExceptionTest.mrb_protect { raise 'test' } + end +end + +assert 'mrb_ensure' do + a = false + assert_equal 'test' do + ExceptionTest.mrb_ensure Proc.new { 'test' }, Proc.new { a = true } + end + assert_true a + + a = false + assert_raise RuntimeError do + ExceptionTest.mrb_ensure Proc.new { raise 'test' }, Proc.new { a = true } + end + assert_true a +end + +assert 'mrb_rescue' do + assert_equal 'test' do + ExceptionTest.mrb_rescue Proc.new { 'test' }, Proc.new {} + end + + class CustomExp < Exception + end + + assert_raise CustomExp do + ExceptionTest.mrb_rescue Proc.new { raise CustomExp.new 'test' }, Proc.new { 'rescue' } + end + + assert_equal 'rescue' do + ExceptionTest.mrb_rescue Proc.new { raise 'test' }, Proc.new { 'rescue' } + end +end + +assert 'mrb_rescue_exceptions' do + assert_equal 'test' do + ExceptionTest.mrb_rescue_exceptions Proc.new { 'test' }, Proc.new {} + end + + assert_raise RangeError do + ExceptionTest.mrb_rescue_exceptions Proc.new { raise RangeError.new 'test' }, Proc.new { 'rescue' } + end + + assert_equal 'rescue' do + ExceptionTest.mrb_rescue_exceptions Proc.new { raise TypeError.new 'test' }, Proc.new { 'rescue' } + end +end From f6b5a829729479d4ae557effc15656605ca71781 Mon Sep 17 00:00:00 2001 From: take_cheeze Date: Mon, 22 Jun 2015 10:49:37 +0900 Subject: [PATCH 125/218] Use class array instead of variadic. --- include/mruby/error.h | 3 ++- mrbgems/mruby-error/src/exception.c | 14 ++++++-------- mrbgems/mruby-error/test/exception.c | 4 +++- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/mruby/error.h b/include/mruby/error.h index 3a985236a..d02e9166c 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -35,7 +35,8 @@ MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data); MRB_API mrb_value mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, - mrb_func_t rescue, mrb_value r_data, ...); + mrb_func_t rescue, mrb_value r_data, + mrb_int len, struct RClass **classes); #if defined(__cplusplus) } /* extern "C" { */ diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c index abd03bc29..7199e0801 100644 --- a/mrbgems/mruby-error/src/exception.c +++ b/mrbgems/mruby-error/src/exception.c @@ -1,4 +1,3 @@ -#include #include "mruby.h" #include "mruby/throw.h" #include "mruby/error.h" @@ -52,18 +51,19 @@ MRB_API mrb_value mrb_rescue(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data) { - return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, mrb->eStandardError_class, NULL); + return mrb_rescue_exceptions(mrb, body, b_data, rescue, r_data, 1, &mrb->eStandardError_class); } MRB_API mrb_value -mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, ...) +mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t rescue, mrb_value r_data, + mrb_int len, struct RClass **classes) { struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; - va_list excs; struct RClass *cls; mrb_bool error_matched = FALSE; + mrb_int i; MRB_TRY(&c_jmp) { mrb->jmp = &c_jmp; @@ -72,14 +72,12 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; - va_start(excs, r_data); - while((cls = va_arg(excs, struct RClass*))) { - if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), cls)) { + for (i = 0; i < len; ++i) { + if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) { error_matched = TRUE; break; } } - va_end(excs); if (!error_matched) { MRB_THROW(mrb->jmp); } diff --git a/mrbgems/mruby-error/test/exception.c b/mrbgems/mruby-error/test/exception.c index 7c15fb457..2a943aaae 100644 --- a/mrbgems/mruby-error/test/exception.c +++ b/mrbgems/mruby-error/test/exception.c @@ -40,8 +40,10 @@ static mrb_value run_rescue_exceptions(mrb_state *mrb, mrb_value self) { mrb_value b, r; + struct RClass *cls[1]; mrb_get_args(mrb, "oo", &b, &r); - return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, E_TYPE_ERROR, NULL); + cls[0] = E_TYPE_ERROR; + return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, 1, cls); } void From c0bf76d0a1ef631813c01d785500c1544d18a506 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 15 Jul 2015 14:43:34 +0900 Subject: [PATCH 126/218] remove unused variable declaration --- mrbgems/mruby-error/src/exception.c | 1 - 1 file changed, 1 deletion(-) diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c index 7199e0801..9d77c6adf 100644 --- a/mrbgems/mruby-error/src/exception.c +++ b/mrbgems/mruby-error/src/exception.c @@ -61,7 +61,6 @@ mrb_rescue_exceptions(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_fun struct mrb_jmpbuf *prev_jmp = mrb->jmp; struct mrb_jmpbuf c_jmp; mrb_value result; - struct RClass *cls; mrb_bool error_matched = FALSE; mrb_int i; From 1085167fefe010be8e2d39e2adb31134a5512b15 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 15 Jul 2015 14:44:19 +0900 Subject: [PATCH 127/218] add an small comment description in mruby/error.h header --- include/mruby/error.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mruby/error.h b/include/mruby/error.h index d02e9166c..e3e2b25e2 100644 --- a/include/mruby/error.h +++ b/include/mruby/error.h @@ -29,6 +29,7 @@ MRB_API mrb_noreturn void mrb_no_method_error(mrb_state *mrb, mrb_sym id, mrb_va /* declaration for fail method */ MRB_API mrb_value mrb_f_raise(mrb_state*, mrb_value); +/* functions defined in mruby-error mrbgem */ MRB_API mrb_value mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state); MRB_API mrb_value mrb_ensure(mrb_state *mrb, mrb_func_t body, mrb_value b_data, mrb_func_t ensure, mrb_value e_data); From 207577f0af72874d9d643f2c46b881a9159d42d7 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 15 Jul 2015 14:45:32 +0900 Subject: [PATCH 128/218] mrb_protect() to return the exception raised (with the state of true) --- mrbgems/mruby-error/src/exception.c | 1 + mrbgems/mruby-error/test/exception.rb | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-error/src/exception.c b/mrbgems/mruby-error/src/exception.c index 9d77c6adf..911fde0be 100644 --- a/mrbgems/mruby-error/src/exception.c +++ b/mrbgems/mruby-error/src/exception.c @@ -17,6 +17,7 @@ mrb_protect(mrb_state *mrb, mrb_func_t body, mrb_value data, mrb_bool *state) mrb->jmp = prev_jmp; } MRB_CATCH(&c_jmp) { mrb->jmp = prev_jmp; + result = mrb_obj_value(mrb->exc); mrb->exc = NULL; if (state) { *state = TRUE; } } MRB_END_EXC(&c_jmp); diff --git a/mrbgems/mruby-error/test/exception.rb b/mrbgems/mruby-error/test/exception.rb index b5ea719a2..0bbc2a0e7 100644 --- a/mrbgems/mruby-error/test/exception.rb +++ b/mrbgems/mruby-error/test/exception.rb @@ -1,10 +1,12 @@ assert 'mrb_protect' do + # no failure in protect returns [result, false] assert_equal ['test', false] do ExceptionTest.mrb_protect { 'test' } end - assert_equal [nil, true] do - ExceptionTest.mrb_protect { raise 'test' } - end + # failure in protect returns [exception, true] + result = ExceptionTest.mrb_protect { raise 'test' } + assert_kind_of RuntimeError, result[0] + assert_true result[1] end assert 'mrb_ensure' do From 667f7788db2b3b78cc4cc65c0f37ab38347116c5 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Wed, 15 Jul 2015 07:27:31 -0500 Subject: [PATCH 129/218] Renamed MRB_FLAG_IS_INSTANCE to MRB_INSTANCE_TT_MASK --- include/mruby/class.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/mruby/class.h b/include/mruby/class.h index 9f2c32bb0..80a0cbe35 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -51,9 +51,9 @@ mrb_class(mrb_state *mrb, mrb_value v) // TODO: figure out where to put user flags #define MRB_FLAG_IS_ORIGIN (1 << 20) -#define MRB_FLAG_IS_INSTANCE (0xFF) -#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_FLAG_IS_INSTANCE) | (char)tt) -#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_FLAG_IS_INSTANCE) +#define MRB_INSTANCE_TT_MASK (0xFF) +#define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt) +#define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK) MRB_API struct RClass* mrb_define_class_id(mrb_state*, mrb_sym, struct RClass*); MRB_API struct RClass* mrb_define_module_id(mrb_state*, mrb_sym); From 938ed044f4e053c1832be3868230d80ccba190e8 Mon Sep 17 00:00:00 2001 From: cremno Date: Thu, 16 Jul 2015 03:56:31 +0200 Subject: [PATCH 130/218] use mrb_str_cat_str() instead of mrb_str_append() If the argument is always a string, then mrb_str_cat_str() can be directly called instead of indirectly by mrb_str_append(). mrb_any_to_s(), mrb_obj_as_string(), mrb_inspect() always return a string. --- src/class.c | 4 ++-- src/error.c | 4 ++-- src/range.c | 4 ++-- src/variable.c | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/class.c b/src/class.c index 1d54c91f4..33fb61211 100644 --- a/src/class.c +++ b/src/class.c @@ -1608,10 +1608,10 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass) case MRB_TT_CLASS: case MRB_TT_MODULE: case MRB_TT_SCLASS: - mrb_str_append(mrb, str, mrb_inspect(mrb, v)); + mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v)); break; default: - mrb_str_append(mrb, str, mrb_any_to_s(mrb, v)); + mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v)); break; } return mrb_str_cat_lit(mrb, str, ">"); diff --git a/src/error.c b/src/error.c index 20c63bd43..359e5737b 100644 --- a/src/error.c +++ b/src/error.c @@ -152,7 +152,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc) mrb_str_append(mrb, str, line); mrb_str_cat_lit(mrb, str, ": "); if (append_mesg) { - mrb_str_append(mrb, str, mesg); + mrb_str_cat_str(mrb, str, mesg); mrb_str_cat_lit(mrb, str, " ("); } mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); @@ -165,7 +165,7 @@ exc_inspect(mrb_state *mrb, mrb_value exc) str = mrb_str_new_cstr(mrb, cname); mrb_str_cat_lit(mrb, str, ": "); if (append_mesg) { - mrb_str_append(mrb, str, mesg); + mrb_str_cat_str(mrb, str, mesg); } else { mrb_str_cat_cstr(mrb, str, cname); diff --git a/src/range.c b/src/range.c index b427dc1b7..b58b6a1c8 100644 --- a/src/range.c +++ b/src/range.c @@ -290,7 +290,7 @@ range_to_s(mrb_state *mrb, mrb_value range) str2 = mrb_obj_as_string(mrb, r->edges->end); str = mrb_str_dup(mrb, str); mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); - mrb_str_append(mrb, str, str2); + mrb_str_cat_str(mrb, str, str2); return str; } @@ -315,7 +315,7 @@ range_inspect(mrb_state *mrb, mrb_value range) str2 = mrb_inspect(mrb, r->edges->end); str = mrb_str_dup(mrb, str); mrb_str_cat(mrb, str, "...", r->excl ? 3 : 2); - mrb_str_append(mrb, str, str2); + mrb_str_cat_str(mrb, str, str2); return str; } diff --git a/src/variable.c b/src/variable.c index 1b2ad56a7..efe6fad12 100644 --- a/src/variable.c +++ b/src/variable.c @@ -609,7 +609,7 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) else { ins = mrb_inspect(mrb, v); } - mrb_str_append(mrb, str, ins); + mrb_str_cat_str(mrb, str, ins); return 0; } From 0f284091d161dbca6e07de85896cbdc9abd2de6b Mon Sep 17 00:00:00 2001 From: cremno Date: Thu, 16 Jul 2015 04:58:21 +0200 Subject: [PATCH 131/218] delete mrb_free()-related non-NULL checks No need to optimize since a program only exits once and errors are rare. Also the mruby source code doesn't have these kind of checks elsewhere. The ones in {Time,Random}#initialize are kept because there it actually matters since initialization always happens and re-initialization is unlikely. --- mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 3 +-- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 5 ++--- src/dump.c | 8 ++------ 3 files changed, 5 insertions(+), 11 deletions(-) diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index f27f87a5d..301dde1c6 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -161,8 +161,7 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) static void cleanup(mrb_state *mrb, struct mrbc_args *args) { - if (args->outfile) - mrb_free(mrb, (void*)args->outfile); + mrb_free(mrb, (void*)args->outfile); mrb_close(mrb); } diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 141ea151b..5ca744388 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -159,10 +159,9 @@ cleanup(mrb_state *mrb, struct _args *args) { if (args->rfp && args->rfp != stdin) fclose(args->rfp); - if (args->cmdline && !args->fname) + if (!args->fname) mrb_free(mrb, args->cmdline); - if (args->argv) - mrb_free(mrb, args->argv); + mrb_free(mrb, args->argv); mrb_close(mrb); } diff --git a/src/dump.c b/src/dump.c index 2f2e5edcb..462e036b4 100644 --- a/src/dump.c +++ b/src/dump.c @@ -978,12 +978,8 @@ error_exit: mrb_free(mrb, *bin); *bin = NULL; } - if (lv_syms) { - mrb_free(mrb, lv_syms); - } - if (filenames) { - mrb_free(mrb, filenames); - } + mrb_free(mrb, lv_syms); + mrb_free(mrb, filenames); return result; } From 67e187f0f883789131c596ccc56980c32471bbbf Mon Sep 17 00:00:00 2001 From: takkaw Date: Thu, 16 Jul 2015 18:40:07 +0900 Subject: [PATCH 132/218] 64bit Cygwin also doesn't have frexpl(3) --- src/fmt_fp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fmt_fp.c b/src/fmt_fp.c index b467435a3..b27ebd6e9 100644 --- a/src/fmt_fp.c +++ b/src/fmt_fp.c @@ -90,7 +90,7 @@ fmt_u(uint32_t x, char *s) typedef char compiler_defines_long_double_incorrectly[9-(int)sizeof(long double)]; #endif -#if ((defined(__CYGWIN32__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__)) || defined(__android__) +#if ((defined(__CYGWIN__) || defined(__NetBSD__) || defined(mips)) && !defined(__linux__)) || defined(__android__) #undef frexpl #define frexpl frexp #endif From ae1ece72282fdfa558810e8422bb690bbc6d2193 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Thu, 16 Jul 2015 15:25:14 -0500 Subject: [PATCH 133/218] Make include_module_at static Since I can't forsee any reason to use it directly inplace of using prepend/include --- src/class.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/class.c b/src/class.c index f342ded20..90c463579 100644 --- a/src/class.c +++ b/src/class.c @@ -797,7 +797,7 @@ include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) return ic; } -MRB_API int +static int include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) { struct RClass *p, *ic; From 26bee4a16b5763b407a842bd1697389961600d68 Mon Sep 17 00:00:00 2001 From: Corey Powell Date: Thu, 16 Jul 2015 15:25:27 -0500 Subject: [PATCH 134/218] Added mrb_prepend_module to mruby header --- include/mruby.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/mruby.h b/include/mruby.h index 1b792ce90..b4ec13fdc 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -206,6 +206,7 @@ MRB_API struct RClass *mrb_define_class(mrb_state *, const char*, struct RClass* MRB_API struct RClass *mrb_define_module(mrb_state *, const char*); MRB_API mrb_value mrb_singleton_class(mrb_state*, mrb_value); MRB_API void mrb_include_module(mrb_state*, struct RClass*, struct RClass*); +MRB_API void mrb_prepend_module(mrb_state*, struct RClass*, struct RClass*); MRB_API void mrb_define_method(mrb_state*, struct RClass*, const char*, mrb_func_t, mrb_aspec); MRB_API void mrb_define_class_method(mrb_state *, struct RClass *, const char *, mrb_func_t, mrb_aspec); From 08c12ab7bffaa1b96a3e4f9eee34e155eeec9310 Mon Sep 17 00:00:00 2001 From: Jared Breeden Date: Thu, 16 Jul 2015 15:33:07 -0700 Subject: [PATCH 135/218] Don't crash if pattern not found for sub --- mrblib/string.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/mrblib/string.rb b/mrblib/string.rb index ee097ad6d..23cf02e97 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -111,6 +111,7 @@ class String def sub(*args, &block) if args.size == 2 pre, post = split(args[0], 2) + return self unless post # The sub target wasn't found in the string pre + args[1].__sub_replace(pre, args[0], post) + post elsif args.size == 1 && block split(args[0], 2).join(block.call(args[0])) From 78a40fce8881247419955291f34ca36eb0549126 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 17 Jul 2015 14:21:13 -0400 Subject: [PATCH 136/218] Update hash.h.md --- doc/api/mruby/hash.h.md | 272 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 272 insertions(+) diff --git a/doc/api/mruby/hash.h.md b/doc/api/mruby/hash.h.md index 1d713d59e..bdc2a7f2b 100644 --- a/doc/api/mruby/hash.h.md +++ b/doc/api/mruby/hash.h.md @@ -47,6 +47,17 @@ Example_Class.new ### mrb_hash_set +```C +void mrb_hash_set(mrb_state *mrb, mrb_value hash, mrb_value key, mrb_value val); +``` + +Sets a keys and values to hashes. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example sets a key and value pair to a hash. In pure Ruby doing this is equivalent to a = {:da_key => 80}. + + ```C #include #include @@ -93,4 +104,265 @@ After compiling you should get these results. Hash ``` +### mrb_hash_get +```C +mrb_value mrb_hash_get(mrb_state *mrb, mrb_value hash, mrb_value key); +``` + +Gets a value from a key. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example gets a value from a key. In pure Ruby doing this is equivalent to a = {:da_key => 80} +a[:da_key]. + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_value; // Declare variable for getting a value from a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + get_hash_value = mrb_hash_get(mrb, new_hash, mrb_symbol_value(hash_key_b)); // Get value from hash. + mrb_funcall(mrb, obj, "method_name", 1, get_hash_value); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` + +#### Result + +After compiling you should get these results. + +```Ruby +90 +Fixnum +``` + +### mrb_hash_delete_key + +```C +mrb_value mrb_hash_delete_key(mrb_state *mrb, mrb_value hash, mrb_value key); +``` + +Deletes hash key and value pair. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example deletes hash key and value pair. In pure Ruby doing this is equivalent to a = {:da_key1 => 80,:da_key2 => 90} +a.delete(:da_key2) + + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_value; // Declare variable for getting a value from a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + mrb_hash_delete_key(mrb, new_hash, mrb_symbol_value(hash_key_b)); + mrb_funcall(mrb, obj, "another_method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +```Ruby +class Example_Class + def method_name(a) + puts "Hash pre deletion #{a}" + #puts a.class + end + # Show deleted key and value pair. + def another_method_name(a) + puts "Hash post deletion #{a}" + end +end +Example_Class.new +``` + +#### Result + +After compiling you should get these results. + +```Ruby +Hash pre deletion {:da_key1 => 80, :da_key2 => 90} +Hash post deletion {:da_key1 => 80} +``` + +### mrb_hash_keys + +```C +mrb_value mrb_hash_keys(mrb_state *mrb, mrb_value hash); +``` + +Gets an array of keys. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example gets an array of keys from a hash. + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_keys; // Declare variable for getting an array of keys. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + get_hash_keys = mrb_hash_keys(mrb, new_hash); // get an array of keys. + mrb_funcall(mrb, obj, "method_name", 1, get_hash_keys); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +```Ruby +class Example_Class + def method_name(a) + puts a + puts a.class + end +end +Example_Class.new +``` + +#### Result + +After compiling you should get these results. + +```Ruby +[:da_key1, :da_key2] +Array +``` + +### mrb_hash_clear + +```C +mrb_value mrb_hash_clear(mrb_state *mrb, mrb_value hash); +``` + +Clears the hash. +#### Example + +In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument +and what class the passed in value is. This example clears the hash. In pure Ruby doing this is equivalent to +a = {:da_key1 => 80,:da_key2 => 90} +a.clear + +```C +#include +#include +#include "mruby/hash.h" // Needs the hash header. +#include "mruby/compile.h" + +int main(int argc, char *argv[]) +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash; // Declare variable for getting a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + get_hash = mrb_hash_clear(mrb, new_hash); + mrb_funcall(mrb, obj, "another_method_name", 1, get_hash); + fclose(fp); + mrb_close(mrb); + return 0; +} +``` + +#### test_ext.rb + +```Ruby +class Example_Class + def method_name(a) + puts "Hash pre clear #{a}" + #puts a.class + end + # Show clear hash. + def another_method_name(a) + puts "Hash post clear #{a}" + end +end +Example_Class.new +``` + +#### Result + +After compiling you should get these results. + +```Ruby +Hash pre clear {:da_key1 => 80, :da_key2 => 90} +Hash post clear {} +``` From f282d947933b81a4c93f2cccf0313c3431458b51 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Fri, 17 Jul 2015 14:25:15 -0400 Subject: [PATCH 137/218] Update hash.h.md --- doc/api/mruby/hash.h.md | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/doc/api/mruby/hash.h.md b/doc/api/mruby/hash.h.md index bdc2a7f2b..b7962696c 100644 --- a/doc/api/mruby/hash.h.md +++ b/doc/api/mruby/hash.h.md @@ -55,8 +55,11 @@ Sets a keys and values to hashes. #### Example In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument -and what class the passed in value is. This example sets a key and value pair to a hash. In pure Ruby doing this is equivalent to a = {:da_key => 80}. +and what class the passed in value is. This example sets a key and value pair to a hash. In pure Ruby doing this is equivalent to: +```Ruby +a = {:da_key => 80} +``` ```C #include @@ -114,8 +117,12 @@ Gets a value from a key. #### Example In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument -and what class the passed in value is. This example gets a value from a key. In pure Ruby doing this is equivalent to a = {:da_key => 80} -a[:da_key]. +and what class the passed in value is. This example gets a value from a key. In pure Ruby doing this is equivalent to: + +```Ruby +a = {:da_key => 80} +a[:da_key] +``` ```C #include @@ -177,9 +184,12 @@ Deletes hash key and value pair. #### Example In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument -and what class the passed in value is. This example deletes hash key and value pair. In pure Ruby doing this is equivalent to a = {:da_key1 => 80,:da_key2 => 90} -a.delete(:da_key2) +and what class the passed in value is. This example deletes hash key and value pair. In pure Ruby doing this is equivalent to: +```Ruby +a = {:da_key1 => 80,:da_key2 => 90} +a.delete(:da_key2) +``` ```C #include @@ -308,9 +318,12 @@ Clears the hash. #### Example In this example we read from a Ruby file inside C. The Ruby code will print what you pass as an argument -and what class the passed in value is. This example clears the hash. In pure Ruby doing this is equivalent to +and what class the passed in value is. This example clears the hash. In pure Ruby doing this is equivalent to: + +```Ruby a = {:da_key1 => 80,:da_key2 => 90} a.clear +``` ```C #include From 6619dc4d75126d98f77e0989d542a079982639b3 Mon Sep 17 00:00:00 2001 From: "Ralph Desir(Mav7)" Date: Fri, 17 Jul 2015 14:43:55 -0400 Subject: [PATCH 138/218] Deleted range and string markdowns for now. --- doc/api/mruby/range.h.md | 0 doc/api/mruby/string.h.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/api/mruby/range.h.md delete mode 100644 doc/api/mruby/string.h.md diff --git a/doc/api/mruby/range.h.md b/doc/api/mruby/range.h.md deleted file mode 100644 index e69de29bb..000000000 diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md deleted file mode 100644 index e69de29bb..000000000 From 18a0900a8241575795838f6b803208dfb7bfa0b1 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sun, 19 Jul 2015 22:34:48 +0900 Subject: [PATCH 139/218] Fix indents; Indent is two spaces; Delete tabs [skip ci] --- doc/api/mruby/array.h.md | 223 ++++++++++++++++---------------- doc/api/mruby/hash.h.md | 273 +++++++++++++++++++-------------------- doc/api/mruby/value.h.md | 40 +++--- 3 files changed, 267 insertions(+), 269 deletions(-) diff --git a/doc/api/mruby/array.h.md b/doc/api/mruby/array.h.md index e1fb0003d..36c253cec 100644 --- a/doc/api/mruby/array.h.md +++ b/doc/api/mruby/array.h.md @@ -12,28 +12,27 @@ In this example we read from a Ruby file inside C. The Ruby code will print what #include "mruby/array.h" // Needs the array header. #include "mruby/compile.h" - int main(int argc, char *argv[]) -{ - mrb_value new_ary; // Declare variable. - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - FILE *fp = fopen("test.rb","r"); - new_ary = mrb_ary_new(mrb); - mrb_value obj = mrb_load_file(mrb,fp); - mrb_funcall(mrb, obj, "method_name", 1, new_ary); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_value new_ary; // Declare variable. + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; } ``` test.rb ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -52,32 +51,32 @@ In this example we read from a Ruby file inside C. The Ruby code will print what #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_value new_ary; // Declare variable. - mrb_int random_value1 = 70; // Initialize variable - mrb_int random_value2 = 60; // Initialize variable - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - FILE *fp = fopen("test.rb","r"); - new_ary = mrb_ary_new(mrb); // Initialize ruby array. - /* Pushes the fixnum value from random_value1 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); - /* Pushes the fixnum value from random_value2 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); - mrb_value obj = mrb_load_file(mrb,fp); - mrb_funcall(mrb, obj, "method_name", 1, new_ary); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; } ``` test.rb ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -103,37 +102,37 @@ called pop_ary that will return the array alone(just to be clean) and you should #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_value new_ary; // Declare variable. - mrb_int random_value1 = 70; // Initialize variable - mrb_int random_value2 = 60; // Initialize variable - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - FILE *fp = fopen("test.rb","r"); - new_ary = mrb_ary_new(mrb); // Initialize ruby array. - /* Pushes the fixnum value from random_value1 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); - /* Pushes the fixnum value from random_value2 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); - mrb_value obj = mrb_load_file(mrb,fp); - mrb_funcall(mrb, obj, "method_name", 1, new_ary); - mrb_ary_pop(mrb, new_ary); // Pops the last element of the array. In this case 60. - mrb_funcall(mrb, obj, "pop_ary", 1, new_ary); // Calls the method again to show the results. - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_ary); + mrb_ary_pop(mrb, new_ary); // Pops the last element of the array. In this case 60. + mrb_funcall(mrb, obj, "pop_ary", 1, new_ary); // Calls the method again to show the results. + fclose(fp); + mrb_close(mrb); + return 0; } ``` test.rb ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end - def pop_ary(a) - puts a - end + def method_name(a) + puts a + puts a.class + end + def pop_ary(a) + puts a + end end Example_Class.new ``` @@ -158,35 +157,35 @@ In this example we read from a Ruby file inside C. The Ruby code will print what #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_value ary_ref; // Declare variable. - mrb_value new_ary; // Declare variable. - mrb_int random_value1 = 70; // Initialize variable - mrb_int random_value2 = 60; // Initialize variable - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - FILE *fp = fopen("test.rb","r"); - new_ary = mrb_ary_new(mrb); // Initialize ruby array. - /* Pushes the fixnum value from random_value1 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); - /* Pushes the fixnum value from random_value2 to the new_ary instance. */ - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); - ary_ref = mrb_ary_ref(mrb, new_ary, 1); // Gets the value of new_ary's second element at index 1. - mrb_value obj = mrb_load_file(mrb,fp); - /* Passing the value from ary_ref to the method method_name.*/ - mrb_funcall(mrb, obj, "method_name", 1, ary_ref); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_value ary_ref; // Declare variable. + mrb_value new_ary; // Declare variable. + mrb_int random_value1 = 70; // Initialize variable + mrb_int random_value2 = 60; // Initialize variable + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); // Initialize ruby array. + /* Pushes the fixnum value from random_value1 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + /* Pushes the fixnum value from random_value2 to the new_ary instance. */ + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + ary_ref = mrb_ary_ref(mrb, new_ary, 1); // Gets the value of new_ary's second element at index 1. + mrb_value obj = mrb_load_file(mrb,fp); + /* Passing the value from ary_ref to the method method_name.*/ + mrb_funcall(mrb, obj, "method_name", 1, ary_ref); + fclose(fp); + mrb_close(mrb); + return 0; } ``` test.rb ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -211,36 +210,36 @@ In this example we read from a Ruby file inside C. The Ruby code will print what #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_value new_ary; - mrb_value ary_obj; - mrb_int random_value1 = 70; - mrb_int random_value2 = 60; - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - FILE *fp = fopen("test.rb","r"); - new_ary = mrb_ary_new(mrb); - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); - mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); - /* Sets the fixnum value of 7 to the second index of the array.*/ - mrb_ary_set(mrb, new_ary, 2, mrb_fixnum_value(7)); - mrb_value obj = mrb_load_file(mrb,fp); - mrb_funcall(mrb, obj, "before_after", 1, new_ary); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_value new_ary; + mrb_value ary_obj; + mrb_int random_value1 = 70; + mrb_int random_value2 = 60; + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + new_ary = mrb_ary_new(mrb); + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value1)); + mrb_ary_push(mrb, new_ary, mrb_fixnum_value(random_value2)); + /* Sets the fixnum value of 7 to the second index of the array.*/ + mrb_ary_set(mrb, new_ary, 2, mrb_fixnum_value(7)); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "before_after", 1, new_ary); + fclose(fp); + mrb_close(mrb); + return 0; } ``` test.rb ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end - def before_after(a) - puts a - end + def method_name(a) + puts a + puts a.class + end + def before_after(a) + puts a + end end Example_Class.new ``` diff --git a/doc/api/mruby/hash.h.md b/doc/api/mruby/hash.h.md index b7962696c..fa12ea670 100644 --- a/doc/api/mruby/hash.h.md +++ b/doc/api/mruby/hash.h.md @@ -17,19 +17,18 @@ to Hash.new. #include "mruby/hash.h" // Needs the hash header. #include "mruby/compile.h" - int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_funcall(mrb, obj, "method_name", 1, new_hash); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -37,10 +36,10 @@ int main(int argc, char *argv[]) ``` Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -67,22 +66,21 @@ a = {:da_key => 80} #include "mruby/hash.h" // Needs the hash header. #include "mruby/compile.h" - int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable. - mrb_sym hash_key = mrb_intern_cstr(mrb, "da_key"); // Declare a symbol. - mrb_int hash_value = 80; // Declare a fixnum value. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key), mrb_fixnum_value(hash_value)); // Set values to hash. - mrb_funcall(mrb, obj, "method_name", 1, new_hash); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable. + mrb_sym hash_key = mrb_intern_cstr(mrb, "da_key"); // Declare a symbol. + mrb_int hash_value = 80; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key), mrb_fixnum_value(hash_value)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -90,10 +88,10 @@ int main(int argc, char *argv[]) ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -131,25 +129,25 @@ a[:da_key] #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable for new hash object. - mrb_value get_hash_value; // Declare variable for getting a value from a hash. - mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. - mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. - mrb_int hash_value_a = 80; // Declare a fixnum value. - mrb_int hash_value_b = 90; // Declare a fixnum value. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. - get_hash_value = mrb_hash_get(mrb, new_hash, mrb_symbol_value(hash_key_b)); // Get value from hash. - mrb_funcall(mrb, obj, "method_name", 1, get_hash_value); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_value; // Declare variable for getting a value from a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + get_hash_value = mrb_hash_get(mrb, new_hash, mrb_symbol_value(hash_key_b)); // Get value from hash. + mrb_funcall(mrb, obj, "method_name", 1, get_hash_value); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -157,10 +155,10 @@ int main(int argc, char *argv[]) ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -198,26 +196,27 @@ a.delete(:da_key2) #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable for new hash object. - mrb_value get_hash_value; // Declare variable for getting a value from a hash. - mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. - mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. - mrb_int hash_value_a = 80; // Declare a fixnum value. - mrb_int hash_value_b = 90; // Declare a fixnum value. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. - mrb_funcall(mrb, obj, "method_name", 1, new_hash); - mrb_hash_delete_key(mrb, new_hash, mrb_symbol_value(hash_key_b)); - mrb_funcall(mrb, obj, "another_method_name", 1, new_hash); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_value; // Declare variable for getting a value from a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + mrb_hash_delete_key(mrb, new_hash, mrb_symbol_value(hash_key_b)); + mrb_funcall(mrb, obj, "another_method_name", 1, new_hash); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -225,14 +224,14 @@ int main(int argc, char *argv[]) ```Ruby class Example_Class - def method_name(a) - puts "Hash pre deletion #{a}" - #puts a.class - end - # Show deleted key and value pair. - def another_method_name(a) - puts "Hash post deletion #{a}" - end + def method_name(a) + puts "Hash pre deletion #{a}" + #puts a.class + end + # Show deleted key and value pair. + def another_method_name(a) + puts "Hash post deletion #{a}" + end end Example_Class.new ``` @@ -265,25 +264,25 @@ and what class the passed in value is. This example gets an array of keys from a #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable for new hash object. - mrb_value get_hash_keys; // Declare variable for getting an array of keys. - mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. - mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. - mrb_int hash_value_a = 80; // Declare a fixnum value. - mrb_int hash_value_b = 90; // Declare a fixnum value. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. - get_hash_keys = mrb_hash_keys(mrb, new_hash); // get an array of keys. - mrb_funcall(mrb, obj, "method_name", 1, get_hash_keys); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash_keys; // Declare variable for getting an array of keys. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + get_hash_keys = mrb_hash_keys(mrb, new_hash); // get an array of keys. + mrb_funcall(mrb, obj, "method_name", 1, get_hash_keys); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -291,10 +290,10 @@ int main(int argc, char *argv[]) ```Ruby class Example_Class - def method_name(a) - puts a - puts a.class - end + def method_name(a) + puts a + puts a.class + end end Example_Class.new ``` @@ -332,26 +331,26 @@ a.clear #include "mruby/compile.h" int main(int argc, char *argv[]) -{ - mrb_state *mrb = mrb_open(); - if (!mrb) { /* handle error */ } - mrb_value new_hash; // Declare variable for new hash object. - mrb_value get_hash; // Declare variable for getting a hash. - mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. - mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. - mrb_int hash_value_a = 80; // Declare a fixnum value. - mrb_int hash_value_b = 90; // Declare a fixnum value. - FILE *fp = fopen("test_ext.rb","r"); - new_hash = mrb_hash_new(mrb); // Initialize hash. - mrb_value obj = mrb_load_file(mrb,fp); - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. - mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. - mrb_funcall(mrb, obj, "method_name", 1, new_hash); - get_hash = mrb_hash_clear(mrb, new_hash); - mrb_funcall(mrb, obj, "another_method_name", 1, get_hash); - fclose(fp); - mrb_close(mrb); - return 0; +{ + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + mrb_value new_hash; // Declare variable for new hash object. + mrb_value get_hash; // Declare variable for getting a hash. + mrb_sym hash_key_a = mrb_intern_cstr(mrb, "da_key1"); // Declare a symbol. + mrb_sym hash_key_b = mrb_intern_cstr(mrb, "da_key2"); // Declare a symbol. + mrb_int hash_value_a = 80; // Declare a fixnum value. + mrb_int hash_value_b = 90; // Declare a fixnum value. + FILE *fp = fopen("test_ext.rb","r"); + new_hash = mrb_hash_new(mrb); // Initialize hash. + mrb_value obj = mrb_load_file(mrb,fp); + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_a), mrb_fixnum_value(hash_value_a)); // Set values to hash. + mrb_hash_set(mrb, new_hash, mrb_symbol_value(hash_key_b), mrb_fixnum_value(hash_value_b)); // Set values to hash. + mrb_funcall(mrb, obj, "method_name", 1, new_hash); + get_hash = mrb_hash_clear(mrb, new_hash); + mrb_funcall(mrb, obj, "another_method_name", 1, get_hash); + fclose(fp); + mrb_close(mrb); + return 0; } ``` @@ -359,14 +358,14 @@ int main(int argc, char *argv[]) ```Ruby class Example_Class - def method_name(a) - puts "Hash pre clear #{a}" - #puts a.class - end - # Show clear hash. - def another_method_name(a) - puts "Hash post clear #{a}" - end + def method_name(a) + puts "Hash pre clear #{a}" + #puts a.class + end + # Show clear hash. + def another_method_name(a) + puts "Hash post clear #{a}" + end end Example_Class.new ``` diff --git a/doc/api/mruby/value.h.md b/doc/api/mruby/value.h.md index f3ae2d421..fbf2dadf1 100644 --- a/doc/api/mruby/value.h.md +++ b/doc/api/mruby/value.h.md @@ -38,10 +38,10 @@ main(void) test.rb ```Ruby class My_Class - def method_name(s) - puts s - puts s.class - end + def method_name(s) + puts s + puts s.class + end end a = My_Class.new ``` @@ -86,10 +86,10 @@ main(void) test.rb ```Ruby class My_Class - def method_name(s) - puts s - puts s.class - end + def method_name(s) + puts s + puts s.class + end end a = My_Class.new ``` @@ -134,10 +134,10 @@ main(void) test.rb ```Ruby class My_Class - def method_name(s) - puts s - puts s.class - end + def method_name(s) + puts s + puts s.class + end end a = My_Class.new ``` @@ -181,10 +181,10 @@ main(void) test.rb ```Ruby class My_Class - def method_name(s) - puts s - puts s.class - end + def method_name(s) + puts s + puts s.class + end end a = My_Class.new ``` @@ -229,10 +229,10 @@ main(void) test.rb ```Ruby class My_Class - def method_name(s) - puts s - puts s.class - end + def method_name(s) + puts s + puts s.class + end end a = My_Class.new ``` From f01704477fd420839e002875e146a58a3af91c73 Mon Sep 17 00:00:00 2001 From: Seba Gamboa Date: Wed, 22 Jul 2015 21:57:20 -0300 Subject: [PATCH 140/218] Add ability to change compiler versions for androideabi --- tasks/toolchains/androideabi.rake | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake index 7cdb9e43a..d2d5dcec4 100644 --- a/tasks/toolchains/androideabi.rake +++ b/tasks/toolchains/androideabi.rake @@ -27,6 +27,8 @@ MRuby::Toolchain.new(:androideabi) do |conf| ANDROID_TARGET_ARCH = ENV['ANDROID_TARGET_ARCH'] || DEFAULT_ANDROID_TARGET_ARCH ANDROID_TARGET_ARCH_ABI = ENV['ANDROID_TARGET_ARCH_ABI'] || DEFAULT_ANDROID_TARGET_ARCH_ABI ANDROID_TOOLCHAIN = ENV['ANDROID_TOOLCHAIN'] || DEFAULT_ANDROID_TOOLCHAIN + GCC_VERSION = ENV['GCC_VERSION'] || GCC_VERSION + CLANG_VERSION = ENV['CLANG_VERSION'] || CLANG_VERSION case ANDROID_TARGET_ARCH.downcase when 'arch-arm', 'arm' then @@ -74,9 +76,9 @@ MRuby::Toolchain.new(:androideabi) do |conf| else # Any other architecture are not supported by Android NDK. end - path_to_toolchain += DEFAULT_GCC_VERSION + '/prebuilt/' + HOST_PLATFORM + path_to_toolchain += GCC_VERSION + '/prebuilt/' + HOST_PLATFORM else - path_to_toolchain += 'llvm-' + DEFAULT_CLANG_VERSION + '/prebuilt/' + HOST_PLATFORM + path_to_toolchain += 'llvm-' + CLANG_VERSION + '/prebuilt/' + HOST_PLATFORM end else path_to_toolchain = ANDROID_STANDALONE_TOOLCHAIN From 007d26f168689f785be9ddf97cc5293ad534a4c7 Mon Sep 17 00:00:00 2001 From: xuejianqing Date: Sat, 25 Jul 2015 18:43:27 +0800 Subject: [PATCH 141/218] fix android compile bug : uninitialized constant GCC_VERSION --- tasks/toolchains/androideabi.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake index d2d5dcec4..272e802f7 100644 --- a/tasks/toolchains/androideabi.rake +++ b/tasks/toolchains/androideabi.rake @@ -27,8 +27,8 @@ MRuby::Toolchain.new(:androideabi) do |conf| ANDROID_TARGET_ARCH = ENV['ANDROID_TARGET_ARCH'] || DEFAULT_ANDROID_TARGET_ARCH ANDROID_TARGET_ARCH_ABI = ENV['ANDROID_TARGET_ARCH_ABI'] || DEFAULT_ANDROID_TARGET_ARCH_ABI ANDROID_TOOLCHAIN = ENV['ANDROID_TOOLCHAIN'] || DEFAULT_ANDROID_TOOLCHAIN - GCC_VERSION = ENV['GCC_VERSION'] || GCC_VERSION - CLANG_VERSION = ENV['CLANG_VERSION'] || CLANG_VERSION + GCC_VERSION = ENV['GCC_VERSION'] || DEFAULT_GCC_VERSION + CLANG_VERSION = ENV['CLANG_VERSION'] || DEFAULT_CLANG_VERSION case ANDROID_TARGET_ARCH.downcase when 'arch-arm', 'arm' then From 54c853ff4aed510d777767dcefd9da5e05d6f505 Mon Sep 17 00:00:00 2001 From: xuejianqing Date: Sun, 26 Jul 2015 21:52:56 +0800 Subject: [PATCH 142/218] update mrbgems doc --- doc/mrbgems/README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/doc/mrbgems/README.md b/doc/mrbgems/README.md index e0c60daf2..f75231f71 100644 --- a/doc/mrbgems/README.md +++ b/doc/mrbgems/README.md @@ -198,17 +198,21 @@ end In case your GEM has more complex build requirements you can use the following options additionally inside of your GEM specification: -* `spec.cflags` (C compiler flags) -* `spec.mruby_cflags` (global C compiler flags for everything) -* `spec.mruby_ldflags` (global linker flags for everything) -* `spec.mruby_libs` (global libraries for everything) -* `spec.mruby_includes` (global includes for everything) +* `spec.cc.flags` (C compiler flags) +* `spec.cc.defines` (C compiler defines) +* `spec.cc.include_paths` (C compiler include paths) +* `spec.linker.flags` (Linker flags) +* `spec.linker.libraries` (Linker libraries) +* `spec.linker.library_paths` (Linker additional library path) +* `spec.bins` (Generate binary file) * `spec.rbfiles` (Ruby files to compile) * `spec.objs` (Object files to compile) * `spec.test_rbfiles` (Ruby test files for integration into mrbtest) * `spec.test_objs` (Object test files for integration into mrbtest) * `spec.test_preload` (Initialization files for mrbtest) +You also can use `spec.mruby.cc` and `spec.mruby.linker` to add extra global parameters for compiler and linker. + ### include_paths and dependency Your GEM can export include paths to another GEMs that depends on your GEM. From 578db292fd9a829d10f81cbcd274993219166f32 Mon Sep 17 00:00:00 2001 From: xuejianqing Date: Mon, 27 Jul 2015 12:22:23 +0800 Subject: [PATCH 143/218] mrbgem compile should be depend on mrbgem.rake --- tasks/mrbgem_spec.rake | 2 +- tasks/mruby_build_commands.rake | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index 04a9c39f0..d13e7733f 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -130,7 +130,7 @@ module MRuby end def define_gem_init_builder - file objfile("#{build_dir}/gem_init") => "#{build_dir}/gem_init.c" + file objfile("#{build_dir}/gem_init") => [ "#{build_dir}/gem_init.c", File.join(dir, "mrbgem.rake") ] file "#{build_dir}/gem_init.c" => [build.mrbcfile, __FILE__] + [rbfiles].flatten do |t| FileUtils.mkdir_p build_dir generate_gem_init("#{build_dir}/gem_init.c") diff --git a/tasks/mruby_build_commands.rake b/tasks/mruby_build_commands.rake index 4fbfaa785..f4805f46d 100644 --- a/tasks/mruby_build_commands.rake +++ b/tasks/mruby_build_commands.rake @@ -92,6 +92,8 @@ module MRuby def define_rules(build_dir, source_dir='') @out_ext = build.exts.object + gemrake = File.join(source_dir, "mrbgem.rake") + rakedep = File.exist?(gemrake) ? [ gemrake ] : [] if build_dir.include? "mrbgems/" generated_file_matcher = Regexp.new("^#{Regexp.escape build_dir}/(.*)#{Regexp.escape out_ext}$") @@ -104,7 +106,7 @@ module MRuby file.sub(generated_file_matcher, "#{source_dir}/\\1#{ext}") }, proc { |file| - get_dependencies(file) + get_dependencies(file) + rakedep } ] do |t| run t.name, t.prerequisites.first @@ -115,7 +117,7 @@ module MRuby file.sub(generated_file_matcher, "#{build_dir}/\\1#{ext}") }, proc { |file| - get_dependencies(file) + get_dependencies(file) + rakedep } ] do |t| run t.name, t.prerequisites.first From 923e04cf5051cde3000ee84604a2a3e14b5e655d Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Mon, 27 Jul 2015 17:16:37 -0400 Subject: [PATCH 144/218] Shallow clone mgem source --- tasks/mruby_build_gem.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index 26990a380..f0282aee0 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -59,7 +59,7 @@ module MRuby git.run_pull mgem_list_dir, mgem_list_url if $pull_gems else FileUtils.mkdir_p mgem_list_dir - git.run_clone mgem_list_dir, mgem_list_url + git.run_clone mgem_list_dir, mgem_list_url, "--depth 1" end require 'yaml' From ca49936468a5b2f10aa743ad2363ddcf29ff96d1 Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 29 Jul 2015 20:52:32 +0200 Subject: [PATCH 145/218] pop cmdarg in lambda body; fix [ruby-bug#11380] regression introduced by 2fe556d9c039839c20965a2c90dff703f04e40ec --- mrbgems/mruby-compiler/core/parse.y | 1 + 1 file changed, 1 insertion(+) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index b057cac17..338f6b9e3 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -2154,6 +2154,7 @@ primary : literal $$ = new_lambda(p, $3, $5); local_unnest(p); p->cmdarg_stack = $4; + CMDARG_LEXPOP(); } | keyword_if expr_value then compstmt From 89ebb0c4f15db5ed0e5e6d0715bfcf4fb0a1beac Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 30 Jul 2015 16:45:31 +0900 Subject: [PATCH 146/218] vm: execute ensure at the top of the fiber; fix #2903 --- src/vm.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/vm.c b/src/vm.c index 22ea177e0..765512a34 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1497,6 +1497,9 @@ RETRY_TRY_BLOCK: MRB_THROW(prev_jmp); } if (ci == mrb->c->cibase) { + while (eidx > 0) { + ecall(mrb, --eidx); + } if (ci->ridx == 0) { if (mrb->c == mrb->root_c) { regs = mrb->c->stack = mrb->c->stbase; From f0040b537136e8f36ff3a6de2508ca8c7c8974a6 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 30 Jul 2015 16:46:31 +0900 Subject: [PATCH 147/218] vm: execute ensure without exception at the top of the fiber; fix #2904 --- src/vm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vm.c b/src/vm.c index 765512a34..025b487bc 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1032,7 +1032,7 @@ RETRY_TRY_BLOCK: mrb_callinfo *ci = mrb->c->ci; int n, eidx = ci->eidx; - for (n=0; n ci[-1].eidx; n++) { + for (n=0; nc->cibase || eidx > ci[-1].eidx); n++) { ecall(mrb, --eidx); ARENA_RESTORE(mrb, ai); } From 52a9712c26baafe0763557eba4da0057c2b57509 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 1 Aug 2015 16:16:22 +0900 Subject: [PATCH 148/218] link libncurses when there's /usr/include/curses.h; fix #2905 --- mrbgems/mruby-bin-mirb/mrbgem.rake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mrbgems/mruby-bin-mirb/mrbgem.rake b/mrbgems/mruby-bin-mirb/mrbgem.rake index 7d45409c9..a74871d81 100644 --- a/mrbgems/mruby-bin-mirb/mrbgem.rake +++ b/mrbgems/mruby-bin-mirb/mrbgem.rake @@ -20,6 +20,9 @@ MRuby::Gem::Specification.new('mruby-bin-mirb') do |spec| spec.linker.libraries << 'edit' else spec.linker.libraries << 'readline' + if spec.build.cc.search_header_path 'curses.h' + spec.linker.libraries << 'ncurses' + end end elsif spec.build.cc.search_header_path 'linenoise.h' spec.cc.defines << "ENABLE_LINENOISE" From 5c055d670a7c45e0d6ba201aa8ca44a4fd24ecba Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Sun, 2 Aug 2015 14:37:12 +0200 Subject: [PATCH 149/218] be able to source with :path for mrbgems --- tasks/mruby_build_gem.rake | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake index f0282aee0..896aeb147 100644 --- a/tasks/mruby_build_gem.rake +++ b/tasks/mruby_build_gem.rake @@ -76,6 +76,9 @@ module MRuby if params[:core] gemdir = "#{root}/mrbgems/#{params[:core]}" + elsif params[:path] + require 'pathname' + gemdir = Pathname.new(params[:path]).absolute? ? params[:path] : "#{root}/#{params[:path]}" elsif params[:git] url = params[:git] gemdir = "#{gem_clone_dir}/#{url.match(/([-\w]+)(\.[-\w]+|)$/).to_a[1]}" From 95412aeb502298e58233117d6be7dc2e95912491 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 3 Aug 2015 13:24:04 +0900 Subject: [PATCH 150/218] better hash value from enumerables; fix #2906 --- mrblib/enum.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mrblib/enum.rb b/mrblib/enum.rb index 6bf219283..e979fe90e 100644 --- a/mrblib/enum.rb +++ b/mrblib/enum.rb @@ -402,8 +402,11 @@ module Enumerable # redefine #hash 15.3.1.3.15 def hash h = 12347 + i = 0 self.each do |e| - h ^= e.hash + n = e.hash << (i % 16) + h ^= n + i += 1 end h end From 996d0c03450a6ebd9e004b0a323ed7724386ebc5 Mon Sep 17 00:00:00 2001 From: Hiro Asari Date: Mon, 3 Aug 2015 19:22:46 -0400 Subject: [PATCH 151/218] Set language, and use the new Trusty env --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f7be58c8a..b1230ede7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,6 @@ -# no installation... +language: c + +sudo: 9000 install: - sudo apt-get -q install gperf From dd612950b418b607812b1ccee3a1c2b1ec2a7f46 Mon Sep 17 00:00:00 2001 From: Hiro Asari Date: Mon, 3 Aug 2015 19:47:49 -0400 Subject: [PATCH 152/218] Update package list --- .travis.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index b1230ede7..95e20ef2a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,8 @@ language: c sudo: 9000 install: - - sudo apt-get -q install gperf + - sudo apt-get update -qq + - sudo apt-get -q install gperf env: MRUBY_CONFIG=travis_config.rb script: "./minirake all test" From fca9522af35a5ec89d783b5611d31ad455d433c0 Mon Sep 17 00:00:00 2001 From: Hiro Asari Date: Mon, 3 Aug 2015 19:55:44 -0400 Subject: [PATCH 153/218] Build matrix of size 2 --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 95e20ef2a..928c28efe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,8 @@ language: c -sudo: 9000 +matrix: + include: + - sudo: 9000 install: - sudo apt-get update -qq From e3361fbc2ad3fc10e7e06aa611542fff783fabfe Mon Sep 17 00:00:00 2001 From: Hiro Asari Date: Mon, 3 Aug 2015 20:05:15 -0400 Subject: [PATCH 154/218] Add OS X build to the matrix --- .travis.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 928c28efe..a3978577c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,11 +2,12 @@ language: c matrix: include: - - sudo: 9000 + - os: linux + sudo: 9000 + - os: osx install: - - sudo apt-get update -qq - - sudo apt-get -q install gperf + - if [ $TRAVIS_OS_NAME = 'linux' ]; then sudo apt-get update -qq; sudo apt-get -q install gperf; fi env: MRUBY_CONFIG=travis_config.rb script: "./minirake all test" From bfcc55fbf98665b33ca7110349aeb66d3ef0df1d Mon Sep 17 00:00:00 2001 From: Hiro Asari Date: Mon, 3 Aug 2015 20:34:45 -0400 Subject: [PATCH 155/218] Try building on Xcode 6.4 The default 6.1 was slow --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index a3978577c..bcfce3984 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,6 +5,7 @@ matrix: - os: linux sudo: 9000 - os: osx + osx_image: xcod6.4 install: - if [ $TRAVIS_OS_NAME = 'linux' ]; then sudo apt-get update -qq; sudo apt-get -q install gperf; fi From 4fdf492219ded3a48382970e2678f04b4fc912cd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 5 Aug 2015 11:28:41 +0900 Subject: [PATCH 156/218] add String#setbyte and String#byteslice to mruby-string-ext --- mrbgems/mruby-string-ext/src/string.c | 56 +++++++++++++++++++++++++ mrbgems/mruby-string-ext/test/string.rb | 16 +++++++ 2 files changed, 72 insertions(+) diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c index e925a82a7..12657e129 100644 --- a/mrbgems/mruby-string-ext/src/string.c +++ b/mrbgems/mruby-string-ext/src/string.c @@ -3,6 +3,7 @@ #include "mruby/array.h" #include "mruby/class.h" #include "mruby/string.h" +#include "mruby/range.h" static mrb_value mrb_str_getbyte(mrb_state *mrb, mrb_value str) @@ -18,6 +19,59 @@ mrb_str_getbyte(mrb_state *mrb, mrb_value str) return mrb_fixnum_value((unsigned char)RSTRING_PTR(str)[pos]); } +static mrb_value +mrb_str_setbyte(mrb_state *mrb, mrb_value str) +{ + mrb_int pos, byte; + long len = RSTRING_LEN(str); + + mrb_get_args(mrb, "ii", &pos, &byte); + + if (pos < -len || len <= pos) + mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos)); + if (pos < 0) + pos += len; + + mrb_str_modify(mrb, mrb_str_ptr(str)); + byte &= 0xff; + RSTRING_PTR(str)[pos] = byte; + return mrb_fixnum_value((unsigned char)byte); +} + +static mrb_value +mrb_str_byteslice(mrb_state *mrb, mrb_value str) +{ + mrb_value a1; + mrb_int len; + int argc; + + argc = mrb_get_args(mrb, "o|i", &a1, &len); + if (argc == 2) { + return mrb_str_substr(mrb, str, mrb_fixnum(a1), len); + } + switch (mrb_type(a1)) { + case MRB_TT_RANGE: + { + mrb_int beg; + + len = RSTRING_LEN(str); + if (mrb_range_beg_len(mrb, a1, &beg, &len, len)) { + return mrb_str_substr(mrb, str, beg, len); + } + return mrb_nil_value(); + } + case MRB_TT_FLOAT: + a1 = mrb_fixnum_value((mrb_int)mrb_float(a1)); + /* fall through */ + case MRB_TT_FIXNUM: + return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1); + default: + mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument"); + } + /* not reached */ + return mrb_nil_value(); +} + /* * call-seq: * str.swapcase! -> str or nil @@ -375,6 +429,8 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, s, "dump", mrb_str_dump, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "getbyte", mrb_str_getbyte, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, s, "setbyte", mrb_str_setbyte, MRB_ARGS_REQ(2)); + mrb_define_method(mrb, s, "byteslice", mrb_str_byteslice, MRB_ARGS_REQ(1)|MRB_ARGS_OPT(1)); mrb_define_method(mrb, s, "swapcase!", mrb_str_swapcase_bang, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "swapcase", mrb_str_swapcase, MRB_ARGS_NONE()); mrb_define_method(mrb, s, "concat", mrb_str_concat2, MRB_ARGS_REQ(1)); diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb index 14e00428e..5e4847f05 100644 --- a/mrbgems/mruby-string-ext/test/string.rb +++ b/mrbgems/mruby-string-ext/test/string.rb @@ -13,6 +13,22 @@ assert('String#getbyte') do assert_equal bytes2[0], str2.getbyte(0) end +assert('String#setbyte') do + str1 = "hello" + h = "H".getbyte(0) + str1.setbyte(0, h) + assert_equal(h, str1.getbyte(0)) + assert_equal("Hello", str1) +end + +assert('String#byteslice') do + str1 = "hello" + assert_equal("e", str1.byteslice(1)) + assert_equal("o", str1.byteslice(-1)) + assert_equal("ell", str1.byteslice(1..3)) + assert_equal("el", str1.byteslice(1...3)) +end + assert('String#dump') do ("\1" * 100).dump # should not raise an exception - regress #1210 "\0".inspect == "\"\\000\"" and From 0c7d29dff68b4d85fbbc9c6f8c0328ddb303f000 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Fri, 7 Aug 2015 15:30:52 +0900 Subject: [PATCH 157/218] FIXABLE() may work wrong on MRB_INT64; fix #2909 --- src/numeric.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/numeric.c b/src/numeric.c index b9aef51d9..14c0b76a6 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -55,7 +55,8 @@ num_pow(mrb_state *mrb, mrb_value x) mrb_get_args(mrb, "o", &y); yv = mrb_to_flo(mrb, y); d = pow(mrb_to_flo(mrb, x), yv); - if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0) + if (mrb_fixnum_p(x) && mrb_fixnum_p(y) && FIXABLE(d) && yv > 0 && + (d < 0 || (d > 0 && (mrb_int)d > 0))) return mrb_fixnum_value((mrb_int)d); return mrb_float_value(mrb, d); } From 5af770cd59f6edb6f111f497fef4df3fe956cc62 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 10 Aug 2015 11:41:01 +0900 Subject: [PATCH 158/218] prevent out-of-bounds ensure clause access; fix #2910 --- src/vm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vm.c b/src/vm.c index 025b487bc..00636a870 100644 --- a/src/vm.c +++ b/src/vm.c @@ -266,6 +266,7 @@ ecall(mrb_state *mrb, int i) mrb_value *self = mrb->c->stack; struct RObject *exc; + if (i<0) return; p = mrb->c->ensure[i]; if (!p) return; if (mrb->c->ci->eidx > i) From b34ee9a4b4cf75135ab8c6887068687bbd9f5b06 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 10 Aug 2015 14:55:48 +0900 Subject: [PATCH 159/218] codegen: reserve stack region for OP_APOST; fix #2824 --- mrbgems/mruby-compiler/core/codegen.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index cefde8b7b..b128231cf 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -406,7 +406,18 @@ push_(codegen_scope *s) nregs_update; } +static void +push_n_(codegen_scope *s, size_t n) +{ + if (s->sp+n > 511) { + codegen_error(s, "too complex expression"); + } + s->sp+=n; + nregs_update; +} + #define push() push_(s) +#define push_n(n) push_n_(s,n) #define pop_(s) ((s)->sp--) #define pop() pop_(s) #define pop_n(n) (s->sp-=(n)) @@ -1001,6 +1012,8 @@ gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val) else { pop(); } + push_n(post); + pop_n(post); genop(s, MKOP_ABC(OP_APOST, cursp(), n, post)); n = 1; if (t->car) { /* rest */ From dfaff83eba8fbf3953b6ab0e92df41899de2eccc Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 10 Aug 2015 15:11:00 +0900 Subject: [PATCH 160/218] codegen: add peep hole optimization to skip overridden OP_MOVE --- mrbgems/mruby-compiler/core/codegen.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index b128231cf..ba451309e 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -188,6 +188,11 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (val) break; switch (c0) { case OP_MOVE: + if (GETARG_A(i) == GETARG_A(i0)) { + /* skip overriden OP_MOVE */ + s->pc--; + return genop_peep(s, i, val); + } if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { /* skip swapping OP_MOVE */ return 0; From e4f32ad9ad96fddb5613178a848fafe5c869f7c9 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 10 Aug 2015 15:19:32 +0900 Subject: [PATCH 161/218] codegen: don't need to genop(); just update s->iseq directly --- mrbgems/mruby-compiler/core/codegen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c index ba451309e..3853814ec 100644 --- a/mrbgems/mruby-compiler/core/codegen.c +++ b/mrbgems/mruby-compiler/core/codegen.c @@ -191,7 +191,7 @@ genop_peep(codegen_scope *s, mrb_code i, int val) if (GETARG_A(i) == GETARG_A(i0)) { /* skip overriden OP_MOVE */ s->pc--; - return genop_peep(s, i, val); + s->iseq[s->pc] = i; } if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { /* skip swapping OP_MOVE */ From 2574adab48d0995204ee45b812125b2134c6c8f3 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Tue, 11 Aug 2015 16:27:48 +0900 Subject: [PATCH 162/218] compiler: allow "class A end" by tweaking the superclass rule like CRuby2.3 --- mrbgems/mruby-compiler/core/parse.y | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 338f6b9e3..097d63ac4 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -2942,7 +2942,7 @@ backref : tNTH_REF | tBACK_REF ; -superclass : term +superclass : /* term */ { $$ = 0; } @@ -2954,12 +2954,12 @@ superclass : term expr_value term { $$ = $3; - } + } /* | error term { yyerrok; $$ = 0; - } + } */ ; f_arglist : '(' f_args rparen From 96c948d812f06c1ad1024f6db5089e47dbd58d23 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Tue, 11 Aug 2015 18:02:12 +0900 Subject: [PATCH 163/218] Remove non-need tmp value --- src/etc.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/etc.c b/src/etc.c index a8a21e740..f5a502795 100644 --- a/src/etc.c +++ b/src/etc.c @@ -67,17 +67,15 @@ mrb_data_get_ptr(mrb_state *mrb, mrb_value obj, const mrb_data_type *type) MRB_API mrb_sym mrb_obj_to_sym(mrb_state *mrb, mrb_value name) { - mrb_value tmp; mrb_sym id; switch (mrb_type(name)) { default: - tmp = mrb_check_string_type(mrb, name); - if (mrb_nil_p(tmp)) { - tmp = mrb_inspect(mrb, name); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); + name = mrb_check_string_type(mrb, name); + if (mrb_nil_p(name)) { + name = mrb_inspect(mrb, name); + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", name); } - name = tmp; /* fall through */ case MRB_TT_STRING: name = mrb_str_intern(mrb, name); From c7fad5aa33f77d1869d9b879c9f8aeb5e688d64c Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Wed, 12 Aug 2015 10:20:55 +0900 Subject: [PATCH 164/218] Remove duplicated RARRAY_LEN check --- src/array.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/array.c b/src/array.c index 0a99040c0..2622ee528 100644 --- a/src/array.c +++ b/src/array.c @@ -19,7 +19,6 @@ static inline mrb_value ary_elt(mrb_value ary, mrb_int offset) { - if (RARRAY_LEN(ary) == 0) return mrb_nil_value(); if (offset < 0 || RARRAY_LEN(ary) <= offset) { return mrb_nil_value(); } From ad50a6c4103b6a95e25ed7eaaf99b79a220d36cf Mon Sep 17 00:00:00 2001 From: cremno Date: Wed, 29 Jul 2015 21:54:06 +0200 Subject: [PATCH 165/218] fix irep float dump format string for MRB_USE_FLOAT IEC 60559 single format has 6 to 9 significant decimal digits precision. However the printf conversion specifier e (and E, of course) already writes 1 digit - the one before the decimal point - and precision specifies the number of digits to write after the decimal point. --- src/dump.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/dump.c b/src/dump.c index 462e036b4..734f38043 100644 --- a/src/dump.c +++ b/src/dump.c @@ -16,7 +16,7 @@ #define FLAG_BYTEORDER_NONATIVE 0 #ifdef MRB_USE_FLOAT -#define MRB_FLOAT_FMT "%.9e" +#define MRB_FLOAT_FMT "%.8e" #else #define MRB_FLOAT_FMT "%.16e" #endif From eec00ccf6074cfe5d5b7357180b58282d0dd8c66 Mon Sep 17 00:00:00 2001 From: cremno Date: Mon, 17 Aug 2015 20:51:25 +0200 Subject: [PATCH 166/218] delete duplicate definition of Exception.exception It overwrote the original definition in src/error.c, line 446. --- mrblib/error.rb | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/mrblib/error.rb b/mrblib/error.rb index d76dd9c56..2674af7a2 100644 --- a/mrblib/error.rb +++ b/mrblib/error.rb @@ -1,18 +1,3 @@ -## -# Exception -# -# ISO 15.2.22 -class Exception - - ## - # Raise an exception. - # - # ISO 15.2.22.4.1 - def self.exception(*args, &block) - self.new(*args, &block) - end -end - # ISO 15.2.24 class ArgumentError < StandardError end From c326f065e17b31035815bf90a7f3cbf7e605a275 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Wed, 19 Aug 2015 16:17:06 +0900 Subject: [PATCH 167/218] array.rb: refactor some code --- mrblib/array.rb | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/mrblib/array.rb b/mrblib/array.rb index 933f822db..ef2b53725 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -16,7 +16,7 @@ class Array while idx < length and length <= self.length and length = self.length-1 elm = self[idx += 1] unless elm - if elm == nil and length >= self.length + if elm.nil? and length >= self.length break end end @@ -50,9 +50,7 @@ class Array def collect!(&block) return to_enum :collect! unless block_given? - self.each_index{|idx| - self[idx] = block.call(self[idx]) - } + self.each_index { |idx| self[idx] = block.call(self[idx]) } self end @@ -72,7 +70,7 @@ class Array self.clear if size > 0 - self[size - 1] = nil # allocate + self[size - 1] = nil # allocate idx = 0 while idx < size @@ -158,14 +156,11 @@ class Array len = self.size n = other.size - if len > n - len = n - end + len = n if len > n i = 0 while i < len n = (self[i] <=> other[i]) - return n if n == nil - return n if n != 0 + return n if n.nil? || n != 0 i += 1 end len = self.size - other.size @@ -185,7 +180,7 @@ class Array self.delete_at(i) ret = key end - if ret == nil && block + if ret.nil? && block block.call else ret From cf588bd5cb094e6ee22d8d45c2005cf0da55d197 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 17:28:34 +0900 Subject: [PATCH 168/218] range.rb: refactor code (use ! instead of not, use favor modifier if and unless usage when having a single-line body) --- mrblib/range.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/mrblib/range.rb b/mrblib/range.rb index 64fa0cb6c..5e5fd9bdc 100644 --- a/mrblib/range.rb +++ b/mrblib/range.rb @@ -26,9 +26,7 @@ class Range return self end - unless val.respond_to? :succ - raise TypeError, "can't iterate" - end + raise TypeError, "can't iterate" unless val.respond_to? :succ return self if (val <=> last) > 0 @@ -37,18 +35,14 @@ class Range val = val.succ end - if not exclude_end? and (val <=> last) == 0 - block.call(val) - end + block.call(val) if !exclude_end? && (val <=> last) == 0 self end # redefine #hash 15.3.1.3.15 def hash h = first.hash ^ last.hash - if self.exclude_end? - h += 1 - end + h += 1 if self.exclude_end? h end end From cb870de2b52fad05c8ba0b23893008d0ba77ac3b Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 17:33:16 +0900 Subject: [PATCH 169/218] numeric.rb: refactor code (Avoid using {...} for multi-line blocks, Surrounding space missing in default value assignment) --- mrblib/numeric.rb | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb index cf608b04b..206185e78 100644 --- a/mrblib/numeric.rb +++ b/mrblib/numeric.rb @@ -100,7 +100,7 @@ module Integral # Calls the given block from +self+ to +num+ # incremented by +step+ (default 1). # - def step(num, step=1, &block) + def step(num, step = 1, &block) raise ArgumentError, "step can't be 0" if step == 0 return to_enum(:step, num, step) unless block_given? @@ -165,16 +165,12 @@ class Float # floats should be compatible to integers. def >> other n = self.to_i - other.to_i.times { - n /= 2 - } + other.to_i.times { n /= 2 } n end def << other n = self.to_i - other.to_i.times { - n *= 2 - } + other.to_i.times { n *= 2 } n.to_i end end From 11524f6f678fde684941937413b6bc2cba23b630 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 17:52:30 +0900 Subject: [PATCH 170/218] string.rb: refactor code (remove redundant code) --- mrblib/string.rb | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/mrblib/string.rb b/mrblib/string.rb index 23cf02e97..05b13cb43 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -80,12 +80,8 @@ class String # ISO 15.2.10.5.19 def gsub!(*args, &block) str = self.gsub(*args, &block) - if str != self - self.replace(str) - self - else - nil - end + return nil if str == self + self.replace(str) end ## @@ -129,12 +125,8 @@ class String # ISO 15.2.10.5.37 def sub!(*args, &block) str = self.sub(*args, &block) - if str != self - self.replace(str) - self - else - nil - end + return nil if str == self + self.replace(str) end ## @@ -165,20 +157,16 @@ class String # Modify +self+ by replacing the content of +self+ # at the position +pos+ with +value+. def []=(pos, value) - if pos < 0 - pos += self.length - end + pos += self.length if pos < 0 b = self[0, pos] - a = self[pos+1..-1] + a = self[pos + 1..-1] self.replace([b, value, a].join('')) end ## # ISO 15.2.10.5.3 def =~(re) - if re.respond_to? :to_str - raise TypeError, "type mismatch: String given" - end + raise TypeError, "type mismatch: String given" if re.respond_to? :to_str re =~ self end From 931a7223e6ec20bfc5dbb894c74e7e7d638dc538 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 18:53:13 +0900 Subject: [PATCH 171/218] array.rb: refactor (use onliner code if possible) --- mrblib/array.rb | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/mrblib/array.rb b/mrblib/array.rb index ef2b53725..65dd0d665 100644 --- a/mrblib/array.rb +++ b/mrblib/array.rb @@ -180,20 +180,14 @@ class Array self.delete_at(i) ret = key end - if ret.nil? && block - block.call - else - ret - end + return block.call if ret.nil? && block + ret end # internal method to convert multi-value to single value def __svalue - if self.size < 2 - self.first - else - self - end + return self.first if self.size < 2 + self end end From 85f0dd7da0fe41310883d9a65156c429135590f5 Mon Sep 17 00:00:00 2001 From: "go.kikuta" Date: Thu, 20 Aug 2015 18:53:56 +0900 Subject: [PATCH 172/218] enum.rb: refactor code (remove redundant code) --- mrblib/enum.rb | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) diff --git a/mrblib/enum.rb b/mrblib/enum.rb index e979fe90e..f0c9a4884 100644 --- a/mrblib/enum.rb +++ b/mrblib/enum.rb @@ -24,17 +24,9 @@ module Enumerable # ISO 15.3.2.2.1 def all?(&block) if block - self.each{|*val| - unless block.call(*val) - return false - end - } + self.each{|*val| return false unless block.call(*val)} else - self.each{|*val| - unless val.__svalue - return false - end - } + self.each{|*val| return false unless val.__svalue} end true end @@ -49,17 +41,9 @@ module Enumerable # ISO 15.3.2.2.2 def any?(&block) if block - self.each{|*val| - if block.call(*val) - return true - end - } + self.each{|*val| return true if block.call(*val)} else - self.each{|*val| - if val.__svalue - return true - end - } + self.each{|*val| return true if val.__svalue} end false end @@ -75,9 +59,7 @@ module Enumerable return to_enum :collect unless block ary = [] - self.each{|*val| - ary.push(block.call(*val)) - } + self.each{|*val| ary.push(block.call(*val))} ary end @@ -183,9 +165,7 @@ module Enumerable # ISO 15.3.2.2.10 def include?(obj) self.each{|*val| - if val.__svalue == obj - return true - end + return true if val.__svalue == obj } false end From 0d055559f1d447b1ae694aae2ded63dbff7cd7c2 Mon Sep 17 00:00:00 2001 From: INOUE Yasuyuki Date: Sat, 22 Aug 2015 19:57:11 +0900 Subject: [PATCH 173/218] Use #nil? instead of == nil. --- mrbgems/mruby-array-ext/mrblib/array.rb | 24 +++++++++++------------ mrbgems/mruby-enum-ext/mrblib/enum.rb | 6 +++--- mrbgems/mruby-string-ext/mrblib/string.rb | 12 ++++++------ 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/mrbgems/mruby-array-ext/mrblib/array.rb b/mrbgems/mruby-array-ext/mrblib/array.rb index fd80fa0bb..1f1d97376 100644 --- a/mrbgems/mruby-array-ext/mrblib/array.rb +++ b/mrbgems/mruby-array-ext/mrblib/array.rb @@ -217,7 +217,7 @@ class Array # [ "a", "b", "c" ].compact! #=> nil # def compact! - result = self.select { |e| e != nil } + result = self.select { |e| !e.nil? } if result.size == self.size nil else @@ -262,7 +262,7 @@ class Array # def fetch(n=nil, ifnone=NONE, &block) - warn "block supersedes default value argument" if n != nil && ifnone != NONE && block + warn "block supersedes default value argument" if !n.nil? && ifnone != NONE && block idx = n if idx < 0 @@ -312,51 +312,51 @@ class Array # def fill(arg0=nil, arg1=nil, arg2=nil, &block) - if arg0 == nil && arg1 == nil && arg2 == nil && !block + if arg0.nil? && arg1.nil? && arg2.nil? && !block raise ArgumentError, "wrong number of arguments (0 for 1..3)" end beg = len = 0 ary = [] if block - if arg0 == nil && arg1 == nil && arg2 == nil + if arg0.nil? && arg1.nil? && arg2.nil? # ary.fill { |index| block } -> ary beg = 0 len = self.size - elsif arg0 != nil && arg0.kind_of?(Range) + elsif !arg0.nil? && arg0.kind_of?(Range) # ary.fill(range) { |index| block } -> ary beg = arg0.begin beg += self.size if beg < 0 len = arg0.end len += self.size if len < 0 len += 1 unless arg0.exclude_end? - elsif arg0 != nil + elsif !arg0.nil? # ary.fill(start [, length] ) { |index| block } -> ary beg = arg0 beg += self.size if beg < 0 - if arg1 == nil + if arg1.nil? len = self.size else len = arg0 + arg1 end end else - if arg0 != nil && arg1 == nil && arg2 == nil + if !arg0.nil? && arg1.nil? && arg2.nil? # ary.fill(obj) -> ary beg = 0 len = self.size - elsif arg0 != nil && arg1 != nil && arg1.kind_of?(Range) + elsif !arg0.nil? && !arg1.nil? && arg1.kind_of?(Range) # ary.fill(obj, range ) -> ary beg = arg1.begin beg += self.size if beg < 0 len = arg1.end len += self.size if len < 0 len += 1 unless arg1.exclude_end? - elsif arg0 != nil && arg1 != nil + elsif !arg0.nil? && !arg1.nil? # ary.fill(obj, start [, length]) -> ary beg = arg1 beg += self.size if beg < 0 - if arg2 == nil + if arg2.nil? len = self.size else len = beg + arg2 @@ -582,7 +582,7 @@ class Array elsif v == true satisfied = true smaller = true - elsif v == false || v == nil + elsif v == false || v.nil? smaller = false end if smaller diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb index f6629ed79..6fef0c077 100644 --- a/mrbgems/mruby-enum-ext/mrblib/enum.rb +++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb @@ -515,7 +515,7 @@ module Enumerable # def each_with_object(obj=nil, &block) - raise ArgumentError, "wrong number of arguments (0 for 1)" if obj == nil + raise ArgumentError, "wrong number of arguments (0 for 1)" if obj.nil? return to_enum(:each_with_object, obj) unless block @@ -574,10 +574,10 @@ module Enumerable # def cycle(n=nil, &block) - return to_enum(:cycle, n) if !block && n == nil + return to_enum(:cycle, n) if !block && n.nil? ary = [] - if n == nil + if n.nil? self.each do|*val| ary.push val block.call(*val) diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb index 2b61fdb48..7d9bc00b9 100644 --- a/mrbgems/mruby-string-ext/mrblib/string.rb +++ b/mrbgems/mruby-string-ext/mrblib/string.rb @@ -164,9 +164,9 @@ class String # string #=> "thsa sting" # def slice!(arg1, arg2=nil) - raise "wrong number of arguments (for 1..2)" if arg1 == nil && arg2 == nil + raise "wrong number of arguments (for 1..2)" if arg1.nil? && arg2.nil? - if arg1 != nil && arg2 != nil + if !arg1.nil? && !arg2.nil? idx = arg1 idx += self.size if arg1 < 0 if idx >= 0 && idx <= self.size && arg2 > 0 @@ -196,8 +196,8 @@ class String return nil end end - unless str == nil || str == "" - if arg1 != nil && arg2 !=nil + unless str.nil? || str == "" + if !arg1.nil? && !arg2.nil? idx = arg1 >= 0 ? arg1 : self.size+arg1 str2 = self[0...idx] + self[idx+arg2..-1].to_s else @@ -207,13 +207,13 @@ class String str2 = self[0...idx] + self[idx2+1..-1].to_s elsif arg1.kind_of?(String) idx = self.index(arg1) - str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx == nil + str2 = self[0...idx] + self[idx+arg1.size..-1] unless idx.nil? else idx = arg1 >= 0 ? arg1 : self.size+arg1 str2 = self[0...idx] + self[idx+1..-1].to_s end end - self.replace(str2) unless str2 == nil + self.replace(str2) unless str2.nil? end str end From 383a7d24d369bbd0e8813d7aabc587fb769e9d9c Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sat, 22 Aug 2015 10:18:12 -0400 Subject: [PATCH 174/218] Move test source code and rake task to mrbgem --- {test => mrbgems/mruby-test}/README.md | 0 {test => mrbgems/mruby-test}/driver.c | 0 {test => mrbgems/mruby-test}/init_mrbtest.c | 0 test/mrbtest.rake => mrbgems/mruby-test/mrbgem.rake | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {test => mrbgems/mruby-test}/README.md (100%) rename {test => mrbgems/mruby-test}/driver.c (100%) rename {test => mrbgems/mruby-test}/init_mrbtest.c (100%) rename test/mrbtest.rake => mrbgems/mruby-test/mrbgem.rake (100%) diff --git a/test/README.md b/mrbgems/mruby-test/README.md similarity index 100% rename from test/README.md rename to mrbgems/mruby-test/README.md diff --git a/test/driver.c b/mrbgems/mruby-test/driver.c similarity index 100% rename from test/driver.c rename to mrbgems/mruby-test/driver.c diff --git a/test/init_mrbtest.c b/mrbgems/mruby-test/init_mrbtest.c similarity index 100% rename from test/init_mrbtest.c rename to mrbgems/mruby-test/init_mrbtest.c diff --git a/test/mrbtest.rake b/mrbgems/mruby-test/mrbgem.rake similarity index 100% rename from test/mrbtest.rake rename to mrbgems/mruby-test/mrbgem.rake From c7d0f8ebcbcd21fbe624bfd1e9b43a8037703a6d Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sat, 22 Aug 2015 10:20:15 -0400 Subject: [PATCH 175/218] Refactor test/mrbtest.rake and tasks/mrbgems_test.rake into mrbgem.rake --- mrbgems/mruby-test/mrbgem.rake | 173 ++++++++++++++++++++++++++------- 1 file changed, 139 insertions(+), 34 deletions(-) diff --git a/mrbgems/mruby-test/mrbgem.rake b/mrbgems/mruby-test/mrbgem.rake index b9616fe9d..8370f4713 100644 --- a/mrbgems/mruby-test/mrbgem.rake +++ b/mrbgems/mruby-test/mrbgem.rake @@ -1,47 +1,152 @@ -MRuby.each_target do - current_dir = File.dirname(__FILE__).relative_path_from(Dir.pwd) - relative_from_root = File.dirname(__FILE__).relative_path_from(MRUBY_ROOT) - current_build_dir = "#{build_dir}/#{relative_from_root}" +MRuby::Gem::Specification.new('mruby-test') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.summary = 'mruby test' - exec = exefile("#{current_build_dir}/mrbtest") - clib = "#{current_build_dir}/mrbtest.c" + build.bins << 'mrbtest' + spec.add_dependency('mruby-compiler', :core => 'mruby-compiler') + + clib = "#{build_dir}/mrbtest.c" mlib = clib.ext(exts.object) - mrbs = Dir.glob("#{current_dir}/t/*.rb") - init = "#{current_dir}/init_mrbtest.c" - ass_c = "#{current_build_dir}/assert.c" - ass_lib = ass_c.ext(exts.object) + mrbs = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb") + exec = exefile("#{build.build_dir}/bin/mrbtest") - mrbtest_lib = libfile("#{current_build_dir}/mrbtest") - mrbtest_objs = [mlib, ass_lib] - gems.each do |v| + libmruby = libfile("#{build.build_dir}/lib/libmruby") + libmruby_core = libfile("#{build.build_dir}/lib/libmruby_core") + + mrbtest_lib = libfile("#{build_dir}/mrbtest") + mrbtest_objs = [] + + driver_obj = objfile("#{build_dir}/driver") + driver = "#{spec.dir}/driver.c" + + assert_c = "#{build_dir}/assert.c" + assert_rb = "#{MRUBY_ROOT}/test/assert.rb" + assert_lib = assert_c.ext(exts.object) + mrbtest_objs << assert_lib + + file assert_lib => assert_c + file assert_c => [build.mrbcfile, assert_rb] do |t| + open(t.name, 'w') do |f| + mrbc.run f, assert_rb, 'mrbtest_assert_irep' + end + end + + gem_table = build.gems.generate_gem_table self + + build.gems.each do |g| + test_rbobj = g.test_rbireps.ext(exts.object) + g.test_objs << test_rbobj + dep_list = build.gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions) + + file test_rbobj => g.test_rbireps + file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| + FileUtils.mkdir_p File.dirname(t.name) + open(t.name, 'w') do |f| + g.print_gem_test_header(f) + test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| + File.expand_path(g.test_preload, dir) + }.find {|file| File.exist?(file) } + + f.puts %Q[/*] + f.puts %Q[ * This file contains a test code for #{g.name} gem.] + f.puts %Q[ *] + f.puts %Q[ * IMPORTANT:] + f.puts %Q[ * This file was generated!] + f.puts %Q[ * All manual changes will get lost.] + f.puts %Q[ */] + if test_preload.nil? + f.puts %Q[extern const uint8_t mrbtest_assert_irep[];] + else + g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload" + end + g.test_rbfiles.flatten.each_with_index do |rbfile, i| + g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" + end + f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? + dep_list.each do |d| + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] + f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] + end + f.puts %Q[void mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose);] + f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] + f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] + unless g.test_rbfiles.empty? + f.puts %Q[ mrb_state *mrb2;] + unless g.test_args.empty? + f.puts %Q[ mrb_value test_args_hash;] + end + f.puts %Q[ int ai;] + g.test_rbfiles.count.times do |i| + f.puts %Q[ ai = mrb_gc_arena_save(mrb);] + f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] + f.puts %Q[ if (mrb2 == NULL) {] + f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + dep_list.each do |d| + f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] + f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] + end + f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] + if test_preload.nil? + f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] + else + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] + end + f.puts %Q[ if (mrb2->exc) {] + f.puts %Q[ mrb_print_error(mrb2);] + f.puts %Q[ exit(EXIT_FAILURE);] + f.puts %Q[ }] + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] + + unless g.test_args.empty? + f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] + g.test_args.each do |arg_name, arg_value| + escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') + escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') + f.puts %Q[ mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ] + end + f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ] + end + + f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? + + f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] + f.puts %Q[ ] + + f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] + f.puts %Q[ mrb_close(mrb2);] + f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] + end + end + f.puts %Q[}] + end + end + end + + build.gems.each do |v| mrbtest_objs.concat v.test_objs end + file mrbtest_lib => mrbtest_objs do |t| - archiver.run t.name, t.prerequisites + build.archiver.run t.name, t.prerequisites end - unless build_mrbtest_lib_only? - driver_obj = objfile("#{current_build_dir}/driver") - file exec => [driver_obj, mrbtest_lib, libfile("#{build_dir}/lib/libmruby")] do |t| - gem_flags = gems.map { |g| g.linker.flags } - gem_flags_before_libraries = gems.map { |g| g.linker.flags_before_libraries } - gem_flags_after_libraries = gems.map { |g| g.linker.flags_after_libraries } - gem_libraries = gems.map { |g| g.linker.libraries } - gem_library_paths = gems.map { |g| g.linker.library_paths } - linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries - end - end - - file ass_lib => ass_c - file ass_c => ["#{current_dir}/assert.rb", __FILE__] do |t| - FileUtils.mkdir_p File.dirname t.name - open(t.name, 'w') do |f| - mrbc.run f, [t.prerequisites.first], 'mrbtest_assert_irep' + unless build.build_mrbtest_lib_only? + file exec => [driver_obj, mlib, mrbtest_lib, libmruby_core, libmruby] do |t| + gem_flags = build.gems.map { |g| g.linker.flags } + gem_flags_before_libraries = build.gems.map { |g| g.linker.flags_before_libraries } + gem_flags_after_libraries = build.gems.map { |g| g.linker.flags_after_libraries } + gem_libraries = build.gems.map { |g| g.linker.libraries } + gem_library_paths = build.gems.map { |g| g.linker.library_paths } + build.linker.run t.name, t.prerequisites, gem_libraries, gem_library_paths, gem_flags, gem_flags_before_libraries end end + init = "#{spec.dir}/init_mrbtest.c" file mlib => clib - file clib => [mrbcfile, init, __FILE__] + mrbs do |t| + file clib => [build.mrbcfile, init] do |t| _pp "GEN", "*.rb", "#{clib.relative_path}" FileUtils.mkdir_p File.dirname(clib) open(clib, 'w') do |f| @@ -56,11 +161,11 @@ MRuby.each_target do f.puts %Q[] f.puts IO.read(init) mrbc.run f, mrbs, 'mrbtest_irep' - gems.each do |g| + build.gems.each do |g| f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);] end f.puts %Q[void mrbgemtest_init(mrb_state* mrb) {] - gems.each do |g| + build.gems.each do |g| f.puts %Q[ GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb);] end f.puts %Q[}] From 133d57cb0d989b956bac899ccc5171351d15fc06 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Sat, 22 Aug 2015 10:21:52 -0400 Subject: [PATCH 176/218] Add mruby-test build config and update :test task to use mrbgem binary Removed old mrbgems_test.rake which was merged into mrbgem spec --- Rakefile | 9 ++-- build_config.rb | 10 +++++ tasks/mrbgems_test.rake | 94 ----------------------------------------- tasks/mruby_build.rake | 2 +- 4 files changed, 15 insertions(+), 100 deletions(-) delete mode 100644 tasks/mrbgems_test.rake diff --git a/Rakefile b/Rakefile index 89dab05e7..574c1365a 100644 --- a/Rakefile +++ b/Rakefile @@ -26,9 +26,6 @@ load "#{MRUBY_ROOT}/mrblib/mrblib.rake" load "#{MRUBY_ROOT}/tasks/mrbgems.rake" load "#{MRUBY_ROOT}/tasks/libmruby.rake" -load "#{MRUBY_ROOT}/tasks/mrbgems_test.rake" -load "#{MRUBY_ROOT}/test/mrbtest.rake" - load "#{MRUBY_ROOT}/tasks/benchmark.rake" ############################## @@ -117,9 +114,11 @@ task :all => depfiles do end desc "run all mruby tests" -task :test => ["all"] + MRuby.targets.values.map { |t| t.build_mrbtest_lib_only? ? t.libfile("#{t.build_dir}/test/mrbtest") : t.exefile("#{t.build_dir}/test/mrbtest") } do +task :test => ["all"] do MRuby.each_target do - run_test unless build_mrbtest_lib_only? + if gems.find { |v| v.name == 'mruby-test' } + run_test unless build_mrbtest_lib_only? + end end end diff --git a/build_config.rb b/build_config.rb index 3408f19a1..e1178d6b2 100644 --- a/build_config.rb +++ b/build_config.rb @@ -108,6 +108,16 @@ MRuby::Build.new('host-debug') do |conf| # conf.enable_bintest end +MRuby::Build.new('test') do |conf| + toolchain :gcc + + enable_debug + conf.enable_bintest + + conf.gembox 'default' + conf.gem :core => "mruby-test" +end + # Define cross build settings # MRuby::CrossBuild.new('32bit') do |conf| # toolchain :gcc diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake deleted file mode 100644 index 0ee508360..000000000 --- a/tasks/mrbgems_test.rake +++ /dev/null @@ -1,94 +0,0 @@ -MRuby.each_target do - gem_table = gems.generate_gem_table self - - gems.each do |g| - test_rbobj = g.test_rbireps.ext(exts.object) - g.test_objs << test_rbobj - dep_list = gems.tsort_dependencies(g.test_dependencies, gem_table).select(&:generate_functions) - - file test_rbobj => g.test_rbireps - file g.test_rbireps => [g.test_rbfiles].flatten + [File.join(g.dir, 'mrbgem.rake'), g.build.mrbcfile, __FILE__, "#{MRUBY_ROOT}/tasks/mrbgem_spec.rake"] do |t| - FileUtils.mkdir_p File.dirname(t.name) - open(t.name, 'w') do |f| - g.print_gem_test_header(f) - test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir| - File.expand_path(g.test_preload, dir) - }.find {|file| File.exist?(file) } - - f.puts %Q[/*] - f.puts %Q[ * This file contains a test code for #{g.name} gem.] - f.puts %Q[ *] - f.puts %Q[ * IMPORTANT:] - f.puts %Q[ * This file was generated!] - f.puts %Q[ * All manual changes will get lost.] - f.puts %Q[ */] - if test_preload.nil? - f.puts %Q[extern const uint8_t mrbtest_assert_irep[];] - else - g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload" - end - g.test_rbfiles.flatten.each_with_index do |rbfile, i| - g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}" - end - f.puts %Q[void mrb_#{g.funcname}_gem_test(mrb_state *mrb);] unless g.test_objs.empty? - dep_list.each do |d| - f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb_state *mrb);] - f.puts %Q[void GENERATED_TMP_mrb_#{d.funcname}_gem_final(mrb_state *mrb);] - end - f.puts %Q[void mrb_init_test_driver(mrb_state *mrb, mrb_bool verbose);] - f.puts %Q[void mrb_t_pass_result(mrb_state *dst, mrb_state *src);] - f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb) {] - unless g.test_rbfiles.empty? - f.puts %Q[ mrb_state *mrb2;] - unless g.test_args.empty? - f.puts %Q[ mrb_value test_args_hash;] - end - f.puts %Q[ int ai;] - g.test_rbfiles.count.times do |i| - f.puts %Q[ ai = mrb_gc_arena_save(mrb);] - f.puts %Q[ mrb2 = mrb_open_core(mrb_default_allocf, NULL);] - f.puts %Q[ if (mrb2 == NULL) {] - f.puts %Q[ fprintf(stderr, "Invalid mrb_state, exiting \%s", __FUNCTION__);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - dep_list.each do |d| - f.puts %Q[ GENERATED_TMP_mrb_#{d.funcname}_gem_init(mrb2);] - f.puts %Q[ mrb_state_atexit(mrb2, GENERATED_TMP_mrb_#{d.funcname}_gem_final);] - end - f.puts %Q[ mrb_init_test_driver(mrb2, mrb_test(mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"))));] - if test_preload.nil? - f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);] - else - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);] - end - f.puts %Q[ if (mrb2->exc) {] - f.puts %Q[ mrb_print_error(mrb2);] - f.puts %Q[ exit(EXIT_FAILURE);] - f.puts %Q[ }] - f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));] - - unless g.test_args.empty? - f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ] - g.test_args.each do |arg_name, arg_value| - escaped_arg_name = arg_name.gsub('\\', '\\\\\\\\').gsub('"', '\"') - escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"') - f.puts %Q[ mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ] - end - f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ] - end - - f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] if g.custom_test_init? - - f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_#{i});] - f.puts %Q[ ] - - f.puts %Q[ mrb_t_pass_result(mrb, mrb2);] - f.puts %Q[ mrb_close(mrb2);] - f.puts %Q[ mrb_gc_arena_restore(mrb, ai);] - end - end - f.puts %Q[}] - end - end - end -end diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index 9f8b4eda5..b3a5dcdad 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -249,7 +249,7 @@ EOS def run_test puts ">>> Test #{name} <<<" - mrbtest = exefile("#{build_dir}/test/mrbtest") + mrbtest = exefile("#{build_dir}/bin/mrbtest") sh "#{filename mrbtest.relative_path}#{$verbose ? ' -v' : ''}" puts run_bintest if @enable_bintest From 1a45447b8b66159a4a7d0348c4a01a175b3778fd Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 27 Aug 2015 17:54:30 +0900 Subject: [PATCH 177/218] add String#freeze to the core --- include/mruby/string.h | 11 ++++++++--- src/string.c | 21 +++++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/mruby/string.h b/include/mruby/string.h index 5228dcbca..c4b31216e 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -59,6 +59,10 @@ struct RString { #define RSTR_SET_NOFREE_FLAG(s) ((s)->flags |= MRB_STR_NOFREE) #define RSTR_UNSET_NOFREE_FLAG(s) ((s)->flags &= ~MRB_STR_NOFREE) +#define RSTR_FROZEN_P(s) ((s)->flags & MRB_STR_FROZEN) +#define RSTR_SET_FROZEN_FLAG(s) ((s)->flags |= MRB_STR_FROZEN) +#define RSTR_UNSET_FROZEN_FLAG(s) ((s)->flags &= ~MRB_STR_FROZEN) + #define mrb_str_ptr(s) ((struct RString*)(mrb_ptr(s))) #define RSTRING(s) mrb_str_ptr(s) #define RSTRING_PTR(s) RSTR_PTR(RSTRING(s)) @@ -70,9 +74,10 @@ mrb_int mrb_str_strlen(mrb_state*, struct RString*); #define MRB_STR_SHARED 1 #define MRB_STR_NOFREE 2 -#define MRB_STR_EMBED 4 -#define MRB_STR_EMBED_LEN_MASK 0xf8 -#define MRB_STR_EMBED_LEN_SHIFT 3 +#define MRB_STR_FROZEN 4 +#define MRB_STR_EMBED 8 +#define MRB_STR_EMBED_LEN_MASK 0x1f0 +#define MRB_STR_EMBED_LEN_SHIFT 4 void mrb_gc_free_str(mrb_state*, struct RString*); MRB_API void mrb_str_modify(mrb_state*, struct RString*); diff --git a/src/string.c b/src/string.c index 45ba38c9d..e5f446bde 100644 --- a/src/string.c +++ b/src/string.c @@ -75,9 +75,18 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared) } } +static void +check_frozen(mrb_state *mrb, struct RString *s) +{ + if (RSTR_FROZEN_P(s)) { + mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen string"); + } +} + MRB_API void mrb_str_modify(mrb_state *mrb, struct RString *s) { + check_frozen(mrb, s); if (RSTR_SHARED_P(s)) { mrb_shared_string *shared = s->as.heap.aux.shared; @@ -119,6 +128,15 @@ mrb_str_modify(mrb_state *mrb, struct RString *s) } } +static mrb_value +mrb_str_freeze(mrb_state *mrb, mrb_value str) +{ + struct RString *s = mrb_str_ptr(str); + + RSTR_SET_FROZEN_FLAG(s); + return str; +} + MRB_API mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len) { @@ -1345,6 +1363,7 @@ str_replace(mrb_state *mrb, struct RString *s1, struct RString *s2) { long len; + check_frozen(mrb, s1); len = RSTR_LEN(s2); if (RSTR_SHARED_P(s1)) { str_decref(mrb, s1->as.heap.aux.shared); @@ -2514,4 +2533,6 @@ mrb_init_string(mrb_state *mrb) mrb_define_method(mrb, s, "upcase!", mrb_str_upcase_bang, MRB_ARGS_NONE()); /* 15.2.10.5.43 */ mrb_define_method(mrb, s, "inspect", mrb_str_inspect, MRB_ARGS_NONE()); /* 15.2.10.5.46(x) */ mrb_define_method(mrb, s, "bytes", mrb_str_bytes, MRB_ARGS_NONE()); + + mrb_define_method(mrb, s, "freeze", mrb_str_freeze, MRB_ARGS_NONE()); } From 69e835cd0f1ab24da191e8c09e23288bf64a2fcf Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Thu, 27 Aug 2015 21:44:56 +0900 Subject: [PATCH 178/218] Add String#freeze test --- test/t/string.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/t/string.rb b/test/t/string.rb index ee6fe0848..7326adce9 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -542,3 +542,11 @@ assert('String#each_byte') do assert_equal bytes1, bytes2 end + +assert('String#freeze') do + str = "hello" + str.freeze + + assert_raise(RuntimeError) { str.upcase! } +end + From 0f2b3643ba47a0778eb8571b029e93f16e142b23 Mon Sep 17 00:00:00 2001 From: "Ralph Desir(Mav7)" Date: Sun, 30 Aug 2015 20:20:45 -0400 Subject: [PATCH 179/218] Added string markdown. --- doc/api/mruby/string.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/mruby/string.h.md diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md new file mode 100644 index 000000000..e69de29bb From a2f6152be8a2d1775830f32ca955864237fd1081 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Sun, 30 Aug 2015 23:55:55 -0400 Subject: [PATCH 180/218] Update string.h.md --- doc/api/mruby/string.h.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md index e69de29bb..b031c564c 100644 --- a/doc/api/mruby/string.h.md +++ b/doc/api/mruby/string.h.md @@ -0,0 +1,10 @@ +### mrb_str_plus +```C + mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value); +``` +Adds to strings together. +### mrb_ptr_to_str +```C + mrb_value mrb_ptr_to_str(mrb_state *, void*); +``` +Converts pointer into a Ruby string. From 00dd2dfa3939d15e437d1779a7de23b1018a7cd7 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 31 Aug 2015 14:11:17 -0400 Subject: [PATCH 181/218] Update string.h.md --- doc/api/mruby/string.h.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md index b031c564c..e2a10c2cf 100644 --- a/doc/api/mruby/string.h.md +++ b/doc/api/mruby/string.h.md @@ -8,3 +8,8 @@ Adds to strings together. mrb_value mrb_ptr_to_str(mrb_state *, void*); ``` Converts pointer into a Ruby string. +### mrb_obj_as_string +```C + mrb_obj_as_string(mrb_state *mrb, mrb_value obj); +``` +Returns an object as a Ruby string. From b432f12fddafb6ad4ac987361bf07560efbc8fad Mon Sep 17 00:00:00 2001 From: Terence Lee Date: Mon, 31 Aug 2015 18:54:42 -0400 Subject: [PATCH 182/218] run bintests within subfolders of bintest/ --- test/bintest.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/bintest.rb b/test/bintest.rb index 0ff3341a0..49990abb9 100644 --- a/test/bintest.rb +++ b/test/bintest.rb @@ -2,7 +2,7 @@ $:.unshift File.dirname(File.dirname(File.expand_path(__FILE__))) require 'test/assert.rb' ARGV.each do |gem| - Dir["#{gem}/bintest/*.rb"].each do |file| + Dir["#{gem}/bintest/**/*.rb"].each do |file| load file end end From d78d0017342ef42cc0d5db517446c805e23ae344 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Mon, 31 Aug 2015 23:16:45 -0400 Subject: [PATCH 183/218] Update string.h.md --- doc/api/mruby/string.h.md | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md index e2a10c2cf..428a3ca40 100644 --- a/doc/api/mruby/string.h.md +++ b/doc/api/mruby/string.h.md @@ -10,6 +10,36 @@ Adds to strings together. Converts pointer into a Ruby string. ### mrb_obj_as_string ```C - mrb_obj_as_string(mrb_state *mrb, mrb_value obj); + mrb_value mrb_obj_as_string(mrb_state *mrb, mrb_value obj); ``` Returns an object as a Ruby string. +### mrb_str_resize +```C + mrb_value mrb_str_resize(mrb_state *mrb, mrb_value str, mrb_int len); +``` +Resizes the string's length. +### mrb_str_substr +```C + mrb_value mrb_str_substr(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len); +``` +Returns a sub string. +### mrb_string_type +```C + mrb_value mrb_string_type(mrb_state *mrb, mrb_value str); +``` +Returns a Ruby string type. +### mrb_str_new_cstr +```C + const char *mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr); +``` +Returns a Ruby string as a C string. +### mrb_str_dup +```C + mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str); +``` +Duplicates a string object. +### mrb_str_intern +```C + mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); +``` +Returns a symbol from a passed in string. From a2385c05f5f07b30c039a46b497ae22bc0c5e212 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Mon, 31 Aug 2015 20:36:33 +0900 Subject: [PATCH 184/218] Refactor version.h macros --- include/mruby/version.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/include/mruby/version.h b/include/mruby/version.h index ea044d6da..b3e4df029 100644 --- a/include/mruby/version.h +++ b/include/mruby/version.h @@ -7,25 +7,27 @@ #ifndef MRUBY_VERSION_H #define MRUBY_VERSION_H +#define MRB_STRINGIZE0(expr) #expr +#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr) + #define MRUBY_RUBY_VERSION "1.9" #define MRUBY_RUBY_ENGINE "mruby" -#define MRUBY_VERSION "1.1.0" #define MRUBY_RELEASE_MAJOR 1 #define MRUBY_RELEASE_MINOR 1 #define MRUBY_RELEASE_TEENY 1 -#define MRUBY_RELEASE_NO 10101 -#define MRUBY_RELEASE_DATE "2014-11-19" + +#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR)"."MRB_STRINGIZE(MRUBY_RELEASE_MINOR)"."MRB_STRINGIZE(MRUBY_RELEASE_TEENY) +#define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY) #define MRUBY_RELEASE_YEAR 2014 #define MRUBY_RELEASE_MONTH 11 #define MRUBY_RELEASE_DAY 19 +#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR)"-"MRB_STRINGIZE(MRUBY_RELEASE_MONTH)"-"MRB_STRINGIZE(MRUBY_RELEASE_DAY) #define MRUBY_BIRTH_YEAR 2010 #define MRUBY_AUTHOR "mruby developers" -#define MRB_STRINGIZE0(expr) #expr -#define MRB_STRINGIZE(expr) MRB_STRINGIZE0(expr) #define MRUBY_DESCRIPTION \ "mruby " MRUBY_VERSION \ From e9b4cb11cf7b6b8b45e5a0a03e6eda3f12a93407 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Mon, 31 Aug 2015 20:32:30 +0900 Subject: [PATCH 185/218] Add a global const variable MRUBY_RELEASE_NO --- src/version.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/version.c b/src/version.c index 7aac44d62..fc3b2fc7a 100644 --- a/src/version.c +++ b/src/version.c @@ -7,6 +7,7 @@ mrb_init_version(mrb_state* mrb) mrb_define_global_const(mrb, "RUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_RUBY_VERSION)); mrb_define_global_const(mrb, "RUBY_ENGINE", mrb_str_new_lit(mrb, MRUBY_RUBY_ENGINE)); mrb_define_global_const(mrb, "MRUBY_VERSION", mrb_str_new_lit(mrb, MRUBY_VERSION)); + mrb_define_global_const(mrb, "MRUBY_RELEASE_NO", mrb_fixnum_value(MRUBY_RELEASE_NO)); mrb_define_global_const(mrb, "MRUBY_RELEASE_DATE", mrb_str_new_lit(mrb, MRUBY_RELEASE_DATE)); mrb_define_global_const(mrb, "MRUBY_DESCRIPTION", mrb_str_new_lit(mrb, MRUBY_DESCRIPTION)); mrb_define_global_const(mrb, "MRUBY_COPYRIGHT", mrb_str_new_lit(mrb, MRUBY_COPYRIGHT)); From 8ad8c547dda2850e67113f6d5a8c4b4d186fe27f Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Tue, 1 Sep 2015 13:50:27 -0400 Subject: [PATCH 186/218] Update string.h.md --- doc/api/mruby/string.h.md | 46 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md index 428a3ca40..1268792e0 100644 --- a/doc/api/mruby/string.h.md +++ b/doc/api/mruby/string.h.md @@ -1,3 +1,7 @@ +## Macros +### mrb_str_ptr(s) +Returns a pointer from a Ruby string. +## Functions ### mrb_str_plus ```C mrb_value mrb_str_plus(mrb_state*, mrb_value, mrb_value); @@ -43,3 +47,45 @@ Duplicates a string object. mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self); ``` Returns a symbol from a passed in string. +### mrb_str_to_str +```C + mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str); +``` +Returns a converted string type. +### mrb_str_equal +```C + mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2); +``` +Returns true if the strings match and false if the strings don't match. +### mrb_str_cat +```C + mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len); +``` +Returns a concated string comprised of a Ruby string and a C string. +### mrb_str_cat_cstr +```C + mrb_value mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2); +``` +Returns a concated string comprised of a Ruby string and a C string(A shorter alternative to mrb_str_cat). +### mrb_str_append +```C + mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2); +``` +Adds str2 to the end of str1. +### mrb_str_cmp +```C + int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2); +``` +Returns 0 if both Ruby strings are equal. +Returns a value < 0 if Ruby str1 is less than Ruby str2. +Returns a value > 0 if Ruby str2 is greater than Ruby str1. +### mrb_str_to_cstr +```C + char *mrb_str_to_cstr(mrb_state *mrb, mrb_value str); +``` +Returns a C string from a Ruby string. +### mrb_str_inspect +```C + mrb_str_inspect(mrb_state *mrb, mrb_value str); +``` +Returns a printable version of str, surrounded by quote marks, with special characters escaped. From 80598f40bf23d310530427808885826e4436330d Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Tue, 1 Sep 2015 20:54:27 -0400 Subject: [PATCH 187/218] mruby-test should be opt-in --- mrbgems/full-core.gembox | 2 +- travis_config.rb | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/mrbgems/full-core.gembox b/mrbgems/full-core.gembox index d1ff5f414..9a5b7081b 100644 --- a/mrbgems/full-core.gembox +++ b/mrbgems/full-core.gembox @@ -4,6 +4,6 @@ MRuby::GemBox.new do |conf| Dir.glob("#{root}/mrbgems/mruby-*/mrbgem.rake") do |x| g = File.basename File.dirname x - conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger)$/ + conf.gem :core => g unless g =~ /^mruby-(print|sprintf|bin-debugger|test)$/ end end diff --git a/travis_config.rb b/travis_config.rb index 2b4059cf1..458473f96 100644 --- a/travis_config.rb +++ b/travis_config.rb @@ -38,3 +38,13 @@ MRuby::Build.new('cxx_abi') do |conf| build_mrbc_exec end + +MRuby::Build.new('test') do |conf| + toolchain :gcc + + enable_debug + conf.enable_bintest + + conf.gembox 'full-core' + conf.gem :core => "mruby-test" +end From 5ed13da7d6056c76a5f8063a2b9b2cd57ac323bf Mon Sep 17 00:00:00 2001 From: jbreeden Date: Tue, 1 Sep 2015 18:09:32 -0700 Subject: [PATCH 188/218] C++ 11 requires a space between literal and identifiers --- include/mruby/version.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/mruby/version.h b/include/mruby/version.h index b3e4df029..c2a9b6306 100644 --- a/include/mruby/version.h +++ b/include/mruby/version.h @@ -17,12 +17,12 @@ #define MRUBY_RELEASE_MINOR 1 #define MRUBY_RELEASE_TEENY 1 -#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR)"."MRB_STRINGIZE(MRUBY_RELEASE_MINOR)"."MRB_STRINGIZE(MRUBY_RELEASE_TEENY) +#define MRUBY_VERSION MRB_STRINGIZE(MRUBY_RELEASE_MAJOR) "." MRB_STRINGIZE(MRUBY_RELEASE_MINOR) "." MRB_STRINGIZE(MRUBY_RELEASE_TEENY) #define MRUBY_RELEASE_NO (MRUBY_RELEASE_MAJOR * 100 * 100 + MRUBY_RELEASE_MINOR * 100 + MRUBY_RELEASE_TEENY) #define MRUBY_RELEASE_YEAR 2014 #define MRUBY_RELEASE_MONTH 11 #define MRUBY_RELEASE_DAY 19 -#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR)"-"MRB_STRINGIZE(MRUBY_RELEASE_MONTH)"-"MRB_STRINGIZE(MRUBY_RELEASE_DAY) +#define MRUBY_RELEASE_DATE MRB_STRINGIZE(MRUBY_RELEASE_YEAR) "-" MRB_STRINGIZE(MRUBY_RELEASE_MONTH) "-" MRB_STRINGIZE(MRUBY_RELEASE_DAY) #define MRUBY_BIRTH_YEAR 2010 From c0ff5b475f6338e51f964a17697dee6d851d57a9 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Tue, 1 Sep 2015 23:43:36 -0400 Subject: [PATCH 189/218] Typo in mruby-bin-debugger/mrbgem.rake --- mrbgems/mruby-bin-debugger/mrbgem.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mrbgems/mruby-bin-debugger/mrbgem.rake b/mrbgems/mruby-bin-debugger/mrbgem.rake index b9d664779..764f431af 100755 --- a/mrbgems/mruby-bin-debugger/mrbgem.rake +++ b/mrbgems/mruby-bin-debugger/mrbgem.rake @@ -1,7 +1,7 @@ MRuby::Gem::Specification.new('mruby-bin-debugger') do |spec| spec.license = 'MIT' spec.author = 'mruby developers' - spec.summary = 'mruby debuggeer command' + spec.summary = 'mruby debugger command' spec.add_dependency('mruby-eval', :core => 'mruby-eval') From 14f0e4a4e4657fe0dc6512cf735c9c75201bd406 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 2 Sep 2015 15:09:50 +0900 Subject: [PATCH 190/218] update string.h.md; ref #2931 --- doc/api/mruby/string.h.md | 2 +- src/string.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/api/mruby/string.h.md b/doc/api/mruby/string.h.md index 1268792e0..7bf94df5b 100644 --- a/doc/api/mruby/string.h.md +++ b/doc/api/mruby/string.h.md @@ -69,7 +69,7 @@ Returns a concated string comprised of a Ruby string and a C string. Returns a concated string comprised of a Ruby string and a C string(A shorter alternative to mrb_str_cat). ### mrb_str_append ```C - mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2); + mrb_value mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2); ``` Adds str2 to the end of str1. ### mrb_str_cmp diff --git a/src/string.c b/src/string.c index e5f446bde..73ef341bb 100644 --- a/src/string.c +++ b/src/string.c @@ -2385,10 +2385,10 @@ mrb_str_cat_str(mrb_state *mrb, mrb_value str, mrb_value str2) } MRB_API mrb_value -mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2) +mrb_str_append(mrb_state *mrb, mrb_value str1, mrb_value str2) { str2 = mrb_str_to_str(mrb, str2); - return mrb_str_cat_str(mrb, str, str2); + return mrb_str_cat_str(mrb, str1, str2); } #define CHAR_ESC_LEN 13 /* sizeof(\x{ hex of 32bit unsigned int } \0) */ From 6ddd79fd0ebfd88a9b36be08d509e665a9322567 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 2 Sep 2015 21:46:51 +0900 Subject: [PATCH 191/218] ensure must not be called before rescue; fix #2933 --- src/vm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/vm.c b/src/vm.c index 00636a870..8419931d0 100644 --- a/src/vm.c +++ b/src/vm.c @@ -1486,9 +1486,6 @@ RETRY_TRY_BLOCK: if (ci->ridx == 0) goto L_STOP; goto L_RESCUE; } - while (eidx > ci[-1].eidx) { - ecall(mrb, --eidx); - } while (ci[0].ridx == ci[-1].ridx) { cipop(mrb); ci = mrb->c->ci; From 74696ffd9625e4dca43aa010d71020f10030de24 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 2 Sep 2015 22:29:01 +0900 Subject: [PATCH 192/218] Float << and >> should be more compatible to Fixnum --- mrblib/numeric.rb | 26 ++++++++++++++++++++++---- test/t/float.rb | 22 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/mrblib/numeric.rb b/mrblib/numeric.rb index 206185e78..6e4c5027f 100644 --- a/mrblib/numeric.rb +++ b/mrblib/numeric.rb @@ -165,12 +165,30 @@ class Float # floats should be compatible to integers. def >> other n = self.to_i - other.to_i.times { n /= 2 } - n + other = other.to_i + if other < 0 + n << -other + else + other.times { n /= 2 } + if n.abs < 1 + if n >= 0 + 0 + else + -1 + end + else + n.to_i + end + end end def << other n = self.to_i - other.to_i.times { n *= 2 } - n.to_i + other = other.to_i + if other < 0 + n >> -other + else + other.times { n *= 2 } + n + end end end diff --git a/test/t/float.rb b/test/t/float.rb index d45709173..0aab0b1f2 100644 --- a/test/t/float.rb +++ b/test/t/float.rb @@ -178,3 +178,25 @@ assert('Float#nan?') do assert_false (1.0/0.0).nan? assert_false (-1.0/0.0).nan? end + +assert('Float#<<') do + # Left Shift by one + assert_equal 46, 23.0 << 1 + + # Left Shift by a negative is Right Shift + assert_equal 23, 46.0 << -1 +end + +assert('Float#>>') do + # Right Shift by one + assert_equal 23, 46.0 >> 1 + + # Right Shift by a negative is Left Shift + assert_equal 46, 23.0 >> -1 + + # Don't raise on large Right Shift + assert_equal 0, 23.0 >> 128 + + # Don't raise on large Right Shift + assert_equal -1, -23.0 >> 128 +end From 87564dc98f22a7710f9e6565f6750bfaa220f965 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Wed, 2 Sep 2015 09:52:37 -0400 Subject: [PATCH 193/218] Make travis happy We have do this because mruby's test files are found using MRUBY_ROOT, like this: mrbs = Dir.glob("#{MRUBY_ROOT}/test/t/*.rb") --- test/t/syntax.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/t/syntax.rb b/test/t/syntax.rb index dc1a4a3b9..fb6ffe408 100644 --- a/test/t/syntax.rb +++ b/test/t/syntax.rb @@ -1,6 +1,6 @@ assert('__FILE__') do - file = __FILE__ - assert_true 'test/t/syntax.rb' == file || 'test\t\syntax.rb' == file + file = __FILE__.split('test/')[1] + assert_true 't/syntax.rb' == file || 't\syntax.rb' == file end assert('__LINE__') do From 3a462fe4687fa2a52d2c9c20d10ae46901292b99 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Wed, 2 Sep 2015 23:41:51 +0900 Subject: [PATCH 194/218] Integer << and >> to use Float instead of raising RangeError --- src/numeric.c | 12 +++++++----- test/t/integer.rb | 10 ---------- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/numeric.c b/src/numeric.c index 14c0b76a6..1a3c903f0 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -820,11 +820,13 @@ fix_xor(mrb_state *mrb, mrb_value x) static mrb_value lshift(mrb_state *mrb, mrb_int val, mrb_int width) { - mrb_assert(width >= 0); + mrb_assert(width > 0); if (width > NUMERIC_SHIFT_WIDTH_MAX) { - mrb_raisef(mrb, E_RANGE_ERROR, "width(%S) > (%S:MRB_INT_BIT-1)", - mrb_fixnum_value(width), - mrb_fixnum_value(NUMERIC_SHIFT_WIDTH_MAX)); + mrb_float f = (mrb_float)val; + while (width--) { + f *= 2; + } + return mrb_float_value(mrb, f); } return mrb_fixnum_value(val << width); } @@ -832,7 +834,7 @@ lshift(mrb_state *mrb, mrb_int val, mrb_int width) static mrb_value rshift(mrb_int val, mrb_int width) { - mrb_assert(width >= 0); + mrb_assert(width > 0); if (width >= NUMERIC_SHIFT_WIDTH_MAX) { if (val < 0) { return mrb_fixnum_value(-1); diff --git a/test/t/integer.rb b/test/t/integer.rb index 6b8cc308d..be3c13db2 100644 --- a/test/t/integer.rb +++ b/test/t/integer.rb @@ -147,11 +147,6 @@ assert('Integer#<<', '15.2.8.3.12') do # Left Shift by a negative is Right Shift assert_equal 23, 46 << -1 - - # Raise when shift is too large - assert_raise(RangeError) do - 2 << 128 - end end assert('Integer#>>', '15.2.8.3.13') do @@ -165,11 +160,6 @@ assert('Integer#>>', '15.2.8.3.13') do # Don't raise on large Right Shift assert_equal 0, 23 >> 128 - - # Raise when shift is too large - assert_raise(RangeError) do - 2 >> -128 - end end assert('Integer#ceil', '15.2.8.3.14') do From e35c3aff83d400dfe27fe105b7e282ac81b1197a Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 3 Sep 2015 00:14:37 +0900 Subject: [PATCH 195/218] unsigned long may be smaller than mrb_int; use uint64_t instead; fix #2935 --- mrbgems/mruby-sprintf/src/sprintf.c | 2 +- src/string.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c index de216f69f..81b48b10d 100644 --- a/mrbgems/mruby-sprintf/src/sprintf.c +++ b/mrbgems/mruby-sprintf/src/sprintf.c @@ -73,7 +73,7 @@ mrb_fix2binstr(mrb_state *mrb, mrb_value x, int base) { char buf[64], *b = buf + sizeof buf; mrb_int num = mrb_fixnum(x); - unsigned long val = (unsigned long)num; + uint64_t val = (uint64_t)num; char d; if (base != 2) { diff --git a/src/string.c b/src/string.c index 73ef341bb..08caf3bae 100644 --- a/src/string.c +++ b/src/string.c @@ -1863,7 +1863,7 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) const char *p; char sign = 1; int c, uscore; - unsigned long n = 0; + uint64_t n = 0; mrb_int val; #define conv_digit(c) \ @@ -1983,9 +1983,9 @@ mrb_cstr_to_inum(mrb_state *mrb, const char *str, int base, int badcheck) } n *= base; n += c; - } - if (n > MRB_INT_MAX) { - mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", mrb_str_new_cstr(mrb, str)); + if (n > MRB_INT_MAX) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "string (%S) too big for integer", mrb_str_new_cstr(mrb, str)); + } } val = n; if (badcheck) { From 7b5f8b07285eeb9900ef1a85cb2c764fbbd34461 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 3 Sep 2015 01:39:17 +0900 Subject: [PATCH 196/218] remove trailing spaces from bc9c47d5 --- build_config.rb | 3 ++- include/mruby/dump.h | 4 ++-- src/load.c | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/build_config.rb b/build_config.rb index e1178d6b2..34b92637c 100644 --- a/build_config.rb +++ b/build_config.rb @@ -21,6 +21,7 @@ MRuby::Build.new do |conf| # include the default GEMs conf.gembox 'default' + conf.gem :core => 'mruby-eval' # C compiler settings # conf.cc do |cc| @@ -105,7 +106,7 @@ MRuby::Build.new('host-debug') do |conf| conf.gem :core => "mruby-bin-debugger" # bintest - # conf.enable_bintest + conf.enable_bintest end MRuby::Build.new('test') do |conf| diff --git a/include/mruby/dump.h b/include/mruby/dump.h index 45774d872..4cee3c0ac 100644 --- a/include/mruby/dump.h +++ b/include/mruby/dump.h @@ -17,8 +17,8 @@ extern "C" { #define DUMP_DEBUG_INFO 1 #define DUMP_ENDIAN_BIG 2 #define DUMP_ENDIAN_LIL 4 -#define DUMP_ENDIAN_NAT 6 -#define DUMP_ENDIAN_MASK 6 +#define DUMP_ENDIAN_NAT 6 +#define DUMP_ENDIAN_MASK 6 int mrb_dump_irep(mrb_state *mrb, mrb_irep *irep, uint8_t flags, uint8_t **bin, size_t *bin_size); #ifdef ENABLE_STDIO diff --git a/src/load.c b/src/load.c index a9f1641bf..36fae9aee 100644 --- a/src/load.c +++ b/src/load.c @@ -529,7 +529,7 @@ read_binary_header(const uint8_t *bin, size_t *bin_size, uint16_t *crc, uint8_t else if (memcmp(header->binary_ident, RITE_BINARY_IDENT_LIL, sizeof(header->binary_ident)) == 0) { if (bigendian_p()) *flags |= FLAG_BYTEORDER_LIL; - else + else *flags |= FLAG_BYTEORDER_NATIVE; } else { From cc0b28373a304541308b6386f4be15aedf30ce43 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 3 Sep 2015 01:46:35 +0900 Subject: [PATCH 197/218] clear DUMP_ENDIAN flags before setting --- mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c index 301dde1c6..2f507904a 100644 --- a/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c +++ b/mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c @@ -119,10 +119,10 @@ parse_args(mrb_state *mrb, int argc, char **argv, struct mrbc_args *args) args->flags |= DUMP_DEBUG_INFO; break; case 'E': - args->flags = DUMP_ENDIAN_BIG | (args->flags & DUMP_DEBUG_INFO); + args->flags = DUMP_ENDIAN_BIG | (args->flags & ~DUMP_ENDIAN_MASK); break; case 'e': - args->flags = DUMP_ENDIAN_LIL | (args->flags & DUMP_DEBUG_INFO); + args->flags = DUMP_ENDIAN_LIL | (args->flags & ~DUMP_ENDIAN_MASK); break; case 'h': return -1; From da0dc6937da11dec6c47f93f24bfac3ca02d1464 Mon Sep 17 00:00:00 2001 From: "Ralph Desir(Mav7)" Date: Wed, 2 Sep 2015 18:19:53 -0400 Subject: [PATCH 198/218] doc/api/mruby/version.h.md --- doc/api/mruby/version.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/mruby/version.h.md diff --git a/doc/api/mruby/version.h.md b/doc/api/mruby/version.h.md new file mode 100644 index 000000000..e69de29bb From 6beae5ec71718f36efbb60037f929f1b5e279208 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Wed, 2 Sep 2015 18:45:03 -0400 Subject: [PATCH 199/218] Created version.h markdown. --- doc/api/mruby/version.h.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/api/mruby/version.h.md b/doc/api/mruby/version.h.md index e69de29bb..daf87077d 100644 --- a/doc/api/mruby/version.h.md +++ b/doc/api/mruby/version.h.md @@ -0,0 +1,33 @@ +#### Macros +### MRUBY_RUBY_VERSION +The version of Ruby used by mruby. +### MRUBY_RUBY_ENGINE +Ruby engine. +### MRUBY_VERSION +The mruby version. +### MRUBY_RELEASE_MAJOR +Major release version. +### MRUBY_RELEASE_MINOR +Minor release version. +### MRUBY_RELEASE_NO +Release number. +### MRUBY_RELEASE_DATE +Release date as a string. +### MRUBY_RELEASE_YEAR +Release year. +### MRUBY_RELEASE_MONTH +Release month. +### MRUBY_RELEASE_DAY +Release day. +### MRUBY_BIRTH_YEAR +The year mruby was first created. +### MRUBY_AUTHOR +Mruby's authors. +### MRB_STRINGIZE0(expr) +A passed in expression. +### MRB_STRINGIZE(expr) +Passes in an expression to MRB_STRINGIZE0. +### MRUBY_DESCRIPTION +mruby's version, and release date. +### MRUBY_COPYRIGHT +mruby's copyright information. From 1bd5c4859615f3b6012093ace07b032c86336c69 Mon Sep 17 00:00:00 2001 From: "Ralph Desir(Mav7)" Date: Wed, 2 Sep 2015 18:52:16 -0400 Subject: [PATCH 200/218] Added regular expression header markdown. --- doc/api/mruby/re.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/mruby/re.h.md diff --git a/doc/api/mruby/re.h.md b/doc/api/mruby/re.h.md new file mode 100644 index 000000000..e69de29bb From 79aa0866cea908d9ce03da4a3828816e1abed7cb Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Wed, 2 Sep 2015 18:57:00 -0400 Subject: [PATCH 201/218] Added reg.h markdown. --- doc/api/mruby/re.h.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/api/mruby/re.h.md b/doc/api/mruby/re.h.md index e69de29bb..01e18c6a5 100644 --- a/doc/api/mruby/re.h.md +++ b/doc/api/mruby/re.h.md @@ -0,0 +1,3 @@ +#### Macros +### REGEXP_CLASS +A string with the name of the REGEXP class. From bacb8268682e8d931a00e7894ed7904bc789d8c4 Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Wed, 2 Sep 2015 23:11:18 -0400 Subject: [PATCH 202/218] Add build_mrbtest after config block is evaluated This allows us to add `enable_test` anywhere in a build target, without having to worry about the order in which they are included. Previously, there was a bug that occured when adding 'mruby-test' gem to dependencies before additional gems. Instead of adding the 'mruby-test' gem dependency manually to a test build, we now only need to call `enable_test` in the target. This also allows us to call `test_enabled?` downstream when running mruby tests ourselves. /cc #2924 --- Rakefile | 4 +--- build_config.rb | 2 +- mrbgems/mruby-test/mrbgem.rake | 2 +- tasks/mruby_build.rake | 21 ++++++++++++++++++--- travis_config.rb | 12 ++---------- 5 files changed, 23 insertions(+), 18 deletions(-) diff --git a/Rakefile b/Rakefile index 574c1365a..8a8912af5 100644 --- a/Rakefile +++ b/Rakefile @@ -116,9 +116,7 @@ end desc "run all mruby tests" task :test => ["all"] do MRuby.each_target do - if gems.find { |v| v.name == 'mruby-test' } - run_test unless build_mrbtest_lib_only? - end + run_test if test_enabled? end end diff --git a/build_config.rb b/build_config.rb index 34b92637c..d3c1ebc1f 100644 --- a/build_config.rb +++ b/build_config.rb @@ -114,9 +114,9 @@ MRuby::Build.new('test') do |conf| enable_debug conf.enable_bintest + conf.enable_test conf.gembox 'default' - conf.gem :core => "mruby-test" end # Define cross build settings diff --git a/mrbgems/mruby-test/mrbgem.rake b/mrbgems/mruby-test/mrbgem.rake index 8370f4713..b6b247ff6 100644 --- a/mrbgems/mruby-test/mrbgem.rake +++ b/mrbgems/mruby-test/mrbgem.rake @@ -32,7 +32,7 @@ MRuby::Gem::Specification.new('mruby-test') do |spec| end end - gem_table = build.gems.generate_gem_table self + gem_table = build.gems.generate_gem_table build build.gems.each do |g| test_rbobj = g.test_rbireps.ext(exts.object) diff --git a/tasks/mruby_build.rake b/tasks/mruby_build.rake index b3a5dcdad..6863b635a 100644 --- a/tasks/mruby_build.rake +++ b/tasks/mruby_build.rake @@ -46,7 +46,7 @@ module MRuby include LoadGems attr_accessor :name, :bins, :exts, :file_separator, :build_dir, :gem_clone_dir attr_reader :libmruby, :gems, :toolchains - attr_writer :enable_bintest + attr_writer :enable_bintest, :enable_test COMPILERS = %w(cc cxx objc asm) COMMANDS = COMPILERS + %w(linker archiver yacc gperf git exts mrbc) @@ -85,6 +85,8 @@ module MRuby @build_mrbtest_lib_only = false @cxx_abi_enabled = false @cxx_exception_disabled = false + @enable_bintest = false + @enable_test = false @toolchains = [] MRuby.targets[@name] = self @@ -94,6 +96,7 @@ module MRuby MRuby.targets[@name].instance_eval(&block) build_mrbc_exec if name == 'host' + build_mrbtest if test_enabled? end def enable_debug @@ -170,6 +173,18 @@ EOS MRUBY_ROOT end + def enable_test + @enable_test = true + end + + def test_enabled? + @enable_test + end + + def build_mrbtest + gem :core => 'mruby-test' + end + def build_mrbc_exec gem :core => 'mruby-bin-mrbc' end @@ -252,7 +267,7 @@ EOS mrbtest = exefile("#{build_dir}/bin/mrbtest") sh "#{filename mrbtest.relative_path}#{$verbose ? ' -v' : ''}" puts - run_bintest if @enable_bintest + run_bintest if bintest_enabled? end def run_bintest @@ -297,7 +312,7 @@ EOS end def run_test - mrbtest = exefile("#{build_dir}/test/mrbtest") + mrbtest = exefile("#{build_dir}/bin/mrbtest") if (@test_runner.command == nil) puts "You should run #{mrbtest} on target device." puts diff --git a/travis_config.rb b/travis_config.rb index 458473f96..4ee6d752b 100644 --- a/travis_config.rb +++ b/travis_config.rb @@ -22,6 +22,7 @@ MRuby::Build.new do |conf| c.defines += %w(MRB_GC_FIXED_ARENA) end conf.enable_bintest + conf.enable_test end MRuby::Build.new('cxx_abi') do |conf| @@ -33,18 +34,9 @@ MRuby::Build.new('cxx_abi') do |conf| c.defines += %w(MRB_GC_FIXED_ARENA) end conf.enable_bintest + conf.enable_test enable_cxx_abi build_mrbc_exec end - -MRuby::Build.new('test') do |conf| - toolchain :gcc - - enable_debug - conf.enable_bintest - - conf.gembox 'full-core' - conf.gem :core => "mruby-test" -end From 93aaa0673678ec53cf977ac908e962225db962cf Mon Sep 17 00:00:00 2001 From: "Ralph Desir(Mav7)" Date: Thu, 3 Sep 2015 14:16:57 -0400 Subject: [PATCH 203/218] Added range markdown. --- doc/api/mruby/range.h.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/api/mruby/range.h.md diff --git a/doc/api/mruby/range.h.md b/doc/api/mruby/range.h.md new file mode 100644 index 000000000..e69de29bb From e1beb502ab133d4bfae5fa3df856aa2b851e2655 Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 3 Sep 2015 14:19:02 -0400 Subject: [PATCH 204/218] Cleaned up the re.h markdown. --- doc/api/mruby/re.h.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/api/mruby/re.h.md b/doc/api/mruby/re.h.md index 01e18c6a5..f5cd2a71e 100644 --- a/doc/api/mruby/re.h.md +++ b/doc/api/mruby/re.h.md @@ -1,3 +1,3 @@ -#### Macros -### REGEXP_CLASS +### Macros +#### REGEXP_CLASS A string with the name of the REGEXP class. From 8a09515c6c7b1e8315c6b1accb92cb93d8e8138c Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 3 Sep 2015 14:20:16 -0400 Subject: [PATCH 205/218] Cleaned up the version.h markdown. --- doc/api/mruby/version.h.md | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/doc/api/mruby/version.h.md b/doc/api/mruby/version.h.md index daf87077d..f627b1da1 100644 --- a/doc/api/mruby/version.h.md +++ b/doc/api/mruby/version.h.md @@ -1,33 +1,33 @@ -#### Macros -### MRUBY_RUBY_VERSION +### Macros +#### MRUBY_RUBY_VERSION The version of Ruby used by mruby. -### MRUBY_RUBY_ENGINE +#### MRUBY_RUBY_ENGINE Ruby engine. -### MRUBY_VERSION +#### MRUBY_VERSION The mruby version. -### MRUBY_RELEASE_MAJOR +#### MRUBY_RELEASE_MAJOR Major release version. -### MRUBY_RELEASE_MINOR +#### MRUBY_RELEASE_MINOR Minor release version. -### MRUBY_RELEASE_NO +#### MRUBY_RELEASE_NO Release number. -### MRUBY_RELEASE_DATE +#### MRUBY_RELEASE_DATE Release date as a string. -### MRUBY_RELEASE_YEAR +#### MRUBY_RELEASE_YEAR Release year. -### MRUBY_RELEASE_MONTH +#### MRUBY_RELEASE_MONTH Release month. -### MRUBY_RELEASE_DAY +#### MRUBY_RELEASE_DAY Release day. -### MRUBY_BIRTH_YEAR +#### MRUBY_BIRTH_YEAR The year mruby was first created. -### MRUBY_AUTHOR +#### MRUBY_AUTHOR Mruby's authors. -### MRB_STRINGIZE0(expr) +#### MRB_STRINGIZE0(expr) A passed in expression. -### MRB_STRINGIZE(expr) +#### MRB_STRINGIZE(expr) Passes in an expression to MRB_STRINGIZE0. -### MRUBY_DESCRIPTION +#### MRUBY_DESCRIPTION mruby's version, and release date. -### MRUBY_COPYRIGHT +#### MRUBY_COPYRIGHT mruby's copyright information. From 743432d4ecc2052f6808d1e1012eb356e85ccb1e Mon Sep 17 00:00:00 2001 From: Ralph Desir Date: Thu, 3 Sep 2015 14:52:21 -0400 Subject: [PATCH 206/218] Update range.h.md --- doc/api/mruby/range.h.md | 47 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/doc/api/mruby/range.h.md b/doc/api/mruby/range.h.md index e69de29bb..188e6ede6 100644 --- a/doc/api/mruby/range.h.md +++ b/doc/api/mruby/range.h.md @@ -0,0 +1,47 @@ +#### mrb_range_new +```C + mrb_value mrb_range_new(mrb_state*, mrb_value, mrb_value, mrb_bool); +``` +Initializes a Range. The first mrb_value being the beginning value and second being the ending value. +The third parameter is an mrb_bool value that represents the inclusion or exclusion of the last value. +If the third parameter is 0 then it includes the last value in the range. If the third parameter is 1 +then it excludes the last value in the range. +C code +```C + #include + #include + #include "mruby/range.h" // Needs the range header. + #include "mruby/compile.h" + + int main(int argc, char *argv[]) + { + mrb_int beg = 0; + mrb_int end = 2; + mrb_bool exclude = 1; + mrb_value range_obj; + mrb_state *mrb = mrb_open(); + if (!mrb) { /* handle error */ } + FILE *fp = fopen("test.rb","r"); + range_obj = mrb_range_new(mrb, mrb_fixnum_value(beg), mrb_fixnum_value(end), exclude); + mrb_value obj = mrb_load_file(mrb,fp); + mrb_funcall(mrb, obj, "method_name", 1, range_obj); + fclose(fp); + mrb_close(mrb); + return 0; + } +``` +Ruby code +```Ruby + class Example_Class + def method_name(a) + puts a + puts a.class + end + end + Example_Class.new +``` +This returns the following: +```Ruby + 0...2 + Range +``` From c6860bc0c4978d3158a96b32d4fe9965c03424dd Mon Sep 17 00:00:00 2001 From: Zachary Scott Date: Fri, 4 Sep 2015 10:50:58 -0400 Subject: [PATCH 207/218] Allow rbfiles in mrblib and test to have subdirs --- tasks/mrbgem_spec.rake | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake index d13e7733f..74aa5b817 100644 --- a/tasks/mrbgem_spec.rake +++ b/tasks/mrbgem_spec.rake @@ -54,7 +54,7 @@ module MRuby end @linker = LinkerConfig.new([], [], [], []) - @rbfiles = Dir.glob("#{dir}/mrblib/*.rb").sort + @rbfiles = Dir.glob("#{dir}/mrblib/**/*.rb").sort @objs = Dir.glob("#{dir}/src/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| objfile(f.relative_path_from(@dir).to_s.pathmap("#{build_dir}/%X")) end @@ -62,7 +62,7 @@ module MRuby @generate_functions = !(@rbfiles.empty? && @objs.empty?) @objs << objfile("#{build_dir}/gem_init") if @generate_functions - @test_rbfiles = Dir.glob("#{dir}/test/*.rb") + @test_rbfiles = Dir.glob("#{dir}/test/**/*.rb") @test_objs = Dir.glob("#{dir}/test/*.{c,cpp,cxx,cc,m,asm,s,S}").map do |f| objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X")) end From 6ced9c3752eefbb1b2a9ad971953f82f530c1a04 Mon Sep 17 00:00:00 2001 From: Jun Hiroe Date: Sat, 5 Sep 2015 00:04:43 +0900 Subject: [PATCH 208/218] Revert 7b5f8b0 except removing trailing spaces --- build_config.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build_config.rb b/build_config.rb index d3c1ebc1f..96b1d4684 100644 --- a/build_config.rb +++ b/build_config.rb @@ -21,7 +21,6 @@ MRuby::Build.new do |conf| # include the default GEMs conf.gembox 'default' - conf.gem :core => 'mruby-eval' # C compiler settings # conf.cc do |cc| @@ -106,7 +105,7 @@ MRuby::Build.new('host-debug') do |conf| conf.gem :core => "mruby-bin-debugger" # bintest - conf.enable_bintest + # conf.enable_bintest end MRuby::Build.new('test') do |conf| From 2550edd570f1d7485e862ce11ceb50ea59dee3c5 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sat, 5 Sep 2015 02:01:02 +0900 Subject: [PATCH 209/218] remove `origin` member to implement prepend from struct RClass; ref #2885 instead origin is saved in ICLASS with MRB_FLAG_IS_ORIGIN set. --- include/mruby/class.h | 10 +++++++++- src/class.c | 44 +++++++++++++++++++++++-------------------- src/kernel.c | 29 ++++++++++++++-------------- src/object.c | 2 +- 4 files changed, 49 insertions(+), 36 deletions(-) diff --git a/include/mruby/class.h b/include/mruby/class.h index 80a0cbe35..85f3e12c6 100644 --- a/include/mruby/class.h +++ b/include/mruby/class.h @@ -16,7 +16,6 @@ struct RClass { struct iv_tbl *iv; struct kh_mt *mt; struct RClass *super; - struct RClass *origin; }; #define mrb_class_ptr(v) ((struct RClass*)(mrb_ptr(v))) @@ -50,7 +49,16 @@ mrb_class(mrb_state *mrb, mrb_value v) } // TODO: figure out where to put user flags +#define MRB_FLAG_IS_PREPENDED (1 << 19) #define MRB_FLAG_IS_ORIGIN (1 << 20) +#define MRB_CLASS_ORIGIN(c) do {\ + if (c->flags & MRB_FLAG_IS_PREPENDED) {\ + c = c->super;\ + while (!(c->flags & MRB_FLAG_IS_ORIGIN)) {\ + c = c->super;\ + }\ + }\ +} while (0) #define MRB_INSTANCE_TT_MASK (0xFF) #define MRB_SET_INSTANCE_TT(c, tt) c->flags = ((c->flags & ~MRB_INSTANCE_TT_MASK) | (char)tt) #define MRB_INSTANCE_TT(c) (enum mrb_vtype)(c->flags & MRB_INSTANCE_TT_MASK) diff --git a/src/class.c b/src/class.c index 462ab40b5..c3c3e0b8f 100644 --- a/src/class.c +++ b/src/class.c @@ -76,7 +76,6 @@ prepare_singleton_class(mrb_state *mrb, struct RBasic *o) if (o->c->tt == MRB_TT_SCLASS) return; sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); - sc->origin = sc; sc->mt = kh_init(mt, mrb); sc->iv = 0; if (o->tt == MRB_TT_CLASS) { @@ -188,6 +187,13 @@ mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name) return c; } +static struct RClass* +find_origin(struct RClass *c) +{ + MRB_CLASS_ORIGIN(c); + return c; +} + static struct RClass* define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer) { @@ -195,7 +201,7 @@ define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass * if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { c = class_from_sym(mrb, outer, name); - c = c->origin; + MRB_CLASS_ORIGIN(c); if (super && mrb_class_real(c->super) != super) { mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", mrb_sym2str(mrb, name), @@ -327,7 +333,8 @@ mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RPro { khash_t(mt) *h; khiter_t k; - h = c->origin->mt; + MRB_CLASS_ORIGIN(c); + h = c->mt; if (!h) h = c->mt = kh_init(mt, mrb); k = kh_put(mt, mrb, h, mid); @@ -809,7 +816,6 @@ boot_defclass(mrb_state *mrb, struct RClass *super) struct RClass *c; c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); - c->origin = c; if (super) { c->super = super; mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); @@ -824,7 +830,6 @@ boot_defclass(mrb_state *mrb, struct RClass *super) static void boot_initmod(mrb_state *mrb, struct RClass *mod) { - mod->origin = mod; mod->mt = kh_init(mt, mrb); } @@ -835,9 +840,9 @@ include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) if (m->tt == MRB_TT_ICLASS) { m = m->c; } - ic->origin = ic; + MRB_CLASS_ORIGIN(m); ic->iv = m->iv; - ic->mt = m->origin->mt; + ic->mt = m->mt; ic->super = super; if (m->tt == MRB_TT_ICLASS) { ic->c = m->c; @@ -851,12 +856,12 @@ static int include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) { struct RClass *p, *ic; - void *klass_mt = c->origin->mt; + void *klass_mt = find_origin(c)->mt; while (m) { int superclass_seen = 0; - if (m->origin != m) + if (m->flags & MRB_FLAG_IS_PREPENDED) goto skip; if (klass_mt && klass_mt == m->mt) @@ -891,7 +896,7 @@ include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, stru MRB_API void mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) { - int changed = include_module_at(mrb, c, c->origin, m, 1); + int changed = include_module_at(mrb, c, find_origin(c), m, 1); if (changed < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); } @@ -903,17 +908,15 @@ mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) struct RClass *origin; int changed = 0; - origin = c->origin; - if (origin == c) { + if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); origin->flags |= MRB_FLAG_IS_ORIGIN; - origin->origin = origin; origin->super = c->super; c->super = origin; - c->origin = origin; origin->mt = c->mt; c->mt = kh_init(mt, mrb); - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)c->origin); + mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin); + c->flags |= MRB_FLAG_IS_PREPENDED; } changed = include_module_at(mrb, c, c, m, 0); if (changed < 0) { @@ -1026,7 +1029,7 @@ mrb_mod_ancestors(mrb_state *mrb, mrb_value self) if (c->tt == MRB_TT_ICLASS) { mrb_ary_push(mrb, result, mrb_obj_value(c->c)); } - else if (c->origin == c) { + else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { mrb_ary_push(mrb, result, mrb_obj_value(c)); } c = c->super; @@ -1051,8 +1054,9 @@ mrb_mod_included_modules(mrb_state *mrb, mrb_value self) { mrb_value result; struct RClass *c = mrb_class_ptr(self); - struct RClass *origin = c->origin; + struct RClass *origin = c; + MRB_CLASS_ORIGIN(origin); result = mrb_ary_new(mrb); while (c) { if (c != origin && c->tt == MRB_TT_ICLASS) { @@ -1391,9 +1395,9 @@ mrb_class_superclass(mrb_state *mrb, mrb_value klass) struct RClass *c; c = mrb_class_ptr(klass); - c = c->origin->super; + c = find_origin(c)->super; while (c && c->tt == MRB_TT_ICLASS) { - c = c->origin->super; + c = find_origin(c)->super; } if (!c) return mrb_nil_value(); return mrb_obj_value(c); @@ -1990,7 +1994,7 @@ static void remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) { struct RClass *c = mrb_class_ptr(mod); - khash_t(mt) *h = c->origin->mt; + khash_t(mt) *h = find_origin(c)->mt; khiter_t k; if (h) { diff --git a/src/kernel.c b/src/kernel.c index 36ad683ee..225f7fa54 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -240,19 +240,12 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) /* copy singleton(unnamed) class */ struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); - if ((mrb_type(obj) == MRB_TT_CLASS) || - (mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */ + if ((mrb_type(obj) == MRB_TT_CLASS) || (mrb_type(obj) == MRB_TT_SCLASS)) { clone->c = clone; } else { clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); } - - if (klass->origin != klass) - clone->origin = klass->origin; - else - clone->origin = clone; - clone->super = klass->super; if (klass->iv) { mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); @@ -276,10 +269,18 @@ copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) struct RClass *sc = mrb_class_ptr(src); /* if the origin is not the same as the class, then the origin and the current class need to be copied */ - if (sc->origin != sc) { - dc->origin = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(sc->origin))); - } else { - dc->origin = dc; + if (sc->flags & MRB_FLAG_IS_PREPENDED) { + struct RClass *c0 = sc->super; + struct RClass *c1 = dc; + + /* copy prepended iclasses */ + while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) { + c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); + c1 = c1->super; + c0 = c0->super; + } + c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); + c1->super->flags |= MRB_FLAG_IS_ORIGIN; } dc->mt = kh_copy(mt, mrb, sc->mt); dc->super = sc->super; @@ -657,8 +658,8 @@ mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* kl struct RClass* oldklass; khash_t(st)* set = kh_init(st, mrb); - if (!recur && klass->origin != klass) { - klass = klass->origin; + if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) { + MRB_CLASS_ORIGIN(klass); prepended = 1; } diff --git a/src/object.c b/src/object.c index c834ee04f..2e0bd245f 100644 --- a/src/object.c +++ b/src/object.c @@ -487,7 +487,7 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) mrb_raise(mrb, E_TYPE_ERROR, "class or module required"); } - c = c->origin; + MRB_CLASS_ORIGIN(c); while (cl) { if (cl == c || cl->mt == c->mt) return TRUE; From 44eb1492bed2f9584623ec10ecf14cc46af4bf12 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 10 Sep 2015 22:24:10 +0900 Subject: [PATCH 210/218] freeze the hash key (fixes #2945) --- src/hash.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/hash.c b/src/hash.c index 0bda2b48b..42b40482a 100644 --- a/src/hash.c +++ b/src/hash.c @@ -104,9 +104,11 @@ static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); static inline mrb_value mrb_hash_ht_key(mrb_state *mrb, mrb_value key) { - if (mrb_string_p(key)) - return mrb_str_dup(mrb, key); - else + if (mrb_string_p(key)) { + key = mrb_str_dup(mrb, key); + RSTR_SET_FROZEN_FLAG(mrb_str_ptr(key)); + return key; + } else return key; } From 8256d77c7fe551011cc744ddb204ca20c4eea175 Mon Sep 17 00:00:00 2001 From: Kazuho Oku Date: Thu, 10 Sep 2015 22:50:01 +0900 Subject: [PATCH 211/218] avoid unnecessary string duplications by checking the frozen flag --- src/hash.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/hash.c b/src/hash.c index 42b40482a..ffb8bd931 100644 --- a/src/hash.c +++ b/src/hash.c @@ -104,12 +104,11 @@ static void mrb_hash_modify(mrb_state *mrb, mrb_value hash); static inline mrb_value mrb_hash_ht_key(mrb_state *mrb, mrb_value key) { - if (mrb_string_p(key)) { + if (mrb_string_p(key) && !RSTR_FROZEN_P(mrb_str_ptr(key))) { key = mrb_str_dup(mrb, key); RSTR_SET_FROZEN_FLAG(mrb_str_ptr(key)); - return key; - } else - return key; + } + return key; } #define KEY(key) mrb_hash_ht_key(mrb, key) From 698b3c925d757cd7113f9916db2dbb7e2eabf2f4 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Thu, 10 Sep 2015 23:03:53 +0900 Subject: [PATCH 212/218] add Hash#rehash to handle key modification; ref #2945 --- mrblib/hash.rb | 23 +++++++++++++++++++++++ test/t/hash.rb | 9 +++++++++ 2 files changed, 32 insertions(+) diff --git a/mrblib/hash.rb b/mrblib/hash.rb index cb52c1ffe..48ac96e56 100644 --- a/mrblib/hash.rb +++ b/mrblib/hash.rb @@ -319,6 +319,29 @@ class Hash h end + ## + # call-seq: + # hsh.rehash -> hsh + # + # Rebuilds the hash based on the current hash values for each key. If + # values of key objects have changed since they were inserted, this + # method will reindex hsh. + # + # h = {"AAA" => "b"} + # h.keys[0].chop! + # h #=> {"AA"=>"b"} + # h["AA"] #=> nil + # h.rehash #=> {"AA"=>"b"} + # h["AA"] #=> "b" + # + def rehash + h = {} + self.each{|k,v| + h[k] = v + } + self.replace(h) + end + def __update(h) h.each_key{|k| self[k] = h[k]} self diff --git a/test/t/hash.rb b/test/t/hash.rb index eee7c7b6a..3196cc97a 100644 --- a/test/t/hash.rb +++ b/test/t/hash.rb @@ -342,3 +342,12 @@ assert('Hash#inspect') do assert_include ret, '"a"=>100' assert_include ret, '"d"=>400' end + +assert('Hash#rehash') do + h = {[:a] => "b"} + # hash key modified + h.keys[0][0] = :b + # h[[:b]] => nil + h.rehash + assert_equal("b", h[[:b]]) +end From 291265ec86e2b4a8d66b33be3e2d65fa6744da84 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Fri, 11 Sep 2015 00:15:01 +0900 Subject: [PATCH 213/218] Customize installation directory using INSTALL_DIR environment variable Previously, minirake installed several commands (e.g., mrbc) in repository locally under bin directory. But there was no knob for users to change this directory. It effectively made `make distcheck` fail if mruby was embedded into project managed by autotools. This change adds a way for the user to change installation directory by setting INSTALL_DIR environment variable. --- Rakefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Rakefile b/Rakefile index 8a8912af5..3e03b1096 100644 --- a/Rakefile +++ b/Rakefile @@ -32,7 +32,7 @@ load "#{MRUBY_ROOT}/tasks/benchmark.rake" # generic build targets, rules task :default => :all -bin_path = "#{MRUBY_ROOT}/bin" +bin_path = ENV['INSTALL_DIR'] || "#{MRUBY_ROOT}/bin" FileUtils.mkdir_p bin_path, { :verbose => $verbose } depfiles = MRuby.targets['host'].bins.map do |bin| @@ -71,7 +71,7 @@ MRuby.each_target do |target| end if target == MRuby.targets['host'] - install_path = MRuby.targets['host'].exefile("#{MRUBY_ROOT}/bin/#{bin}") + install_path = MRuby.targets['host'].exefile("#{bin_path}/#{bin}") file install_path => exec do |t| FileUtils.rm_f t.name, { :verbose => $verbose } @@ -80,7 +80,7 @@ MRuby.each_target do |target| depfiles += [ install_path ] elsif target == MRuby.targets['host-debug'] unless MRuby.targets['host'].gems.map {|g| g.bins}.include?([bin]) - install_path = MRuby.targets['host-debug'].exefile("#{MRUBY_ROOT}/bin/#{bin}") + install_path = MRuby.targets['host-debug'].exefile("#{bin_path}/#{bin}") file install_path => exec do |t| FileUtils.rm_f t.name, { :verbose => $verbose } From 8277e950eee4e8c6135eca281a7d5ca91077d2b4 Mon Sep 17 00:00:00 2001 From: Yasuhiro Matsumoto Date: Fri, 11 Sep 2015 11:12:03 +0900 Subject: [PATCH 214/218] Support windows locale Add mrb_utf8_from_locale, mrb_utf8_free, mrb_locale_from_utf8, mrb_locale_free. Just works for windows. --- include/mruby.h | 12 ++++ mrbgems/mruby-bin-mirb/tools/mirb/mirb.c | 10 +++- mrbgems/mruby-bin-mruby/tools/mruby/mruby.c | 11 +++- mrbgems/mruby-print/src/print.c | 13 +++-- src/string.c | 63 +++++++++++++++++++++ 5 files changed, 99 insertions(+), 10 deletions(-) diff --git a/include/mruby.h b/include/mruby.h index b4ec13fdc..dedbd0748 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -292,6 +292,18 @@ MRB_API mrb_value mrb_str_new_cstr(mrb_state*, const char*); MRB_API mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len); #define mrb_str_new_lit(mrb, lit) mrb_str_new_static(mrb, (lit), mrb_strlen_lit(lit)) +#ifdef _WIN32 +char* mrb_utf8_from_locale(const char *p, size_t len); +char* mrb_locale_from_utf8(const char *p, size_t len); +#define mrb_locale_free(p) free(p) +#define mrb_utf8_free(p) free(p) +#else +#define mrb_utf8_from_locale(p, l) (p) +#define mrb_locale_from_utf8(p, l) (p) +#define mrb_locale_free(p) +#define mrb_utf8_free(p) +#endif + MRB_API mrb_state* mrb_open(void); MRB_API mrb_state* mrb_open_allocf(mrb_allocf, void *ud); MRB_API mrb_state* mrb_open_core(mrb_allocf, void *ud); diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c index 0f3649a35..37fda352c 100644 --- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c +++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c @@ -366,6 +366,8 @@ main(int argc, char **argv) ai = mrb_gc_arena_save(mrb); while (TRUE) { + char *utf8; + #ifndef ENABLE_READLINE print_cmdline(code_block_open); @@ -415,17 +417,21 @@ main(int argc, char **argv) strcpy(ruby_code, last_code_line); } + utf8 = mrb_utf8_from_locale(ruby_code, -1); + if (!utf8) abort(); + /* parse code */ parser = mrb_parser_new(mrb); if (parser == NULL) { fputs("create parser state error\n", stderr); break; } - parser->s = ruby_code; - parser->send = ruby_code + strlen(ruby_code); + parser->s = utf8; + parser->send = utf8 + strlen(utf8); parser->lineno = cxt->lineno; mrb_parser_parse(parser, cxt); code_block_open = is_code_block_open(parser); + mrb_utf8_free(utf8); if (code_block_open) { /* no evaluation of code */ diff --git a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c index 5ca744388..cc1ca3055 100644 --- a/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c +++ b/mrbgems/mruby-bin-mruby/tools/mruby/mruby.c @@ -191,7 +191,11 @@ main(int argc, char **argv) ARGV = mrb_ary_new_capa(mrb, args.argc); for (i = 0; i < args.argc; i++) { - mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, args.argv[i])); + char* utf8 = mrb_utf8_from_locale(args.argv[i], -1); + if (utf8) { + mrb_ary_push(mrb, ARGV, mrb_str_new_cstr(mrb, utf8)); + mrb_utf8_free(utf8); + } } mrb_define_global_const(mrb, "ARGV", ARGV); @@ -222,7 +226,10 @@ main(int argc, char **argv) v = mrb_load_file_cxt(mrb, args.rfp, c); } else { - v = mrb_load_string_cxt(mrb, args.cmdline, c); + char* utf8 = mrb_utf8_from_locale(args.cmdline, -1); + if (!utf8) abort(); + v = mrb_load_string_cxt(mrb, utf8, c); + mrb_utf8_free(utf8); } mrbc_context_free(mrb, c); diff --git a/mrbgems/mruby-print/src/print.c b/mrbgems/mruby-print/src/print.c index 673ba2172..e7e21dd4b 100644 --- a/mrbgems/mruby-print/src/print.c +++ b/mrbgems/mruby-print/src/print.c @@ -1,17 +1,18 @@ #include "mruby.h" #include "mruby/string.h" #include +#include +#include static void printstr(mrb_state *mrb, mrb_value obj) { - char *s; - mrb_int len; - if (mrb_string_p(obj)) { - s = RSTRING_PTR(obj); - len = RSTRING_LEN(obj); - fwrite(s, len, 1, stdout); + char* ptr = mrb_locale_from_utf8(RSTRING_PTR(obj), RSTRING_LEN(obj)); + if (ptr) { + fwrite(ptr, strlen(ptr), 1, stdout); + mrb_locale_free(ptr); + } } } diff --git a/src/string.c b/src/string.c index 08caf3bae..e93fd4606 100644 --- a/src/string.c +++ b/src/string.c @@ -43,6 +43,69 @@ mrb_str_strlen(mrb_state *mrb, struct RString *s) return max; } +#ifdef _WIN32 +#include + +char* +mrb_utf8_from_locale(const char *str, size_t len) +{ + wchar_t* wcsp; + char* mbsp; + size_t mbssize, wcssize; + + if (len == 0) + return strdup(""); + if (len == -1) + len = strlen(str); + wcssize = MultiByteToWideChar(GetACP(), 0, str, len, NULL, 0); + wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); + if (!wcsp) + return NULL; + wcssize = MultiByteToWideChar(GetACP(), 0, str, len, wcsp, wcssize + 1); + wcsp[wcssize] = 0; + + mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); + mbsp = (char*) malloc((mbssize + 1)); + if (!mbsp) { + free(wcsp); + return NULL; + } + mbssize = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); + mbsp[mbssize] = 0; + free(wcsp); + return mbsp; +} + +char* +mrb_locale_from_utf8(const char *utf8, size_t len) +{ + wchar_t* wcsp; + char* mbsp; + size_t mbssize, wcssize; + + if (len == 0) + return strdup(""); + if (len == -1) + len = strlen(utf8); + wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, NULL, 0); + wcsp = (wchar_t*) malloc((wcssize + 1) * sizeof(wchar_t)); + if (!wcsp) + return NULL; + wcssize = MultiByteToWideChar(CP_UTF8, 0, utf8, len, wcsp, wcssize + 1); + wcsp[wcssize] = 0; + mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, NULL, 0, NULL, NULL); + mbsp = (char*) malloc((mbssize + 1)); + if (!mbsp) { + free(wcsp); + return NULL; + } + mbssize = WideCharToMultiByte(GetACP(), 0, (LPCWSTR) wcsp, -1, mbsp, mbssize, NULL, NULL); + mbsp[mbssize] = 0; + free(wcsp); + return mbsp; +} +#endif + static inline void resize_capa(mrb_state *mrb, struct RString *s, mrb_int capacity) { From a085c04e3741825ab4c4ceda60b640e250ae56d5 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sat, 12 Sep 2015 12:11:10 +0900 Subject: [PATCH 215/218] Don't crash if NULL is passed to mrb_close Sometimes it is very useful just return from mrb_close if NULL is passed as mrb. This is the same spirit of free(3), which just does nothing if NULL is passed. --- src/state.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/state.c b/src/state.c index 2efd34334..bfd99e4c3 100644 --- a/src/state.c +++ b/src/state.c @@ -234,6 +234,7 @@ mrb_free_context(mrb_state *mrb, struct mrb_context *c) MRB_API void mrb_close(mrb_state *mrb) { + if (!mrb) return; if (mrb->atexit_stack_len > 0) { mrb_int i; for (i = mrb->atexit_stack_len; i > 0; --i) { From e8f88daa9c0486485072a1fb1c61a60ede0ff5c0 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Mon, 14 Sep 2015 15:56:54 +0900 Subject: [PATCH 216/218] instance_eval should set target_class; close #2936 target_class should be singleton class of the receiver --- mrbgems/mruby-eval/src/eval.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index 8bfa2f112..dd5fd5024 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -235,12 +235,12 @@ f_instance_eval(mrb_state *mrb, mrb_value self) mrb_int len; char *file = NULL; mrb_int line = 1; + mrb_value cv; mrb_get_args(mrb, "s|zi", &s, &len, &file, &line); c->ci->acc = CI_ACC_SKIP; - if (c->ci->target_class->tt == MRB_TT_ICLASS) { - c->ci->target_class = c->ci->target_class->c; - } + cv = mrb_singleton_class(mrb, self); + c->ci->target_class = mrb_class_ptr(cv); return mrb_run(mrb, create_proc_from_string(mrb, s, len, mrb_nil_value(), file, line), self); } else { From b88ca625ab44a063c9b105f06789446f791c8b3e Mon Sep 17 00:00:00 2001 From: takahashim Date: Wed, 16 Sep 2015 02:57:41 +0900 Subject: [PATCH 217/218] fix block variable in Hash#fetch --- mrbgems/mruby-hash-ext/mrblib/hash.rb | 2 +- mrbgems/mruby-hash-ext/test/hash.rb | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mrbgems/mruby-hash-ext/mrblib/hash.rb b/mrbgems/mruby-hash-ext/mrblib/hash.rb index c970b9d02..5056d0720 100644 --- a/mrbgems/mruby-hash-ext/mrblib/hash.rb +++ b/mrbgems/mruby-hash-ext/mrblib/hash.rb @@ -126,7 +126,7 @@ class Hash def fetch(key, none=NONE, &block) unless self.key?(key) if block - block.call + block.call(key) elsif none != NONE none else diff --git a/mrbgems/mruby-hash-ext/test/hash.rb b/mrbgems/mruby-hash-ext/test/hash.rb index e1afdaaa3..4950ef354 100644 --- a/mrbgems/mruby-hash-ext/test/hash.rb +++ b/mrbgems/mruby-hash-ext/test/hash.rb @@ -75,6 +75,7 @@ assert('Hash#fetch') do assert_equal "feline", h.fetch("cat") assert_equal "mickey", h.fetch("mouse", "mickey") assert_equal "minny", h.fetch("mouse"){"minny"} + assert_equal "mouse", h.fetch("mouse"){|k| k} begin h.fetch("gnu") rescue => e From f1c23a0f75a4a38c5077e1df30af200f3700752f Mon Sep 17 00:00:00 2001 From: takahashim Date: Wed, 16 Sep 2015 18:50:03 +0900 Subject: [PATCH 218/218] support String#[]= with 3 args --- mrblib/string.rb | 49 +++++++++++++++++++++++++++++++------ test/t/string.rb | 63 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 105 insertions(+), 7 deletions(-) diff --git a/mrblib/string.rb b/mrblib/string.rb index 05b13cb43..5765cff9b 100644 --- a/mrblib/string.rb +++ b/mrblib/string.rb @@ -154,13 +154,48 @@ class String end ## - # Modify +self+ by replacing the content of +self+ - # at the position +pos+ with +value+. - def []=(pos, value) - pos += self.length if pos < 0 - b = self[0, pos] - a = self[pos + 1..-1] - self.replace([b, value, a].join('')) + # Modify +self+ by replacing the content of +self+. + # The portion of the string affected is determined using the same criteria as +String#[]+. + def []=(*args) + anum = args.size + if anum == 2 + pos, value = args + if pos.kind_of? String + posnum = self.index(pos) + if posnum + b = self[0, posnum.to_i] + a = self[(posnum + pos.length)..-1] + self.replace([b, value, a].join('')) + return value + else + raise IndexError, "string not matched" + end + else + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + b = self[0, pos.to_i] + a = self[pos + 1..-1] + self.replace([b, value, a].join('')) + return value + end + elsif anum == 3 + pos, len, value = args + pos += self.length if pos < 0 + if pos < 0 || pos > self.length + raise IndexError, "index #{args[0]} out of string" + end + if len < 0 + raise IndexError, "negative length #{len}" + end + b = self[0, pos.to_i] + a = self[pos + len..-1] + self.replace([b, value, a].join('')) + return value + else + raise ArgumentError, "wrong number of arguments (#{anum} for 2..3)" + end end ## diff --git a/test/t/string.rb b/test/t/string.rb index 7326adce9..87aec0e21 100644 --- a/test/t/string.rb +++ b/test/t/string.rb @@ -122,6 +122,69 @@ assert('String#[] with Range') do assert_equal 'bc', j2 end +assert('String#[]=') do + # length of args is 1 + a = 'abc' + a[0] = 'X' + assert_equal 'Xbc', a + + b = 'abc' + b[-1] = 'X' + assert_equal 'abX', b + + c = 'abc' + assert_raise(IndexError) do + c[10] = 'X' + end + + d = 'abc' + assert_raise(IndexError) do + d[-10] = 'X' + end + + e = 'abc' + e[1.1] = 'X' + assert_equal 'aXc', e + + + # length of args is 2 + a1 = 'abc' + assert_raise(IndexError) do + a1[0, -1] = 'X' + end + + b1 = 'abc' + assert_raise(IndexError) do + b1[10, 0] = 'X' + end + + c1 = 'abc' + assert_raise(IndexError) do + c1[-10, 0] = 'X' + end + + d1 = 'abc' + d1[0, 0] = 'X' + assert_equal 'Xabc', d1 + + e1 = 'abc' + e1[1, 3] = 'X' + assert_equal 'aX', e1 + + # args is RegExp + # It will be tested in mrbgems. + + # args is String + a3 = 'abc' + a3['bc'] = 'X' + assert_equal a3, 'aX' + + b3 = 'abc' + assert_raise(IndexError) do + b3['XX'] = 'Y' + end +end + assert('String#capitalize', '15.2.10.5.7') do a = 'abc' a.capitalize