summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.travis.yml11
-rw-r--r--doc/api/mruby.h.md20
-rw-r--r--doc/api/mruby/array.h.md223
-rw-r--r--doc/api/mruby/hash.h.md273
-rw-r--r--doc/api/mruby/value.h.md40
-rw-r--r--doc/mrbgems/README.md14
-rw-r--r--include/mruby/error.h12
-rw-r--r--include/mruby/string.h11
-rw-r--r--include/mruby/version.h12
-rw-r--r--mrbgems/mruby-array-ext/mrblib/array.rb24
-rw-r--r--mrbgems/mruby-bin-mirb/mrbgem.rake3
-rw-r--r--mrbgems/mruby-bin-mrbc/tools/mrbc/mrbc.c3
-rw-r--r--mrbgems/mruby-bin-mruby/tools/mruby/mruby.c5
-rw-r--r--mrbgems/mruby-compiler/core/codegen.c18
-rw-r--r--mrbgems/mruby-compiler/core/parse.y7
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb6
-rw-r--r--mrbgems/mruby-error/mrbgem.rake10
-rw-r--r--mrbgems/mruby-error/src/exception.c100
-rw-r--r--mrbgems/mruby-error/test/exception.c59
-rw-r--r--mrbgems/mruby-error/test/exception.rb55
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb12
-rw-r--r--mrbgems/mruby-string-ext/src/string.c56
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb16
-rw-r--r--mrbgems/mruby-time/src/time.c4
-rw-r--r--mrblib/array.rb29
-rw-r--r--mrblib/enum.rb37
-rw-r--r--mrblib/error.rb15
-rw-r--r--mrblib/numeric.rb10
-rw-r--r--mrblib/range.rb12
-rw-r--r--mrblib/string.rb27
-rw-r--r--src/array.c7
-rw-r--r--src/class.c119
-rw-r--r--src/dump.c10
-rw-r--r--src/error.c9
-rw-r--r--src/etc.c10
-rw-r--r--src/fmt_fp.c2
-rw-r--r--src/numeric.c3
-rw-r--r--src/range.c4
-rw-r--r--src/string.c21
-rw-r--r--src/variable.c2
-rw-r--r--src/version.c1
-rw-r--r--src/vm.c19
-rw-r--r--tasks/mrbgem_spec.rake2
-rw-r--r--tasks/mruby_build.rake7
-rw-r--r--tasks/mruby_build_commands.rake6
-rw-r--r--tasks/mruby_build_gem.rake5
-rw-r--r--tasks/toolchains/androideabi.rake6
-rw-r--r--test/bintest.rb2
-rw-r--r--test/t/string.rb8
49 files changed, 879 insertions, 488 deletions
diff --git a/.travis.yml b/.travis.yml
index f7be58c8a..bcfce3984 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,14 @@
-# no installation...
+language: c
+
+matrix:
+ include:
+ - os: linux
+ sudo: 9000
+ - os: osx
+ osx_image: xcod6.4
install:
- - 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"
diff --git a/doc/api/mruby.h.md b/doc/api/mruby.h.md
index 8862fee2c..06bab2d56 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 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) {
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
```
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.
diff --git a/include/mruby/error.h b/include/mruby/error.h
index 52f6772bd..e3e2b25e2 100644
--- a/include/mruby/error.h
+++ b/include/mruby/error.h
@@ -24,11 +24,21 @@ 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);
+/* 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);
+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_int len, struct RClass **classes);
+
#if defined(__cplusplus)
} /* extern "C" { */
#endif
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/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 \
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-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"
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/mrbgems/mruby-compiler/core/codegen.c b/mrbgems/mruby-compiler/core/codegen.c
index cefde8b7b..3853814ec 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--;
+ s->iseq[s->pc] = i;
+ }
if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) {
/* skip swapping OP_MOVE */
return 0;
@@ -406,7 +411,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 +1017,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 */
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index b057cac17..097d63ac4 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 = $<stack>4;
+ CMDARG_LEXPOP();
}
| keyword_if expr_value then
compstmt
@@ -2941,7 +2942,7 @@ backref : tNTH_REF
| tBACK_REF
;
-superclass : term
+superclass : /* term */
{
$$ = 0;
}
@@ -2953,12 +2954,12 @@ superclass : term
expr_value term
{
$$ = $3;
- }
+ } /*
| error term
{
yyerrok;
$$ = 0;
- }
+ } */
;
f_arglist : '(' f_args rparen
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-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..911fde0be
--- /dev/null
+++ b/mrbgems/mruby-error/src/exception.c
@@ -0,0 +1,100 @@
+#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;
+ result = mrb_obj_value(mrb->exc);
+ 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, 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_int len, struct RClass **classes)
+{
+ struct mrb_jmpbuf *prev_jmp = mrb->jmp;
+ struct mrb_jmpbuf c_jmp;
+ mrb_value result;
+ mrb_bool error_matched = FALSE;
+ mrb_int i;
+
+ 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;
+
+ for (i = 0; i < len; ++i) {
+ if (mrb_obj_is_kind_of(mrb, mrb_obj_value(mrb->exc), classes[i])) {
+ error_matched = TRUE;
+ break;
+ }
+ }
+
+ 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..2a943aaae
--- /dev/null
+++ b/mrbgems/mruby-error/test/exception.c
@@ -0,0 +1,59 @@
+#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;
+ struct RClass *cls[1];
+ mrb_get_args(mrb, "oo", &b, &r);
+ cls[0] = E_TYPE_ERROR;
+ return mrb_rescue_exceptions(mrb, protect_cb, b, protect_cb, r, 1, cls);
+}
+
+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..0bbc2a0e7
--- /dev/null
+++ b/mrbgems/mruby-error/test/exception.rb
@@ -0,0 +1,55 @@
+assert 'mrb_protect' do
+ # no failure in protect returns [result, false]
+ assert_equal ['test', false] do
+ ExceptionTest.mrb_protect { '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
+ 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
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
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
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 <sys/time.h>
#endif
diff --git a/mrblib/array.rb b/mrblib/array.rb
index 933f822db..65dd0d665 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,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
diff --git a/mrblib/enum.rb b/mrblib/enum.rb
index 6bf219283..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
@@ -402,8 +382,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
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
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
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
diff --git a/mrblib/string.rb b/mrblib/string.rb
index ee097ad6d..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
##
@@ -111,6 +107,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]))
@@ -128,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
##
@@ -164,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
diff --git a/src/array.c b/src/array.c
index f48719310..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();
}
@@ -295,7 +294,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 +348,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 +1030,7 @@ 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, "|S!", &sep);
return mrb_ary_join(mrb, ary, sep);
}
diff --git a/src/class.c b/src/class.c
index e9cbc592d..33fb61211 100644
--- a/src/class.c
+++ b/src/class.c
@@ -435,12 +435,12 @@ to_sym(mrb_state *mrb, mrb_value ss)
----------------------------------------------------------------------------------------------
o: Object [mrb_value]
C: class/module [mrb_value]
- S: String [mrb_value]
- A: Array [mrb_value]
- H: Hash [mrb_value]
- 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 [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]
@@ -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 (i < argc && mrb_nil_p(*sp)) {
+ *p = *sp++;
+ i++;
+ break;
+ }
+ }
if (i < argc) {
*p = to_str(mrb, *sp++);
i++;
@@ -536,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++;
@@ -547,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++;
@@ -561,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);
@@ -575,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);
@@ -591,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);
@@ -676,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;
@@ -1262,6 +1320,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 +1384,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();
}
@@ -1543,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/dump.c b/src/dump.c
index 2f2e5edcb..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
@@ -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;
}
diff --git a/src/error.c b/src/error.c
index a800f77f9..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);
@@ -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/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);
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
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);
}
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/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());
}
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;
}
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));
diff --git a/src/vm.c b/src/vm.c
index 15a3926e3..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)
@@ -723,6 +724,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)
{
@@ -1030,7 +1033,7 @@ RETRY_TRY_BLOCK:
mrb_callinfo *ci = mrb->c->ci;
int n, eidx = ci->eidx;
- for (n=0; n<a && eidx > ci[-1].eidx; n++) {
+ for (n=0; n<a && (ci == mrb->c->cibase || eidx > ci[-1].eidx); n++) {
ecall(mrb, --eidx);
ARENA_RESTORE(mrb, ai);
}
@@ -1078,8 +1081,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) {
@@ -1488,6 +1498,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;
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.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 <<EOS
+ FileUtils.mkdir_p File.dirname t.name
+ IO.write t.name, <<EOS
#define __STDC_CONSTANT_MACROS
#define __STDC_LIMIT_MACROS
@@ -136,9 +136,8 @@ extern "C" {
#include "#{src}"
}
-#{File.basename(src) == 'error.c'? 'mrb_int mrb_jmpbuf::jmpbuf_id = 0;' : ''}
+#{src == "#{MRUBY_ROOT}/src/error.c"? 'mrb_int mrb_jmpbuf::jmpbuf_id = 0;' : ''}
EOS
- end
end
file obj => cxx_src do |t|
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
diff --git a/tasks/mruby_build_gem.rake b/tasks/mruby_build_gem.rake
index 26990a380..896aeb147 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'
@@ -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]}"
diff --git a/tasks/toolchains/androideabi.rake b/tasks/toolchains/androideabi.rake
index 7cdb9e43a..272e802f7 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'] || DEFAULT_GCC_VERSION
+ CLANG_VERSION = ENV['CLANG_VERSION'] || DEFAULT_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
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
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
+