diff options
| -rw-r--r-- | Doxyfile | 2 | ||||
| -rw-r--r-- | README.md | 2 | ||||
| -rw-r--r-- | doc/guides/debugger.md | 2 | ||||
| -rw-r--r-- | doc/limitations.md | 20 | ||||
| -rw-r--r-- | include/mrbconf.h | 3 | ||||
| -rw-r--r-- | include/mruby/array.h | 6 | ||||
| -rw-r--r-- | include/mruby/string.h | 6 | ||||
| -rw-r--r-- | include/mruby/value.h | 8 | ||||
| -rw-r--r-- | include/mruby/version.h | 8 | ||||
| -rw-r--r-- | mrbgems/mruby-compiler/core/parse.y | 64 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 6 | ||||
| -rw-r--r-- | mrbgems/mruby-exit/src/mruby-exit.c | 13 | ||||
| -rw-r--r-- | mrbgems/mruby-io/test/mruby_io_test.c | 25 | ||||
| -rw-r--r-- | mrbgems/mruby-kernel-ext/src/kernel.c | 2 | ||||
| -rw-r--r-- | mrbgems/mruby-metaprog/src/metaprog.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-proc-ext/src/proc.c | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-sprintf/src/kernel.c | 4 | ||||
| -rw-r--r-- | src/kernel.c | 2 | ||||
| -rw-r--r-- | src/string.c | 93 |
19 files changed, 110 insertions, 164 deletions
@@ -6,7 +6,7 @@ DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = "mruby" -PROJECT_NUMBER = 2.0.1 +PROJECT_NUMBER = 2.1.0 PROJECT_BRIEF = "mruby is the lightweight implementation of the Ruby language" @@ -17,7 +17,7 @@ of the Ministry of Economy, Trade and Industry of Japan. ## How to get mruby -The stable version 2.0.1 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.0.1.zip](https://github.com/mruby/mruby/archive/2.0.1.zip) +The stable version 2.1.0 of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/archive/2.1.0.zip](https://github.com/mruby/mruby/archive/2.1.0.zip) The latest development version of mruby can be downloaded via the following URL: [https://github.com/mruby/mruby/zipball/master](https://github.com/mruby/mruby/zipball/master) diff --git a/doc/guides/debugger.md b/doc/guides/debugger.md index 81c0e9d63..a94ef1802 100644 --- a/doc/guides/debugger.md +++ b/doc/guides/debugger.md @@ -38,7 +38,7 @@ To confirm mrdb was installed properly, run mrdb with the `--version` option: ```bash $ mrdb --version -mruby 2.0.1 (2019-4-4) +mruby 2.1.0 (2019-11-19) ``` ## 2.2 Basic Operation diff --git a/doc/limitations.md b/doc/limitations.md index 6958d396f..9ad2019f7 100644 --- a/doc/limitations.md +++ b/doc/limitations.md @@ -38,7 +38,7 @@ puts [1,2,3] 3 ``` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] ``` [1, 2, 3] @@ -61,7 +61,7 @@ end `ZeroDivisionError` is raised. -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] No exception is raised. @@ -89,7 +89,7 @@ p Liste.new "foobar" ` [] ` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] `ArgumentError` is raised. @@ -119,7 +119,7 @@ false true ``` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] ``` true @@ -156,7 +156,7 @@ p 'ok' ok ``` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] ``` test.rb:8: undefined method 'test_func' (NoMethodError) @@ -178,7 +178,7 @@ defined?(Foo) nil ``` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] `NameError` is raised. @@ -195,7 +195,7 @@ alias $a $__a__ ` nil ` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] Syntax error @@ -217,7 +217,7 @@ end `ArgumentError` is raised. The re-defined `+` operator does not accept any arguments. -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] ` 'ab' ` Behavior of the operator wasn't changed. @@ -233,7 +233,7 @@ $ ruby -e 'puts Proc.new {}.binding' #<Binding:0x00000e9deabb9950> ``` -#### mruby [2.0.1 (2019-4-4)] +#### mruby [2.1.0 (2019-11-19)] ``` $ ./bin/mruby -e 'puts Proc.new {}.binding' @@ -255,7 +255,7 @@ $ ruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)' [[{"a"=>1}], {:b=>2}] ``` -#### mruby [mruby 2.0.1] +#### mruby [mruby 2.1.0] ``` $ ./bin/mruby -e 'def m(*r,**k) p [r,k] end; m("a"=>1,:b=>2)' diff --git a/include/mrbconf.h b/include/mrbconf.h index b86ce82e8..0509f4ff9 100644 --- a/include/mrbconf.h +++ b/include/mrbconf.h @@ -62,9 +62,6 @@ # endif #endif -#define MRB_COMPLEX_NUMBERS -#define MRB_RATIONAL_NUMBERS - /* define on big endian machines; used by MRB_NAN_BOXING, etc. */ #ifndef MRB_ENDIAN_BIG # if (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) || \ diff --git a/include/mruby/array.h b/include/mruby/array.h index 9664214d6..e2dd9bb1c 100644 --- a/include/mruby/array.h +++ b/include/mruby/array.h @@ -17,7 +17,7 @@ MRB_BEGIN_DECL typedef struct mrb_shared_array { int refcnt; - mrb_int len; + mrb_ssize len; mrb_value *ptr; } mrb_shared_array; @@ -26,9 +26,9 @@ struct RArray { MRB_OBJECT_HEADER; union { struct { - mrb_int len; + mrb_ssize len; union { - mrb_int capa; + mrb_ssize capa; mrb_shared_array *shared; } aux; mrb_value *ptr; diff --git a/include/mruby/string.h b/include/mruby/string.h index 9039aaab3..e5a046073 100644 --- a/include/mruby/string.h +++ b/include/mruby/string.h @@ -23,9 +23,9 @@ struct RString { MRB_OBJECT_HEADER; union { struct { - mrb_int len; + mrb_ssize len; union { - mrb_int capa; + mrb_ssize capa; struct mrb_shared_string *shared; struct RString *fshared; } aux; @@ -54,7 +54,7 @@ struct RStringEmbed { RSTR_SET_EMBED_LEN((s),(n));\ }\ else {\ - (s)->as.heap.len = (mrb_int)(n);\ + (s)->as.heap.len = (mrb_ssize)(n);\ }\ } while (0) #define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary) diff --git a/include/mruby/value.h b/include/mruby/value.h index 84ea7fb0a..5a909a5cf 100644 --- a/include/mruby/value.h +++ b/include/mruby/value.h @@ -174,6 +174,14 @@ typedef void mrb_value; #define MRB_SYMBOL_MAX UINT32_MAX #endif +#if INTPTR_MAX < MRB_INT_MAX + typedef intptr_t mrb_ssize; +# define MRB_SSIZE_MAX (INTPTR_MAX>>MRB_FIXNUM_SHIFT) +#else + typedef mrb_int mrb_ssize; +# define MRB_SSIZE_MAX MRB_INT_MAX +#endif + #ifndef mrb_immediate_p #define mrb_immediate_p(o) (mrb_type(o) < MRB_TT_FREE) #endif diff --git a/include/mruby/version.h b/include/mruby/version.h index 1c7655a47..f4ef21021 100644 --- a/include/mruby/version.h +++ b/include/mruby/version.h @@ -42,12 +42,12 @@ MRB_BEGIN_DECL /* * Minor release version number. */ -#define MRUBY_RELEASE_MINOR 0 +#define MRUBY_RELEASE_MINOR 1 /* * Tiny release version number. */ -#define MRUBY_RELEASE_TEENY 1 +#define MRUBY_RELEASE_TEENY 0 /* * The mruby version. @@ -67,12 +67,12 @@ MRB_BEGIN_DECL /* * Release month. */ -#define MRUBY_RELEASE_MONTH 4 +#define MRUBY_RELEASE_MONTH 11 /* * Release day. */ -#define MRUBY_RELEASE_DAY 4 +#define MRUBY_RELEASE_DAY 19 /* * Release date as a string. diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y index 5a405b8cb..911812706 100644 --- a/mrbgems/mruby-compiler/core/parse.y +++ b/mrbgems/mruby-compiler/core/parse.y @@ -71,23 +71,8 @@ typedef unsigned int stack_type; #define nint(x) ((node*)(intptr_t)(x)) #define intn(x) ((int)(intptr_t)(x)) -#if defined(MRB_COMPLEX_NUMBERS) || defined(MRB_RATIONAL_NUMBERS) - #define MRB_SUFFIX_SUPPORT - - #ifdef MRB_RATIONAL_NUMBERS - #define NUM_SUFFIX_R (1<<0) - #else - #define NUM_SUFFIX_R 0 - #endif - - #ifdef MRB_COMPLEX_NUMBERS - #define NUM_SUFFIX_I (1<<1) - #else - #define NUM_SUFFIX_I 0 - #endif - - #define NUM_SUFFIX_ALL (NUM_SUFFIX_R | NUM_SUFFIX_I) -#endif +#define NUM_SUFFIX_R (1<<0) +#define NUM_SUFFIX_I (1<<1) static inline mrb_sym intern_cstr_gen(parser_state *p, const char *s) @@ -866,37 +851,29 @@ new_op_asgn(parser_state *p, node *a, mrb_sym op, node *b) return list4((node*)NODE_OP_ASGN, a, nsym(op), b); } -#ifdef MRB_COMPLEX_NUMBERS static node* new_imaginary(parser_state *p, node *imaginary) { return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Complex"), list1(list2(list3((node*)NODE_INT, (node*)strdup("0"), nint(10)), imaginary)), 1); } -#endif -#ifdef MRB_RATIONAL_NUMBERS static node* new_rational(parser_state *p, node *rational) { return new_call(p, new_const(p, intern_lit("Kernel")), intern_lit("Rational"), list1(list1(rational)), 1); } -#endif /* (:int . i) */ static node* new_int(parser_state *p, const char *s, int base, int suffix) { node* result = list3((node*)NODE_INT, (node*)strdup(s), nint(base)); -#ifdef MRB_RATIONAL_NUMBERS if (suffix & NUM_SUFFIX_R) { result = new_rational(p, result); } -#endif -#ifdef MRB_COMPLEX_NUMBERS if (suffix & NUM_SUFFIX_I) { result = new_imaginary(p, result); } -#endif return result; } @@ -906,16 +883,12 @@ static node* new_float(parser_state *p, const char *s, int suffix) { node* result = cons((node*)NODE_FLOAT, (node*)strdup(s)); -#ifdef MRB_RATIONAL_NUMBERS if (suffix & NUM_SUFFIX_R) { result = new_rational(p, result); } -#endif -#ifdef MRB_COMPLEX_NUMBERS if (suffix & NUM_SUFFIX_I) { result = new_imaginary(p, result); } -#endif return result; } #endif @@ -4585,13 +4558,13 @@ parse_string(parser_state *p) return tSTRING; } -#ifdef MRB_SUFFIX_SUPPORT static int -number_literal_suffix(parser_state *p, int mask) +number_literal_suffix(parser_state *p) { int c, result = 0; node *list = 0; int column = p->column; + int mask = NUM_SUFFIX_R|NUM_SUFFIX_I; while ((c = nextc(p)) != -1) { list = push(list, (node*)(intptr_t)c); @@ -4623,7 +4596,6 @@ number_literal_suffix(parser_state *p, int mask) } return result; } -#endif static int heredoc_identifier(parser_state *p) @@ -5246,9 +5218,7 @@ parser_yylex(parser_state *p) no_digits(); } else if (nondigit) goto trailing_uc; - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, tok(p), 16, suffix); return tINTEGER; } @@ -5273,9 +5243,7 @@ parser_yylex(parser_state *p) no_digits(); } else if (nondigit) goto trailing_uc; - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, tok(p), 2, suffix); return tINTEGER; } @@ -5300,9 +5268,7 @@ parser_yylex(parser_state *p) no_digits(); } else if (nondigit) goto trailing_uc; - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, tok(p), 10, suffix); return tINTEGER; } @@ -5336,9 +5302,7 @@ parser_yylex(parser_state *p) pushback(p, c); tokfix(p); if (nondigit) goto trailing_uc; - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, tok(p), 8, suffix); return tINTEGER; } @@ -5356,9 +5320,7 @@ parser_yylex(parser_state *p) } else { pushback(p, c); - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, "0", 10, suffix); return tINTEGER; } @@ -5448,16 +5410,12 @@ parser_yylex(parser_state *p) yywarning_s(p, "float out of range", tok(p)); errno = 0; } - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_float(p, tok(p), suffix); return tFLOAT; #endif } - #ifdef MRB_SUFFIX_SUPPORT - suffix = number_literal_suffix(p, NUM_SUFFIX_ALL); - #endif + suffix = number_literal_suffix(p); pylval.nd = new_int(p, tok(p), 10, suffix); return tINTEGER; } diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c index e2388f026..ca046d88e 100644 --- a/mrbgems/mruby-eval/src/eval.c +++ b/mrbgems/mruby-eval/src/eval.c @@ -110,8 +110,8 @@ patch_irep(mrb_state *mrb, mrb_irep *irep, int bnest, mrb_irep *top) insn = iseq[i]; switch(insn){ case OP_EPUSH: - b = PEEK_S(iseq+i+1); - patch_irep(mrb, irep->reps[b], bnest + 1, top); + a = PEEK_B(iseq+i+1); + patch_irep(mrb, irep->reps[a], bnest + 1, top); break; case OP_LAMBDA: @@ -390,7 +390,7 @@ void mrb_mruby_eval_gem_init(mrb_state* mrb) { mrb_define_module_function(mrb, mrb->kernel_module, "eval", f_eval, MRB_ARGS_ARG(1, 3)); - mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_ARG(1, 2)); + mrb_define_method(mrb, mrb_class_get(mrb, "BasicObject"), "instance_eval", f_instance_eval, MRB_ARGS_OPT(3)|MRB_ARGS_BLOCK()); } void diff --git a/mrbgems/mruby-exit/src/mruby-exit.c b/mrbgems/mruby-exit/src/mruby-exit.c index 05c929622..4ff2f932c 100644 --- a/mrbgems/mruby-exit/src/mruby-exit.c +++ b/mrbgems/mruby-exit/src/mruby-exit.c @@ -4,12 +4,17 @@ static mrb_value f_exit(mrb_state *mrb, mrb_value self) { - mrb_int i = EXIT_SUCCESS; + mrb_value status = mrb_true_value(); + int istatus; + + mrb_get_args(mrb, "|o", &status); + istatus = mrb_true_p(status) ? EXIT_SUCCESS : + mrb_false_p(status) ? EXIT_FAILURE : + (int)mrb_int(mrb, status); + exit(istatus); - mrb_get_args(mrb, "|i", &i); - exit((int)i); /* not reached */ - return mrb_nil_value(); + return status; } void diff --git a/mrbgems/mruby-io/test/mruby_io_test.c b/mrbgems/mruby-io/test/mruby_io_test.c index eb552c41a..f5c55499b 100644 --- a/mrbgems/mruby-io/test/mruby_io_test.c +++ b/mrbgems/mruby-io/test/mruby_io_test.c @@ -177,28 +177,6 @@ mrb_io_test_io_cleanup(mrb_state *mrb, mrb_value self) } static mrb_value -mrb_io_test_file_setup(mrb_state *mrb, mrb_value self) -{ - mrb_value ary = mrb_io_test_io_setup(mrb, self); -#if !defined(_WIN32) && !defined(_WIN64) - if (symlink("/usr/bin", "test-bin") == -1) { - mrb_raise(mrb, E_RUNTIME_ERROR, "can't make a symbolic link"); - } -#endif - - return ary; -} - -static mrb_value -mrb_io_test_file_cleanup(mrb_state *mrb, mrb_value self) -{ - mrb_io_test_io_cleanup(mrb, self); - remove("test-bin"); - - return mrb_nil_value(); -} - -static mrb_value mrb_io_test_mkdtemp(mrb_state *mrb, mrb_value klass) { mrb_value str; @@ -245,9 +223,6 @@ mrb_mruby_io_gem_test(mrb_state* mrb) mrb_define_class_method(mrb, io_test, "io_test_setup", mrb_io_test_io_setup, MRB_ARGS_NONE()); mrb_define_class_method(mrb, io_test, "io_test_cleanup", mrb_io_test_io_cleanup, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, io_test, "file_test_setup", mrb_io_test_file_setup, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, io_test, "file_test_cleanup", mrb_io_test_file_cleanup, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, io_test, "mkdtemp", mrb_io_test_mkdtemp, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, io_test, "rmdir", mrb_io_test_rmdir, MRB_ARGS_REQ(1)); mrb_define_class_method(mrb, io_test, "win?", mrb_io_win_p, MRB_ARGS_NONE()); diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index a2af6b46f..427740c1c 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -213,7 +213,7 @@ mrb_mruby_kernel_ext_gem_init(mrb_state *mrb) mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2)); mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2)); mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE()); - mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY()); + mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ARG(1,1)); #ifndef MRB_WITHOUT_FLOAT mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1)); #endif diff --git a/mrbgems/mruby-metaprog/src/metaprog.c b/mrbgems/mruby-metaprog/src/metaprog.c index 3f22596eb..bca8ab34c 100644 --- a/mrbgems/mruby-metaprog/src/metaprog.c +++ b/mrbgems/mruby-metaprog/src/metaprog.c @@ -694,8 +694,8 @@ mrb_mruby_metaprog_gem_init(mrb_state* mrb) mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */ mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */ mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */ - mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY()); - mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */ + mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_REQ(1)|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.44 */ mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_OPT(1)); /* 15.2.2.4.19 */ mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */ diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c index a7faeebea..424906c00 100644 --- a/mrbgems/mruby-proc-ext/src/proc.c +++ b/mrbgems/mruby-proc-ext/src/proc.c @@ -175,8 +175,8 @@ mrb_mruby_proc_ext_gem_init(mrb_state* mrb) mrb_define_method(mrb, p, "inspect", mrb_proc_inspect, MRB_ARGS_NONE()); mrb_define_method(mrb, p, "parameters", mrb_proc_parameters, MRB_ARGS_NONE()); - mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); - mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()); + mrb_define_class_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); + mrb_define_method(mrb, mrb->kernel_module, "proc", mrb_kernel_proc, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); } void diff --git a/mrbgems/mruby-sprintf/src/kernel.c b/mrbgems/mruby-sprintf/src/kernel.c index 946b43a8a..a0f0a78ba 100644 --- a/mrbgems/mruby-sprintf/src/kernel.c +++ b/mrbgems/mruby-sprintf/src/kernel.c @@ -18,8 +18,8 @@ mrb_mruby_sprintf_gem_init(mrb_state* mrb) } krn = mrb->kernel_module; - mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_ANY()); - mrb_define_method(mrb, krn, "format", mrb_f_sprintf, MRB_ARGS_ANY()); + mrb_define_method(mrb, krn, "sprintf", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST()); + mrb_define_method(mrb, krn, "format", mrb_f_sprintf, MRB_ARGS_REQ(1)|MRB_ARGS_REST()); } void diff --git a/src/kernel.c b/src/kernel.c index 20f7e693f..69a7311e0 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -794,7 +794,7 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */ - mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */ + mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ARG(1,1)); /* 15.3.1.3.43 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ mrb_define_method(mrb, krn, "__to_int", mrb_to_int, MRB_ARGS_NONE()); /* internal */ diff --git a/src/string.c b/src/string.c index bf0d696d7..3399e46a9 100644 --- a/src/string.c +++ b/src/string.c @@ -24,7 +24,7 @@ typedef struct mrb_shared_string { int refcnt; - mrb_int capa; + mrb_ssize capa; char *ptr; } mrb_shared_string; @@ -40,8 +40,8 @@ str_init_normal_capa(mrb_state *mrb, struct RString *s, if (p) memcpy(dst, p, len); dst[len] = '\0'; s->as.heap.ptr = dst; - s->as.heap.len = (mrb_int)len; - s->as.heap.aux.capa = (mrb_int)capa; + s->as.heap.len = (mrb_ssize)len; + s->as.heap.aux.capa = (mrb_ssize)capa; RSTR_UNSET_TYPE_FLAG(s); return s; } @@ -66,7 +66,7 @@ static struct RString* str_init_nofree(struct RString *s, const char *p, size_t len) { s->as.heap.ptr = (char *)p; - s->as.heap.len = (mrb_int)len; + s->as.heap.len = (mrb_ssize)len; s->as.heap.aux.capa = 0; /* nofree */ RSTR_SET_TYPE_FLAG(s, NOFREE); return s; @@ -118,7 +118,7 @@ str_new_static(mrb_state *mrb, const char *p, size_t len) if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_INT_MAX) { + if (len >= MRB_SSIZE_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } return str_init_nofree(mrb_obj_alloc_string(mrb), p, len); @@ -130,7 +130,7 @@ str_new(mrb_state *mrb, const char *p, size_t len) if (RSTR_EMBEDDABLE_P(len)) { return str_init_embed(mrb_obj_alloc_string(mrb), p, len); } - if (len >= MRB_INT_MAX) { + if (len >= MRB_SSIZE_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } if (p && mrb_ro_data_p(p)) { @@ -162,7 +162,7 @@ mrb_str_new_capa(mrb_state *mrb, size_t capa) if (RSTR_EMBEDDABLE_P(capa)) { s = str_init_embed(mrb_obj_alloc_string(mrb), NULL, 0); } - else if (capa >= MRB_INT_MAX) { + else if (capa >= MRB_SSIZE_MAX) { mrb_raise(mrb, E_ARGUMENT_ERROR, "string capacity size too big"); /* not reached */ s = NULL; @@ -190,8 +190,8 @@ mrb_str_buf_new(mrb_state *mrb, size_t capa) static void resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) { -#if SIZE_MAX > MRB_INT_MAX - mrb_assert(capacity < MRB_INT_MAX); +#if SIZE_MAX > MRB_SSIZE_MAX + mrb_assert(capacity < MRB_SSIZE_MAX); #endif if (RSTR_EMBED_P(s)) { if (!RSTR_EMBEDDABLE_P(capacity)) { @@ -200,7 +200,7 @@ resize_capa(mrb_state *mrb, struct RString *s, size_t capacity) } else { s->as.heap.ptr = (char*)mrb_realloc(mrb, RSTR_PTR(s), capacity+1); - s->as.heap.aux.capa = (mrb_int)capacity; + s->as.heap.aux.capa = (mrb_ssize)capacity; } } @@ -246,6 +246,28 @@ str_decref(mrb_state *mrb, mrb_shared_string *shared) } static void +str_modify_keep_ascii(mrb_state *mrb, struct RString *s) +{ + if (RSTR_SHARED_P(s)) { + mrb_shared_string *shared = s->as.heap.aux.shared; + + if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { + s->as.heap.aux.capa = shared->capa; + s->as.heap.ptr[s->as.heap.len] = '\0'; + RSTR_UNSET_SHARED_FLAG(s); + mrb_free(mrb, shared); + } + else { + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + str_decref(mrb, shared); + } + } + else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { + str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); + } +} + +static void check_null_byte(mrb_state *mrb, mrb_value str) { mrb_to_str(mrb, str); @@ -546,7 +568,7 @@ str_share(mrb_state *mrb, struct RString *orig, struct RString *s) else { if (orig->as.heap.aux.capa > orig->as.heap.len) { orig->as.heap.ptr = (char *)mrb_realloc(mrb, orig->as.heap.ptr, len+1); - orig->as.heap.aux.capa = len; + orig->as.heap.aux.capa = (mrb_ssize)len; } str_init_shared(mrb, orig, s, NULL); str_init_shared(mrb, orig, orig, s->as.heap.aux.shared); @@ -591,8 +613,8 @@ mrb_str_byte_subseq(mrb_state *mrb, mrb_value str, mrb_int beg, mrb_int len) } else { str_share(mrb, orig, s); - s->as.heap.ptr += beg; - s->as.heap.len = len; + s->as.heap.ptr += (mrb_ssize)beg; + s->as.heap.len = (mrb_ssize)len; } RSTR_COPY_ASCII_FLAG(s, orig); return mrb_obj_value(s); @@ -814,23 +836,7 @@ MRB_API void mrb_str_modify_keep_ascii(mrb_state *mrb, struct RString *s) { mrb_check_frozen(mrb, s); - if (RSTR_SHARED_P(s)) { - mrb_shared_string *shared = s->as.heap.aux.shared; - - if (shared->refcnt == 1 && s->as.heap.ptr == shared->ptr) { - s->as.heap.aux.capa = shared->capa; - s->as.heap.ptr[s->as.heap.len] = '\0'; - RSTR_UNSET_SHARED_FLAG(s); - mrb_free(mrb, shared); - } - else { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); - str_decref(mrb, shared); - } - } - else if (RSTR_NOFREE_P(s) || RSTR_FSHARED_P(s)) { - str_init_modifiable(mrb, s, s->as.heap.ptr, (size_t)s->as.heap.len); - } + str_modify_keep_ascii(mrb, s); } MRB_API void @@ -955,7 +961,7 @@ mrb_str_times(mrb_state *mrb, mrb_value self) if (times < 0) { mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argument"); } - if (times && MRB_INT_MAX / times < RSTRING_LEN(self)) { + if (times && MRB_SSIZE_MAX / times < RSTRING_LEN(self)) { mrb_raise(mrb, E_ARGUMENT_ERROR, "argument too big"); } @@ -1296,7 +1302,7 @@ str_replace_partial(mrb_state *mrb, mrb_value src, mrb_int pos, mrb_int end, mrb replen = (mrb_nil_p(rep) ? 0 : RSTRING_LEN(rep)); newlen = replen + len - (end - pos); - if (newlen >= MRB_INT_MAX || newlen < replen /* overflowed */) { + if (newlen >= MRB_SSIZE_MAX || newlen < replen /* overflowed */) { mrb_raise(mrb, E_RUNTIME_ERROR, "string size too big"); } @@ -2423,15 +2429,12 @@ mrb_string_value_cstr(mrb_state *mrb, mrb_value *ptr) if (p[len] == '\0') { return p; } - if (mrb_frozen_p(ps) || RSTR_CAPA(ps) == len) { - ps = str_new(mrb, NULL, len+1); - memcpy(RSTR_PTR(ps), p, len); - RSTR_SET_LEN(ps, len); - *ptr = mrb_obj_value(ps); - } - else { - mrb_str_modify(mrb, ps); - } + + /* + * Even after str_modify_keep_ascii(), NULL termination is not ensured if + * RSTR_SET_LEN() is used explicitly (e.g. String#delete_suffix!). + */ + str_modify_keep_ascii(mrb, ps); RSTR_PTR(ps)[len] = '\0'; return RSTR_PTR(ps); } @@ -2672,21 +2675,21 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) capa = RSTR_CAPA(s); total = RSTR_LEN(s)+len; - if (total >= MRB_INT_MAX) { + if (total >= MRB_SSIZE_MAX) { size_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "string size too big"); } if (capa <= total) { if (capa == 0) capa = 1; while (capa <= total) { - if (capa <= MRB_INT_MAX / 2) { + if (capa <= MRB_SSIZE_MAX / 2) { capa *= 2; } else { capa = total+1; } } - if (capa <= total || capa > MRB_INT_MAX) { + if (capa <= total || capa > MRB_SSIZE_MAX) { goto size_error; } resize_capa(mrb, s, capa); @@ -2695,7 +2698,7 @@ mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len) ptr = RSTR_PTR(s) + off; } memcpy(RSTR_PTR(s) + RSTR_LEN(s), ptr, len); - mrb_assert_int_fit(size_t, total, mrb_int, MRB_INT_MAX); + mrb_assert_int_fit(size_t, total, mrb_ssize, MRB_SSIZE_MAX); RSTR_SET_LEN(s, total); RSTR_PTR(s)[total] = '\0'; /* sentinel */ return str; |
