diff options
| -rw-r--r-- | AUTHORS | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-strip/bintest/mruby-strip.rb | 53 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-strip/mrbgem.rake | 5 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c | 58 | ||||
| -rw-r--r-- | src/array.c | 10 | ||||
| -rw-r--r-- | src/class.c | 12 | ||||
| -rw-r--r-- | src/error.c | 12 | ||||
| -rw-r--r-- | src/gc.c | 14 | ||||
| -rw-r--r-- | src/hash.c | 2 | ||||
| -rw-r--r-- | src/object.c | 2 | ||||
| -rw-r--r-- | src/string.c | 8 | ||||
| -rw-r--r-- | src/variable.c | 10 | ||||
| -rw-r--r-- | src/vm.c | 10 | ||||
| -rw-r--r-- | test/t/array.rb | 6 | ||||
| -rw-r--r-- | test/t/kernel.rb | 10 |
15 files changed, 177 insertions, 36 deletions
@@ -17,3 +17,4 @@ Original Authors "mruby developers" are: Jun Hiroe Narihiro Nakamura Yuichi Nishiwaki + Tatsuhiko Kubo diff --git a/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb b/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb new file mode 100644 index 000000000..4f27d2fce --- /dev/null +++ b/mrbgems/mruby-bin-strip/bintest/mruby-strip.rb @@ -0,0 +1,53 @@ +require 'tempfile' + +assert('no files') do + o = `bin/mruby-strip 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "no files to strip\n", o +end + +assert('file not found') do + o = `bin/mruby-strip not_found.mrb 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "can't open file not_found.mrb\n", o +end + +assert('not irep file') do + t = Tempfile.new('script.rb') + t.write 'p test\n' + t.flush + o = `bin/mruby-strip #{t.path} 2>&1` + assert_equal 1, $?.exitstatus + assert_equal "can't read irep file #{t.path}\n", o +end + +assert('success') do + script_file, compiled1, compiled2 = + Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb') + script_file.write "p 'test'\n" + script_file.flush + `bin/mrbc -g -o #{compiled1.path} #{script_file.path}` + `bin/mrbc -g -o #{compiled2.path} #{script_file.path}` + + o = `bin/mruby-strip #{compiled1.path}` + assert_equal 0, $?.exitstatus + assert_equal "", o + + o = `bin/mruby-strip #{compiled1.path} #{compiled2.path}` + assert_equal 0, $?.exitstatus + assert_equal "", o +end + +assert('check debug section') do + script_file, with_debug, without_debug = + Tempfile.new('script.rb'), Tempfile.new('c1.mrb'), Tempfile.new('c2.mrb') + script_file.write "p 'test'\n" + script_file.flush + `bin/mrbc -o #{without_debug.path} #{script_file.path}` + `bin/mrbc -g -o #{with_debug.path} #{script_file.path}` + + assert_true with_debug.size >= without_debug.size + + `bin/mruby-strip #{with_debug.path}` + assert_equal without_debug.size, with_debug.size +end diff --git a/mrbgems/mruby-bin-strip/mrbgem.rake b/mrbgems/mruby-bin-strip/mrbgem.rake new file mode 100644 index 000000000..47304b2a5 --- /dev/null +++ b/mrbgems/mruby-bin-strip/mrbgem.rake @@ -0,0 +1,5 @@ +MRuby::Gem::Specification.new('mruby-bin-strip') do |spec| + spec.license = 'MIT' + spec.author = 'mruby developers' + spec.bins = %w(mruby-strip) +end diff --git a/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c new file mode 100644 index 000000000..dee3e0cd6 --- /dev/null +++ b/mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c @@ -0,0 +1,58 @@ +#include <stdio.h> +#include <stdlib.h> +#include "mruby.h" +#include "mruby/irep.h" +#include "mruby/dump.h" + +int +main(int argc, char **argv) +{ + int i, dump_result; + FILE **files; + mrb_irep **ireps; + mrb_state *mrb; + + if (argc <= 1) { + fprintf(stderr, "no files to strip\n"); + return EXIT_FAILURE; + } + + files = (FILE**)malloc(sizeof(FILE*) * argc); + for (i = 1; i < argc; ++i) { + files[i] = fopen(argv[i], "rb"); + + if (!files[i]) { + fprintf(stderr, "can't open file %s\n", argv[i]); + return EXIT_FAILURE; + } + } + + mrb = mrb_open(); + + ireps = (mrb_irep**)malloc(sizeof(mrb_irep*) * argc); + for (i = 1; i < argc; ++i) { + ireps[i] = mrb_read_irep_file(mrb, files[i]); + if (!ireps[i]) { + fprintf(stderr, "can't read irep file %s\n", argv[i]); + return EXIT_FAILURE; + } + fclose(files[i]); + files[i] = fopen(argv[i], "wb"); + if (!ireps[i]) { + fprintf(stderr, "can't reopen irep file %s\n", argv[i]); + return EXIT_FAILURE; + } + } + + for (i = 1; i < argc; ++i) { + /* debug flag must be alway false */ + dump_result = mrb_dump_irep_binary(mrb, ireps[i], FALSE, files[i]); + if (dump_result != MRB_DUMP_OK) { + fprintf(stderr, "error occur when dumping %s", argv[i]); + return EXIT_FAILURE; + } + } + + mrb_close(mrb); + return EXIT_SUCCESS; +} diff --git a/src/array.c b/src/array.c index 5ad90efff..7a268b894 100644 --- a/src/array.c +++ b/src/array.c @@ -185,13 +185,11 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); } + if (capa == 0) { + capa = ARY_DEFAULT_LEN; + } while (capa < len) { - if (capa == 0) { - capa = ARY_DEFAULT_LEN; - } - else { - capa *= 2; - } + capa *= 2; } if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ diff --git a/src/class.c b/src/class.c index 84f8ea70e..e0d45a7f3 100644 --- a/src/class.c +++ b/src/class.c @@ -1296,7 +1296,7 @@ mrb_class_name(mrb_state *mrb, struct RClass* c) if (mrb_nil_p(path)) { path = mrb_str_new_lit(mrb, "#<Class:"); mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c)); - mrb_str_cat(mrb, path, ">", 1); + mrb_str_cat_lit(mrb, path, ">"); } return mrb_str_ptr(path)->ptr; } @@ -1431,7 +1431,7 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass) mrb_str_append(mrb, str, mrb_any_to_s(mrb, v)); break; } - mrb_str_cat(mrb, str, ">", 1); + mrb_str_cat_lit(mrb, str, ">"); } else { struct RClass *c; @@ -1444,20 +1444,20 @@ mrb_mod_to_s(mrb_state *mrb, mrb_value klass) if (mrb_nil_p(path)) { switch (mrb_type(klass)) { case MRB_TT_CLASS: - mrb_str_cat(mrb, str, "#<Class:", 8); + mrb_str_cat_lit(mrb, str, "#<Class:"); break; case MRB_TT_MODULE: - mrb_str_cat(mrb, str, "#<Module:", 9); + mrb_str_cat_lit(mrb, str, "#<Module:"); break; default: /* Shouldn't be happened? */ - mrb_str_cat(mrb, str, "#<??????:", 9); + mrb_str_cat_lit(mrb, str, "#<??????:"); break; } mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c)); - mrb_str_cat(mrb, str, ">", 1); + mrb_str_cat_lit(mrb, str, ">"); } else { str = path; diff --git a/src/error.c b/src/error.c index 26dc97166..db516d766 100644 --- a/src/error.c +++ b/src/error.c @@ -128,26 +128,26 @@ exc_inspect(mrb_state *mrb, mrb_value exc) if (!mrb_nil_p(file) && !mrb_nil_p(line)) { str = file; - mrb_str_cat(mrb, str, ":", 1); + mrb_str_cat_lit(mrb, str, ":"); mrb_str_append(mrb, str, line); - mrb_str_cat(mrb, str, ": ", 2); + mrb_str_cat_lit(mrb, str, ": "); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { mrb_str_append(mrb, str, mesg); - mrb_str_cat(mrb, str, " (", 2); + mrb_str_cat_lit(mrb, str, " ("); } mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { - mrb_str_cat(mrb, str, ")", 1); + mrb_str_cat_lit(mrb, str, ")"); } } else { str = mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, exc)); if (!mrb_nil_p(mesg) && RSTRING_LEN(mesg) > 0) { - mrb_str_cat(mrb, str, ": ", 2); + mrb_str_cat_lit(mrb, str, ": "); mrb_str_append(mrb, str, mesg); } else { - mrb_str_cat(mrb, str, ": ", 2); + mrb_str_cat_lit(mrb, str, ": "); mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, exc)); } } @@ -460,13 +460,15 @@ mark_context(mrb_state *mrb, struct mrb_context *c) for (i=0; i<e; i++) { mrb_gc_mark(mrb, (struct RBasic*)c->ensure[i]); } - /* mark closure */ - for (ci = c->cibase; ci <= c->ci; ci++) { - if (!ci) continue; - mrb_gc_mark(mrb, (struct RBasic*)ci->env); - mrb_gc_mark(mrb, (struct RBasic*)ci->proc); - mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + /* mark VM stack */ + if (c->cibase) { + for (ci = c->cibase; ci <= c->ci; ci++) { + mrb_gc_mark(mrb, (struct RBasic*)ci->env); + mrb_gc_mark(mrb, (struct RBasic*)ci->proc); + mrb_gc_mark(mrb, (struct RBasic*)ci->target_class); + } } + /* mark fibers */ if (c->prev && c->prev->fib) { mrb_gc_mark(mrb, (struct RBasic*)c->prev->fib); } diff --git a/src/hash.c b/src/hash.c index 566728253..9d7927bb9 100644 --- a/src/hash.c +++ b/src/hash.c @@ -672,7 +672,7 @@ inspect_hash(mrb_state *mrb, mrb_value hash, int recur) ai = mrb_gc_arena_save(mrb); - if (RSTRING_LEN(str) > 1) mrb_str_cat(mrb, str, ", ", 2); + if (RSTRING_LEN(str) > 1) mrb_str_cat_lit(mrb, str, ", "); str2 = mrb_inspect(mrb, kh_key(h,k)); mrb_str_append(mrb, str, str2); diff --git a/src/object.c b/src/object.c index 172f2dbda..c6b72640f 100644 --- a/src/object.c +++ b/src/object.c @@ -444,7 +444,7 @@ mrb_any_to_s(mrb_state *mrb, mrb_value obj) mrb_str_buf_cat(mrb, str, "#<", 2); mrb_str_cat_cstr(mrb, str, cname); - mrb_str_cat(mrb, str, ":", 1); + mrb_str_cat_lit(mrb, str, ":"); mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, mrb_cptr(obj))); mrb_str_buf_cat(mrb, str, ">", 1); diff --git a/src/string.c b/src/string.c index 6424626d2..aa1afec47 100644 --- a/src/string.c +++ b/src/string.c @@ -216,6 +216,9 @@ mrb_value mrb_str_new(mrb_state *mrb, const char *p, size_t len) { struct RString *s; + if ((mrb_int)len < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)"); + } s = str_new(mrb, p, len); return mrb_obj_value(s); @@ -253,6 +256,9 @@ mrb_value mrb_str_new_static(mrb_state *mrb, const char *p, size_t len) { struct RString *s; + if ((mrb_int)len < 0) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "negative string size (or size too big)"); + } s = mrb_obj_alloc_string(mrb); s->len = len; @@ -2361,7 +2367,7 @@ mrb_str_dump(mrb_state *mrb, mrb_value str) } } } - *q++ = '"'; + *q = '"'; return mrb_obj_value(result); } diff --git a/src/variable.c b/src/variable.c index 957383ad2..c313a8f14 100644 --- a/src/variable.c +++ b/src/variable.c @@ -568,14 +568,14 @@ inspect_i(mrb_state *mrb, mrb_sym sym, mrb_value v, void *p) /* need not to show internal data */ if (RSTRING_PTR(str)[0] == '-') { /* first element */ RSTRING_PTR(str)[0] = '#'; - mrb_str_cat(mrb, str, " ", 1); + mrb_str_cat_lit(mrb, str, " "); } else { - mrb_str_cat(mrb, str, ", ", 2); + mrb_str_cat_lit(mrb, str, ", "); } s = mrb_sym2name_len(mrb, sym, &len); mrb_str_cat(mrb, str, s, len); - mrb_str_cat(mrb, str, "=", 1); + mrb_str_cat_lit(mrb, str, "="); if (mrb_type(v) == MRB_TT_OBJECT) { ins = mrb_any_to_s(mrb, v); } @@ -598,11 +598,11 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) mrb_str_buf_cat(mrb, str, "-<", 2); mrb_str_cat_cstr(mrb, str, cn); - mrb_str_cat(mrb, str, ":", 1); + mrb_str_cat_lit(mrb, str, ":"); mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, obj)); iv_foreach(mrb, t, inspect_i, &str); - mrb_str_cat(mrb, str, ">", 1); + mrb_str_cat_lit(mrb, str, ">"); return str; } return mrb_any_to_s(mrb, mrb_obj_value(obj)); @@ -954,7 +954,8 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int ci = mrb->c->ci; if (!ci->target_class) { /* return from context modifying method (resume/yield) */ if (!MRB_PROC_CFUNC_P(ci[-1].proc)) { - irep = ci[-1].proc->body.irep; + proc = ci[-1].proc; + irep = proc->body.irep; pool = irep->pool; syms = irep->syms; } @@ -1358,6 +1359,13 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int localjump_error(mrb, LOCALJUMP_ERROR_BREAK); goto L_RAISE; } + /* break from fiber block */ + if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) { + struct mrb_context *c = mrb->c; + + mrb->c = c->prev; + c->prev = NULL; + } ci = mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1; break; default: diff --git a/test/t/array.rb b/test/t/array.rb index 1398bdc6e..48f2fe0c4 100644 --- a/test/t/array.rb +++ b/test/t/array.rb @@ -51,9 +51,9 @@ assert('Array#[]', '15.2.12.5.4') do assert_equal(nil, [1,2,3].[](-4)) a = [ "a", "b", "c", "d", "e" ] - a[1.1] == "b" and - a[1,2] == ["b", "c"] and - a[1..-2] == ["b", "c", "d"] + assert_equal("b", a[1.1]) + assert_equal(["b", "c"], a[1,2]) + assert_equal(["b", "c", "d"], a[1..-2]) end assert('Array#[]=', '15.2.12.5.5') do diff --git a/test/t/kernel.rb b/test/t/kernel.rb index 2d409940b..c7066fdd9 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -264,6 +264,16 @@ assert('Kernel#inspect', '15.3.1.3.17') do assert_equal "main", s end +assert('Kernel#instance_variable_defined?', '15.3.1.3.20') do + o = Object.new + o.instance_variable_set(:@a, 1) + + assert_true o.instance_variable_defined?("@a") + assert_false o.instance_variable_defined?("@b") + assert_true o.instance_variable_defined?("@a"[0,2]) + assert_true o.instance_variable_defined?("@abc"[0,2]) +end + assert('Kernel#instance_variables', '15.3.1.3.23') do o = Object.new o.instance_eval do |
