summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrbgems/default.gembox3
-rw-r--r--mrbgems/mruby-bin-mirb/tools/mirb/mirb.c7
-rw-r--r--mrbgems/mruby-compar-ext/mrbgem.rake5
-rw-r--r--mrbgems/mruby-compar-ext/mrblib/compar.rb31
-rw-r--r--mrbgems/mruby-compiler/core/parse.y6
-rw-r--r--mrbgems/mruby-enum-ext/mrblib/enum.rb16
-rw-r--r--mrbgems/mruby-enum-lazy/mrblib/lazy.rb15
-rw-r--r--mrbgems/mruby-kernel-ext/mrblib/kernel.rb13
-rw-r--r--mrbgems/mruby-string-ext/mrblib/string.rb15
-rw-r--r--mrbgems/mruby-string-ext/src/string.c120
-rw-r--r--mrbgems/mruby-string-ext/test/string.rb15
-rw-r--r--mrbgems/mruby-struct/src/struct.c39
-rw-r--r--mrbgems/mruby-symbol-ext/mrblib/symbol.rb15
-rw-r--r--src/numeric.c16
-rw-r--r--src/variable.c9
-rw-r--r--tasks/mrbgems.rake10
16 files changed, 303 insertions, 32 deletions
diff --git a/mrbgems/default.gembox b/mrbgems/default.gembox
index 64f05de10..65584681d 100644
--- a/mrbgems/default.gembox
+++ b/mrbgems/default.gembox
@@ -14,6 +14,9 @@ MRuby::GemBox.new do |conf|
# Use standard Struct class
conf.gem :core => "mruby-struct"
+ # Use Comparable module extension
+ conf.gem :core => "mruby-compar-ext"
+
# Use Enumerable module extension
conf.gem :core => "mruby-enum-ext"
diff --git a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
index fe311d830..891259a3f 100644
--- a/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
+++ b/mrbgems/mruby-bin-mirb/tools/mirb/mirb.c
@@ -544,6 +544,13 @@ done:
if (args.verbose) {
mrb_codedump_all(mrb, proc);
}
+ /* adjest stack length of toplevel environment */
+ if (mrb->c->cibase->env) {
+ struct REnv *e = mrb->c->cibase->env;
+ if (MRB_ENV_STACK_LEN(e) < proc->body.irep->nlocals) {
+ MRB_SET_ENV_STACK_LEN(e, proc->body.irep->nlocals);
+ }
+ }
/* pass a proc for evaluation */
/* evaluate the bytecode */
result = mrb_vm_run(mrb,
diff --git a/mrbgems/mruby-compar-ext/mrbgem.rake b/mrbgems/mruby-compar-ext/mrbgem.rake
new file mode 100644
index 000000000..dcf584339
--- /dev/null
+++ b/mrbgems/mruby-compar-ext/mrbgem.rake
@@ -0,0 +1,5 @@
+MRuby::Gem::Specification.new('mruby-compar-ext') do |spec|
+ spec.license = 'MIT'
+ spec.author = 'mruby developers'
+ spec.summary = 'Enumerable module extension'
+end
diff --git a/mrbgems/mruby-compar-ext/mrblib/compar.rb b/mrbgems/mruby-compar-ext/mrblib/compar.rb
new file mode 100644
index 000000000..d66f816ef
--- /dev/null
+++ b/mrbgems/mruby-compar-ext/mrblib/compar.rb
@@ -0,0 +1,31 @@
+module Comparable
+ ##
+ # Returns <i>min</i> if <i>obj</i> <code><=></code> <i>min</i> is less
+ # than zero, <i>max</i> if <i>obj</i> <code><=></code> <i>max</i> is
+ # greater than zero and <i>obj</i> otherwise.
+ #
+ # 12.clamp(0, 100) #=> 12
+ # 523.clamp(0, 100) #=> 100
+ # -3.123.clamp(0, 100) #=> 0
+ #
+ # 'd'.clamp('a', 'f') #=> 'd'
+ # 'z'.clamp('a', 'f') #=> 'f'
+ #
+ def clamp(min, max)
+ if (min <=> max) > 0
+ raise ArgumentError, "min argument must be smaller than max argument"
+ end
+ c = self <=> min
+ if c == 0
+ return self
+ elsif c < 0
+ return min
+ end
+ c = self <=> max
+ if c > 0
+ return max
+ else
+ return self
+ end
+ end
+end
diff --git a/mrbgems/mruby-compiler/core/parse.y b/mrbgems/mruby-compiler/core/parse.y
index 82e4c7bdd..bf9d3fe85 100644
--- a/mrbgems/mruby-compiler/core/parse.y
+++ b/mrbgems/mruby-compiler/core/parse.y
@@ -2577,7 +2577,7 @@ do_block : keyword_do_block
local_nest(p);
}
opt_block_param
- compstmt
+ bodystmt
keyword_end
{
$$ = new_block(p,$3,$4);
@@ -2667,7 +2667,7 @@ brace_block : '{'
$<num>$ = p->lineno;
}
opt_block_param
- compstmt keyword_end
+ bodystmt keyword_end
{
$$ = new_block(p,$3,$4);
SET_LINENO($$, $<num>2);
@@ -5723,7 +5723,7 @@ mrb_parser_set_filename(struct mrb_parser_state *p, const char *f)
new_table = (mrb_sym*)parser_palloc(p, sizeof(mrb_sym) * p->filename_table_length);
if (p->filename_table) {
- memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->filename_table_length);
+ memmove(new_table, p->filename_table, sizeof(mrb_sym) * p->current_filename_index);
}
p->filename_table = new_table;
p->filename_table[p->filename_table_length - 1] = sym;
diff --git a/mrbgems/mruby-enum-ext/mrblib/enum.rb b/mrbgems/mruby-enum-ext/mrblib/enum.rb
index 7741e515d..327b573d4 100644
--- a/mrbgems/mruby-enum-ext/mrblib/enum.rb
+++ b/mrbgems/mruby-enum-ext/mrblib/enum.rb
@@ -708,4 +708,20 @@ module Enumerable
def nil.to_h
{}
end
+
+ def uniq(&block)
+ hash = {}
+ if block
+ self.each do|*v|
+ v = v.__svalue
+ hash[block.call(v)] ||= v
+ end
+ else
+ self.each do|*v|
+ v = v.__svalue
+ hash[v] ||= v
+ end
+ end
+ hash.values
+ end
end
diff --git a/mrbgems/mruby-enum-lazy/mrblib/lazy.rb b/mrbgems/mruby-enum-lazy/mrblib/lazy.rb
index c98681edf..9227abe8a 100644
--- a/mrbgems/mruby-enum-lazy/mrblib/lazy.rb
+++ b/mrbgems/mruby-enum-lazy/mrblib/lazy.rb
@@ -158,6 +158,21 @@ class Enumerator
}
end
+ def uniq(&block)
+ hash = {}
+ Lazy.new(self){|yielder, val|
+ if block
+ v = block.call(val)
+ else
+ v = val
+ end
+ unless hash.include?(v)
+ yielder << val
+ hash[v] = val
+ end
+ }
+ end
+
alias force to_a
end
end
diff --git a/mrbgems/mruby-kernel-ext/mrblib/kernel.rb b/mrbgems/mruby-kernel-ext/mrblib/kernel.rb
new file mode 100644
index 000000000..25a4d4ed4
--- /dev/null
+++ b/mrbgems/mruby-kernel-ext/mrblib/kernel.rb
@@ -0,0 +1,13 @@
+module Kernel
+ # call-seq:
+ # obj.yield_self {|_obj|...} -> an_object
+ #
+ # Yields <i>obj</i> and returns the result.
+ #
+ # 'my string'.yield_self {|s|s.upcase} #=> "MY STRING"
+ #
+ def yield_self(&block)
+ return to_enum :yield_self unless block
+ block.call(self)
+ end
+end
diff --git a/mrbgems/mruby-string-ext/mrblib/string.rb b/mrbgems/mruby-string-ext/mrblib/string.rb
index c3a7eb380..cb36d9a48 100644
--- a/mrbgems/mruby-string-ext/mrblib/string.rb
+++ b/mrbgems/mruby-string-ext/mrblib/string.rb
@@ -144,7 +144,20 @@ class String
def casecmp(str)
self.downcase <=> str.to_str.downcase
rescue NoMethodError
- raise TypeError, "no implicit conversion of #{str.class} into String"
+ nil
+ end
+
+ ##
+ # call-seq:
+ # str.casecmp?(other) -> true, false, or nil
+ #
+ # Returns true if str and other_str are equal after case folding,
+ # false if they are not equal, and nil if other_str is not a string.
+
+ def casecmp?(str)
+ c = self.casecmp(str)
+ return nil if c.nil?
+ return c == 0
end
def partition(sep)
diff --git a/mrbgems/mruby-string-ext/src/string.c b/mrbgems/mruby-string-ext/src/string.c
index 63f181749..612fc5335 100644
--- a/mrbgems/mruby-string-ext/src/string.c
+++ b/mrbgems/mruby-string-ext/src/string.c
@@ -650,6 +650,118 @@ mrb_str_upto(mrb_state *mrb, mrb_value beg)
return beg;
}
+/*
+ * call-seq:
+ * str.delete_prefix!(prefix) -> self or nil
+ *
+ * Deletes leading <code>prefix</code> from <i>str</i>, returning
+ * <code>nil</code> if no change was made.
+ *
+ * "hello".delete_prefix!("hel") #=> "lo"
+ * "hello".delete_prefix!("llo") #=> nil
+ */
+static mrb_value
+mrb_str_del_prefix_bang(mrb_state *mrb, mrb_value self)
+{
+ mrb_int plen, slen;
+ char *ptr, *s;
+ struct RString *str = RSTRING(self);
+
+ mrb_get_args(mrb, "s", &ptr, &plen);
+ slen = RSTR_LEN(str);
+ if (plen > slen) return mrb_nil_value();
+ s = RSTR_PTR(str);
+ if (memcmp(s, ptr, plen) != 0) return mrb_nil_value();
+ if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
+ str->as.heap.ptr += plen;
+ }
+ else {
+ mrb_str_modify(mrb, str);
+ s = RSTR_PTR(str);
+ memmove(s, s+plen, slen-plen);
+ }
+ RSTR_SET_LEN(str, slen-plen);
+ return self;
+}
+
+/*
+ * call-seq:
+ * str.delete_prefix(prefix) -> new_str
+ *
+ * Returns a copy of <i>str</i> with leading <code>prefix</code> deleted.
+ *
+ * "hello".delete_prefix("hel") #=> "lo"
+ * "hello".delete_prefix("llo") #=> "hello"
+ */
+static mrb_value
+mrb_str_del_prefix(mrb_state *mrb, mrb_value self)
+{
+ mrb_int plen, slen;
+ char *ptr;
+
+ mrb_get_args(mrb, "s", &ptr, &plen);
+ slen = RSTRING_LEN(self);
+ if (plen > slen) return mrb_str_dup(mrb, self);
+ if (memcmp(RSTRING_PTR(self), ptr, plen) != 0)
+ return mrb_str_dup(mrb, self);
+ return mrb_str_substr(mrb, self, plen, slen-plen);
+}
+
+/*
+ * call-seq:
+ * str.delete_suffix!(suffix) -> self or nil
+ *
+ * Deletes trailing <code>suffix</code> from <i>str</i>, returning
+ * <code>nil</code> if no change was made.
+ *
+ * "hello".delete_suffix!("llo") #=> "he"
+ * "hello".delete_suffix!("hel") #=> nil
+ */
+static mrb_value
+mrb_str_del_suffix_bang(mrb_state *mrb, mrb_value self)
+{
+ mrb_int plen, slen;
+ char *ptr, *s;
+ struct RString *str = RSTRING(self);
+
+ mrb_get_args(mrb, "s", &ptr, &plen);
+ slen = RSTR_LEN(str);
+ if (plen > slen) return mrb_nil_value();
+ s = RSTR_PTR(str);
+ if (memcmp(s+slen-plen, ptr, plen) != 0) return mrb_nil_value();
+ if (!MRB_FROZEN_P(str) && (RSTR_SHARED_P(str) || RSTR_FSHARED_P(str))) {
+ /* no need to modify string */
+ }
+ else {
+ mrb_str_modify(mrb, str);
+ }
+ RSTR_SET_LEN(str, slen-plen);
+ return self;
+}
+
+/*
+ * call-seq:
+ * str.delete_suffix(suffix) -> new_str
+ *
+ * Returns a copy of <i>str</i> with leading <code>suffix</code> deleted.
+ *
+ * "hello".delete_suffix("hel") #=> "lo"
+ * "hello".delete_suffix("llo") #=> "hello"
+ */
+static mrb_value
+mrb_str_del_suffix(mrb_state *mrb, mrb_value self)
+{
+ mrb_int plen, slen;
+ char *ptr;
+
+ mrb_get_args(mrb, "s", &ptr, &plen);
+ slen = RSTRING_LEN(self);
+ if (plen > slen) return mrb_str_dup(mrb, self);
+ if (memcmp(RSTRING_PTR(self)+slen-plen, ptr, plen) != 0)
+ return mrb_str_dup(mrb, self);
+ return mrb_str_substr(mrb, self, 0, slen-plen);
+}
+
void
mrb_mruby_string_ext_gem_init(mrb_state* mrb)
{
@@ -673,8 +785,12 @@ mrb_mruby_string_ext_gem_init(mrb_state* mrb)
mrb_define_method(mrb, s, "succ!", mrb_str_succ_bang, MRB_ARGS_NONE());
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next"), mrb_intern_lit(mrb, "succ"));
mrb_alias_method(mrb, s, mrb_intern_lit(mrb, "next!"), mrb_intern_lit(mrb, "succ!"));
- mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
- mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
+ mrb_define_method(mrb, s, "ord", mrb_str_ord, MRB_ARGS_NONE());
+ mrb_define_method(mrb, s, "upto", mrb_str_upto, MRB_ARGS_ANY());
+ mrb_define_method(mrb, s, "delete_prefix!", mrb_str_del_prefix_bang, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, s, "delete_prefix", mrb_str_del_prefix, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, s, "delete_suffix!", mrb_str_del_suffix_bang, MRB_ARGS_REQ(1));
+ mrb_define_method(mrb, s, "delete_suffix", mrb_str_del_suffix, MRB_ARGS_REQ(1));
mrb_define_method(mrb, mrb->fixnum_class, "chr", mrb_fixnum_chr, MRB_ARGS_NONE());
}
diff --git a/mrbgems/mruby-string-ext/test/string.rb b/mrbgems/mruby-string-ext/test/string.rb
index 2a568c7d6..b6146fb90 100644
--- a/mrbgems/mruby-string-ext/test/string.rb
+++ b/mrbgems/mruby-string-ext/test/string.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
##
# String(Ext) Test
@@ -665,3 +666,17 @@ assert('String#each_codepoint(UTF-8)') do
end
assert_equal expect, cp
end if UTF8STRING
+
+assert('String#delete_prefix') do
+ assert_equal "llo", "hello".delete_prefix("he")
+ assert_equal "hello", "hello".delete_prefix("llo")
+ assert_equal "llo", "hello".delete_prefix!("he")
+ assert_nil "hello".delete_prefix!("llo")
+end
+
+assert('String#delete_suffix') do
+ assert_equal "he", "hello".delete_suffix("llo")
+ assert_equal "hello", "hello".delete_suffix("he")
+ assert_equal "he", "hello".delete_suffix!("llo")
+ assert_nil "hello".delete_suffix!("he")
+end
diff --git a/mrbgems/mruby-struct/src/struct.c b/mrbgems/mruby-struct/src/struct.c
index 67762a948..fed9e8105 100644
--- a/mrbgems/mruby-struct/src/struct.c
+++ b/mrbgems/mruby-struct/src/struct.c
@@ -12,6 +12,7 @@
#include <mruby/variable.h>
#include <mruby/hash.h>
#include <mruby/range.h>
+#include <mruby/proc.h>
#define RSTRUCT_LEN(st) RARRAY_LEN(st)
#define RSTRUCT_PTR(st) RARRAY_PTR(st)
@@ -113,12 +114,14 @@ mrb_struct_members(mrb_state *mrb, mrb_value obj)
return mrb_struct_s_members_m(mrb, mrb_obj_value(mrb_obj_class(mrb, obj)));
}
-static mrb_value struct_aref_sym(mrb_state *mrb, mrb_value obj, mrb_sym id);
-
static mrb_value
mrb_struct_ref(mrb_state *mrb, mrb_value obj)
{
- return struct_aref_sym(mrb, obj, mrb->c->ci->mid);
+ mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
+ mrb_value *ptr = RSTRUCT_PTR(obj);
+
+ if (!ptr) return mrb_nil_value();
+ return ptr[i];
}
static mrb_sym
@@ -140,24 +143,23 @@ mrb_id_attrset(mrb_state *mrb, mrb_sym id)
return mid;
}
-static mrb_value mrb_struct_aset_sym(mrb_state *mrb, mrb_value s, mrb_sym id, mrb_value val);
-
static mrb_value
mrb_struct_set_m(mrb_state *mrb, mrb_value obj)
{
+ mrb_int i = mrb_fixnum(mrb_proc_cfunc_env_get(mrb, 0));
+ mrb_value *ptr;
mrb_value val;
- const char *name;
- mrb_int slen;
- mrb_sym mid;
-
mrb_get_args(mrb, "o", &val);
-
- /* get base id */
- name = mrb_sym2name_len(mrb, mrb->c->ci->mid, &slen);
- mid = mrb_intern(mrb, name, slen-1); /* omit last "=" */
-
- return mrb_struct_aset_sym(mrb, obj, mid, val);
+ mrb_struct_modify(mrb, obj);
+ ptr = RSTRUCT_PTR(obj);
+ if (ptr == NULL || i >= RSTRUCT_LEN(obj)) {
+ mrb_ary_set(mrb, obj, i, val);
+ }
+ else {
+ ptr[i] = val;
+ }
+ return val;
}
static mrb_bool
@@ -187,8 +189,11 @@ make_struct_define_accessors(mrb_state *mrb, mrb_value members, struct RClass *c
const char *name = mrb_sym2name_len(mrb, id, NULL);
if (is_local_id(mrb, name) || is_const_id(mrb, name)) {
- mrb_define_method_id(mrb, c, id, mrb_struct_ref, MRB_ARGS_NONE());
- mrb_define_method_id(mrb, c, mrb_id_attrset(mrb, id), mrb_struct_set_m, MRB_ARGS_REQ(1));
+ mrb_value at = mrb_fixnum_value(i);
+ struct RProc *aref = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_ref, 1, &at);
+ struct RProc *aset = mrb_proc_new_cfunc_with_env(mrb, mrb_struct_set_m, 1, &at);
+ mrb_define_method_raw(mrb, c, id, aref);
+ mrb_define_method_raw(mrb, c, mrb_id_attrset(mrb, id), aset);
mrb_gc_arena_restore(mrb, ai);
}
}
diff --git a/mrbgems/mruby-symbol-ext/mrblib/symbol.rb b/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
index 1e3d24b80..28cce3156 100644
--- a/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
+++ b/mrbgems/mruby-symbol-ext/mrblib/symbol.rb
@@ -48,10 +48,23 @@ class Symbol
def casecmp(other)
return nil unless other.kind_of?(Symbol)
lhs = self.to_s; lhs.upcase!
- rhs = other.to_s; rhs.upcase!
+ rhs = other.to_s.upcase
lhs <=> rhs
end
+ ##
+ # call-seq:
+ # sym.casecmp?(other) -> true, false, or nil
+ #
+ # Returns true if sym and other_sym are equal after case folding,
+ # false if they are not equal, and nil if other_sym is not a string.
+
+ def casecmp?(sym)
+ c = self.casecmp(sym)
+ return nil if c.nil?
+ return c == 0
+ end
+
#
# call-seq:
# sym.empty? -> true or false
diff --git a/src/numeric.c b/src/numeric.c
index 8c7d448bd..b381bd206 100644
--- a/src/numeric.c
+++ b/src/numeric.c
@@ -1254,6 +1254,20 @@ num_cmp(mrb_state *mrb, mrb_value self)
}
}
+static mrb_value
+num_finite_p(mrb_state *mrb, mrb_value self)
+{
+ mrb_get_args(mrb, "");
+ return mrb_true_value();
+}
+
+static mrb_value
+num_infinite_p(mrb_state *mrb, mrb_value self)
+{
+ mrb_get_args(mrb, "");
+ return mrb_false_value();
+}
+
/* 15.2.9.3.1 */
/*
* call-seq:
@@ -1284,6 +1298,8 @@ mrb_init_numeric(mrb_state *mrb)
mrb_define_method(mrb, numeric, "/", num_div, MRB_ARGS_REQ(1)); /* 15.2.8.3.4 */
mrb_define_method(mrb, numeric, "quo", num_div, MRB_ARGS_REQ(1)); /* 15.2.7.4.5 (x) */
mrb_define_method(mrb, numeric, "<=>", num_cmp, MRB_ARGS_REQ(1)); /* 15.2.9.3.6 */
+ mrb_define_method(mrb, numeric, "finite?", num_finite_p, MRB_ARGS_NONE());
+ mrb_define_method(mrb, numeric, "infinite?",num_infinite_p, MRB_ARGS_NONE());
/* Integer Class */
integer = mrb_define_class(mrb, "Integer", numeric); /* 15.2.8 */
diff --git a/src/variable.c b/src/variable.c
index 50fc70682..4fbe82dd9 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -663,17 +663,18 @@ mod_const_check(mrb_state *mrb, mrb_value mod)
}
static mrb_value
-const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
+const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym, mrb_bool top)
{
struct RClass *c = base;
mrb_value v;
iv_tbl *t;
mrb_bool retry = FALSE;
mrb_value name;
+ struct RClass *oclass = mrb->object_class;
L_RETRY:
while (c) {
- if (c->iv) {
+ if (c->iv && (top || c != oclass || base == oclass)) {
t = c->iv;
if (iv_get(mrb, t, sym, &v))
return v;
@@ -693,7 +694,7 @@ MRB_API mrb_value
mrb_const_get(mrb_state *mrb, mrb_value mod, mrb_sym sym)
{
mod_const_check(mrb, mod);
- return const_get(mrb, mrb_class_ptr(mod), sym);
+ return const_get(mrb, mrb_class_ptr(mod), sym, FALSE);
}
mrb_value
@@ -729,7 +730,7 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
}
irep = irep->outer;
}
- return const_get(mrb, c, sym);
+ return const_get(mrb, c, sym, TRUE);
}
MRB_API void
diff --git a/tasks/mrbgems.rake b/tasks/mrbgems.rake
index 65368c303..1b964524c 100644
--- a/tasks/mrbgems.rake
+++ b/tasks/mrbgems.rake
@@ -34,11 +34,13 @@ MRuby.each_target do
f.puts %Q[#include <mruby.h>]
f.puts %Q[]
f.write gem_func_decls
+ unless gem_final_calls.empty?
f.puts %Q[]
- f.puts %Q[static void]
- f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
- f.write gem_final_calls
- f.puts %Q[}]
+ f.puts %Q[static void]
+ f.puts %Q[mrb_final_mrbgems(mrb_state *mrb) {]
+ f.write gem_final_calls
+ f.puts %Q[}]
+ end
f.puts %Q[]
f.puts %Q[void]
f.puts %Q[mrb_init_mrbgems(mrb_state *mrb) {]