summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS1
-rw-r--r--mrbgems/mruby-bin-strip/bintest/mruby-strip.rb53
-rw-r--r--mrbgems/mruby-bin-strip/mrbgem.rake5
-rw-r--r--mrbgems/mruby-bin-strip/tools/mruby-strip/mruby-strip.c58
-rw-r--r--src/array.c10
-rw-r--r--src/class.c12
-rw-r--r--src/error.c12
-rw-r--r--src/gc.c14
-rw-r--r--src/hash.c2
-rw-r--r--src/object.c2
-rw-r--r--src/string.c8
-rw-r--r--src/variable.c10
-rw-r--r--src/vm.c10
-rw-r--r--test/t/array.rb6
-rw-r--r--test/t/kernel.rb10
15 files changed, 177 insertions, 36 deletions
diff --git a/AUTHORS b/AUTHORS
index 85d117f31..36eca92b2 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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));
}
}
diff --git a/src/gc.c b/src/gc.c
index 028133ea2..8eda76b26 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -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));
diff --git a/src/vm.c b/src/vm.c
index 13aa7c226..ffdd2e5dd 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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