summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--README.md7
-rw-r--r--include/mruby.h3
-rw-r--r--include/mruby/error.h3
-rw-r--r--include/mruby/string.h3
-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--mrbgems/mruby-fiber/src/fiber.c38
-rw-r--r--mrbgems/mruby-numeric-ext/test/numeric.rb9
-rw-r--r--mrbgems/mruby-proc-ext/src/proc.c12
-rw-r--r--mrbgems/mruby-sprintf/src/sprintf.c23
-rw-r--r--mrbgems/mruby-string-utf8/src/string.c37
-rw-r--r--mrbgems/mruby-struct/src/struct.c10
-rw-r--r--src/array.c10
-rw-r--r--src/backtrace.c36
-rw-r--r--src/class.c43
-rw-r--r--src/error.c16
-rw-r--r--src/gc.c14
-rw-r--r--src/hash.c2
-rw-r--r--src/kernel.c2
-rw-r--r--src/object.c2
-rw-r--r--src/string.c8
-rw-r--r--src/variable.c10
-rw-r--r--src/vm.c14
-rw-r--r--tasks/mrbgem_spec.rake2
-rw-r--r--tasks/mrbgems_test.rake32
-rw-r--r--test/init_mrbtest.c2
-rw-r--r--test/mrbtest.rake19
-rw-r--r--test/t/array.rb6
-rw-r--r--test/t/kernel.rb10
-rw-r--r--test/t/syntax.rb8
32 files changed, 374 insertions, 125 deletions
diff --git a/AUTHORS b/AUTHORS
index 85d117f31..3791ad723 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -17,3 +17,5 @@ Original Authors "mruby developers" are:
Jun Hiroe
Narihiro Nakamura
Yuichi Nishiwaki
+ Tatsuhiko Kubo
+ Takeshi Watanabe
diff --git a/README.md b/README.md
index 7386f28bb..f7633019f 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,3 @@
-# !!Notice!!
- This is a preliminary release for internal team review.
- The URLs and addresses described below are not available yet.
- The official release will be announced later.
- Any suggestions for modification are welcome.
- Delays in replies are to be expected. Sorry in advance.
-
[![Build Status](https://travis-ci.org/mruby/mruby.png?branch=master)](https://travis-ci.org/mruby/mruby)
## What's mruby
diff --git a/include/mruby.h b/include/mruby.h
index 30c2dbbb1..4f404fb8e 100644
--- a/include/mruby.h
+++ b/include/mruby.h
@@ -374,6 +374,9 @@ mrb_value mrb_attr_get(mrb_state *mrb, mrb_value obj, mrb_sym id);
mrb_bool mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid);
mrb_bool mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c);
+/* fiber functions (you need to link mruby-fiber mrbgem to use) */
+mrb_value mrb_fiber_yield(mrb_state *mrb, int argc, mrb_value *argv);
+
/* memory pool implementation */
typedef struct mrb_pool mrb_pool;
struct mrb_pool* mrb_pool_open(mrb_state*);
diff --git a/include/mruby/error.h b/include/mruby/error.h
index b04dc1082..96c4092b5 100644
--- a/include/mruby/error.h
+++ b/include/mruby/error.h
@@ -13,5 +13,8 @@ mrb_value mrb_make_exception(mrb_state *mrb, int argc, mrb_value *argv);
mrb_value mrb_format(mrb_state *mrb, const char *format, ...);
void mrb_exc_print(mrb_state *mrb, struct RObject *exc);
void mrb_longjmp(mrb_state *mrb);
+void mrb_print_backtrace(mrb_state *mrb);
+mrb_value mrb_exc_backtrace(mrb_state *mrb, mrb_value exc);
+mrb_value mrb_get_backtrace(mrb_state *mrb);
#endif /* MRUBY_ERROR_H */
diff --git a/include/mruby/string.h b/include/mruby/string.h
index 675dadb5c..966f0bf77 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -53,7 +53,6 @@ char *mrb_string_value_ptr(mrb_state *mrb, mrb_value ptr);
int mrb_str_offset(mrb_state *mrb, mrb_value str, int pos);
mrb_value mrb_str_dup(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_intern(mrb_state *mrb, mrb_value self);
-mrb_value mrb_str_cat_cstr(mrb_state *, mrb_value, const char *);
mrb_value mrb_str_to_inum(mrb_state *mrb, mrb_value str, int base, mrb_bool badcheck);
double mrb_str_to_dbl(mrb_state *mrb, mrb_value str, mrb_bool badcheck);
mrb_value mrb_str_to_str(mrb_state *mrb, mrb_value str);
@@ -63,6 +62,8 @@ mrb_value mrb_str_inspect(mrb_state *mrb, mrb_value str);
mrb_bool mrb_str_equal(mrb_state *mrb, mrb_value str1, mrb_value str2);
mrb_value mrb_str_dump(mrb_state *mrb, mrb_value str);
mrb_value mrb_str_cat(mrb_state *mrb, mrb_value str, const char *ptr, size_t len);
+mrb_value mrb_str_cat_cstr(mrb_state *mrb, mrb_value str, const char *ptr);
+#define mrb_str_cat_lit(mrb, str, lit) mrb_str_cat(mrb, str, (lit), sizeof(lit) - 1)
mrb_value mrb_str_append(mrb_state *mrb, mrb_value str, mrb_value str2);
int mrb_str_cmp(mrb_state *mrb, mrb_value str1, mrb_value str2);
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/mrbgems/mruby-fiber/src/fiber.c b/mrbgems/mruby-fiber/src/fiber.c
index 6ee22eded..0dbdad871 100644
--- a/mrbgems/mruby-fiber/src/fiber.c
+++ b/mrbgems/mruby-fiber/src/fiber.c
@@ -205,23 +205,11 @@ fiber_alive_p(mrb_state *mrb, mrb_value self)
return mrb_bool_value(c->status != MRB_FIBER_TERMINATED);
}
-/*
- * call-seq:
- * Fiber.yield(args, ...) -> obj
- *
- * Yields control back to the context that resumed the fiber, passing
- * along any arguments that were passed to it. The fiber will resume
- * processing at this point when <code>resume</code> is called next.
- * Any arguments passed to the next <code>resume</code> will be the
- * value that this <code>Fiber.yield</code> expression evaluates to.
- */
-static mrb_value
-fiber_yield(mrb_state *mrb, mrb_value self)
+mrb_value
+mrb_fiber_yield(mrb_state *mrb, int len, mrb_value *a)
{
struct mrb_context *c = mrb->c;
mrb_callinfo *ci;
- mrb_value *a;
- int len;
for (ci = c->ci; ci >= c->cibase; ci--) {
if (ci->acc < 0) {
@@ -231,7 +219,7 @@ fiber_yield(mrb_state *mrb, mrb_value self)
if (!c->prev) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "can't yield from root fiber");
}
- mrb_get_args(mrb, "*", &a, &len);
+
c->prev->status = MRB_FIBER_RUNNING;
mrb->c = c->prev;
c->prev = NULL;
@@ -241,6 +229,26 @@ fiber_yield(mrb_state *mrb, mrb_value self)
/*
* call-seq:
+ * Fiber.yield(args, ...) -> obj
+ *
+ * Yields control back to the context that resumed the fiber, passing
+ * along any arguments that were passed to it. The fiber will resume
+ * processing at this point when <code>resume</code> is called next.
+ * Any arguments passed to the next <code>resume</code> will be the
+ * value that this <code>Fiber.yield</code> expression evaluates to.
+ */
+static mrb_value
+fiber_yield(mrb_state *mrb, mrb_value self)
+{
+ mrb_value *a;
+ int len;
+
+ mrb_get_args(mrb, "*", &a, &len);
+ return mrb_fiber_yield(mrb, len, a);
+}
+
+/*
+ * call-seq:
* Fiber.current() -> fiber
*
* Returns the current fiber. You need to <code>require 'fiber'</code>
diff --git a/mrbgems/mruby-numeric-ext/test/numeric.rb b/mrbgems/mruby-numeric-ext/test/numeric.rb
index 7d85eaaa2..1ca01648e 100644
--- a/mrbgems/mruby-numeric-ext/test/numeric.rb
+++ b/mrbgems/mruby-numeric-ext/test/numeric.rb
@@ -5,6 +5,11 @@ assert('Integer#chr') do
assert_equal("A", 65.chr)
assert_equal("B", 0x42.chr)
- # multibyte encoding (not support yet)
- assert_raise(RangeError) { 12345.chr }
+ if "こんにちわ世界".size == 7 then
+ # UTF-8 gem is configured
+ assert_raise(RangeError) { 0x110000.chr }
+ else
+ # multibyte encoding (not support yet)
+ assert_raise(RangeError) { 256.chr }
+ end
end
diff --git a/mrbgems/mruby-proc-ext/src/proc.c b/mrbgems/mruby-proc-ext/src/proc.c
index f27356bb7..3bb0d3570 100644
--- a/mrbgems/mruby-proc-ext/src/proc.c
+++ b/mrbgems/mruby-proc-ext/src/proc.c
@@ -39,29 +39,29 @@ mrb_proc_inspect(mrb_state *mrb, mrb_value self)
if (!MRB_PROC_CFUNC_P(p)) {
mrb_irep *irep = p->body.irep;
- mrb_str_cat_cstr(mrb, str, "@");
+ mrb_str_cat_lit(mrb, str, "@");
if (irep->filename) {
mrb_str_cat_cstr(mrb, str, irep->filename);
}
else {
- mrb_str_cat_cstr(mrb, str, "-");
+ mrb_str_cat_lit(mrb, str, "-");
}
- mrb_str_cat_cstr(mrb, str, ":");
+ mrb_str_cat_lit(mrb, str, ":");
if (irep->lines) {
mrb_str_append(mrb, str, mrb_fixnum_value(*irep->lines));
}
else {
- mrb_str_cat_cstr(mrb, str, "-");
+ mrb_str_cat_lit(mrb, str, "-");
}
}
if (MRB_PROC_STRICT_P(p)) {
- mrb_str_cat_cstr(mrb, str, " (lambda)");
+ mrb_str_cat_lit(mrb, str, " (lambda)");
}
- mrb_str_cat_cstr(mrb, str, ">");
+ mrb_str_cat_lit(mrb, str, ">");
return str;
}
diff --git a/mrbgems/mruby-sprintf/src/sprintf.c b/mrbgems/mruby-sprintf/src/sprintf.c
index 64b9f0787..ff9627437 100644
--- a/mrbgems/mruby-sprintf/src/sprintf.c
+++ b/mrbgems/mruby-sprintf/src/sprintf.c
@@ -654,7 +654,7 @@ retry:
case '\n':
case '\0':
p--;
-
+ /* fallthrough */
case '%':
if (flags != FNONE) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid format character - %");
@@ -665,38 +665,37 @@ retry:
case 'c': {
mrb_value val = GETARG();
mrb_value tmp;
- unsigned int c;
+ char *c;
tmp = mrb_check_string_type(mrb, val);
if (!mrb_nil_p(tmp)) {
- if (RSTRING_LEN(tmp) != 1 ) {
+ if (mrb_fixnum(mrb_funcall(mrb, tmp, "size", 0)) != 1 ) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "%c requires a character");
}
- c = RSTRING_PTR(tmp)[0];
- n = 1;
}
- else {
- c = mrb_fixnum(val);
- n = 1;
+ else if (mrb_fixnum_p(val)) {
+ tmp = mrb_funcall(mrb, val, "chr", 0);
}
- if (n <= 0) {
+ else {
mrb_raise(mrb, E_ARGUMENT_ERROR, "invalid character");
}
+ c = RSTRING_PTR(tmp);
+ n = RSTRING_LEN(tmp);
if (!(flags & FWIDTH)) {
CHECK(n);
- buf[blen] = c;
+ memcpy(buf+blen, c, n);
blen += n;
}
else if ((flags & FMINUS)) {
CHECK(n);
- buf[blen] = c;
+ memcpy(buf+blen, c, n);
blen += n;
FILL(' ', width-1);
}
else {
FILL(' ', width-1);
CHECK(n);
- buf[blen] = c;
+ memcpy(buf+blen, c, n);
blen += n;
}
}
diff --git a/mrbgems/mruby-string-utf8/src/string.c b/mrbgems/mruby-string-utf8/src/string.c
index 2dd848c86..4f3833944 100644
--- a/mrbgems/mruby-string-utf8/src/string.c
+++ b/mrbgems/mruby-string-utf8/src/string.c
@@ -279,6 +279,41 @@ mrb_str_reverse(mrb_state *mrb, mrb_value str)
return mrb_str_reverse_bang(mrb, mrb_str_dup(mrb, str));
}
+static mrb_value
+mrb_fixnum_chr(mrb_state *mrb, mrb_value num)
+{
+ mrb_int cp = mrb_fixnum(num);
+ char utf8[4];
+ int len;
+
+ if (cp < 0 || 0x10FFFF < cp) {
+ mrb_raisef(mrb, E_RANGE_ERROR, "%S out of char range", num);
+ }
+ if (cp < 0x80) {
+ utf8[0] = (char)cp;
+ len = 1;
+ }
+ else if (cp < 0x800) {
+ utf8[0] = (char)(0xC0 | (cp >> 6));
+ utf8[1] = (char)(0x80 | (cp & 0x3F));
+ len = 2;
+ }
+ else if (cp < 0x10000) {
+ utf8[0] = (char)(0xE0 | (cp >> 12));
+ utf8[1] = (char)(0x80 | ((cp >> 6) & 0x3F));
+ utf8[2] = (char)(0x80 | ( cp & 0x3F));
+ len = 3;
+ }
+ else {
+ utf8[0] = (char)(0xF0 | (cp >> 18));
+ utf8[1] = (char)(0x80 | ((cp >> 12) & 0x3F));
+ utf8[2] = (char)(0x80 | ((cp >> 6) & 0x3F));
+ utf8[3] = (char)(0x80 | ( cp & 0x3F));
+ len = 4;
+ }
+ return mrb_str_new(mrb, utf8, len);
+}
+
void
mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
{
@@ -290,6 +325,8 @@ mrb_mruby_string_utf8_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "slice", mrb_str_aref_m, MRB_ARGS_ANY());
mrb_define_method(mrb, s, "reverse", mrb_str_reverse, MRB_ARGS_NONE());
mrb_define_method(mrb, s, "reverse!", mrb_str_reverse_bang, MRB_ARGS_NONE());
+
+ mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
}
void
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 23ee81fa6..baac2d3a2 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -450,7 +450,7 @@ inspect_struct(mrb_state *mrb, mrb_value s, int recur)
mrb_str_append(mrb, str, mrb_str_new_cstr(mrb, cn));
}
if (recur) {
- return mrb_str_cat_cstr(mrb, str, ":...>");
+ return mrb_str_cat_lit(mrb, str, ":...>");
}
members = mrb_struct_members(mrb, s);
@@ -462,10 +462,10 @@ inspect_struct(mrb_state *mrb, mrb_value s, int recur)
mrb_sym id;
if (i > 0) {
- mrb_str_cat_cstr(mrb, str, ", ");
+ mrb_str_cat_lit(mrb, str, ", ");
}
else if (cn) {
- mrb_str_cat_cstr(mrb, str, " ");
+ mrb_str_cat_lit(mrb, str, " ");
}
slot = ptr_members[i];
id = mrb_symbol(slot);
@@ -479,10 +479,10 @@ inspect_struct(mrb_state *mrb, mrb_value s, int recur)
else {
mrb_str_append(mrb, str, mrb_inspect(mrb, slot));
}
- mrb_str_cat_cstr(mrb, str, "=");
+ mrb_str_cat_lit(mrb, str, "=");
mrb_str_append(mrb, str, mrb_inspect(mrb, ptr[i]));
}
- mrb_str_cat_cstr(mrb, str, ">");
+ mrb_str_cat_lit(mrb, str, ">");
return str;
}
diff --git a/src/array.c b/src/array.c
index 6c0f59e9d..ce43a0392 100644
--- a/src/array.c
+++ b/src/array.c
@@ -188,13 +188,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/backtrace.c b/src/backtrace.c
index a221d5e5c..6469fc069 100644
--- a/src/backtrace.c
+++ b/src/backtrace.c
@@ -12,6 +12,7 @@
#include "mruby/string.h"
#include "mruby/class.h"
#include "mruby/debug.h"
+#include "mruby/error.h"
typedef void (*output_stream_func)(mrb_state*, void*, int, const char*, ...);
@@ -57,14 +58,12 @@ get_backtrace_i(mrb_state *mrb, void *stream, int level, const char *format, ...
}
static void
-mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream)
+output_backtrace(mrb_state *mrb, mrb_int ciidx, mrb_code *pc0, output_stream_func func, void *stream)
{
mrb_callinfo *ci;
- mrb_int ciidx;
const char *filename, *method, *sep;
int i, lineno, tracehead = 1;
- ciidx = mrb_fixnum(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "ciidx")));
if (ciidx >= mrb->c->ciend - mrb->c->cibase)
ciidx = 10; /* ciidx is broken... */
@@ -87,7 +86,7 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
pc = mrb->c->cibase[i+1].pc - 1;
}
else {
- pc = (mrb_code*)mrb_cptr(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "lastpc")));
+ pc = pc0;
}
filename = mrb_debug_get_filename(irep, pc - irep->iseq);
lineno = mrb_debug_get_line(irep, pc - irep->iseq);
@@ -129,6 +128,14 @@ mrb_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func fun
}
}
+static void
+exc_output_backtrace(mrb_state *mrb, struct RObject *exc, output_stream_func func, void *stream)
+{
+ output_backtrace(mrb, mrb_fixnum(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "ciidx"))),
+ (mrb_code*)mrb_cptr(mrb_obj_iv_get(mrb, exc, mrb_intern_lit(mrb, "lastpc"))),
+ func, stream);
+}
+
/* mrb_print_backtrace/mrb_get_backtrace:
function to retrieve backtrace information from the exception.
@@ -140,17 +147,32 @@ void
mrb_print_backtrace(mrb_state *mrb)
{
#ifdef ENABLE_STDIO
- mrb_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr);
+ exc_output_backtrace(mrb, mrb->exc, print_backtrace_i, (void*)stderr);
#endif
}
mrb_value
-mrb_get_backtrace(mrb_state *mrb, mrb_value self)
+mrb_exc_backtrace(mrb_state *mrb, mrb_value self)
+{
+ mrb_value ary;
+
+ ary = mrb_ary_new(mrb);
+ exc_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary));
+
+ return ary;
+}
+
+mrb_value
+mrb_get_backtrace(mrb_state *mrb)
{
mrb_value ary;
+ mrb_callinfo *ci = mrb->c->ci;
+ mrb_code *pc = ci->pc;
+ mrb_int ciidx = ci - mrb->c->cibase - 1;
+ if (ciidx < 0) ciidx = 0;
ary = mrb_ary_new(mrb);
- mrb_output_backtrace(mrb, mrb_obj_ptr(self), get_backtrace_i, (void*)mrb_ary_ptr(ary));
+ output_backtrace(mrb, ciidx, pc, get_backtrace_i, (void*)mrb_ary_ptr(ary));
return ary;
}
diff --git a/src/class.c b/src/class.c
index 2c1145ed3..e0d45a7f3 100644
--- a/src/class.c
+++ b/src/class.c
@@ -731,8 +731,13 @@ boot_defclass(mrb_state *mrb, struct RClass *super)
struct RClass *c;
c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class);
- c->super = super ? super : mrb->object_class;
- mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
+ if (super) {
+ c->super = super;
+ mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
+ }
+ else {
+ c->super = mrb->object_class;
+ }
c->mt = kh_init(mt, mrb);
return c;
}
@@ -1118,7 +1123,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv)
}
new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
if (!mrb_nil_p(blk)) {
- mrb_funcall_with_block(mrb, new_class, mrb_intern_cstr(mrb, "class_eval"), 0, NULL, blk);
+ mrb_funcall_with_block(mrb, new_class, mrb_intern_lit(mrb, "class_eval"), 0, NULL, blk);
}
mrb_funcall(mrb, super, "inherited", 1, new_class);
return new_class;
@@ -1189,22 +1194,28 @@ mrb_bob_missing(mrb_state *mrb, mrb_value mod)
mrb_sym name;
mrb_value *a;
int alen;
- mrb_value inspect;
+ mrb_sym inspect;
+ mrb_value repr;
mrb_get_args(mrb, "n*", &name, &a, &alen);
- if (mrb_respond_to(mrb,mod,mrb_intern_lit(mrb, "inspect"))){
- inspect = mrb_funcall(mrb, mod, "inspect", 0);
- if (RSTRING_LEN(inspect) > 64) {
- inspect = mrb_any_to_s(mrb, mod);
+ 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)) {
+ repr = mrb_funcall_argv(mrb, mod, inspect, 0, 0);
+ if (RSTRING_LEN(repr) > 64) {
+ repr = mrb_any_to_s(mrb, mod);
}
}
else {
- inspect = mrb_any_to_s(mrb, mod);
+ repr = mrb_any_to_s(mrb, mod);
}
mrb_raisef(mrb, E_NOMETHOD_ERROR, "undefined method '%S' for %S",
- mrb_sym2str(mrb, name), inspect);
+ mrb_sym2str(mrb, name), repr);
/* not reached */
return mrb_nil_value();
}
@@ -1285,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;
}
@@ -1420,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;
@@ -1433,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 8d0ec67e0..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));
}
}
@@ -431,8 +431,6 @@ mrb_sys_fail(mrb_state *mrb, const char *mesg)
}
}
-mrb_value mrb_get_backtrace(mrb_state*, mrb_value);
-
void
mrb_init_exception(mrb_state *mrb)
{
@@ -446,7 +444,7 @@ mrb_init_exception(mrb_state *mrb)
mrb_define_method(mrb, e, "to_s", exc_to_s, MRB_ARGS_NONE());
mrb_define_method(mrb, e, "message", exc_message, MRB_ARGS_NONE());
mrb_define_method(mrb, e, "inspect", exc_inspect, MRB_ARGS_NONE());
- mrb_define_method(mrb, e, "backtrace", mrb_get_backtrace, MRB_ARGS_NONE());
+ mrb_define_method(mrb, e, "backtrace", mrb_exc_backtrace, MRB_ARGS_NONE());
mrb->eStandardError_class = mrb_define_class(mrb, "StandardError", mrb->eException_class); /* 15.2.23 */
mrb_define_class(mrb, "RuntimeError", mrb->eStandardError_class); /* 15.2.28 */
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/kernel.c b/src/kernel.c
index 25863c897..e61a602be 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -585,7 +585,7 @@ get_valid_iv_sym(mrb_state *mrb, mrb_value iv_name)
mrb_assert(mrb_symbol_p(iv_name) || mrb_string_p(iv_name));
if (mrb_string_p(iv_name)) {
- iv_name_id = mrb_intern_cstr(mrb, RSTRING_PTR(iv_name));
+ iv_name_id = mrb_intern(mrb, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name));
valid_iv_name(mrb, iv_name_id, RSTRING_PTR(iv_name), RSTRING_LEN(iv_name));
}
else {
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 f11caedd7..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;
}
@@ -1342,7 +1343,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
goto L_RAISE;
}
if (mrb->c->prev->ci == mrb->c->prev->cibase) {
- mrb_value exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mrb_str_new(mrb, "double resume", 13));
+ mrb_value exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, mrb_str_new_lit(mrb, "double resume"));
mrb->exc = mrb_obj_ptr(exc);
goto L_RAISE;
}
@@ -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:
@@ -2173,7 +2181,7 @@ mrb_context_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int
mrb_value
mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
{
- return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
+ return mrb_context_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
}
void
diff --git a/tasks/mrbgem_spec.rake b/tasks/mrbgem_spec.rake
index e9caf1d3a..6af28694e 100644
--- a/tasks/mrbgem_spec.rake
+++ b/tasks/mrbgem_spec.rake
@@ -62,7 +62,7 @@ module MRuby
@test_objs = Dir.glob("#{dir}/test/*.{c,cpp,cxx,m,asm,S}").map do |f|
objfile(f.relative_path_from(dir).to_s.pathmap("#{build_dir}/%X"))
end
- @test_preload = 'test/assert.rb'
+ @test_preload = nil # 'test/assert.rb'
@test_args = {}
@bins = []
diff --git a/tasks/mrbgems_test.rake b/tasks/mrbgems_test.rake
index 36c8e84b7..33f1fdb48 100644
--- a/tasks/mrbgems_test.rake
+++ b/tasks/mrbgems_test.rake
@@ -6,11 +6,15 @@ MRuby.each_target do
file g.test_rbireps => [g.test_rbfiles].flatten + [g.build.mrbcfile] do |t|
open(t.name, 'w') do |f|
g.print_gem_test_header(f)
- test_preload = [g.dir, MRUBY_ROOT].map {|dir|
+ test_preload = g.test_preload and [g.dir, MRUBY_ROOT].map {|dir|
File.expand_path(g.test_preload, dir)
}.find {|file| File.exist?(file) }
- g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload"
+ if test_preload.nil?
+ f.puts %Q[extern const uint8_t mrbtest_assert_irep[];]
+ else
+ g.build.mrbc.run f, test_preload, "gem_test_irep_#{g.funcname}_preload"
+ end
g.test_rbfiles.flatten.each_with_index do |rbfile, i|
g.build.mrbc.run f, rbfile, "gem_test_irep_#{g.funcname}_#{i}"
end
@@ -27,16 +31,20 @@ MRuby.each_target do
g.test_rbfiles.count.times do |i|
f.puts %Q[ ai = mrb_gc_arena_save(mrb);]
f.puts %Q[ mrb2 = mrb_open();]
- f.puts %Q[ val3 = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$mrbtest_verbose"));]
+ f.puts %Q[ val3 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$mrbtest_verbose"));]
f.puts %Q[ if (mrb_test(val3)) {]
- f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_cstr(mrb2, "$mrbtest_verbose"), val3);]
+ f.puts %Q[ mrb_gv_set(mrb2, mrb_intern_lit(mrb2, "$mrbtest_verbose"), val3);]
f.puts %Q[ }]
- f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);]
+ if test_preload.nil?
+ f.puts %Q[ mrb_load_irep(mrb2, mrbtest_assert_irep);]
+ else
+ f.puts %Q[ mrb_load_irep(mrb2, gem_test_irep_#{g.funcname}_preload);]
+ end
f.puts %Q[ if (mrb2->exc) {]
f.puts %Q[ mrb_p(mrb2, mrb_obj_value(mrb2->exc));]
f.puts %Q[ exit(EXIT_FAILURE);]
f.puts %Q[ }]
- f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_cstr(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));]
+ f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "GEMNAME"), mrb_str_new(mrb2, "#{g.name}", #{g.name.length}));]
unless g.test_args.empty?
f.puts %Q[ test_args_hash = mrb_hash_new_capa(mrb, #{g.test_args.length}); ]
@@ -45,7 +53,7 @@ MRuby.each_target do
escaped_arg_value = arg_value.gsub('\\', '\\\\\\\\').gsub('"', '\"')
f.puts %Q[ mrb_hash_set(mrb2, test_args_hash, mrb_str_new(mrb2, "#{escaped_arg_name.to_s}", #{escaped_arg_name.to_s.length}), mrb_str_new(mrb2, "#{escaped_arg_value.to_s}", #{escaped_arg_value.to_s.length})); ]
end
- f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_cstr(mrb2, "TEST_ARGS"), test_args_hash); ]
+ f.puts %Q[ mrb_const_set(mrb2, mrb_obj_value(mrb2->object_class), mrb_intern_lit(mrb2, "TEST_ARGS"), test_args_hash); ]
end
f.puts %Q[ mrb_#{g.funcname}_gem_test(mrb2);] unless g.test_objs.empty?
@@ -58,16 +66,16 @@ MRuby.each_target do
f.puts %Q[ ]
%w(ok_test ko_test kill_test).each do |vname|
- f.puts %Q[ val2 = mrb_gv_get(mrb2, mrb_intern_cstr(mrb2, "$#{vname}"));]
+ f.puts %Q[ val2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$#{vname}"));]
f.puts %Q[ if (mrb_fixnum_p(val2)) {]
- f.puts %Q[ val1 = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$#{vname}"));]
- f.puts %Q[ mrb_gv_set(mrb, mrb_intern_cstr(mrb, "$#{vname}"), mrb_fixnum_value(mrb_fixnum(val1) + mrb_fixnum(val2)));]
+ f.puts %Q[ val1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$#{vname}"));]
+ f.puts %Q[ mrb_gv_set(mrb, mrb_intern_lit(mrb, "$#{vname}"), mrb_fixnum_value(mrb_fixnum(val1) + mrb_fixnum(val2)));]
f.puts %Q[ }\n]
end
- f.puts %Q[ ary2 = mrb_gv_get(mrb2, mrb_intern_cstr(mrb2, "$asserts"));]
+ f.puts %Q[ ary2 = mrb_gv_get(mrb2, mrb_intern_lit(mrb2, "$asserts"));]
f.puts %Q[ if (mrb_test(ary2)) {]
- f.puts %Q[ ary1 = mrb_gv_get(mrb, mrb_intern_cstr(mrb, "$asserts"));]
+ f.puts %Q[ ary1 = mrb_gv_get(mrb, mrb_intern_lit(mrb, "$asserts"));]
f.puts %Q[ val2 = mrb_ary_shift(mrb2, ary2);]
f.puts %Q[ ]
f.puts %Q[ while (mrb_test(val2)) {]
diff --git a/test/init_mrbtest.c b/test/init_mrbtest.c
index 8d01624f0..717578dc8 100644
--- a/test/init_mrbtest.c
+++ b/test/init_mrbtest.c
@@ -2,6 +2,7 @@
#include "mruby.h"
#include "mruby/irep.h"
+extern const uint8_t mrbtest_assert_irep[];
extern const uint8_t mrbtest_irep[];
void mrbgemtest_init(mrb_state* mrb);
@@ -9,6 +10,7 @@ void mrbgemtest_init(mrb_state* mrb);
void
mrb_init_mrbtest(mrb_state *mrb)
{
+ mrb_load_irep(mrb, mrbtest_assert_irep);
mrb_load_irep(mrb, mrbtest_irep);
#ifndef DISABLE_GEMS
mrbgemtest_init(mrb);
diff --git a/test/mrbtest.rake b/test/mrbtest.rake
index 0507981d6..35495889e 100644
--- a/test/mrbtest.rake
+++ b/test/mrbtest.rake
@@ -8,10 +8,11 @@ MRuby.each_target do
mlib = clib.ext(exts.object)
mrbs = Dir.glob("#{current_dir}/t/*.rb")
init = "#{current_dir}/init_mrbtest.c"
- asslib = "#{current_dir}/assert.rb"
+ ass_c = "#{current_build_dir}/assert.c"
+ ass_lib = ass_c.ext(exts.object)
mrbtest_lib = libfile("#{current_build_dir}/mrbtest")
- file mrbtest_lib => [mlib, gems.map(&:test_objs), gems.map { |g| g.test_rbireps.ext(exts.object) }].flatten do |t|
+ file mrbtest_lib => [mlib, ass_lib, gems.map(&:test_objs), gems.map { |g| g.test_rbireps.ext(exts.object) }].flatten do |t|
archiver.run t.name, t.prerequisites
end
@@ -27,13 +28,21 @@ MRuby.each_target do
end
end
- file mlib => [clib]
- file clib => [mrbcfile, init, asslib] + mrbs do |t|
+ file ass_lib => ass_c
+ file ass_c => "#{current_dir}/assert.rb" do |t|
+ FileUtils.mkdir_p File.dirname t.name
+ open(t.name, 'w') do |f|
+ mrbc.run f, [t.prerequisites], 'mrbtest_assert_irep'
+ end
+ end
+
+ file mlib => clib
+ file clib => [mrbcfile, init] + mrbs do |t|
_pp "GEN", "*.rb", "#{clib.relative_path}"
FileUtils.mkdir_p File.dirname(clib)
open(clib, 'w') do |f|
f.puts IO.read(init)
- mrbc.run f, [asslib] + mrbs, 'mrbtest_irep'
+ mrbc.run f, mrbs, 'mrbtest_irep'
gems.each do |g|
f.puts %Q[void GENERATED_TMP_mrb_#{g.funcname}_gem_test(mrb_state *mrb);]
end
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
diff --git a/test/t/syntax.rb b/test/t/syntax.rb
index 13cd1198e..ee300c54d 100644
--- a/test/t/syntax.rb
+++ b/test/t/syntax.rb
@@ -1,3 +1,11 @@
+assert('__FILE__') do
+ assert_equal 'test/t/syntax.rb', __FILE__
+end
+
+assert('__LINE__') do
+ assert_equal 6, __LINE__
+end
+
assert('super', '11.3.4') do
assert_raise NoMethodError do
super