Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/src/kernel.c
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-kernel-ext/src/kernel.c	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/src/kernel.c	(revision 331)
@@ -1,6 +1,64 @@
-#include "mruby.h"
-#include "mruby/error.h"
-#include "mruby/array.h"
-#include "mruby/hash.h"
+#include <mruby.h>
+#include <mruby/error.h>
+#include <mruby/array.h>
+#include <mruby/hash.h>
+#include <mruby/range.h>
+
+static mrb_value
+mrb_f_caller(mrb_state *mrb, mrb_value self)
+{
+  mrb_value bt, v, length;
+  mrb_int bt_len, argc, lev, n;
+
+  bt = mrb_get_backtrace(mrb);
+  bt_len = RARRAY_LEN(bt);
+  argc = mrb_get_args(mrb, "|oo", &v, &length);
+
+  switch (argc) {
+    case 0:
+      lev = 1;
+      n = bt_len - lev;
+      break;
+    case 1:
+      if (mrb_type(v) == MRB_TT_RANGE) {
+        mrb_int beg, len;
+        if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
+          lev = beg;
+          n = len;
+        }
+        else {
+          return mrb_nil_value();
+        }
+      }
+      else {
+        v = mrb_to_int(mrb, v);
+        lev = mrb_fixnum(v);
+        if (lev < 0) {
+          mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+        }
+        n = bt_len - lev;
+      }
+      break;
+    case 2:
+      lev = mrb_fixnum(mrb_to_int(mrb, v));
+      n = mrb_fixnum(mrb_to_int(mrb, length));
+      if (lev < 0) {
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
+      }
+      if (n < 0) {
+        mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length);
+      }
+      break;
+    default:
+      lev = n = 0;
+      break;
+  }
+
+  if (n == 0) {
+    return mrb_ary_new(mrb);
+  }
+
+  return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n));
+}
 
 /*
@@ -62,5 +120,5 @@
  *
  *  Returns <i>arg</i> converted to a float. Numeric types are converted
- *  directly, the rest are converted using <i>arg</i>.to_f. 
+ *  directly, the rest are converted using <i>arg</i>.to_f.
  *
  *     Float(1)           #=> 1.0
@@ -171,4 +229,5 @@
 
   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());
Index: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/test/kernel.rb
===================================================================
--- EcnlProtoTool/trunk/mruby-1.2.0/mrbgems/mruby-kernel-ext/test/kernel.rb	(revision 321)
+++ EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-kernel-ext/test/kernel.rb	(revision 331)
@@ -2,4 +2,35 @@
   assert_raise(RuntimeError) { fail }
   assert_raise(RuntimeError) { Kernel.fail }
+end
+
+assert('Kernel.caller, Kernel#caller') do
+  skip "backtrace isn't available" if caller(0).empty?
+
+  caller_lineno = __LINE__ + 3
+  c = Class.new do
+    def foo(*args)
+      caller(*args)
+    end
+
+    def bar(*args)
+      foo(*args)
+    end
+
+    def baz(*args)
+      bar(*args)
+    end
+  end
+  assert_equal "kernel.rb:#{caller_lineno}:in foo", c.new.baz(0)[0][-19..-1]
+  assert_equal "bar", c.new.baz[0][-3..-1]
+  assert_equal "foo", c.new.baz(0)[0][-3..-1]
+  assert_equal "bar", c.new.baz(1)[0][-3..-1]
+  assert_equal "baz", c.new.baz(2)[0][-3..-1]
+  assert_equal ["foo", "bar"], c.new.baz(0, 2).map { |i| i[-3..-1] }
+  assert_equal ["bar", "baz"], c.new.baz(1..2).map { |i| i[-3..-1] }
+  assert_nil c.new.baz(10..20)
+  assert_raise(ArgumentError) { c.new.baz(-1) }
+  assert_raise(ArgumentError) { c.new.baz(-1, 1) }
+  assert_raise(ArgumentError) { c.new.baz(1, -1) }
+  assert_raise(TypeError) { c.new.baz(nil) }
 end
 
@@ -23,4 +54,6 @@
   assert_equal(930, Integer("0930", 10))
   assert_equal(7, Integer("111", 2))
+  assert_equal(0, Integer("0"))
+  assert_equal(0, Integer("00000"))
   assert_raise(TypeError) { Integer(nil) }
 end
